@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.
Files changed (49) hide show
  1. package/dist/495.js +3 -0
  2. package/dist/703.js +1 -0
  3. package/dist/856.js +3 -0
  4. package/dist/cdcmap.js +724 -120
  5. package/examples/bubble-us.json +362 -362
  6. package/examples/bubble-world.json +426 -426
  7. package/examples/{private/city-state2.json → city-state.json} +2 -2
  8. package/examples/example-city-state.json +202 -25
  9. package/package.json +3 -4
  10. package/src/CdcMap.js +142 -232
  11. package/src/components/BubbleList.js +2 -3
  12. package/src/components/CityList.js +1 -2
  13. package/src/components/DataTable.js +31 -3
  14. package/src/components/EditorPanel.js +73 -16
  15. package/src/components/Filters.js +114 -0
  16. package/src/components/Sidebar.js +0 -6
  17. package/src/components/UsaMap.js +4 -4
  18. package/src/context.js +5 -0
  19. package/src/data/initial-state.js +19 -15
  20. package/src/data/supported-geos.js +3201 -3175
  21. package/src/index.html +32 -28
  22. package/src/scss/datatable.scss +1 -2
  23. package/src/scss/filters.scss +42 -0
  24. package/src/scss/main.scss +4 -3
  25. package/examples/private/atsdr.json +0 -429
  26. package/examples/private/atsdr_new.json +0 -436
  27. package/examples/private/bubble.json +0 -283
  28. package/examples/private/city-state.json +0 -428
  29. package/examples/private/cty-issue.json +0 -42765
  30. package/examples/private/default-usa.json +0 -457
  31. package/examples/private/default-world-data.json +0 -1444
  32. package/examples/private/default.json +0 -968
  33. package/examples/private/diff.json +0 -226
  34. package/examples/private/filters.json +0 -1
  35. package/examples/private/legend-issue.json +0 -3271
  36. package/examples/private/map-issue.json +0 -166
  37. package/examples/private/map-rounding-error.json +0 -42756
  38. package/examples/private/map.csv +0 -60
  39. package/examples/private/mdx.json +0 -210
  40. package/examples/private/monkeypox.json +0 -376
  41. package/examples/private/regions.json +0 -52
  42. package/examples/private/valid-data-map.csv +0 -59
  43. package/examples/private/wcmsrd-13881-data.json +0 -2858
  44. package/examples/private/wcmsrd-13881.json +0 -5819
  45. package/examples/private/wcmsrd-14492-data.json +0 -292
  46. package/examples/private/wcmsrd-14492.json +0 -104
  47. package/examples/private/wcmsrd-test.json +0 -265
  48. package/examples/private/world.json +0 -1580
  49. 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 'toggleDownloadMediaButton':
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
- showDownloadMediaButton: !state.general.showDownloadMediaButton
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
- <label>
2438
- <span className='edit-label'>City Style</span>
2439
- <select
2440
- value={state.visual.cityStyle || false}
2441
- onChange={event => {
2442
- handleEditorChanges('handleCityStyle', event.target.value)
2443
- }}
2444
- >
2445
- <option value='circle'>Circle</option>
2446
- <option value='pin'>Pin</option>
2447
- </select>
2448
- </label>
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
  )
@@ -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
@@ -0,0 +1,5 @@
1
+ import { createContext } from 'react'
2
+
3
+ const ConfigContext = createContext({})
4
+
5
+ export default ConfigContext
@@ -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: "map",
25
+
26
+ type: 'map',
27
27
  color: 'pinkpurple',
28
28
  columns: {
29
29
  geo: {
30
30
  name: 'FIPS Codes',
31
31
  label: 'Location',
32
- tooltip: false,
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: "equalnumber",
56
+ type: 'equalnumber',
57
57
  numberOfItems: 3,
58
- position: "side",
59
- title: "Legend",
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
- { coordinates: [0, 30], zoom: 1 }
81
- };
84
+ mapPosition: { coordinates: [0, 30], zoom: 1 }
85
+ }