@cdc/map 4.24.11 → 4.24.12

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 (42) hide show
  1. package/dist/cdcmap.js +28291 -28264
  2. package/examples/default-geocode.json +13 -4
  3. package/examples/default-usa-regions.json +267 -117
  4. package/examples/example-city-state.json +6 -3
  5. package/examples/pattern.json +861 -0
  6. package/examples/private/default-patterns.json +867 -0
  7. package/index.html +4 -5
  8. package/package.json +3 -3
  9. package/src/CdcMap.tsx +42 -48
  10. package/src/_stories/{CdcMapLegend.stories.tsx → CdcMap.Legend.Gradient.stories.tsx} +1 -20
  11. package/src/_stories/CdcMap.Legend.stories.tsx +40 -0
  12. package/src/_stories/CdcMap.Patterns.stories.tsx +29 -0
  13. package/src/_stories/CdcMap.stories.tsx +59 -0
  14. package/src/_stories/UsaMap.NoData.stories.tsx +19 -0
  15. package/src/_stories/_mock/custom-layer-map.json +1117 -0
  16. package/src/_stories/_mock/default-patterns.json +865 -0
  17. package/src/_stories/_mock/example-city-state.json +858 -0
  18. package/src/components/CityList.tsx +5 -2
  19. package/src/components/EditorPanel/components/EditorPanel.tsx +51 -21
  20. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +1 -1
  21. package/src/components/Legend/components/Legend.tsx +22 -6
  22. package/src/components/Legend/components/index.scss +16 -23
  23. package/src/components/UsaMap/components/SingleState/SingleState.CountyOutput.tsx +40 -6
  24. package/src/components/UsaMap/components/SingleState/SingleState.StateOutput.tsx +10 -2
  25. package/src/components/UsaMap/components/Territory/Territory.Hexagon.tsx +1 -1
  26. package/src/components/UsaMap/components/Territory/Territory.Rectangle.tsx +12 -11
  27. package/src/components/UsaMap/components/UsaMap.County.tsx +11 -13
  28. package/src/components/UsaMap/components/UsaMap.Region.tsx +59 -16
  29. package/src/components/UsaMap/components/UsaMap.SingleState.tsx +2 -1
  30. package/src/components/UsaMap/components/UsaMap.State.tsx +57 -59
  31. package/src/components/WorldMap/WorldMap.tsx +77 -16
  32. package/src/data/initial-state.js +2 -1
  33. package/src/helpers/applyColorToLegend.ts +80 -0
  34. package/src/helpers/colors.ts +23 -0
  35. package/src/hooks/useTooltip.ts +9 -6
  36. package/src/scss/filters.scss +0 -3
  37. package/src/scss/main.scss +0 -1
  38. package/src/scss/map.scss +11 -59
  39. package/src/types/MapConfig.ts +5 -0
  40. package/src/types/MapContext.ts +1 -0
  41. package/examples/default-patterns.json +0 -579
  42. package/src/scss/datatable.scss +0 -6
package/index.html CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  <body>
24
24
  <!-- DEFAULT EXAMPLES -->
25
- <!-- <div class="react-container" data-config="/examples/annotation/usa-map.json"></div> -->
25
+ <!-- <div class="react-container" data-config="/examples/private/default-patterns.json"></div>-->
26
26
  <!-- <div class="react-container" data-config="/examples/hex-colors.json"></div> -->
27
27
  <!-- <div class="react-container" data-config="/examples/private/map.json"></div> -->
28
28
  <!-- <div class="react-container" data-config="/examples/private/zika-issue.json"></div> -->
@@ -30,16 +30,15 @@
30
30
 
31
31
  <!-- <div class="react-container react-container--maps" data-config="/examples/private/tooltip-issue.json"></div> -->
32
32
  <!-- <div class="react-container react-container--maps" data-config="/examples/test.json"></div> -->
33
- <!-- <div class="react-container react-container--maps" data-config="/examples/default-patterns.json"></div> -->
34
33
  <!-- <div class="react-container react-container--maps" data-config="/examples/test.json"></div> -->
35
34
  <!-- <div class="react-container react-container--maps" data-config="/examples/private/map-text-wrap.json"></div> -->
36
35
  <!-- <div class="react-container react-container--maps" data-config="/examples/private/tooltip-issue.json"></div> -->
37
36
  <!-- <div class="react-container react-container--maps" data-config="/examples/test.json"></div> -->
