Skip to content

Commit ec5e3e5

Browse files
committed
Climate legends
1 parent 028543e commit ec5e3e5

5 files changed

Lines changed: 139 additions & 20 deletions

File tree

Eplant/views/WorldEFP/MapContainer.tsx

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import Legend from '../eFP/Viewer/legend'
1616
import ClimateOverlay from './ClimateOverlay'
1717
import MapMarker from './MapMarker'
1818
import MapTypeSelector from './MapTypeSelector'
19+
import OverlayLegend from './OverlayLegend'
1920
import OverlaySelector from './OverlaySelector'
2021
import { ColorMode, WorldEFPData, WorldEFPState } from './types'
2122

@@ -106,28 +107,38 @@ const MapContainer = ({ activeData, state, setState }: MapContainerProps) => {
106107
bottom: theme.spacing(4),
107108
zIndex: 10,
108109
display: 'flex',
109-
flexDirection: 'column',
110-
alignItems: 'flex-start',
110+
flexDirection: 'row',
111+
alignItems: 'flex-end',
111112
gap: theme.spacing(1),
112-
padding: theme.spacing(1),
113-
borderRadius: theme.spacing(1),
114-
backgroundColor: alpha(theme.palette.background.active, 0.4),
115-
boxShadow: '0 8px 24px rgba(0, 0, 0, 0.18)',
116-
border: `1px solid ${alpha(theme.palette.background.edge, 0.7)}`,
117-
backdropFilter: 'blur(8px)',
118-
WebkitBackdropFilter: 'blur(8px)',
119113
})}
120114
>
121-
<GeneDistributionChart
122-
data={activeData.efpData}
123-
containerStyle={{
124-
position: 'static',
125-
width: 'auto',
126-
height: 'auto',
127-
marginLeft: '-12px',
128-
}}
129-
/>
130-
<Legend colorMode={ColorMode.Absolute} data={activeData.efpData}></Legend>
115+
<Box
116+
sx={(theme) => ({
117+
display: 'flex',
118+
flexDirection: 'column',
119+
alignItems: 'flex-start',
120+
gap: theme.spacing(1),
121+
padding: theme.spacing(1),
122+
borderRadius: theme.spacing(1),
123+
backgroundColor: alpha(theme.palette.background.active, 0.4),
124+
boxShadow: '0 8px 24px rgba(0, 0, 0, 0.18)',
125+
border: `1px solid ${alpha(theme.palette.background.edge, 0.7)}`,
126+
backdropFilter: 'blur(8px)',
127+
WebkitBackdropFilter: 'blur(8px)',
128+
})}
129+
>
130+
<GeneDistributionChart
131+
data={activeData.efpData}
132+
containerStyle={{
133+
position: 'static',
134+
width: 'auto',
135+
height: 'auto',
136+
marginLeft: '-12px',
137+
}}
138+
/>
139+
<Legend colorMode={ColorMode.Absolute} data={activeData.efpData} />
140+
</Box>
141+
<OverlayLegend overlay={state.overlay} />
131142
</Box>
132143
</Map>
133144
)
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { Box, Typography } from '@mui/material'
2+
import { alpha } from '@mui/material/styles'
3+
4+
import { OverlayType } from './types'
5+
6+
interface OverlayLegendConfig {
7+
title: [string, string]
8+
imageSrc: string
9+
max: string
10+
min: string
11+
}
12+
13+
const LEGEND_CONFIG: Record<
14+
Exclude<OverlayType, OverlayType.None>,
15+
OverlayLegendConfig
16+
> = {
17+
[OverlayType.Precipitation]: {
18+
title: ['Annual', 'Precipitation'],
19+
imageSrc: '/img/climateLegend.png',
20+
max: '10577 mm',
21+
min: '13 mm',
22+
},
23+
[OverlayType.HistoricalMinTemp]: {
24+
title: ['Minimum', 'Temperature'],
25+
imageSrc: '/img/climateLegendFlip.png',
26+
max: '31.9 °C',
27+
min: '-27.8 °C',
28+
},
29+
[OverlayType.HistoricalMaxTemp]: {
30+
title: ['Maximum', 'Temperature'],
31+
imageSrc: '/img/climateLegendFlip.png',
32+
max: '31.9 °C',
33+
min: '-27.8 °C',
34+
},
35+
}
36+
37+
interface OverlayLegendProps {
38+
overlay: OverlayType
39+
}
40+
41+
const OverlayLegend = ({ overlay }: OverlayLegendProps) => {
42+
if (overlay === OverlayType.None) return null
43+
44+
const { title, imageSrc, max, min } = LEGEND_CONFIG[overlay]
45+
46+
return (
47+
<Box
48+
sx={(theme) => ({
49+
display: 'flex',
50+
flexDirection: 'column',
51+
alignItems: 'flex-start',
52+
gap: theme.spacing(0.5),
53+
padding: theme.spacing(1),
54+
borderRadius: theme.spacing(1),
55+
backgroundColor: alpha(theme.palette.background.active, 0.4),
56+
boxShadow: '0 8px 24px rgba(0, 0, 0, 0.18)',
57+
border: `1px solid ${alpha(theme.palette.background.edge, 0.7)}`,
58+
backdropFilter: 'blur(8px)',
59+
WebkitBackdropFilter: 'blur(8px)',
60+
})}
61+
>
62+
{/* Title */}
63+
<Box>
64+
{title.map((line) => (
65+
<Typography
66+
key={line}
67+
variant='caption'
68+
sx={(theme) => ({
69+
display: 'block',
70+
color: theme.palette.text.primary,
71+
fontWeight: 600,
72+
lineHeight: 1.2,
73+
})}
74+
>
75+
{line}
76+
</Typography>
77+
))}
78+
</Box>
79+
80+
{/* Scale image with max/min labels */}
81+
<Box sx={{ display: 'flex', flexDirection: 'row', gap: 0.75 }}>
82+
<Box
83+
component='img'
84+
src={imageSrc}
85+
sx={{ width: 16, height: 160, display: 'block' }}
86+
/>
87+
<Box
88+
sx={{
89+
display: 'flex',
90+
flexDirection: 'column',
91+
justifyContent: 'space-between',
92+
height: 160,
93+
}}
94+
>
95+
<Typography variant='caption' sx={{ lineHeight: 1 }}>
96+
{max}
97+
</Typography>
98+
<Typography variant='caption' sx={{ lineHeight: 1 }}>
99+
{min}
100+
</Typography>
101+
</Box>
102+
</Box>
103+
</Box>
104+
)
105+
}
106+
107+
export default OverlayLegend

Eplant/views/WorldEFP/OverlaySelector.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const OverlaySelector = ({ overlay, onSelect }: OverlaySelectorProps) => {
3131
return (
3232
<Box
3333
sx={(theme) => ({
34-
width: isOpen ? theme.spacing(15) : theme.spacing(5),
34+
width: isOpen ? theme.spacing(20) : theme.spacing(5),
3535
borderRadius: theme.spacing(1),
3636
backgroundColor: alpha(theme.palette.background.active, 0.7),
3737
boxShadow: '0 8px 24px rgba(0, 0, 0, 0.18)',
@@ -80,6 +80,7 @@ const OverlaySelector = ({ overlay, onSelect }: OverlaySelectorProps) => {
8080
flexDirection: 'column',
8181
gap: theme.spacing(0.5),
8282
padding: theme.spacing(0.5, 1, 1),
83+
minWidth: theme.spacing(20),
8384
})}
8485
>
8586
{OVERLAY_TYPES.map((type) => (

public/img/climateLegend.png

3.38 KB
Loading

public/img/climateLegendFlip.png

3.38 KB
Loading

0 commit comments

Comments
 (0)