@cdc/map 4.22.11 → 4.23.1
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/495.js +3 -0
- package/dist/703.js +1 -0
- package/dist/856.js +3 -0
- package/dist/cdcmap.js +724 -120
- package/examples/bubble-us.json +362 -362
- package/examples/bubble-world.json +426 -426
- package/examples/{private/city-state2.json → city-state.json} +2 -2
- package/examples/example-city-state.json +202 -25
- package/package.json +3 -4
- package/src/CdcMap.js +142 -232
- package/src/components/BubbleList.js +2 -3
- package/src/components/CityList.js +1 -2
- package/src/components/DataTable.js +31 -3
- package/src/components/EditorPanel.js +73 -16
- package/src/components/Filters.js +114 -0
- package/src/components/Sidebar.js +0 -6
- package/src/components/UsaMap.js +4 -4
- package/src/context.js +5 -0
- package/src/data/initial-state.js +19 -15
- package/src/data/supported-geos.js +3201 -3175
- package/src/index.html +32 -28
- package/src/scss/datatable.scss +1 -2
- package/src/scss/filters.scss +42 -0
- package/src/scss/main.scss +4 -3
- package/examples/private/atsdr.json +0 -429
- package/examples/private/atsdr_new.json +0 -436
- package/examples/private/bubble.json +0 -283
- package/examples/private/city-state.json +0 -428
- package/examples/private/cty-issue.json +0 -42765
- package/examples/private/default-usa.json +0 -457
- package/examples/private/default-world-data.json +0 -1444
- package/examples/private/default.json +0 -968
- package/examples/private/diff.json +0 -226
- package/examples/private/filters.json +0 -1
- package/examples/private/legend-issue.json +0 -3271
- package/examples/private/map-issue.json +0 -166
- package/examples/private/map-rounding-error.json +0 -42756
- package/examples/private/map.csv +0 -60
- package/examples/private/mdx.json +0 -210
- package/examples/private/monkeypox.json +0 -376
- package/examples/private/regions.json +0 -52
- package/examples/private/valid-data-map.csv +0 -59
- package/examples/private/wcmsrd-13881-data.json +0 -2858
- package/examples/private/wcmsrd-13881.json +0 -5819
- package/examples/private/wcmsrd-14492-data.json +0 -292
- package/examples/private/wcmsrd-14492.json +0 -104
- package/examples/private/wcmsrd-test.json +0 -265
- package/examples/private/world.json +0 -1580
- package/examples/private/worldmap.json +0 -1490
|
@@ -168,6 +168,16 @@ const EditorPanel = props => {
|
|
|
168
168
|
})
|
|
169
169
|
break
|
|
170
170
|
|
|
171
|
+
case 'toggleDataUrl':
|
|
172
|
+
setState({
|
|
173
|
+
...state,
|
|
174
|
+
table: {
|
|
175
|
+
...state.table,
|
|
176
|
+
showDownloadUrl: value
|
|
177
|
+
}
|
|
178
|
+
})
|
|
179
|
+
break
|
|
180
|
+
|
|
171
181
|
case 'toggleExtraBubbleBorder':
|
|
172
182
|
setState({
|
|
173
183
|
...state,
|
|
@@ -367,12 +377,21 @@ const EditorPanel = props => {
|
|
|
367
377
|
}
|
|
368
378
|
})
|
|
369
379
|
break
|
|
370
|
-
case '
|
|
380
|
+
case 'toggleDownloadImgButton':
|
|
381
|
+
setState({
|
|
382
|
+
...state,
|
|
383
|
+
general: {
|
|
384
|
+
...state.general,
|
|
385
|
+
showDownloadImgButton: !state.general.showDownloadImgButton
|
|
386
|
+
}
|
|
387
|
+
})
|
|
388
|
+
break
|
|
389
|
+
case 'toggleDownloadPdfButton':
|
|
371
390
|
setState({
|
|
372
391
|
...state,
|
|
373
392
|
general: {
|
|
374
393
|
...state.general,
|
|
375
|
-
|
|
394
|
+
showDownloadPdfButton: !state.general.showDownloadPdfButton
|
|
376
395
|
}
|
|
377
396
|
})
|
|
378
397
|
break
|
|
@@ -2185,6 +2204,16 @@ const EditorPanel = props => {
|
|
|
2185
2204
|
/>
|
|
2186
2205
|
<span className='edit-label'>Map loads with data table expanded</span>
|
|
2187
2206
|
</label>
|
|
2207
|
+
<label className='checkbox'>
|
|
2208
|
+
<input
|
|
2209
|
+
type='checkbox'
|
|
2210
|
+
checked={state.table.showDownloadUrl}
|
|
2211
|
+
onChange={event => {
|
|
2212
|
+
handleEditorChanges('toggleDataUrl', event.target.checked)
|
|
2213
|
+
}}
|
|
2214
|
+
/>
|
|
2215
|
+
<span className='edit-label'>Enable Link to Dataset</span>
|
|
2216
|
+
</label>
|
|
2188
2217
|
<label className='checkbox'>
|
|
2189
2218
|
<input
|
|
2190
2219
|
type='checkbox'
|
|
@@ -2195,6 +2224,26 @@ const EditorPanel = props => {
|
|
|
2195
2224
|
/>
|
|
2196
2225
|
<span className='edit-label'>Enable Download CSV Button</span>
|
|
2197
2226
|
</label>
|
|
2227
|
+
{/* <label className='checkbox'>
|
|
2228
|
+
<input
|
|
2229
|
+
type='checkbox'
|
|
2230
|
+
checked={state.general.showDownloadImgButton}
|
|
2231
|
+
onChange={event => {
|
|
2232
|
+
handleEditorChanges('toggleDownloadImgButton', event.target.checked)
|
|
2233
|
+
}}
|
|
2234
|
+
/>
|
|
2235
|
+
<span className='edit-label'>Enable Image Download</span>
|
|
2236
|
+
</label> */}
|
|
2237
|
+
{/* <label className='checkbox'>
|
|
2238
|
+
<input
|
|
2239
|
+
type='checkbox'
|
|
2240
|
+
checked={state.general.showDownloadPdfButton}
|
|
2241
|
+
onChange={event => {
|
|
2242
|
+
handleEditorChanges('toggleDownloadPdfButton', event.target.checked)
|
|
2243
|
+
}}
|
|
2244
|
+
/>
|
|
2245
|
+
<span className='edit-label'>Enable Pdf Download</span>
|
|
2246
|
+
</label> */}
|
|
2198
2247
|
</AccordionItemPanel>
|
|
2199
2248
|
</AccordionItem>
|
|
2200
2249
|
)}
|
|
@@ -2391,6 +2440,13 @@ const EditorPanel = props => {
|
|
|
2391
2440
|
)
|
|
2392
2441
|
})}
|
|
2393
2442
|
</ul>
|
|
2443
|
+
{'us-geocode' === state.general.type && (
|
|
2444
|
+
<label>
|
|
2445
|
+
Geocode Settings
|
|
2446
|
+
<TextField type='number' value={state.visual.geoCodeCircleSize} section='visual' max='10' fieldName='geoCodeCircleSize' label='Geocode Circle Size' updateField={updateField} />
|
|
2447
|
+
</label>
|
|
2448
|
+
)}
|
|
2449
|
+
|
|
2394
2450
|
{state.general.type === 'bubble' && (
|
|
2395
2451
|
<>
|
|
2396
2452
|
<TextField type='number' value={state.visual.minBubbleSize} section='visual' fieldName='minBubbleSize' label='Minimum Bubble Size' updateField={updateField} />
|
|
@@ -2433,20 +2489,21 @@ const EditorPanel = props => {
|
|
|
2433
2489
|
<span className='edit-label'>Bubble Map has extra border</span>
|
|
2434
2490
|
</label>
|
|
2435
2491
|
)}
|
|
2436
|
-
{state.general.geoType === 'us'
|
|
2437
|
-
|
|
2438
|
-
<
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2492
|
+
{state.general.geoType === 'us' ||
|
|
2493
|
+
(state.general.geoType === 'us-county' && (
|
|
2494
|
+
<label>
|
|
2495
|
+
<span className='edit-label'>City Style</span>
|
|
2496
|
+
<select
|
|
2497
|
+
value={state.visual.cityStyle || false}
|
|
2498
|
+
onChange={event => {
|
|
2499
|
+
handleEditorChanges('handleCityStyle', event.target.value)
|
|
2500
|
+
}}
|
|
2501
|
+
>
|
|
2502
|
+
<option value='circle'>Circle</option>
|
|
2503
|
+
<option value='pin'>Pin</option>
|
|
2504
|
+
</select>
|
|
2505
|
+
</label>
|
|
2506
|
+
))}
|
|
2450
2507
|
</AccordionItemPanel>
|
|
2451
2508
|
</AccordionItem>
|
|
2452
2509
|
</Accordion>
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import React, { useState, useContext } from 'react'
|
|
2
|
+
import Context from './../context'
|
|
3
|
+
import Button from '@cdc/core/components/elements/Button'
|
|
4
|
+
|
|
5
|
+
// TODO: Combine Charts/Maps Filters.js files
|
|
6
|
+
const useFilters = () => {
|
|
7
|
+
const { state: config, setState: setConfig, runtimeFilters, setRuntimeFilters } = useContext(Context)
|
|
8
|
+
const [showApplyButton, setShowApplyButton] = useState(false)
|
|
9
|
+
|
|
10
|
+
const sortAsc = (a, b) => {
|
|
11
|
+
return a.toString().localeCompare(b.toString(), 'en', { numeric: true })
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const sortDesc = (a, b) => {
|
|
15
|
+
return b.toString().localeCompare(a.toString(), 'en', { numeric: true })
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const announceChange = text => {}
|
|
19
|
+
|
|
20
|
+
const changeFilterActive = (index, value) => {
|
|
21
|
+
let newFilters = runtimeFilters
|
|
22
|
+
newFilters[index].active = value
|
|
23
|
+
setRuntimeFilters(newFilters)
|
|
24
|
+
setShowApplyButton(true)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const handleApplyButton = () => {
|
|
28
|
+
setConfig({ ...config, filters: runtimeFilters })
|
|
29
|
+
setShowApplyButton(false)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const handleReset = () => {
|
|
33
|
+
let newFilters = runtimeFilters
|
|
34
|
+
|
|
35
|
+
// reset to first item in values array.
|
|
36
|
+
newFilters.map(filter => {
|
|
37
|
+
filter.active = filter.values[0]
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
setConfig({ ...config, filters: newFilters })
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return { announceChange, sortAsc, sortDesc, changeFilterActive, showApplyButton, handleReset, handleApplyButton }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const Filters = () => {
|
|
47
|
+
const { runtimeFilters, state: config } = useContext(Context)
|
|
48
|
+
const { handleApplyButton, changeFilterActive, announceChange, sortAsc, sortDesc, showApplyButton, handleReset } = useFilters()
|
|
49
|
+
|
|
50
|
+
const buttonText = 'Apply Filters'
|
|
51
|
+
const resetText = 'Reset All'
|
|
52
|
+
|
|
53
|
+
const { filters } = config
|
|
54
|
+
|
|
55
|
+
if (filters.length === 0) return false
|
|
56
|
+
|
|
57
|
+
const FilterList = ({ filters: runtimeFilters }) => {
|
|
58
|
+
if (runtimeFilters) {
|
|
59
|
+
return runtimeFilters.map((singleFilter, idx) => {
|
|
60
|
+
const values = []
|
|
61
|
+
|
|
62
|
+
if (undefined === singleFilter.active) return null
|
|
63
|
+
|
|
64
|
+
singleFilter.values.forEach((filterOption, idx) => {
|
|
65
|
+
values.push(
|
|
66
|
+
<option key={idx} value={filterOption}>
|
|
67
|
+
{filterOption}
|
|
68
|
+
</option>
|
|
69
|
+
)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<section className='filter-col single-filter' key={idx}>
|
|
74
|
+
{singleFilter.label.length > 0 && <label htmlFor={`filter-${idx}`}>{singleFilter.label}</label>}
|
|
75
|
+
<select
|
|
76
|
+
id={`filter-${idx}`}
|
|
77
|
+
className='filter-select'
|
|
78
|
+
aria-label='select filter'
|
|
79
|
+
value={singleFilter.active}
|
|
80
|
+
onChange={e => {
|
|
81
|
+
changeFilterActive(idx, e.target.value)
|
|
82
|
+
announceChange(`Filter ${singleFilter.label} value has been changed to ${e.target.value}, please reference the data table to see updated values.`)
|
|
83
|
+
}}
|
|
84
|
+
>
|
|
85
|
+
{values}
|
|
86
|
+
</select>
|
|
87
|
+
</section>
|
|
88
|
+
)
|
|
89
|
+
})
|
|
90
|
+
} else {
|
|
91
|
+
return null
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<section className={`filters-section`} style={{ display: 'block', width: '100%' }}>
|
|
97
|
+
<h3 className='filters-section__title'>Filters</h3>
|
|
98
|
+
<hr />
|
|
99
|
+
<div className='filters-section__wrapper' style={{ flexWrap: 'wrap', display: 'flex', gap: '7px 15px' }}>
|
|
100
|
+
<FilterList filters={runtimeFilters} />
|
|
101
|
+
<div className='filter-section__buttons' style={{ width: '100%' }}>
|
|
102
|
+
<Button onClick={handleApplyButton} disabled={!showApplyButton} style={{ marginRight: '10px' }}>
|
|
103
|
+
{buttonText}
|
|
104
|
+
</Button>
|
|
105
|
+
<a href='#!' role='button' onClick={handleReset}>
|
|
106
|
+
{resetText}
|
|
107
|
+
</a>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
</section>
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export default Filters
|
|
@@ -138,12 +138,6 @@ const Sidebar = props => {
|
|
|
138
138
|
{legendList}
|
|
139
139
|
</ul>
|
|
140
140
|
</section>
|
|
141
|
-
{filtersList.length > 0 && (
|
|
142
|
-
<section className='filters-section' aria-label='Map Filters'>
|
|
143
|
-
<span className='heading-3'>Filters</span>
|
|
144
|
-
<form>{filtersList}</form>
|
|
145
|
-
</section>
|
|
146
|
-
)}
|
|
147
141
|
</aside>
|
|
148
142
|
</ErrorBoundary>
|
|
149
143
|
)
|
package/src/components/UsaMap.js
CHANGED
|
@@ -15,7 +15,7 @@ import { supportedCities, supportedStates } from '../data/supported-geos'
|
|
|
15
15
|
const { features: unitedStates } = feature(topoJSON, topoJSON.objects.states)
|
|
16
16
|
const { features: unitedStatesHex } = feature(hexTopoJSON, hexTopoJSON.objects.states)
|
|
17
17
|
|
|
18
|
-
const Hexagon = ({ label, text, stroke, strokeWidth, ...props }) => {
|
|
18
|
+
const Hexagon = ({ label, text, stroke, strokeWidth, textColor, ...props }) => {
|
|
19
19
|
return (
|
|
20
20
|
<svg viewBox='0 0 45 51'>
|
|
21
21
|
<g {...props}>
|
|
@@ -28,7 +28,7 @@ const Hexagon = ({ label, text, stroke, strokeWidth, ...props }) => {
|
|
|
28
28
|
)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
const Rect = ({ label, text, stroke, strokeWidth, ...props }) => {
|
|
31
|
+
const Rect = ({ label, text, stroke, strokeWidth, textColor, ...props }) => {
|
|
32
32
|
return (
|
|
33
33
|
<svg viewBox='0 0 45 28'>
|
|
34
34
|
<g {...props} strokeLinejoin='round'>
|
|
@@ -37,7 +37,7 @@ const Rect = ({ label, text, stroke, strokeWidth, ...props }) => {
|
|
|
37
37
|
strokeWidth={strokeWidth}
|
|
38
38
|
d='M40,0.5 C41.2426407,0.5 42.3676407,1.00367966 43.1819805,1.81801948 C43.9963203,2.63235931 44.5,3.75735931 44.5,5 L44.5,5 L44.5,23 C44.5,24.2426407 43.9963203,25.3676407 43.1819805,26.1819805 C42.3676407,26.9963203 41.2426407,27.5 40,27.5 L40,27.5 L5,27.5 C3.75735931,27.5 2.63235931,26.9963203 1.81801948,26.1819805 C1.00367966,25.3676407 0.5,24.2426407 0.5,23 L0.5,23 L0.5,5 C0.5,3.75735931 1.00367966,2.63235931 1.81801948,1.81801948 C2.63235931,1.00367966 3.75735931,0.5 5,0.5 L5,0.5 Z'
|
|
39
39
|
/>
|
|
40
|
-
<text textAnchor='middle' dominantBaseline='middle' x='50%' y='54%' fill={text}>
|
|
40
|
+
<text textAnchor='middle' dominantBaseline='middle' x='50%' y='54%' fill={text} stroke={textColor}>
|
|
41
41
|
{label}
|
|
42
42
|
</text>
|
|
43
43
|
</g>
|
|
@@ -168,7 +168,7 @@ const UsaMap = props => {
|
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
return <Shape key={label} label={label} css={styles} text={styles.color} data-tip={toolTip} data-for='tooltip' strokeWidth={1.5} onClick={() => geoClickHandler(territory, territoryData)} />
|
|
171
|
+
return <Shape key={label} label={label} css={styles} text={styles.color} data-tip={toolTip} data-for='tooltip' strokeWidth={1.5} textColor={textColor} onClick={() => geoClickHandler(territory, territoryData)} />
|
|
172
172
|
}
|
|
173
173
|
})
|
|
174
174
|
|
package/src/context.js
ADDED
|
@@ -15,22 +15,22 @@ export default {
|
|
|
15
15
|
expandDataTable: true,
|
|
16
16
|
fullBorder: false,
|
|
17
17
|
type: 'data',
|
|
18
|
-
palette:{
|
|
19
|
-
isReversed:false
|
|
18
|
+
palette: {
|
|
19
|
+
isReversed: false
|
|
20
20
|
},
|
|
21
21
|
allowMapZoom: true,
|
|
22
22
|
hideGeoColumnInTooltip: false,
|
|
23
23
|
hidePrimaryColumnInTooltip: false
|
|
24
24
|
},
|
|
25
|
-
|
|
26
|
-
type:
|
|
25
|
+
|
|
26
|
+
type: 'map',
|
|
27
27
|
color: 'pinkpurple',
|
|
28
28
|
columns: {
|
|
29
29
|
geo: {
|
|
30
30
|
name: 'FIPS Codes',
|
|
31
31
|
label: 'Location',
|
|
32
|
-
|
|
33
|
-
dataTable: true
|
|
32
|
+
tooltip: false,
|
|
33
|
+
dataTable: true
|
|
34
34
|
},
|
|
35
35
|
primary: {
|
|
36
36
|
dataTable: true,
|
|
@@ -43,8 +43,8 @@ export default {
|
|
|
43
43
|
navigate: {
|
|
44
44
|
name: ''
|
|
45
45
|
},
|
|
46
|
-
latitude: { name:
|
|
47
|
-
longitude: { name:
|
|
46
|
+
latitude: { name: '' },
|
|
47
|
+
longitude: { name: '' }
|
|
48
48
|
},
|
|
49
49
|
legend: {
|
|
50
50
|
descriptions: {},
|
|
@@ -53,15 +53,18 @@ export default {
|
|
|
53
53
|
singleColumn: false,
|
|
54
54
|
singleRow: false,
|
|
55
55
|
dynamicDescription: false,
|
|
56
|
-
type:
|
|
56
|
+
type: 'equalnumber',
|
|
57
57
|
numberOfItems: 3,
|
|
58
|
-
position:
|
|
59
|
-
title:
|
|
58
|
+
position: 'side',
|
|
59
|
+
title: 'Legend'
|
|
60
60
|
},
|
|
61
61
|
filters: [],
|
|
62
62
|
dataTable: {
|
|
63
63
|
title: 'Data Table'
|
|
64
64
|
},
|
|
65
|
+
table: {
|
|
66
|
+
showDownloadUrl: false
|
|
67
|
+
},
|
|
65
68
|
tooltips: {
|
|
66
69
|
appearanceType: 'hover',
|
|
67
70
|
linkLabel: 'Learn More',
|
|
@@ -74,8 +77,9 @@ export default {
|
|
|
74
77
|
minBubbleSize: 1,
|
|
75
78
|
maxBubbleSize: 20,
|
|
76
79
|
extraBubbleBorder: false,
|
|
77
|
-
cityStyle: 'circle'
|
|
80
|
+
cityStyle: 'circle',
|
|
81
|
+
geoCodeCircleSize: 2,
|
|
82
|
+
showBubbleZeros: false
|
|
78
83
|
},
|
|
79
|
-
mapPosition:
|
|
80
|
-
|
|
81
|
-
};
|
|
84
|
+
mapPosition: { coordinates: [0, 30], zoom: 1 }
|
|
85
|
+
}
|