38
- <!-- <div class="react-container react-container--maps" data-config="/examples/default-usa-regions.json"></div> -->
37
+ <div class="react-container react-container--maps" data-config="/examples/default-usa-regions.json"></div>
39
38
  <!-- <div class="react-container react-container--maps" data-config="/examples/default-usa.json"></div> -->
40
39
  <!-- <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> -->
41
- <div class="react-container react-container&#45;&#45;maps" data-config="/examples/default-geocode.json"></div>
42
- <div class="react-container react-container&#45;&#45;maps" data-config="/examples/default-single-state.json"></div>
40
+ <!-- <div class="react-container react-container&#45;&#45;maps" data-config="/examples/default-geocode.json"></div> -->
41
+ <!-- <div class="react-container react-container&#45;&#45;maps" data-config="/examples/default-single-state.json"></div> -->
43
42
  <!-- <div class="react-container react-container&#45;&#45;maps" data-config="/examples/bubble-us.json"></div> -->
44
43
  <!-- <div class="react-container react-container&#45;&#45;maps" data-config="/examples/bubble-world.json"></div> -->
45
44
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cdc/map",
3
- "version": "4.24.11",
3
+ "version": "4.24.12",
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",
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "license": "Apache-2.0",
27
27
  "dependencies": {
28
- "@cdc/core": "^4.24.11",
28
+ "@cdc/core": "^4.24.12",
29
29
  "@emotion/core": "^10.0.28",
30
30
  "@emotion/react": "^11.1.5",
31
31
  "@hello-pangea/dnd": "^16.2.0",
@@ -52,5 +52,5 @@
52
52
  "react": "^18.2.0",
53
53
  "react-dom": "^18.2.0"
54
54
  },
55
- "gitHead": "9ab5ee9b2b0ef7321a66a2104be6ce8899ec3808"
55
+ "gitHead": "347414f1da4b0e9bf2f22a7b59335deccf0b2d9c"
56
56
  }
package/src/CdcMap.tsx CHANGED
@@ -5,6 +5,7 @@ import Waiting from '@cdc/core/components/Waiting'
5
5
  import Annotation from './components/Annotation'
6
6
  import Error from './components/EditorPanel/components/Error'
7
7
  import _ from 'lodash'
8
+ import { applyColorToLegend } from './helpers/applyColorToLegend'
8
9
 
9
10
  // types
10
11
  import { type ViewportSize } from './types/MapConfig'
@@ -16,7 +17,6 @@ import ResizeObserver from 'resize-observer-polyfill'
16
17
 
17
18
  // Third party
18
19
  import { Tooltip as ReactTooltip } from 'react-tooltip'
19
- import chroma from 'chroma-js'
20
20
  import Papa from 'papaparse'
21
21
  import parse from 'html-react-parser'
22
22
  import 'react-tooltip/dist/react-tooltip.css'
@@ -77,6 +77,7 @@ import WorldMap from './components/WorldMap' // Future: Lazy
77
77
  import useTooltip from './hooks/useTooltip'
78
78
  import { isSolrCsv, isSolrJson } from '@cdc/core/helpers/isSolr'
79
79
  import SkipTo from '@cdc/core/components/elements/SkipTo'
80
+ import { getGeoFillColor } from './helpers/colors'
80
81
 
81
82
  // Data props
82
83
  const stateKeys = Object.keys(supportedStates)
