Skip to content

Commit

Permalink
switching to zustand for state management; adding router component fo…
Browse files Browse the repository at this point in the history
…r tracking zoom and map center; moving summary stats component to charts directory; cleaning up imports in several components
  • Loading branch information
Jakidxav committed Oct 7, 2024
1 parent 8799786 commit ff415f2
Show file tree
Hide file tree
Showing 21 changed files with 701 additions and 671 deletions.
251 changes: 118 additions & 133 deletions components/map/index.js
Original file line number Diff line number Diff line change
@@ -1,162 +1,147 @@
import { useState, useRef } from 'react'
import { useThemeUI, Box } from 'theme-ui'
import { useThemedColormap } from '@carbonplan/colormaps'
import { Map as MapContainer, Raster, Fill, Line, RegionPicker } from '@carbonplan/maps'
import { Dimmer } from '@carbonplan/components'
import Ruler from './ruler'
import Router from './router'

const Map = ({ getters, setters, mobile }) => {
import useStore from '../store/index'

const Map = ({ mobile }) => {
const { theme } = useThemeUI()
const container = useRef(null)
const [map, setMap] = useState(null)
const [zoom, setZoom] = useState(1)
const zoom = useStore((state) => state.zoom)
const center = useStore((state) => state.center)
const glyphs = useStore((state) => state.glyphs)

const variable = useStore((state) => state.variable)
const band = useStore((state) => state.band)
const clim = useStore((state) => state.clim)
const colormapName = useStore((state) => state.colormapName)
const colormap = (variable == 'lethal_heat_3d') ? useThemedColormap(colormapName, { count: 8 }).slice(0,).reverse() :
(variable.startsWith('tavg')) ? useThemedColormap(colormapName).slice(0,).reverse() :
(variable.startsWith('tc')) ? useThemedColormap(colormapName).slice(0,).reverse() :
(variable == 'slr_3d') ? useThemedColormap(colormapName).slice(0,).reverse() :
useThemedColormap(colormapName)

const opacity = useStore((state) => state.opacity)
const display = useStore((state) => state.display)
const setRegionData = useStore((state) => state.setRegionData)

const showRegionPicker = useStore((state) => state.showRegionPicker)
const showLandOutline = useStore((state) => state.showLandOutline)
const showOceanMask = useStore((state) => state.showOceanMask)
const showLakes = useStore((state) => state.showLakes)
const showCountriesOutline = useStore((state) => state.showCountriesOutline)
const showStatesOutline = useStore((state) => state.showStatesOutline)

const { theme } = useThemeUI()
return (
<Box ref={container} sx={{ flexBasis: '100%', 'canvas.mapboxgl-canvas:focus': { outline: 'none', }, }} >
<MapContainer zoom={zoom} center={center} glyphs={glyphs} >
{showOceanMask && variable != 'slr_3d' && !variable.startsWith('tc') && (
<Fill
color={theme.rawColors.background}
source={'https://storage.googleapis.com/risk-maps/vector_layers/ocean'}
variable={'ocean'}
/>
)}

const [display, setDisplay] = useState(true)
const [opacity, setOpacity] = useState(1)
const [showOceanMask, setShowOceanMask] = useState(true)
const [showLakes, setShowLakes] = useState(false)
const [showLandOutline, setShowLandOutline] = useState(true)

const [showSearch, setShowSearch] = useState(false)

const {
variable,
band,
clim,
colormapName,
colormap,
regionData,
showRegionPicker,
showCountriesOutline,
showStatesOutline
} = getters

const {
setVariable,
setBand,
setClim,
setColormapName,
setRegionData,
setShowRegionPicker,
setShowCountriesOutline,
setShowStatesOutline
} = setters

const sx = {
label: {
fontFamily: 'mono',
letterSpacing: 'mono',
textTransform: 'uppercase',
fontSize: [1, 1, 1, 2],
mt: [3],
},
}

const glyphs = "http://fonts.openmaptiles.org/{fontstack}/{range}.pbf"
{variable == 'slr_3d' && (
<Fill
color={theme.rawColors.background}
source={'https://storage.googleapis.com/risk-maps/vector_layers/land'}
variable={'land'}
/>
)}

return (
<Box ref={container} sx={{flexBasis: '100%', 'canvas.mapboxgl-canvas:focus': {outline: 'none', },}} >
<MapContainer zoom={zoom} center={[-40, 40]} glyphs={glyphs} >
{showOceanMask && variable != 'slr_3d' && !variable.startsWith('tc') && (
<Fill
color={theme.rawColors.background}
source={'https://storage.googleapis.com/risk-maps/vector_layers/ocean'}
variable={'ocean'}
/>
)}

{variable == 'slr_3d' && (
<Fill
color={theme.rawColors.background}
source={'https://storage.googleapis.com/risk-maps/vector_layers/land'}
variable={'land'}
/>
)}

{showStatesOutline && variable != 'slr_3d' && (
<Line
color={theme.rawColors.primary}
source={'https://storage.googleapis.com/risk-maps/vector_layers/states'}
variable={'states'}
width={1}
/>
)}

{showCountriesOutline && variable != 'slr_3d' && (
<Line
color={theme.rawColors.primary}
source={'https://storage.googleapis.com/risk-maps/vector_layers/countries'}
variable={'countries'}
width={1}
/>
)}
{showStatesOutline && variable != 'slr_3d' && (
<Line
color={theme.rawColors.primary}
source={'https://storage.googleapis.com/risk-maps/vector_layers/states'}
variable={'states'}
width={1}
/>
)}

{showCountriesOutline && variable != 'slr_3d' && (
<Line
color={theme.rawColors.primary}
source={'https://storage.googleapis.com/risk-maps/vector_layers/countries'}
variable={'countries'}
width={1}
/>
)}

{showLakes && variable != 'slr_3d' && (
<Fill
color={theme.rawColors.background}
source={'https://storage.googleapis.com/risk-maps/vector_layers/lakes'}
variable={'lakes'}
/>
)}
<Fill
color={theme.rawColors.background}
source={'https://storage.googleapis.com/risk-maps/vector_layers/lakes'}
variable={'lakes'}
/>
)}

{showLakes && variable != 'slr_3d' && (
<Line
color={theme.rawColors.primary}
source={'https://storage.googleapis.com/risk-maps/vector_layers/lakes'}
variable={'lakes'}
width={1}
/>
)}

{showLandOutline && (
<Line
color={theme.rawColors.primary}
source={'https://storage.googleapis.com/risk-maps/vector_layers/land'}
variable={'land'}
width={1}
/>
)}

{showRegionPicker && (
<RegionPicker
color={theme.colors.primary}
backgroundColor={theme.colors.background}
fontFamily={theme.fonts.mono}
fontSize={'14px'}
minRadius={1}
maxRadius={1500}
/>
)}

<Raster
key={variable}
display={display}
opacity={opacity}
source={
`https://storage.googleapis.com/risk-maps/zarr_layers/${variable}.zarr`
}
variable={variable}
clim={clim}
colormap={colormap}
selector={{ band }}
mode={(variable == 'lethal_heat_3d') ? 'grid' : 'texture'} // 'texture', 'grid', 'dotgrid'
regionOptions={{ setData: setRegionData }}
<Line
color={theme.rawColors.primary}
source={'https://storage.googleapis.com/risk-maps/vector_layers/lakes'}
variable={'lakes'}
width={1}
/>
)}

