@cdc/map 4.23.7 → 4.23.9
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/dist/cdcmap.js +12945 -12847
- package/examples/default-geocode.json +142 -117
- package/examples/default-usa.json +983 -967
- package/index.html +10 -4
- package/package.json +3 -3
- package/src/CdcMap.jsx +19 -1
- package/src/components/BubbleList.jsx +4 -4
- package/src/components/CountyMap.jsx +47 -9
- package/src/components/EditorPanel.jsx +69 -27
- package/src/components/Sidebar.jsx +29 -20
- package/src/components/SingleStateMap.jsx +2 -15
- package/src/components/UsaMap.jsx +11 -4
- package/src/components/UsaRegionMap.jsx +2 -18
- package/src/components/WorldMap.jsx +33 -62
- package/src/data/initial-state.js +7 -1
- package/src/data/supported-geos.js +3 -0
- package/src/scss/map.scss +48 -8
- package/src/scss/sidebar.scss +119 -57
package/index.html
CHANGED
|
@@ -16,8 +16,11 @@
|
|
|
16
16
|
|
|
17
17
|
<body>
|
|
18
18
|
<!-- DEFAULT EXAMPLES -->
|
|
19
|
-
|
|
20
|
-
<div class="react-container react-container--maps" data-config="/examples/
|
|
19
|
+
|
|
20
|
+
<!-- <div class="react-container react-container--maps" data-config="/examples/private/wastewater.json"></div> -->
|
|
21
|
+
<!-- <div class="react-container react-container--maps" data-config="/examples/default-county.json"></div> -->
|
|
22
|
+
<div class="react-container react-container--maps" data-config="/examples/default-usa.json"></div>
|
|
23
|
+
<!-- <div class="react-container react-container--maps" data-config="https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/US-County-Level-Map.json"></div> -->
|
|
21
24
|
<!-- <div class="react-container react-container--maps" data-config="/examples/default-geocode.json"></div> -->
|
|
22
25
|
<!-- <div class="react-container react-container--maps" data-config="/examples/default-usa-regions.json"></div> -->
|
|
23
26
|
<!-- <div class="react-container react-container--maps" data-config="/examples/default-single-state.json"></div> -->
|
|
@@ -25,6 +28,9 @@
|
|
|
25
28
|
<!-- <div class="react-container react-container--maps" data-config="/examples/bubble-us.json"></div> -->
|
|
26
29
|
<!-- <div class="react-container react-container--maps" data-config="/examples/bubble-world.json"></div> -->
|
|
27
30
|
|
|
31
|
+
<!-- TESTS DATA TABLE SORT-->
|
|
32
|
+
<div class="react-container" data-config="/examples/private/wastewater.json"></div>
|
|
33
|
+
|
|
28
34
|
<!-- TP4 EXAMPLES -->
|
|
29
35
|
<!-- <div class="react-container react-container--maps" data-config="/examples/example-city-state.json"></div> -->
|
|
30
36
|
<!-- <div class="react-container react-container--maps" data-config="/examples/custom-map-layers.json"></div> -->
|
|
@@ -34,9 +40,9 @@
|
|
|
34
40
|
|
|
35
41
|
<!-- TP4 EXAMPLES -->
|
|
36
42
|
<!-- <div class="react-container react-container--maps" data-config="/examples/example-city-state.json"></div> -->
|
|
37
|
-
<div class="react-container react-container--maps" data-config="/examples/example-city-state-no-territories.json"></div>
|
|
43
|
+
<!-- <div class="react-container react-container--maps" data-config="/examples/example-city-state-no-territories.json"></div> -->
|
|
38
44
|
<!-- <div class="react-container react-container--maps" data-config="/examples/example-world-map.json"></div> -->
|
|
39
|
-
<!-- <div class="react-container react-container--maps" data-config="/examples/default-hex.json"></div>
|
|
45
|
+
<!-- <div class="react-container react-container--maps" data-config="/examples/default-hex.json"></div> -->
|
|
40
46
|
|
|
41
47
|
<!-- <div class="react-container" data-config="/examples/example-hex-map-with-filter.json"></div> -->
|
|
42
48
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdc/map",
|
|
3
|
-
"version": "4.23.
|
|
3
|
+
"version": "4.23.9",
|
|
4
4
|
"description": "React component for visualizing tabular data on a map of the United States or the world.",
|
|
5
5
|
"moduleName": "CdcMap",
|
|
6
6
|
"main": "dist/cdcmap",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"license": "Apache-2.0",
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@cdc/core": "^4.23.
|
|
27
|
+
"@cdc/core": "^4.23.9",
|
|
28
28
|
"@emotion/core": "^10.0.28",
|
|
29
29
|
"@emotion/react": "^11.1.5",
|
|
30
30
|
"@hello-pangea/dnd": "^16.2.0",
|
|
@@ -51,5 +51,5 @@
|
|
|
51
51
|
"react": "^18.2.0",
|
|
52
52
|
"react-dom": "^18.2.0"
|
|
53
53
|
},
|
|
54
|
-
"gitHead": "
|
|
54
|
+
"gitHead": "1a737cd5d226963d5ad9c6efb8d59e4a1311141c"
|
|
55
55
|
}
|
package/src/CdcMap.jsx
CHANGED
|
@@ -115,7 +115,23 @@ const getUniqueValues = (data, columnName) => {
|
|
|
115
115
|
return Object.keys(result)
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
const CdcMap = ({
|
|
118
|
+
const CdcMap = ({
|
|
119
|
+
className,
|
|
120
|
+
config,
|
|
121
|
+
navigationHandler: customNavigationHandler,
|
|
122
|
+
isDashboard = false,
|
|
123
|
+
isEditor = false,
|
|
124
|
+
isDebug = false,
|
|
125
|
+
configUrl,
|
|
126
|
+
logo = '',
|
|
127
|
+
// if you need to test the logo overlay, you can use this url below:
|
|
128
|
+
// 'https://upload.wikimedia.org/wikipedia/commons/4/45/US-CDC-Logo.png',
|
|
129
|
+
setConfig,
|
|
130
|
+
setSharedFilter,
|
|
131
|
+
setSharedFilterValue,
|
|
132
|
+
hostname = 'localhost:8080',
|
|
133
|
+
link
|
|
134
|
+
}) => {
|
|
119
135
|
const transform = new DataTransform()
|
|
120
136
|
const [state, setState] = useState({ ...initialState })
|
|
121
137
|
const [loading, setLoading] = useState(true)
|
|
@@ -1061,6 +1077,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
|
|
|
1061
1077
|
|
|
1062
1078
|
// Attempts to find the corresponding value
|
|
1063
1079
|
const displayGeoName = key => {
|
|
1080
|
+
if (!state.general.convertFipsCodes) return key
|
|
1064
1081
|
let value = key
|
|
1065
1082
|
// Map to first item in values array which is the preferred label
|
|
1066
1083
|
if (stateKeys.includes(value)) {
|
|
@@ -1638,6 +1655,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
|
|
|
1638
1655
|
|
|
1639
1656
|
{general.showSidebar && 'navigation' !== general.type && (
|
|
1640
1657
|
<Sidebar
|
|
1658
|
+
state={state}
|
|
1641
1659
|
viewport={currentViewport}
|
|
1642
1660
|
legend={state.legend}
|
|
1643
1661
|
runtimeLegend={runtimeLegend}
|
|
@@ -61,7 +61,7 @@ export const BubbleList = ({ data: dataImport, state, projection, applyLegendToR
|
|
|
61
61
|
}}
|
|
62
62
|
transform={transform}
|
|
63
63
|
style={{ transition: 'all .25s ease-in-out', cursor: 'pointer' }}
|
|
64
|
-
data-tooltip-id=
|
|
64
|
+
data-tooltip-id='tooltip'
|
|
65
65
|
data-tooltip-html={toolTip}
|
|
66
66
|
/>
|
|
67
67
|
|
|
@@ -88,7 +88,7 @@ export const BubbleList = ({ data: dataImport, state, projection, applyLegendToR
|
|
|
88
88
|
}}
|
|
89
89
|
transform={transform}
|
|
90
90
|
style={{ transition: 'all .25s ease-in-out', cursor: 'pointer' }}
|
|
91
|
-
data-tooltip-id=
|
|
91
|
+
data-tooltip-id='tooltip'
|
|
92
92
|
data-tooltip-html={toolTip}
|
|
93
93
|
/>
|
|
94
94
|
)}
|
|
@@ -155,7 +155,7 @@ export const BubbleList = ({ data: dataImport, state, projection, applyLegendToR
|
|
|
155
155
|
}}
|
|
156
156
|
transform={transform}
|
|
157
157
|
style={{ transition: 'all .25s ease-in-out', cursor: 'pointer' }}
|
|
158
|
-
data-tooltip-id=
|
|
158
|
+
data-tooltip-id='tooltip'
|
|
159
159
|
data-tooltip-html={toolTip}
|
|
160
160
|
/>
|
|
161
161
|
{state.visual.extraBubbleBorder && (
|
|
@@ -182,7 +182,7 @@ export const BubbleList = ({ data: dataImport, state, projection, applyLegendToR
|
|
|
182
182
|
}}
|
|
183
183
|
transform={transform}
|
|
184
184
|
style={{ transition: 'all .25s ease-in-out', cursor: 'pointer' }}
|
|
185
|
-
data-tooltip-id=
|
|
185
|
+
data-tooltip-id='tooltip'
|
|
186
186
|
data-tooltip-html={toolTip}
|
|
187
187
|
/>
|
|
188
188
|
)}
|
|
@@ -179,6 +179,7 @@ const CountyMap = props => {
|
|
|
179
179
|
break
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
|
+
|
|
182
183
|
// If a state is hovered and it is not an unfocused state, search only the counties within that state for the county hovered
|
|
183
184
|
if (hoveredState && (!focus.id || focus.id === hoveredState) && countyIndecies[hoveredState]) {
|
|
184
185
|
for (let i = countyIndecies[hoveredState][0]; i <= countyIndecies[hoveredState][1]; i++) {
|
|
@@ -230,11 +231,20 @@ const CountyMap = props => {
|
|
|
230
231
|
let hoveredGeoIndex
|
|
231
232
|
for (let i = 0; i < runtimeKeys.length; i++) {
|
|
232
233
|
const pixelCoords = projection([data[runtimeKeys[i]][state.columns.longitude.name], data[runtimeKeys[i]][state.columns.latitude.name]])
|
|
233
|
-
if (pixelCoords && Math.sqrt(Math.pow(pixelCoords[0] - x, 2) + Math.pow(pixelCoords[1] - y, 2)) < geoRadius) {
|
|
234
|
+
if (state.visual.cityStyle === 'circle' && pixelCoords && Math.sqrt(Math.pow(pixelCoords[0] - x, 2) + Math.pow(pixelCoords[1] - y, 2)) < geoRadius) {
|
|
234
235
|
hoveredGeo = data[runtimeKeys[i]]
|
|
235
236
|
hoveredGeoIndex = i
|
|
236
237
|
break
|
|
237
238
|
}
|
|
239
|
+
|
|
240
|
+
if (state.visual.cityStyle === 'pin' && pixelCoords) {
|
|
241
|
+
const distance = Math.hypot(pixelCoords[0] - x, pixelCoords[1] - y)
|
|
242
|
+
if (distance < 15) {
|
|
243
|
+
hoveredGeo = data[runtimeKeys[i]]
|
|
244
|
+
hoveredGeoIndex = i
|
|
245
|
+
break
|
|
246
|
+
}
|
|
247
|
+
}
|
|
238
248
|
}
|
|
239
249
|
|
|
240
250
|
if (hoveredGeo && applyLegendToRow(hoveredGeo)) {
|
|
@@ -271,7 +281,7 @@ const CountyMap = props => {
|
|
|
271
281
|
|
|
272
282
|
// Centers the projection on the paramter passed
|
|
273
283
|
if (focus.center) {
|
|
274
|
-
projection.scale(canvas.width * 2.5)
|
|
284
|
+
projection.scale(canvas.width * (focus.id === '72' ? 10 : 2.5))
|
|
275
285
|
let offset = projection(focus.center)
|
|
276
286
|
projection.translate([-offset[0] + canvas.width, -offset[1] + canvas.height])
|
|
277
287
|
}
|
|
@@ -303,7 +313,7 @@ const CountyMap = props => {
|
|
|
303
313
|
|
|
304
314
|
// Renders state/county
|
|
305
315
|
const legendValues = geoData !== undefined ? applyLegendToRow(geoData) : false
|
|
306
|
-
context.fillStyle = legendValues ? legendValues[0] : '#EEE'
|
|
316
|
+
context.fillStyle = legendValues && state.general.type !== 'us-geocode' ? legendValues[0] : '#EEE'
|
|
307
317
|
context.beginPath()
|
|
308
318
|
path(geo)
|
|
309
319
|
context.fill()
|
|
@@ -333,6 +343,33 @@ const CountyMap = props => {
|
|
|
333
343
|
})
|
|
334
344
|
}
|
|
335
345
|
|
|
346
|
+
const drawPin = (pin, ctx) => {
|
|
347
|
+
ctx.save()
|
|
348
|
+
ctx.translate(pin.x, pin.y)
|
|
349
|
+
ctx.beginPath()
|
|
350
|
+
ctx.moveTo(0, 0)
|
|
351
|
+
ctx.bezierCurveTo(2, -10, -20, -25, 0, -30)
|
|
352
|
+
ctx.bezierCurveTo(20, -25, -2, -10, 0, 0)
|
|
353
|
+
ctx.fillStyle = pin.color
|
|
354
|
+
ctx.fill()
|
|
355
|
+
ctx.strokeStyle = 'black'
|
|
356
|
+
ctx.lineWidth = 1.5
|
|
357
|
+
ctx.stroke()
|
|
358
|
+
ctx.beginPath()
|
|
359
|
+
ctx.arc(0, -21, 3, 0, Math.PI * 2)
|
|
360
|
+
ctx.closePath()
|
|
361
|
+
ctx.fill()
|
|
362
|
+
ctx.restore()
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const drawCircle = (circle, context) => {
|
|
366
|
+
context.fillStyle = circle.color
|
|
367
|
+
context.beginPath()
|
|
368
|
+
context.arc(circle.x, circle.y, circle.geoRadius, 0, 2 * Math.PI)
|
|
369
|
+
context.fill()
|
|
370
|
+
context.stroke()
|
|
371
|
+
}
|
|
372
|
+
|
|
336
373
|
if (state.general.type === 'us-geocode') {
|
|
337
374
|
context.strokeStyle = 'black'
|
|
338
375
|
const geoRadius = (state.visual.geoCodeCircleSize || 5) * (focus.id ? 2 : 1)
|
|
@@ -342,12 +379,13 @@ const CountyMap = props => {
|
|
|
342
379
|
|
|
343
380
|
if (pixelCoords) {
|
|
344
381
|
const legendValues = data[key] !== undefined ? applyLegendToRow(data[key]) : false
|
|
345
|
-
if (legendValues) {
|
|
346
|
-
|
|
347
|
-
context
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
382
|
+
if (legendValues && state.visual.cityStyle === 'circle') {
|
|
383
|
+
const circle = { x: pixelCoords[0], y: pixelCoords[1], color: legendValues[0], geoRadius }
|
|
384
|
+
drawCircle(circle, context)
|
|
385
|
+
}
|
|
386
|
+
if (legendValues && state.visual.cityStyle === 'pin') {
|
|
387
|
+
const pin = { x: pixelCoords[0], y: pixelCoords[1], color: legendValues[0] }
|
|
388
|
+
drawPin(pin, context)
|
|
351
389
|
}
|
|
352
390
|
}
|
|
353
391
|
})
|
|
@@ -622,7 +622,8 @@ const EditorPanel = props => {
|
|
|
622
622
|
legend: {
|
|
623
623
|
...state.legend,
|
|
624
624
|
singleColumn: !state.legend.singleColumn,
|
|
625
|
-
singleRow: false
|
|
625
|
+
singleRow: false,
|
|
626
|
+
verticalSorted: false
|
|
626
627
|
}
|
|
627
628
|
})
|
|
628
629
|
break
|
|
@@ -632,6 +633,18 @@ const EditorPanel = props => {
|
|
|
632
633
|
legend: {
|
|
633
634
|
...state.legend,
|
|
634
635
|
singleRow: !state.legend.singleRow,
|
|
636
|
+
singleColumn: false,
|
|
637
|
+
verticalSorted: false
|
|
638
|
+
}
|
|
639
|
+
})
|
|
640
|
+
break
|
|
641
|
+
case 'verticalSortedLegend':
|
|
642
|
+
setState({
|
|
643
|
+
...state,
|
|
644
|
+
legend: {
|
|
645
|
+
...state.legend,
|
|
646
|
+
verticalSorted: !state.legend.verticalSorted,
|
|
647
|
+
singleRow: false,
|
|
635
648
|
singleColumn: false
|
|
636
649
|
}
|
|
637
650
|
})
|
|
@@ -1119,20 +1132,20 @@ const EditorPanel = props => {
|
|
|
1119
1132
|
}, [runtimeLegend]) // eslint-disable-line
|
|
1120
1133
|
|
|
1121
1134
|
// if no state choice by default show alabama
|
|
1122
|
-
useEffect(() => {
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
}, []) // eslint-disable-line
|
|
1135
|
+
// useEffect(() => {
|
|
1136
|
+
// if (!state.general.statePicked) {
|
|
1137
|
+
// setState({
|
|
1138
|
+
// ...state,
|
|
1139
|
+
// general: {
|
|
1140
|
+
// ...general,
|
|
1141
|
+
// statePicked: {
|
|
1142
|
+
// fipsCode: '01',
|
|
1143
|
+
// stateName: 'Alabama'
|
|
1144
|
+
// }
|
|
1145
|
+
// }
|
|
1146
|
+
// })
|
|
1147
|
+
// }
|
|
1148
|
+
// }, []) // eslint-disable-line
|
|
1136
1149
|
|
|
1137
1150
|
const columnsOptions = [
|
|
1138
1151
|
<option value='' key={'Select Option'}>
|
|
@@ -1503,7 +1516,7 @@ const EditorPanel = props => {
|
|
|
1503
1516
|
<label>
|
|
1504
1517
|
<span className='edit-label column-heading'>State Selector</span>
|
|
1505
1518
|
<select
|
|
1506
|
-
value={state.general.
|
|
1519
|
+
value={state.general.statePicked.stateName}
|
|
1507
1520
|
onChange={event => {
|
|
1508
1521
|
handleEditorChanges('chooseState', event.target.value)
|
|
1509
1522
|
}}
|
|
@@ -1734,6 +1747,25 @@ const EditorPanel = props => {
|
|
|
1734
1747
|
{columnsOptions}
|
|
1735
1748
|
</select>
|
|
1736
1749
|
</label>
|
|
1750
|
+
{state.general.type === 'us-geocode' && (
|
|
1751
|
+
<label className='checkbox'>
|
|
1752
|
+
<input
|
|
1753
|
+
type='checkbox'
|
|
1754
|
+
checked={state.general.convertFipsCodes}
|
|
1755
|
+
onChange={event => {
|
|
1756
|
+
setState({
|
|
1757
|
+
...state,
|
|
1758
|
+
general: {
|
|
1759
|
+
...state.general,
|
|
1760
|
+
convertFipsCodes: event.target.checked
|
|
1761
|
+
}
|
|
1762
|
+
})
|
|
1763
|
+
}}
|
|
1764
|
+
/>
|
|
1765
|
+
<span className='edit-label'>Convert FIPS Codes to Geography Name</span>
|
|
1766
|
+
</label>
|
|
1767
|
+
)}
|
|
1768
|
+
|
|
1737
1769
|
<label className='checkbox'>
|
|
1738
1770
|
<input
|
|
1739
1771
|
type='checkbox'
|
|
@@ -2230,6 +2262,16 @@ const EditorPanel = props => {
|
|
|
2230
2262
|
<span className='edit-label'>Single Row Legend</span>
|
|
2231
2263
|
</label>
|
|
2232
2264
|
)}
|
|
2265
|
+
<label className='checkbox'>
|
|
2266
|
+
<input
|
|
2267
|
+
type='checkbox'
|
|
2268
|
+
checked={legend.verticalSorted}
|
|
2269
|
+
onChange={event => {
|
|
2270
|
+
handleEditorChanges('verticalSortedLegend', event.target.checked)
|
|
2271
|
+
}}
|
|
2272
|
+
/>
|
|
2273
|
+
<span className='edit-label'>Vertical sorted legend</span>
|
|
2274
|
+
</label>
|
|
2233
2275
|
{/* always show */}
|
|
2234
2276
|
{
|
|
2235
2277
|
<label className='checkbox'>
|
|
@@ -2585,16 +2627,16 @@ const EditorPanel = props => {
|
|
|
2585
2627
|
/>
|
|
2586
2628
|
<span className='edit-label'>Include Full Geo Name in CSV Download</span>
|
|
2587
2629
|
</label>
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2630
|
+
<label className='checkbox'>
|
|
2631
|
+
<input
|
|
2632
|
+
type='checkbox'
|
|
2633
|
+
checked={state.general.showDownloadImgButton}
|
|
2634
|
+
onChange={event => {
|
|
2635
|
+
handleEditorChanges('toggleDownloadImgButton', event.target.checked)
|
|
2636
|
+
}}
|
|
2637
|
+
/>
|
|
2638
|
+
<span className='edit-label'>Enable Image Download</span>
|
|
2639
|
+
</label>
|
|
2598
2640
|
{/* <label className='checkbox'>
|
|
2599
2641
|
<input
|
|
2600
2642
|
type='checkbox'
|
|
@@ -2780,7 +2822,7 @@ const EditorPanel = props => {
|
|
|
2780
2822
|
)
|
|
2781
2823
|
})}
|
|
2782
2824
|
</ul>
|
|
2783
|
-
{('us-geocode' === state.general.type || 'world-geocode' === state.general.type) && (
|
|
2825
|
+
{('us-geocode' === state.general.type || 'world-geocode' === state.general.type) && state.visual.cityStyle === 'circle' && (
|
|
2784
2826
|
<label>
|
|
2785
2827
|
Geocode Settings
|
|
2786
2828
|
<TextField type='number' value={state.visual.geoCodeCircleSize} section='visual' max='10' fieldName='geoCodeCircleSize' label='Geocode Circle Size' updateField={updateField} />
|
|
@@ -4,9 +4,10 @@ import parse from 'html-react-parser'
|
|
|
4
4
|
|
|
5
5
|
import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
|
|
6
6
|
import LegendCircle from '@cdc/core/components/LegendCircle'
|
|
7
|
+
import useDataVizClasses from '@cdc/core/helpers/useDataVizClasses'
|
|
7
8
|
|
|
8
9
|
const Sidebar = props => {
|
|
9
|
-
const { legend, runtimeFilters, columns, setAccessibleStatus, changeFilterActive, resetLegendToggles, runtimeLegend, setRuntimeLegend, prefix, suffix, viewport, displayDataAsText } = props
|
|
10
|
+
const { legend, runtimeFilters, columns, setAccessibleStatus, changeFilterActive, resetLegendToggles, runtimeLegend, setRuntimeLegend, prefix, suffix, viewport, displayDataAsText, state } = props
|
|
10
11
|
|
|
11
12
|
// Toggles if a legend is active and being applied to the map and data table.
|
|
12
13
|
const toggleLegendActive = (i, legendLabel) => {
|
|
@@ -57,9 +58,16 @@ const Sidebar = props => {
|
|
|
57
58
|
legendLabel = entry.label || entry.value
|
|
58
59
|
}
|
|
59
60
|
|
|
61
|
+
const handleListItemClass = () => {
|
|
62
|
+
let classes = ['legend-container__li']
|
|
63
|
+
if (disabled) classes.push('legend-container__li--disabled')
|
|
64
|
+
if (entry.hasOwnProperty('special')) classes.push('legend-container__li--special-class')
|
|
65
|
+
return classes
|
|
66
|
+
}
|
|
67
|
+
|
|
60
68
|
return (
|
|
61
69
|
<li
|
|
62
|
-
className={
|
|
70
|
+
className={handleListItemClass().join(' ')}
|
|
63
71
|
key={idx}
|
|
64
72
|
title={`Legend item ${legendLabel} - Click to disable`}
|
|
65
73
|
onClick={() => {
|
|
@@ -71,9 +79,13 @@ const Sidebar = props => {
|
|
|
71
79
|
)
|
|
72
80
|
})
|
|
73
81
|
|
|
74
|
-
const
|
|
75
|
-
|
|
82
|
+
const { legendClasses } = useDataVizClasses(state, viewport)
|
|
83
|
+
console.log('legendClasses', legendClasses)
|
|
76
84
|
|
|
85
|
+
const handleReset = e => {
|
|
86
|
+
e.preventDefault()
|
|
87
|
+
resetLegendToggles()
|
|
88
|
+
setAccessibleStatus('Legend has been reset, please reference the data table to see updated values.')
|
|
77
89
|
if (undefined === singleFilter.active) return null
|
|
78
90
|
|
|
79
91
|
singleFilter.values.forEach((filterOption, idx) => {
|
|
@@ -101,30 +113,23 @@ const Sidebar = props => {
|
|
|
101
113
|
</select>
|
|
102
114
|
</section>
|
|
103
115
|
)
|
|
104
|
-
}
|
|
116
|
+
}
|
|
105
117
|
|
|
106
|
-
const columnLogic = legend.position === 'side' && legend.singleColumn ? 'single-column' : legend.position === 'bottom' && legend.singleRow ? 'single-row' : ''
|
|
118
|
+
const columnLogic = legend.position === 'side' && legend.singleColumn ? 'single-column' : legend.position === 'bottom' && legend.singleRow ? 'single-row' : legend.verticalSorted && !legend.singleRow ? 'vertical-sorted' : ''
|
|
107
119
|
|
|
108
120
|
const classNames = [`${legend.position}`, `${columnLogic}`, `cdcdataviz-sr-focusable`, `${viewport}`]
|
|
109
121
|
|
|
110
122
|
return (
|
|
111
123
|
<ErrorBoundary component='Sidebar'>
|
|
112
|
-
<aside id='legend' className={
|
|
113
|
-
<section className=
|
|
124
|
+
<aside id='legend' className={legendClasses.aside.join(' ') || ''} role='region' aria-label='Legend' tabIndex='0'>
|
|
125
|
+
<section className={legendClasses.section.join(' ') || ''} aria-label='Map Legend'>
|
|
114
126
|
{runtimeLegend.disabledAmt > 0 && (
|
|
115
|
-
<button
|
|
116
|
-
onClick={e => {
|
|
117
|
-
e.preventDefault()
|
|
118
|
-
resetLegendToggles()
|
|
119
|
-
setAccessibleStatus('Legend has been reset, please reference the data table to see updated values.')
|
|
120
|
-
}}
|
|
121
|
-
className='clear btn'
|
|
122
|
-
>
|
|
127
|
+
<button onClick={handleReset} className={legendClasses.resetButton.join(' ') || ''}>
|
|
123
128
|
Clear
|
|
124
129
|
</button>
|
|
125
130
|
)}
|
|
126
|
-
{legend.title && <span className='
|
|
127
|
-
{legend.dynamicDescription === false && legend.description && <p>{parse(legend.description)}</p>}
|
|
131
|
+
{legend.title && <span className={legendClasses.title.join(' ') || ''}>{parse(legend.title)}</span>}
|
|
132
|
+
{legend.dynamicDescription === false && legend.description && <p className={legendClasses.description.join(' ') || ''}>{parse(legend.description)}</p>}
|
|
128
133
|
{legend.dynamicDescription === true &&
|
|
129
134
|
runtimeFilters.map((filter, idx) => {
|
|
130
135
|
const lookupStr = `${idx},${filter.values.indexOf(String(filter.active))}`
|
|
@@ -133,11 +138,15 @@ const Sidebar = props => {
|
|
|
133
138
|
const desc = legend.descriptions[lookupStr] || ''
|
|
134
139
|
|
|
135
140
|
if (desc.length > 0) {
|
|
136
|
-
return
|
|
141
|
+
return (
|
|
142
|
+
<p key={`dynamic-description-${lookupStr}`} className={`dynamic-legend-description-${lookupStr}`}>
|
|
143
|
+
{desc}
|
|
144
|
+
</p>
|
|
145
|
+
)
|
|
137
146
|
}
|
|
138
147
|
return true
|
|
139
148
|
})}
|
|
140
|
-
<ul className={
|
|
149
|
+
<ul className={legendClasses.ul.join(' ') || ''} aria-label='Legend items'>
|
|
141
150
|
{legendList}
|
|
142
151
|
</ul>
|
|
143
152
|
</section>
|
|
@@ -128,26 +128,13 @@ const SingleStateMap = props => {
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
return (
|
|
131
|
-
<g
|
|
132
|
-
key={`key--${county.id}`}
|
|
133
|
-
className={`county county--${geoDisplayName.split(' ').join('')} county--${geoData[state.columns.geo.name]}`}
|
|
134
|
-
css={styles}
|
|
135
|
-
onClick={() => geoClickHandler(geoDisplayName, geoData)}
|
|
136
|
-
data-tooltip-id="tooltip"
|
|
137
|
-
data-tooltip-html={toolTip}
|
|
138
|
-
>
|
|
131
|
+
<g key={`key--${county.id}`} className={`county county--${geoDisplayName.split(' ').join('')} county--${geoData[state.columns.geo.name]}`} css={styles} onClick={() => geoClickHandler(geoDisplayName, geoData)} data-tooltip-id='tooltip' data-tooltip-html={toolTip}>
|
|
139
132
|
<path tabIndex={-1} className={`county`} stroke={geoStrokeColor} d={countyPath} strokeWidth={0.75 / scale} />
|
|
140
133
|
</g>
|
|
141
134
|
)
|
|
142
135
|
} else {
|
|
143
136
|
return (
|
|
144
|
-
<g
|
|
145
|
-
key={`key--${county.id}`}
|
|
146
|
-
className={`county county--${geoDisplayName.split(' ').join('')}`}
|
|
147
|
-
style={{ fill: '#e6e6e6' }}
|
|
148
|
-
data-tooltip-id="tooltip"
|
|
149
|
-
data-tooltip-html={toolTip}
|
|
150
|
-
>
|
|
137
|
+
<g key={`key--${county.id}`} className={`county county--${geoDisplayName.split(' ').join('')}`} style={{ fill: '#e6e6e6' }} data-tooltip-id='tooltip' data-tooltip-html={toolTip}>
|
|
151
138
|
<path tabIndex={-1} className={`county`} stroke={geoStrokeColor} d={countyPath} strokeWidth={0.75 / scale} />
|
|
152
139
|
</g>
|
|
153
140
|
)
|
|
@@ -372,11 +372,18 @@ const UsaMap = props => {
|
|
|
372
372
|
</AlbersUsa>
|
|
373
373
|
)}
|
|
374
374
|
</svg>
|
|
375
|
+
|
|
375
376
|
{territories.length > 0 && (
|
|
376
|
-
|
|
377
|
-
<
|
|
378
|
-
|
|
379
|
-
|
|
377
|
+
<>
|
|
378
|
+
<div className='two-col'>
|
|
379
|
+
<div>
|
|
380
|
+
<span className='territories-label label'>{state.general.territoriesLabel}</span>
|
|
381
|
+
</div>
|
|
382
|
+
<div>
|
|
383
|
+
<span className={window.visualViewport.width < 500 ? 'territories--mobile' : 'territories'}>{territories}</span>
|
|
384
|
+
</div>
|
|
385
|
+
</div>
|
|
386
|
+
</>
|
|
380
387
|
)}
|
|
381
388
|
</ErrorBoundary>
|
|
382
389
|
)
|
|
@@ -103,17 +103,7 @@ const UsaRegionMap = props => {
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
return <Shape
|
|
107
|
-
key={label}
|
|
108
|
-
label={label}
|
|
109
|
-
css={styles}
|
|
110
|
-
text={styles.color}
|
|
111
|
-
stroke={geoStrokeColor}
|
|
112
|
-
strokeWidth={1.5}
|
|
113
|
-
onClick={() => geoClickHandler(territory, territoryData)}
|
|
114
|
-
data-tooltip-id="tooltip"
|
|
115
|
-
data-tooltip-html={toolTip}
|
|
116
|
-
/>
|
|
106
|
+
return <Shape key={label} label={label} css={styles} text={styles.color} stroke={geoStrokeColor} strokeWidth={1.5} onClick={() => geoClickHandler(territory, territoryData)} data-tooltip-id='tooltip' data-tooltip-html={toolTip} />
|
|
117
107
|
}
|
|
118
108
|
})
|
|
119
109
|
|
|
@@ -220,13 +210,7 @@ const UsaRegionMap = props => {
|
|
|
220
210
|
// const barFill = barPositive ? "#fff" : "#fff";
|
|
221
211
|
|
|
222
212
|
return (
|
|
223
|
-
<g key={key}
|
|
224
|
-
className='geo-group'
|
|
225
|
-
css={styles}
|
|
226
|
-
onClick={() => geoClickHandler(geoDisplayName, geoData)}
|
|
227
|
-
data-tooltip-id="tooltip"
|
|
228
|
-
data-tooltip-html={toolTip}
|
|
229
|
-
>
|
|
213
|
+
<g key={key} className='geo-group' css={styles} onClick={() => geoClickHandler(geoDisplayName, geoData)} data-tooltip-id='tooltip' data-tooltip-html={toolTip}>
|
|
230
214
|
<path tabIndex={-1} className='single-geo' stroke={geoStrokeColor} strokeWidth={1.3} d={path} />
|
|
231
215
|
<g id={`region-${index + 1}-label`}>
|
|
232
216
|
<circle fill='#fff' stroke='#999' cx={circleRadius} cy={circleRadius} r={circleRadius} />
|