Skip to content

Commit

Permalink
Merge pull request #296 from carbonplan/katamartin/climate-risk-compa…
Browse files Browse the repository at this point in the history
…rison

Add climate risk comparison article
  • Loading branch information
katamartin committed Aug 9, 2024
2 parents 34b51e9 + 36e0c37 commit 3bf5086
Show file tree
Hide file tree
Showing 12 changed files with 7,532 additions and 1 deletion.
6,316 changes: 6,316 additions & 0 deletions articles/climate-risk-comparison/components/article_data.json

Large diffs are not rendered by default.

350 changes: 350 additions & 0 deletions articles/climate-risk-comparison/components/locations.json

Large diffs are not rendered by default.

132 changes: 132 additions & 0 deletions articles/climate-risk-comparison/components/map-figure.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { useEffect, useState } from 'react'
import { Box, useThemeUI } from 'theme-ui'
import { geoPath, geoAlbers } from 'd3-geo'
import { json } from 'd3-fetch'
import { feature } from 'topojson-client'

import useVariableColormap from './use-variable-colormap'
import useData from './use-data'
import locations from './locations.json'

const REGIONS = {
ca: {
name: 'California',
strokeWidth: 1.5,
sx: { width: '100%' },
parallels: [34, 40.5],
rotate: [120, 0],
},
nystate: {
name: 'New York',
strokeWidth: 1.5,
sx: { width: '100%' },
parallels: [40.5, 44.5],
rotate: [74, 0],
},
nyc: {
name: 'New York',
strokeWidth: 1.3,
sx: { width: ['100%', '110%'] },
parallels: [40.5, 44.5],
rotate: [74, 0],
},
}

const MapFigure = ({ region, experiment, variable, provider }) => {
const { theme } = useThemeUI()
const [path, setPath] = useState(null)
const [points, setPoints] = useState(null)
const { [provider]: data } = useData({ region, experiment, variable })
const colormap = useVariableColormap({ region, provider })

useEffect(() => {
if (['ca', 'nystate'].includes(region)) {
json('https://cdn.jsdelivr.net/npm/us-atlas@3/states-10m.json').then(
(us) => {
const geo = feature(
us,
us.objects.states.geometries.find(
(g) => g.properties.name === REGIONS[region].name
)
)

const projection = geoAlbers()
.parallels(REGIONS[region].parallels)
.rotate(REGIONS[region].rotate)
.fitSize([960, 700], geo)
setPath(geoPath(projection)(geo))

setPoints(
Object.keys(locations[region]).reduce((accum, id) => {
accum[id] = geoPath(projection)({
type: 'Feature',
geometry: {
type: 'Point',
coordinates: locations[region][id],
},
})

return accum
}, {})
)
}
)
} else {
// nyc data from https://data.cityofnewyork.us/City-Government/Borough-Boundaries/tqmj-j8zm
json(
'https://carbonplan-maps.s3.us-west-2.amazonaws.com/basemaps/json/nyc.json'
).then((nyc) => {
const geo = feature(nyc, nyc.objects.nyc)

const projection = geoAlbers()
.parallels(REGIONS[region].parallels)
.rotate(REGIONS[region].rotate)
.fitSize([960, 700], geo)
setPath(geoPath(projection)(geo))

setPoints(
Object.keys(locations[region]).reduce((accum, id) => {
accum[id] = geoPath(projection)({
type: 'Feature',
geometry: {
type: 'Point',
coordinates: locations[region][id],
},
})

return accum
}, {})
)
})
}
}, [region])

const getColor = (id) => {
const ratio = data[id] / 5

const [r, g, b] = colormap[Math.round(ratio * (colormap.length - 1))]

return `rgb(${r},${g},${b})`
}

return (
<Box sx={{ width: '100%', position: 'relative' }}>
<Box as='svg' viewBox='0 0 960 700' sx={REGIONS[region].sx}>
{path && (
<path
fill={theme.colors.background}
stroke={theme.colors.primary}
strokeWidth={REGIONS[region].strokeWidth}
d={path}
/>
)}
{points &&
Object.keys(points)
.sort((a, b) => data[a] - data[b])
.map((id) => <path key={id} fill={getColor(id)} d={points[id]} />)}
</Box>
</Box>
)
}

export default MapFigure
95 changes: 95 additions & 0 deletions articles/climate-risk-comparison/components/region-summary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { Column, Filter, Row } from '@carbonplan/components'
import { useState } from 'react'
import { Box, Flex } from 'theme-ui'

import SlopeGraph from './slope-graph'
import MapFigure from './map-figure'
const sx = {
heading: {
fontFamily: 'heading',
letterSpacing: 'smallcaps',
textTransform: 'uppercase',
fontSize: [2, 2, 2, 3],
mb: 1,
},
}

const RegionSummary = ({ region }) => {
const [experiment, setExperiment] = useState('historical')
const [nystateVar, setNystateVar] = useState('riverine')
const [company, setCompany] = useState('xdi')

const variableInfo = region === 'nystate' ? { variable: nystateVar } : {}

return (
<Row columns={6}>
<Column start={1} width={6}>
<Flex
sx={{
gap: [3, 5, 7, 7],
mb: 4,
flexWrap: 'wrap',
}}
>
<Box>
<Box sx={sx.heading}>Company</Box>
<Filter
values={{
xdi: company === 'xdi',
jupiter: company === 'jupiter',
}}
setValues={(obj) => setCompany(obj.xdi ? 'xdi' : 'jupiter')}
sx={{ mr: -2 }}
/>
</Box>

<Box>
<Box sx={sx.heading}>Time period</Box>
<Filter
values={{
historical: experiment === 'historical',
future: experiment === 'future',
}}
setValues={(obj) =>
setExperiment(obj.historical ? 'historical' : 'future')
}
/>
</Box>

{region === 'nystate' && (
<Box>
<Box sx={sx.heading}>Hazard</Box>
<Filter
values={{
riverine: nystateVar === 'riverine',
'surface water': nystateVar === 'surface',
}}
setValues={(obj) =>
setNystateVar(obj['surface water'] ? 'surface' : 'riverine')
}
/>
</Box>
)}
</Flex>
</Column>
<Column start={[1]} width={[6, 3]}>
<MapFigure
region={region}
provider={company}
experiment={experiment}
{...variableInfo}
/>
</Column>
<Column start={[1, 4]} width={[6, 3]} sx={{ mt: [2, 0] }}>
<SlopeGraph
region={region}
experiment={experiment}
provider={company}
{...variableInfo}
/>
</Column>
</Row>
)
}

export default RegionSummary
Loading

0 comments on commit 3bf5086

Please sign in to comment.