{(variable.startsWith('tc')) && (
<Line
{showLandOutline && (
<Line
color={theme.rawColors.primary}
source={'https://storage.googleapis.com/risk-maps/vector_layers/land'}
variable={'land'}
width={1}
/>
)}

{showRegionPicker && (
<RegionPicker
color={theme.colors.primary}
backgroundColor={theme.colors.background}
fontFamily={theme.fonts.mono}
fontSize={'14px'}
minRadius={1}
maxRadius={1500}
/>
)}

<Raster
key={variable}
display={display}
opacity={opacity}
source={
`https://storage.googleapis.com/risk-maps/zarr_layers/${variable}.zarr`
}
variable={variable}
clim={clim}
colormap={colormap}
selector={{ band }}
mode={(variable == 'lethal_heat_3d') ? 'grid' : 'texture'} // 'texture', 'grid', 'dotgrid'
regionOptions={{ setData: setRegionData }}
/>

{(variable.startsWith('tc')) && (
<Line
color={theme.rawColors.secondary}
source={'https://storage.googleapis.com/risk-maps/vector_layers/tc_boundaries'}
variable={'tc_boundaries'}
width={1}
/>
)}
)}

{!mobile && (<Ruler />)}

{!mobile && (<Ruler />)}
<Router />

</MapContainer>