@@ -274,6 +275,22 @@ const CdcMap = ({
274
275
  if (!uid && geoName) {
275
276
  uid = cityKeys.find(key => key === geoName.toUpperCase())
276
277
  }
278
+
279
+ if (state.general.displayAsHex) {
280
+ const upperCaseKey = geoName.toUpperCase()
281
+ const supportedDc = [
282
+ 'WASHINGTON D.C.',
283
+ 'DISTRICT OF COLUMBIA',
284
+ 'WASHINGTON DC',
285
+ 'DC',
286
+ 'WASHINGTON DC.',
287
+ 'D.C.',
288
+ 'D.C'
289
+ ]
290
+ if (supportedDc.includes(upperCaseKey)) {
291
+ uid = 'US-DC'
292
+ }
293
+ }
277
294
  }
278
295
 
279
296
  if ('us-region' === obj.general.geoType && obj.columns.geo.name) {
@@ -374,45 +391,6 @@ const CdcMap = ({
374
391
  10: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
375
392
  }
376
393
 
377
- const applyColorToLegend = legendIdx => {
378
- // Default to "bluegreen" color scheme if the passed color isn't valid
379
- let mapColorPalette = obj.customColors || colorPalettes[obj.color] || colorPalettes['bluegreen']
380
-
381
- // Handle Region Maps need for a 10th color
382
- if (general.geoType === 'us-region' && mapColorPalette.length < 10 && mapColorPalette.length > 8) {
383
- if (!general.palette.isReversed) {
384
- mapColorPalette.push(chroma(mapColorPalette[8]).darken(0.75).hex())
385
- } else {
386
- mapColorPalette.unshift(chroma(mapColorPalette[0]).darken(0.75).hex())
387
- }
388
- }
389
-
390
- let colorIdx = legendIdx - specialClasses
391
-
392
- // Special Classes (No Data)
393
- if (result[legendIdx].special) {
394
- const specialClassColors = chroma.scale(['#D4D4D4', '#939393']).colors(specialClasses)
395
-
396
- return specialClassColors[legendIdx]
397
- }
398
-
399
- if (obj.color.includes('qualitative')) return mapColorPalette[colorIdx]
400
-
401
- let amt = Math.max(result.length - specialClasses, 1)
402
- let distributionArray = colorDistributions[amt]
403
-
404
- let specificColor
405
- if (distributionArray) {
406
- specificColor = distributionArray[colorIdx]
407
- } else if (mapColorPalette[colorIdx]) {
408
- specificColor = colorIdx
409
- } else {
410
- specificColor = mapColorPalette.length - 1
411
- }
412
-
413
- return mapColorPalette[specificColor]
414
- }
415
-
416
394
  let specialClasses = 0
417
395
  let specialClassesHash = {}
418
396
 
@@ -433,7 +411,7 @@ const CdcMap = ({
433
411
  label: specialClass.label
434
412
  })
435
413
 
436
- result[result.length - 1].color = applyColorToLegend(result.length - 1)
414
+ result[result.length - 1].color = applyColorToLegend(result.length - 1, state, result)
437
415
 
438
416
  specialClasses += 1
439
417
  }
@@ -465,7 +443,7 @@ const CdcMap = ({
465
443
  value: val
466
444
  })
467
445
 
468
- result[result.length - 1].color = applyColorToLegend(result.length - 1)
446
+ result[result.length - 1].color = applyColorToLegend(result.length - 1, state, result)
469
447
 
470
448
  specialClasses += 1
471
449
  }
@@ -547,7 +525,7 @@ const CdcMap = ({
547
525
 
548
526
  // Add color to new legend item
549
527
  for (let i = 0; i < result.length; i++) {
550
- result[i].color = applyColorToLegend(i)
528
+ result[i].color = applyColorToLegend(i, state, result)
551
529
  }
552
530
 
553
531
  legendMemo.current = newLegendMemo
@@ -611,7 +589,7 @@ const CdcMap = ({
611
589
  let lastIdx = result.length - 1
612
590
 
613
591
  // Add color to new legend item
614
- result[lastIdx].color = applyColorToLegend(lastIdx)
592
+ result[lastIdx].color = applyColorToLegend(lastIdx, state, result)
615
593
  }
616
594
  }
617
595
 
@@ -663,7 +641,7 @@ const CdcMap = ({
663
641
  max
664
642
  })
665
643
 
666
- result[result.length - 1].color = applyColorToLegend(result.length - 1)
644
+ result[result.length - 1].color = applyColorToLegend(result.length - 1, state, result)
667
645
 
668
646
  changingNumber -= 1
669
647
  numberOfRows -= chunkAmt
@@ -821,16 +799,30 @@ const CdcMap = ({
821
799
 
822
800
  result.push(range)
823
801
 
824
- result[result.length - 1].color = applyColorToLegend(result.length - 1)
802
+ result[result.length - 1].color = applyColorToLegend(result.length - 1, state, result)
825
803
  }
826
804
  }
827
805
 
828
806
  result.forEach((legendItem, idx) => {
829
- legendItem.color = applyColorToLegend(idx, specialClasses, result)
807
+ legendItem.color = applyColorToLegend(idx, state, result)
830
808
  })
831
809
 
832
810
  legendMemo.current = newLegendMemo
833
811
 
812
+ if (state.general.geoType === 'world') {
813
+ const runtimeDataKeys = Object.keys(runtimeData)
814
+ const isCountriesWithNoDataState =
815
+ obj.data === undefined ? false : !countryKeys.every(countryKey => runtimeDataKeys.includes(countryKey))
816
+
817
+ if (result.length > 0 && isCountriesWithNoDataState) {
818
+ result.push({
819
+ min: null,
820
+ max: null,
821
+ color: getGeoFillColor(state)
822
+ })
823
+ }
824
+ }
825
+
834
826
  //----------
835
827
  // DEV-784
836
828
  // before returning the legend result
@@ -1703,6 +1695,7 @@ const CdcMap = ({
1703
1695
  isDebug,
1704
1696
  isEditor,
1705
1697
  loadConfig,
1698
+ logo,
1706
1699
  navigationHandler,
1707
1700
  position,
1708
1701
  resetLegendToggles,
@@ -1846,7 +1839,8 @@ const CdcMap = ({
1846
1839
  {'us-region' === geoType && <UsaMap.Region />}
1847
1840
  {'us-county' === geoType && <UsaMap.County />}
1848
1841
  {'world' === geoType && <WorldMap />}
1849
- {'data' === general.type && logo && (
1842
+ {/* logo is handled in UsaMap.State when applicable */}
1843
+ {'data' === general.type && logo && ('us' !== geoType || 'us-geocode' === state.general.type) && (
1850
1844
  <img src={logo} alt='' className='map-logo' style={{ maxWidth: '50px' }} />
1851
1845
  )}
1852
1846
  </>
@@ -1,12 +1,11 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react'
2
2
  import CdcMap from '../CdcMap'
3
- import SingleStateWithFilters from './_mock/DEV-8942.json'
4
3
  import UsGradient from './_mock/usa-state-gradient.json'
5
4
  import WastewaterMap from './_mock/wastewater-map.json'
6
5
  import { editConfigKeys } from '@cdc/chart/src/helpers/configHelpers'
7
6
 
8
7
  const meta: Meta<typeof CdcMap> = {
9
- title: 'Components/Templates/Map/Legend',
8
+ title: 'Components/Templates/Map/Legend/Gradient',
10
9
  component: CdcMap
11
10
  }
12
11
 
@@ -14,18 +13,6 @@ type Story = StoryObj<typeof CdcMap>
14
13
 
15
14
  export default meta
16
15
 
17
- export const Single_State_With_Filters: Story = {
18
- args: {
19
- config: editConfigKeys(SingleStateWithFilters, [
20
- { path: ['legend', 'style'], value: 'gradient' },
21
- { path: ['legend', 'position'], value: 'top' },
22
- { path: ['legend', 'hideBorder'], value: true },
23
- { path: ['legend', 'title'], value: '' },
24
- { path: ['legend', 'description'], value: '' }
25
- ])
26
- }
27
- }
28
-
29
16
  export const Gradient: Story = {
30
17
  args: {
31
18
  config: UsGradient
@@ -56,12 +43,6 @@ export const Gradient_With_Text: Story = {
56
43
  }
57
44
  }
58
45
 
59
- export const Legend_Right: Story = {
60
- args: {
61
- config: editConfigKeys(SingleStateWithFilters, [{ path: ['legend', 'hideBorder'], value: true }])
62
- }
63
- }
64
-
65
46
  export const Gradient_With_Patterns: Story = {
66
47
  args: {
67
48
  config: WastewaterMap
@@ -0,0 +1,40 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import CdcMap from '../CdcMap'
3
+ import SingleStateWithFilters from './_mock/DEV-8942.json'
4
+ import CustomLayerMap from './_mock/custom-layer-map.json'
5
+ import WastewaterMap from './_mock/wastewater-map.json'
6
+ import { editConfigKeys } from '@cdc/chart/src/helpers/configHelpers'
7
+
8
+ const meta: Meta<typeof CdcMap> = {
9
+ title: 'Components/Templates/Map/Legend',
10
+ component: CdcMap
11
+ }
12
+
13
+ type Story = StoryObj<typeof CdcMap>
14
+
15
+ export default meta
16
+
17
+ export const Legend_Right: Story = {
18
+ args: {
19
+ config: editConfigKeys(SingleStateWithFilters, [{ path: ['legend', 'hideBorder'], value: true }])
20
+ }
21
+ }
22
+
23
+ export const Legend_Bottom: Story = {
24
+ args: {
25
+ config: editConfigKeys(CustomLayerMap, [
26
+ { path: ['legend', 'position'], value: 'bottom' },
27
+ { path: ['legend', 'singleRow'], value: false }
28
+ ])
29
+ }
30
+ }
31
+
32
+ export const Legend_Bottom_Single_Row: Story = {
33
+ args: {
34
+ config: editConfigKeys(WastewaterMap, [
35
+ { path: ['legend', 'position'], value: 'bottom' },
36
+ { path: ['legend', 'style'], value: 'circles' },
37
+ { path: ['legend', 'singleRow'], value: true }
38
+ ])
39
+ }
40
+ }
@@ -0,0 +1,29 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import CdcMap from '../CdcMap'
3
+ import defaultPatterns from './_mock/default-patterns.json'
4
+ import { editConfigKeys } from '@cdc/chart/src/helpers/configHelpers'
5
+
6
+ const meta: Meta<typeof CdcMap> = {
7
+ title: 'Components/Templates/Map/Patterns',
8
+ component: CdcMap
9
+ }
10
+
11
+ type Story = StoryObj<typeof CdcMap>
12
+
13
+ export default meta
14
+
15
+ export const Default_Patterns: Story = {
16
+ args: {
17
+ config: defaultPatterns
18
+ }
19
+ }
20
+
21
+ export const Default_Patterns_Dark: Story = {
22
+ args: {
23
+ isEditor: true,
24
+ config: editConfigKeys(defaultPatterns, [
25
+ { path: ['color'], value: 'bluegreen' },
26
+ { path: ['legend', 'specialClasses'], value: [] }
27
+ ])
28
+ }
29
+ }
@@ -2,6 +2,8 @@ import type { Meta, StoryObj } from '@storybook/react'
2
2
  import CdcMap from '../CdcMap'
3
3
  import EqualNumberOptInExample from './_mock/DEV-7286.json'
4
4
  import SingleStateWithFilters from './_mock/DEV-8942.json'
5
+ import exampleCityState from './_mock/example-city-state.json'
6
+ import { editConfigKeys } from '@cdc/chart/src/helpers/configHelpers'
5
7
 
6
8
  const meta: Meta<typeof CdcMap> = {
7
9
  title: 'Components/Templates/Map',
@@ -94,4 +96,61 @@ export const Single_State_With_Filters: Story = {
94
96
  }
95
97
  }
96
98
 
99
+ let newConfig = editConfigKeys(exampleCityState, [
100
+ { path: ['customColors'], value: ['red', 'orange', 'yellow', 'green', 'blue', 'violet'] }
101
+ ])
102
+ newConfig = editConfigKeys(newConfig, [
103
+ {
104
+ path: ['legend', 'specialClasses'],
105
+ value: [
106
+ {
107
+ key: 'Rate',
108
+ value: '*',
109
+ label: '*'
110
+ }
111
+ ]
112
+ }
113
+ ])
114
+ let exampleCityStateStandardColors = editConfigKeys(exampleCityState, [
115
+ {
116
+ path: ['legend', 'specialClasses'],
117
+ value: [
118
+ {
119
+ key: 'Rate',
120
+ value: '*',
121
+ label: '*'
122
+ }
123
+ ]
124
+ }
125
+ ])
126
+ export const Custom_Color_Distributions_With_Special_Classes: Story = {
127
+ args: {
128
+ config: newConfig
129
+ }
130
+ }
131
+
132
+ export const Custom_Color_Distributions_Without_Special_Classes: Story = {
133
+ args: {
134
+ config: editConfigKeys(newConfig, [{ path: ['legend', 'specialClasses'], value: [] }])
135
+ }
136
+ }
137
+
138
+ export const Standard_Color_Distributions_With_Special_Classes: Story = {
139
+ args: {
140
+ config: exampleCityStateStandardColors
141
+ }
142
+ }
143
+
144
+ export const Standard_Color_Distributions_Without_Special_Classes: Story = {
145
+ args: {
146
+ config: editConfigKeys(exampleCityStateStandardColors, [{ path: ['legend', 'specialClasses'], value: [] }])
147
+ }
148
+ }
149
+
150
+ export const Custom_Color_Distributions_With_Update_Needed: Story = {
151
+ args: {
152
+ config: editConfigKeys(newConfig, [{ path: ['version'], value: '4.24.11' }])
153
+ }
154
+ }
155
+
97
156
  export default meta
@@ -0,0 +1,19 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import CdcMap from '../CdcMap'
3
+ import cityStateConfig from './_mock/example-city-state.json'
4
+ import { editConfigKeys } from '@cdc/chart/src/helpers/configHelpers'
5
+
6
+ const meta: Meta<typeof CdcMap> = {
7
+ title: 'Components/Templates/Map',
8
+ component: CdcMap
9
+ }
10
+
11
+ type Story = StoryObj<typeof CdcMap>
12
+
13
+ export const USA_Map_No_Data: Story = {
14
+ args: {
15
+ config: editConfigKeys(cityStateConfig, [{ path: ['data'], value: [] }])
16
+ }
17
+ }
18
+
19
+ export default meta