@cdc/map 4.25.7 → 4.25.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.local.md +0 -0
- package/dist/cdcmap.js +22037 -22074
- package/examples/private/filter-map.json +909 -0
- package/examples/private/rsv-data.json +532 -0
- package/examples/private/test.json +222 -640
- package/index.html +34 -35
- package/package.json +3 -3
- package/src/CdcMap.tsx +7 -2
- package/src/CdcMapComponent.tsx +26 -8
- package/src/_stories/CdcMap.stories.tsx +8 -11
- package/src/_stories/_mock/multi-state.json +21389 -0
- package/src/components/CityList.tsx +4 -4
- package/src/components/DataTable.tsx +8 -4
- package/src/components/EditorPanel/components/EditorPanel.tsx +24 -38
- package/src/components/Legend/components/Legend.tsx +23 -35
- package/src/components/Modal.tsx +2 -8
- package/src/components/NavigationMenu.tsx +4 -1
- package/src/components/UsaMap/components/SingleState/SingleState.StateOutput.tsx +21 -15
- package/src/components/UsaMap/components/TerritoriesSection.tsx +2 -2
- package/src/components/UsaMap/components/UsaMap.County.tsx +6 -1
- package/src/components/UsaMap/components/UsaMap.SingleState.tsx +36 -24
- package/src/components/UsaMap/helpers/map.ts +16 -8
- package/src/components/WorldMap/WorldMap.tsx +17 -0
- package/src/context.ts +1 -0
- package/src/data/initial-state.js +8 -6
- package/src/data/supported-geos.js +185 -2
- package/src/helpers/addUIDs.ts +8 -8
- package/src/helpers/applyColorToLegend.ts +24 -43
- package/src/helpers/applyLegendToRow.ts +5 -7
- package/src/helpers/displayGeoName.ts +11 -6
- package/src/helpers/formatLegendLocation.ts +1 -3
- package/src/helpers/generateRuntimeLegend.ts +149 -333
- package/src/helpers/getStatesPicked.ts +11 -0
- package/src/helpers/handleMapAriaLabels.ts +2 -2
- package/src/hooks/useStateZoom.tsx +116 -86
- package/src/index.jsx +6 -1
- package/src/scss/main.scss +23 -12
- package/src/store/map.actions.ts +2 -2
- package/src/store/map.reducer.ts +4 -4
- package/src/types/MapConfig.ts +2 -3
- package/src/types/MapContext.ts +2 -1
- package/src/types/runtimeLegend.ts +1 -15
- package/src/_stories/_mock/floating-point.json +0 -427
- package/src/helpers/getStatePicked.ts +0 -8
|
@@ -3,7 +3,7 @@ export const handleMapAriaLabels = (state: MapConfig = '', testing = false) => {
|
|
|
3
3
|
try {
|
|
4
4
|
if (!state.general.geoType) throw Error('handleMapAriaLabels: no geoType found in state')
|
|
5
5
|
const {
|
|
6
|
-
general: { title, geoType,
|
|
6
|
+
general: { title, geoType, statesPicked }
|
|
7
7
|
} = state
|
|
8
8
|
let ariaLabel = ''
|
|
9
9
|
switch (geoType) {
|
|
@@ -17,7 +17,7 @@ export const handleMapAriaLabels = (state: MapConfig = '', testing = false) => {
|
|
|
17
17
|
ariaLabel += `United States county map`
|
|
18
18
|
break
|
|
19
19
|
case 'single-state':
|
|
20
|
-
ariaLabel += `${
|
|
20
|
+
ariaLabel += `${statesPicked.map(sp => sp.stateName).join(', ')} county map`
|
|
21
21
|
break
|
|
22
22
|
case 'us-region':
|
|
23
23
|
ariaLabel += `United States HHS Region map`
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { useContext, useEffect } from 'react'
|
|
1
|
+
import { useContext, useEffect, useMemo, useCallback } from 'react'
|
|
2
2
|
import ConfigContext, { MapDispatchContext } from '../context'
|
|
3
3
|
import { geoAlbersUsaTerritories } from 'd3-composite-projections'
|
|
4
4
|
import { MapContext } from '../types/MapContext'
|
|
5
5
|
import { geoPath, GeoPath } from 'd3-geo'
|
|
6
|
-
import {
|
|
6
|
+
import { getFilterControllingStatesPicked } from '../components/UsaMap/helpers/map'
|
|
7
7
|
import { supportedStatesFipsCodes } from '../data/supported-geos'
|
|
8
8
|
import { SVG_HEIGHT, SVG_WIDTH, SVG_PADDING } from '../helpers'
|
|
9
|
-
import
|
|
9
|
+
import { publishAnalyticsEvent } from '@cdc/core/helpers/metrics/helpers'
|
|
10
10
|
|
|
11
11
|
interface StateData {
|
|
12
12
|
geometry: { type: 'MultiPolygon'; coordinates: number[][][][] }
|
|
@@ -18,116 +18,146 @@ interface StateData {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
const useSetScaleAndTranslate = (topoData: { states: StateData[] }) => {
|
|
21
|
-
const { config, runtimeData, position } = useContext<MapContext>(ConfigContext)
|
|
22
|
-
const statePicked = getFilterControllingStatePicked(config, runtimeData)
|
|
21
|
+
const { config, runtimeData, position, interactionLabel } = useContext<MapContext>(ConfigContext)
|
|
23
22
|
const dispatch = useContext(MapDispatchContext)
|
|
24
23
|
|
|
24
|
+
// Get statesPicked with memoization
|
|
25
|
+
const statesPicked = useMemo(() => {
|
|
26
|
+
const result = getFilterControllingStatesPicked(config, runtimeData)
|
|
27
|
+
if (!result) return []
|
|
28
|
+
if (!Array.isArray(result)) return [result]
|
|
29
|
+
return result
|
|
30
|
+
}, [config.general.statesPicked, runtimeData])
|
|
31
|
+
|
|
32
|
+
// Memoize expensive computations
|
|
33
|
+
const statesData = useMemo(() => {
|
|
34
|
+
return statesPicked.map(state => ({
|
|
35
|
+
fipsCode: Object.keys(supportedStatesFipsCodes).find(key => supportedStatesFipsCodes[key] === state),
|
|
36
|
+
stateName: state
|
|
37
|
+
}))
|
|
38
|
+
}, [statesPicked])
|
|
39
|
+
|
|
40
|
+
// Memoize projection calculations
|
|
41
|
+
const projectionData = useMemo(() => {
|
|
42
|
+
const projection = geoAlbersUsaTerritories()
|
|
43
|
+
.translate([SVG_WIDTH / 2, SVG_HEIGHT / 2])
|
|
44
|
+
.scale(1)
|
|
45
|
+
|
|
46
|
+
const _statesPickedData = topoData?.states?.filter(s => statesPicked.includes(s.properties.name))
|
|
47
|
+
|
|
48
|
+
const combinedData = _statesPickedData?.length
|
|
49
|
+
? {
|
|
50
|
+
type: 'FeatureCollection',
|
|
51
|
+
features: _statesPickedData
|
|
52
|
+
}
|
|
53
|
+
: null
|
|
54
|
+
|
|
55
|
+
const newProjection = combinedData
|
|
56
|
+
? projection.fitExtent(
|
|
57
|
+
[
|
|
58
|
+
[SVG_PADDING, SVG_PADDING],
|
|
59
|
+
[SVG_WIDTH - SVG_PADDING, SVG_HEIGHT - SVG_PADDING]
|
|
60
|
+
],
|
|
61
|
+
combinedData
|
|
62
|
+
)
|
|
63
|
+
: projection
|
|
64
|
+
|
|
65
|
+
const path: GeoPath = geoPath().projection(projection)
|
|
66
|
+
const featureCenter = combinedData ? path.centroid(combinedData as any) : [0, 0]
|
|
67
|
+
const stateCenter = newProjection.invert(featureCenter)
|
|
68
|
+
|
|
69
|
+
return { projection, newProjection, stateCenter }
|
|
70
|
+
}, [topoData, statesPicked])
|
|
71
|
+
|
|
72
|
+
const setScaleAndTranslate = useCallback(
|
|
73
|
+
(zoomFunction: string = '') => {
|
|
74
|
+
const _prevPosition = config.mapPosition
|
|
75
|
+
let newZoom = _prevPosition.zoom
|
|
76
|
+
let newCoordinates = _prevPosition.coordinates
|
|
77
|
+
if (zoomFunction === 'zoomIn' && _prevPosition.zoom < 4) {
|
|
78
|
+
newZoom = _prevPosition.zoom * 1.5
|
|
79
|
+
newCoordinates =
|
|
80
|
+
_prevPosition.coordinates[0] !== 0 && _prevPosition.coordinates[1] !== 0
|
|
81
|
+
? _prevPosition.coordinates
|
|
82
|
+
: projectionData.stateCenter
|
|
83
|
+
publishAnalyticsEvent('map_zoomed_in', 'click', `${interactionLabel}|${newZoom}|${newCoordinates}`, 'map')
|
|
84
|
+
} else if (zoomFunction === 'zoomOut' && _prevPosition.zoom > 1) {
|
|
85
|
+
newZoom = _prevPosition.zoom / 1.5
|
|
86
|
+
newCoordinates =
|
|
87
|
+
_prevPosition.coordinates[0] !== 0 && _prevPosition.coordinates[1] !== 0
|
|
88
|
+
? _prevPosition.coordinates
|
|
89
|
+
: projectionData.stateCenter
|
|
90
|
+
} else if (zoomFunction === 'reset') {
|
|
91
|
+
newZoom = 1
|
|
92
|
+
newCoordinates = projectionData.stateCenter
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
dispatch({ type: 'SET_POSITION', payload: { coordinates: newCoordinates, zoom: newZoom } })
|
|
96
|
+
|
|
97
|
+
if (zoomFunction === 'reset') {
|
|
98
|
+
dispatch({ type: 'SET_TRANSLATE', payload: [0, 0] }) // needed for state switcher
|
|
99
|
+
dispatch({ type: 'SET_SCALE', payload: 1 }) // needed for state switcher
|
|
100
|
+
publishAnalyticsEvent('map_reset_zoom_level', 'click', interactionLabel, 'map')
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
[config.mapPosition, projectionData.stateCenter, interactionLabel, dispatch]
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
// Essential fix: Remove config from dependencies to prevent infinite loops
|
|
25
107
|
useEffect(() => {
|
|
26
|
-
|
|
27
|
-
const stateName = statePicked
|
|
28
|
-
const stateData = { fipsCode, stateName }
|
|
29
|
-
const newConfig = _.cloneDeep(config)
|
|
30
|
-
newConfig.general.statePicked = stateData
|
|
31
|
-
const stateToShow = topoData?.states?.find(s => s.properties.name === statePicked)
|
|
108
|
+
if (!topoData) return
|
|
32
109
|
|
|
33
110
|
dispatch({ type: 'SET_SCALE', payload: 1 })
|
|
34
111
|
dispatch({ type: 'SET_TRANSLATE', payload: [0, 0] })
|
|
35
|
-
dispatch({ type: '
|
|
36
|
-
|
|
37
|
-
}, [topoData])
|
|
112
|
+
dispatch({ type: 'SET_STATES_TO_SHOW', payload: statesPicked })
|
|
113
|
+
}, [topoData, statesPicked, dispatch])
|
|
38
114
|
|
|
39
115
|
useEffect(() => {
|
|
40
|
-
const
|
|
41
|
-
const stateName = statePicked
|
|
42
|
-
const stateData = { fipsCode, stateName }
|
|
43
|
-
const newConfig = _.cloneDeep(config)
|
|
44
|
-
newConfig.general.statePicked = stateData
|
|
45
|
-
dispatch({ type: 'SET_CONFIG', payload: newConfig })
|
|
46
|
-
setScaleAndTranslate('reset')
|
|
47
|
-
}, [statePicked])
|
|
48
|
-
|
|
49
|
-
// TODO: same as city list projection?
|
|
50
|
-
const projection = geoAlbersUsaTerritories()
|
|
51
|
-
.translate([SVG_WIDTH / 2, SVG_HEIGHT / 2])
|
|
52
|
-
.scale(1)
|
|
53
|
-
|
|
54
|
-
const _statePickedData = topoData?.states?.find(s => s.properties.name === statePicked)
|
|
55
|
-
const newProjection = projection.fitExtent(
|
|
56
|
-
[
|
|
57
|
-
[SVG_PADDING, SVG_PADDING],
|
|
58
|
-
[SVG_WIDTH - SVG_PADDING, SVG_HEIGHT - SVG_PADDING]
|
|
59
|
-
],
|
|
60
|
-
_statePickedData
|
|
61
|
-
)
|
|
116
|
+
const currentStatesPicked = config.general.statesPicked?.map(state => state.stateName) || []
|
|
62
117
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
y = y - SVG_HEIGHT / 2
|
|
118
|
+
const alreadySet =
|
|
119
|
+
currentStatesPicked.length === statesPicked.length &&
|
|
120
|
+
currentStatesPicked.every((s: string) => statesPicked.includes(s))
|
|
67
121
|
|
|
68
|
-
|
|
69
|
-
const featureCenter = path.centroid(_statePickedData)
|
|
70
|
-
const stateCenter = newProjection.invert(featureCenter)
|
|
122
|
+
if (alreadySet) return
|
|
71
123
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
124
|
+
const newConfig = { ...config }
|
|
125
|
+
newConfig.general = { ...config.general, statesPicked: statesData }
|
|
126
|
+
dispatch({ type: 'SET_CONFIG', payload: newConfig })
|
|
127
|
+
}, [statesPicked, statesData, dispatch])
|
|
76
128
|
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
let newCoordinates = _prevPosition.coordinates
|
|
81
|
-
if (zoomFunction === 'zoomIn' && _prevPosition.zoom < 4) {
|
|
82
|
-
newZoom = _prevPosition.zoom * 1.5
|
|
83
|
-
newCoordinates =
|
|
84
|
-
_prevPosition.coordinates[0] !== 0 && _prevPosition.coordinates[1] !== 0
|
|
85
|
-
? _prevPosition.coordinates
|
|
86
|
-
: stateCenter
|
|
87
|
-
} else if (zoomFunction === 'zoomOut' && _prevPosition.zoom > 1) {
|
|
88
|
-
newZoom = _prevPosition.zoom / 1.5
|
|
89
|
-
newCoordinates =
|
|
90
|
-
_prevPosition.coordinates[0] !== 0 && _prevPosition.coordinates[1] !== 0
|
|
91
|
-
? _prevPosition.coordinates
|
|
92
|
-
: stateCenter
|
|
93
|
-
} else if (zoomFunction === 'reset') {
|
|
94
|
-
newZoom = 1
|
|
95
|
-
newCoordinates = stateCenter
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
dispatch({ type: 'SET_POSITION', payload: { coordinates: newCoordinates, zoom: newZoom } })
|
|
99
|
-
|
|
100
|
-
if (zoomFunction === 'reset') {
|
|
101
|
-
dispatch({ type: 'SET_TRANSLATE', payload: [0, 0] }) // needed for state switcher
|
|
102
|
-
dispatch({ type: 'SET_SCALE', payload: 1 }) // needed for state switcher
|
|
103
|
-
}
|
|
104
|
-
}
|
|
129
|
+
const switchState = useCallback(() => {
|
|
130
|
+
dispatch({ type: 'SET_STATES_TO_SHOW', payload: statesPicked })
|
|
131
|
+
}, [statesPicked, setScaleAndTranslate, dispatch])
|
|
105
132
|
|
|
106
|
-
const handleZoomIn = () => {
|
|
133
|
+
const handleZoomIn = useCallback(() => {
|
|
107
134
|
setScaleAndTranslate('zoomIn')
|
|
108
|
-
}
|
|
135
|
+
}, [setScaleAndTranslate])
|
|
109
136
|
|
|
110
|
-
const handleZoomOut = () => {
|
|
137
|
+
const handleZoomOut = useCallback(() => {
|
|
111
138
|
setScaleAndTranslate('zoomOut')
|
|
112
|
-
}
|
|
139
|
+
}, [setScaleAndTranslate])
|
|
113
140
|
|
|
114
|
-
const handleMoveEnd =
|
|
115
|
-
|
|
116
|
-
|
|
141
|
+
const handleMoveEnd = useCallback(
|
|
142
|
+
position => {
|
|
143
|
+
dispatch({ type: 'SET_POSITION', payload: position })
|
|
144
|
+
},
|
|
145
|
+
[dispatch]
|
|
146
|
+
)
|
|
117
147
|
|
|
118
|
-
const handleReset = () => {
|
|
148
|
+
const handleReset = useCallback(() => {
|
|
119
149
|
setScaleAndTranslate('reset')
|
|
120
|
-
}
|
|
150
|
+
}, [setScaleAndTranslate])
|
|
121
151
|
|
|
122
152
|
return {
|
|
123
|
-
|
|
153
|
+
statesPicked,
|
|
124
154
|
setScaleAndTranslate,
|
|
125
155
|
switchState,
|
|
126
156
|
handleZoomIn,
|
|
127
157
|
handleZoomOut,
|
|
128
158
|
handleMoveEnd,
|
|
129
159
|
handleReset,
|
|
130
|
-
projection
|
|
160
|
+
projection: projectionData.projection
|
|
131
161
|
}
|
|
132
162
|
}
|
|
133
163
|
|
package/src/index.jsx
CHANGED
|
@@ -12,6 +12,11 @@ let domContainer = document.getElementsByClassName('react-container')[0]
|
|
|
12
12
|
|
|
13
13
|
ReactDOM.createRoot(domContainer).render(
|
|
14
14
|
<React.StrictMode>
|
|
15
|
-
<CdcMap
|
|
15
|
+
<CdcMap
|
|
16
|
+
isEditor={isEditor}
|
|
17
|
+
configUrl={domContainer.attributes['data-config'].value}
|
|
18
|
+
interactionLabel={domContainer.attributes['data-config'].value}
|
|
19
|
+
containerEl={domContainer}
|
|
20
|
+
/>
|
|
16
21
|
</React.StrictMode>
|
|
17
22
|
)
|
package/src/scss/main.scss
CHANGED
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
.cdc-map-outer-container {
|
|
16
16
|
position: relative;
|
|
17
17
|
display: flex; // Needed for the main content
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
.loading>div.la-ball-beat {
|
|
19
20
|
margin-top: 20%;
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -52,12 +53,14 @@
|
|
|
52
53
|
&.bottom {
|
|
53
54
|
flex-direction: column;
|
|
54
55
|
}
|
|
56
|
+
|
|
55
57
|
&.top {
|
|
56
58
|
flex-direction: column-reverse;
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
&.modal-background {
|
|
60
62
|
position: relative;
|
|
63
|
+
|
|
61
64
|
&::before {
|
|
62
65
|
content: ' ';
|
|
63
66
|
position: absolute;
|
|
@@ -65,6 +68,7 @@
|
|
|
65
68
|
bottom: 0;
|
|
66
69
|
z-index: 7;
|
|
67
70
|
}
|
|
71
|
+
|
|
68
72
|
.modal-content {
|
|
69
73
|
background: #fff;
|
|
70
74
|
position: absolute;
|
|
@@ -80,8 +84,10 @@
|
|
|
80
84
|
padding: 16px 40px;
|
|
81
85
|
min-width: 250px;
|
|
82
86
|
width: auto;
|
|
83
|
-
max-height: 90vh;
|
|
84
|
-
|
|
87
|
+
max-height: 90vh;
|
|
88
|
+
/* Constrain the modal's height to 90% of the viewport */
|
|
89
|
+
overflow-y: auto;
|
|
90
|
+
/* Enable vertical scrolling if content overflows */
|
|
85
91
|
font-size: 1rem;
|
|
86
92
|
line-height: 1.4em;
|
|
87
93
|
}
|
|
@@ -122,16 +128,15 @@
|
|
|
122
128
|
margin-left: 0.5em;
|
|
123
129
|
}
|
|
124
130
|
|
|
125
|
-
.modal-content.capitalize p {
|
|
126
|
-
text-transform: capitalize;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
131
|
/* Responsive adjustments for smaller screens */
|
|
130
132
|
@media (max-width: 1048px) {
|
|
131
133
|
.modal-content {
|
|
132
|
-
width: 90%;
|
|
133
|
-
|
|
134
|
-
|
|
134
|
+
width: 90%;
|
|
135
|
+
/* Adjust width to fit smaller screens */
|
|
136
|
+
top: 10%;
|
|
137
|
+
/* Offset from the top for better usability */
|
|
138
|
+
transform: translate(-50%, 0);
|
|
139
|
+
/* Remove vertical centering */
|
|
135
140
|
}
|
|
136
141
|
}
|
|
137
142
|
}
|
|
@@ -141,6 +146,7 @@
|
|
|
141
146
|
em {
|
|
142
147
|
font-style: italic;
|
|
143
148
|
}
|
|
149
|
+
|
|
144
150
|
strong {
|
|
145
151
|
font-weight: bold;
|
|
146
152
|
}
|
|
@@ -167,25 +173,30 @@
|
|
|
167
173
|
z-index: 6;
|
|
168
174
|
width: 100%;
|
|
169
175
|
border-top: var(--lightGray) 1px solid;
|
|
176
|
+
|
|
170
177
|
label {
|
|
171
178
|
flex-grow: 1;
|
|
172
|
-
|
|
179
|
+
|
|
180
|
+
>div.select-heading {
|
|
173
181
|
font-size: 1.1em;
|
|
174
182
|
font-weight: 600;
|
|
175
183
|
margin-bottom: 0.75em;
|
|
176
184
|
}
|
|
177
185
|
}
|
|
186
|
+
|
|
178
187
|
form {
|
|
179
188
|
max-width: 400px;
|
|
180
189
|
display: flex;
|
|
181
190
|
align-items: flex-end;
|
|
182
191
|
}
|
|
192
|
+
|
|
183
193
|
select {
|
|
184
194
|
font-size: 1.2em;
|
|
185
195
|
display: inline-block;
|
|
186
196
|
vertical-align: top;
|
|
187
197
|
width: 100%;
|
|
188
198
|
}
|
|
199
|
+
|
|
189
200
|
input {
|
|
190
201
|
color: #fff;
|
|
191
202
|
font-weight: 700;
|
|
@@ -202,4 +213,4 @@
|
|
|
202
213
|
[tabIndex]:focus {
|
|
203
214
|
outline-color: rgb(0, 95, 204);
|
|
204
215
|
}
|
|
205
|
-
}
|
|
216
|
+
}
|
package/src/store/map.actions.ts
CHANGED
|
@@ -20,7 +20,7 @@ type SET_RUNTIME_DATA = Action<'SET_RUNTIME_DATA', RuntimeData>
|
|
|
20
20
|
type SET_RUNTIME_FILTERS = Action<'SET_RUNTIME_FILTERS', VizFilter[]>
|
|
21
21
|
type SET_RUNTIME_LEGEND = Action<'SET_RUNTIME_LEGEND', GeneratedLegend | []>
|
|
22
22
|
type SET_SCALE = Action<'SET_SCALE', number>
|
|
23
|
-
type
|
|
23
|
+
type SET_STATES_TO_SHOW = Action<'SET_STATES_TO_SHOW', string[]>
|
|
24
24
|
type SET_TOPO_DATA = Action<'SET_TOPO_DATA', any>
|
|
25
25
|
type SET_TRANSLATE = Action<'SET_TRANSLATE', [number, number]>
|
|
26
26
|
|
|
@@ -39,7 +39,7 @@ export type MapActions =
|
|
|
39
39
|
| SET_RUNTIME_FILTERS
|
|
40
40
|
| SET_RUNTIME_LEGEND
|
|
41
41
|
| SET_SCALE
|
|
42
|
-
|
|
|
42
|
+
| SET_STATES_TO_SHOW
|
|
43
43
|
| SET_TOPO_DATA
|
|
44
44
|
| SET_TRANSLATE
|
|
45
45
|
|
package/src/store/map.reducer.ts
CHANGED
|
@@ -24,7 +24,7 @@ export const getInitialState = (configObj = {}): MapState => {
|
|
|
24
24
|
runtimeData: { init: true },
|
|
25
25
|
runtimeFilters: [],
|
|
26
26
|
runtimeLegend: [],
|
|
27
|
-
|
|
27
|
+
statesToShow: []
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -46,7 +46,7 @@ export type MapState = {
|
|
|
46
46
|
runtimeData: object
|
|
47
47
|
runtimeFilters: object[]
|
|
48
48
|
runtimeLegend: object[]
|
|
49
|
-
|
|
49
|
+
statesToShow: string[]
|
|
50
50
|
dataUrl: string
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -84,8 +84,8 @@ const reducer = (state: MapState, action: MapActions): MapState => {
|
|
|
84
84
|
return { ...state, runtimeFilters: action.payload }
|
|
85
85
|
case 'SET_RUNTIME_LEGEND':
|
|
86
86
|
return { ...state, runtimeLegend: action.payload }
|
|
87
|
-
case '
|
|
88
|
-
return { ...state,
|
|
87
|
+
case 'SET_STATES_TO_SHOW':
|
|
88
|
+
return { ...state, statesToShow: action.payload }
|
|
89
89
|
default:
|
|
90
90
|
return state
|
|
91
91
|
}
|
package/src/types/MapConfig.ts
CHANGED
|
@@ -127,10 +127,10 @@ export type MapConfig = Visualization & {
|
|
|
127
127
|
showDownloadPdfButton: boolean
|
|
128
128
|
showSidebar: boolean
|
|
129
129
|
showTitle: boolean
|
|
130
|
-
|
|
130
|
+
statesPicked: {
|
|
131
131
|
fipsCode: string
|
|
132
132
|
stateName: string
|
|
133
|
-
}
|
|
133
|
+
}[]
|
|
134
134
|
territoriesAlwaysShow: boolean
|
|
135
135
|
territoriesLabel: string
|
|
136
136
|
title: string
|
|
@@ -176,7 +176,6 @@ export type MapConfig = Visualization & {
|
|
|
176
176
|
tooltips: {
|
|
177
177
|
appearanceType: 'hover' | 'click'
|
|
178
178
|
linkLabel: string
|
|
179
|
-
capitalizeLabels: boolean
|
|
180
179
|
opacity: number
|
|
181
180
|
}
|
|
182
181
|
runtime: {
|
package/src/types/MapContext.ts
CHANGED
|
@@ -43,10 +43,11 @@ export type MapContext = {
|
|
|
43
43
|
setConfig: (newState: MapConfig) => MapConfig
|
|
44
44
|
config: MapConfig
|
|
45
45
|
viewport: ViewPort
|
|
46
|
-
|
|
46
|
+
statesToShow: string[]
|
|
47
47
|
scale: number
|
|
48
48
|
translate: [number, number]
|
|
49
49
|
topoData: object
|
|
50
50
|
runtimeData: Object[]
|
|
51
51
|
tooltipId: string
|
|
52
|
+
interactionLabel?: string
|
|
52
53
|
}
|
|
@@ -1,15 +1 @@
|
|
|
1
|
-
export type RuntimeLegend = {
|
|
2
|
-
items: {
|
|
3
|
-
disabled?: boolean
|
|
4
|
-
bin?: number
|
|
5
|
-
color?: string
|
|
6
|
-
special?: boolean
|
|
7
|
-
value?: any
|
|
8
|
-
label?: string
|
|
9
|
-
min?: number
|
|
10
|
-
max?: number
|
|
11
|
-
}[]
|
|
12
|
-
disabledAmt?: number
|
|
13
|
-
fromHash?: number
|
|
14
|
-
runtimeDataHash?: number
|
|
15
|
-
}
|
|
1
|
+
export type RuntimeLegend = { disabled; bin; color; special }[]
|