{!mobile && (<Dimmer
{!mobile && (<Dimmer
sx={{
display: ['initial', 'initial', 'initial', 'initial'],
position: 'absolute',
Expand Down
60 changes: 60 additions & 0 deletions components/map/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useEffect, useState } from 'react'
import { useRouter } from 'next/router'
import { useMapbox } from '@carbonplan/maps'

import useStore from '../store/index'

const Router = () => {
const { map } = useMapbox()
const router = useRouter()
const setZoom = useStore((state) => state.setZoom)
const setCenter = useStore((state) => state.setCenter)
const [zoomToBox, setZoomToBox] = useState(null)
const [zoomInitialized, setZoomInitialized] = useState(false)

{/*
* The following three methods are modified from their original source:
* https://github.com/carbonplan/forest-offsets-web/blob/ee51781bcbeb35172e29e051dc6387a1ec5b34cb/components/viewer.js#L129
*/}
useEffect(() => {
const { center, zoom } = router.query

if (map && center && zoom && !zoomInitialized) {
setZoomToBox({
center: center.split(',').map((d) => parseFloat(d)),
zoom: parseFloat(zoom),
})
}
}, [map, router])

useEffect(() => {
if (map && zoomToBox) {
const { center, zoom } = zoomToBox
map.easeTo({
center: center,
zoom: zoom,
duration: 0,
})
setZoomInitialized(true)
setZoomToBox(null)
}
}, [zoomToBox])

useEffect(() => {
map.on('moveend', () => {
const { pathname } = router

let zoom = map.getZoom().toFixed(2)
let center = [parseFloat(map.getCenter().lng.toFixed(2)), parseFloat(map.getCenter().lat.toFixed(2))]
setZoom(zoom)
setCenter(center)

let suffix = `?center=${center[0]},${center[1]}&zoom=${zoom}`
router.replace(pathname + suffix, null, { shallow: true })
})
}, [map])

return null
}

export default Router
26 changes: 12 additions & 14 deletions components/sidebar/about/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,22 @@ import { Dimmer } from '@carbonplan/components'
import InfoDemo from './info-demo'
import GlobeDemo from './globe-demo'

const sx = {
'container': {
mx: [3, 4, 5, 6],
pt: [1],
mt: 2,
pb: [2],
mb: [3],
fontSize: [2, 2, 2, 3],
// border: '1px solid',
// borderColor: 'blue',
width: 'fit-content',
},
}

const Content = () => {
const [showGraticule, setShowGraticule] = useState(false)
const toggleGraticule = () => setShowGraticule(!showGraticule)

const sx = {
'container': {
mx: [3, 4, 5, 6],
pt: [1],
mt: 2,
pb: [2],
mb: [3],
fontSize: [2, 2, 2, 3],
width: 'fit-content',
},
}

return (
<>
<Box sx={sx['container']} >
Expand Down
6 changes: 3 additions & 3 deletions components/sidebar/about/globe-demo.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { useState, useEffect } from 'react'
import { Minimap, Path, Graticule } from '@carbonplan/minimaps'
import { equirectangular, mercator } from '@carbonplan/minimaps/projections'
import { equirectangular } from '@carbonplan/minimaps/projections'
import { useThemeUI } from 'theme-ui'

const GlobeDemo = ({showGraticule}) => {
const GlobeDemo = ({ showGraticule }) => {
const { theme } = useThemeUI()
const [opacity, setOpacity] = useState(0.2)

useEffect(() => {
showGraticule == false ? setOpacity(0.0) : setOpacity(0.2)
}, [showGraticule])

return (
<>
<Minimap projection={equirectangular}>
Expand Down
Loading

0 comments on commit ff415f2

Please sign in to comment.