@cdc/map 4.24.10 → 4.24.12-2

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 (57) hide show
  1. package/dist/cdcmap.js +33447 -32769
  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/DEV-9644.json +184 -0
  7. package/examples/private/DEV-9989.json +229 -0
  8. package/examples/private/ardi.json +180 -0
  9. package/examples/private/colors 2.json +416 -0
  10. package/examples/private/colors.json +416 -0
  11. package/examples/private/colors.json.zip +0 -0
  12. package/examples/private/customColors.json +45348 -0
  13. package/examples/private/default-patterns.json +867 -0
  14. package/examples/private/test.json +1632 -0
  15. package/index.html +4 -5
  16. package/package.json +3 -3
  17. package/src/CdcMap.tsx +93 -83
  18. package/src/_stories/CdcMap.Legend.Gradient.stories.tsx +67 -0
  19. package/src/_stories/CdcMap.Legend.stories.tsx +40 -0
  20. package/src/_stories/CdcMap.Patterns.stories.tsx +29 -0
  21. package/src/_stories/CdcMap.stories.tsx +59 -0
  22. package/src/_stories/UsaMap.NoData.stories.tsx +19 -0
  23. package/src/_stories/_mock/custom-layer-map.json +1117 -0
  24. package/src/_stories/_mock/default-patterns.json +865 -0
  25. package/src/_stories/_mock/example-city-state.json +858 -0
  26. package/src/_stories/_mock/usa-state-gradient.json +238 -0
  27. package/src/_stories/_mock/wastewater-map.json +208 -0
  28. package/src/components/CityList.tsx +5 -2
  29. package/src/components/EditorPanel/components/EditorPanel.tsx +68 -295
  30. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +27 -23
  31. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +75 -16
  32. package/src/components/Legend/components/Legend.tsx +42 -20
  33. package/src/components/Legend/components/index.scss +24 -24
  34. package/src/components/UsaMap/components/HexIcon.tsx +7 -1
  35. package/src/components/UsaMap/components/SingleState/SingleState.CountyOutput.tsx +40 -6
  36. package/src/components/UsaMap/components/SingleState/SingleState.StateOutput.tsx +10 -2
  37. package/src/components/UsaMap/components/Territory/Territory.Hexagon.tsx +57 -12
  38. package/src/components/UsaMap/components/Territory/Territory.Rectangle.tsx +95 -21
  39. package/src/components/UsaMap/components/Territory/TerritoryShape.ts +13 -0
  40. package/src/components/UsaMap/components/UsaMap.County.tsx +11 -13
  41. package/src/components/UsaMap/components/UsaMap.Region.tsx +59 -16
  42. package/src/components/UsaMap/components/UsaMap.SingleState.tsx +2 -1
  43. package/src/components/UsaMap/components/UsaMap.State.tsx +61 -63
  44. package/src/components/UsaMap/helpers/shapes.ts +5 -4
  45. package/src/components/WorldMap/WorldMap.tsx +77 -16
  46. package/src/data/initial-state.js +2 -1
  47. package/src/helpers/applyColorToLegend.ts +80 -0
  48. package/src/helpers/colors.ts +23 -0
  49. package/src/hooks/useTooltip.ts +9 -6
  50. package/src/scss/editor-panel.scss +0 -3
  51. package/src/scss/filters.scss +1 -9
  52. package/src/scss/main.scss +0 -5
  53. package/src/scss/map.scss +11 -63
  54. package/src/types/MapConfig.ts +8 -2
  55. package/src/types/MapContext.ts +1 -0
  56. package/examples/default-patterns.json +0 -579
  57. 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.10",
3
+ "version": "4.24.12-2",
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.10",
28
+ "@cdc/core": "^4.24.12-2",
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": "a4d88d1bc91f596e1b0307d8e25c57ad8c668b75"
55
+ "gitHead": "a60edf1148396309eb473ac9f65426ee40797ddf"
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,8 @@ 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'
81
+ import { SubGrouping } from '@cdc/core/types/VizFilter'
80
82
 
81
83
  // Data props
82
84
  const stateKeys = Object.keys(supportedStates)
@@ -117,10 +119,17 @@ const CdcMap = ({
117
119
  const [loading, setLoading] = useState(true)
118
120
  const [displayPanel, setDisplayPanel] = useState(true)
119
121
  const [currentViewport, setCurrentViewport] = useState<ViewportSize>('lg')
120
- const [topoData, setTopoData] = useState<Topology | {}>({})
122
+ const [topoData, setTopoData] = useState<{}>({})
121
123
  const [runtimeFilters, setRuntimeFilters] = useState([])
122
- const [runtimeLegend, setRuntimeLegend] = useState([])
123
124
  const [runtimeData, setRuntimeData] = useState({ init: true })
125
+ const _setRuntimeData = (data: any) => {
126
+ if (config) {
127
+ setRuntimeData(data)
128
+ } else {
129
+ setRuntimeFilters(data)
130
+ }
131
+ }
132
+ const [runtimeLegend, setRuntimeLegend] = useState([])
124
133
  const [stateToShow, setStateToShow] = useState(null)
125
134
  const [modal, setModal] = useState(null)
126
135
  const [accessibleStatus, setAccessibleStatus] = useState('')
@@ -274,6 +283,22 @@ const CdcMap = ({
274
283
  if (!uid && geoName) {
275
284
  uid = cityKeys.find(key => key === geoName.toUpperCase())
276
285
  }
286
+
287
+ if (state.general.displayAsHex) {
288
+ const upperCaseKey = geoName.toUpperCase()
289
+ const supportedDc = [
290
+ 'WASHINGTON D.C.',
291
+ 'DISTRICT OF COLUMBIA',
292
+ 'WASHINGTON DC',
293
+ 'DC',
294
+ 'WASHINGTON DC.',
295
+ 'D.C.',
296
+ 'D.C'
297
+ ]
298
+ if (supportedDc.includes(upperCaseKey)) {
299
+ uid = 'US-DC'
300
+ }
301
+ }
277
302
  }
278
303
 
279
304
  if ('us-region' === obj.general.geoType && obj.columns.geo.name) {
@@ -341,11 +366,10 @@ const CdcMap = ({
341
366
  })
342
367
 
343
368
  // eslint-disable-next-line
344
- const generateRuntimeLegend = useCallback((obj, runtimeData, hash) => {
369
+ const generateRuntimeLegend = useCallback((obj, runtimeFilters, hash) => {
345
370
  const newLegendMemo = new Map() // Reset memoization
346
371
  const newLegendSpecialClassLastMemo = new Map() // Reset bin memoization
347
372
  let primaryCol = obj.columns.primary.name,
348
- isSingleState = obj.general.geoType === 'single-state',
349
373
  isBubble = obj.general.type === 'bubble',
350
374
  categoricalCol = obj.columns.categorical ? obj.columns.categorical.name : undefined,
351
375
  type = obj.legend.type,
@@ -357,7 +381,7 @@ const CdcMap = ({
357
381
  result.fromHash = hash
358
382
  }
359
383
 
360
- result.runtimeDataHash = runtimeData.fromHash
384
+ result.runtimeDataHash = runtimeFilters?.fromHash
361
385
 
362
386
  // Unified will based the legend off ALL of the data maps received. Otherwise, it will use
363
387
  let dataSet = obj.legend.unified ? obj.data : Object.values(runtimeData)
@@ -375,45 +399,6 @@ const CdcMap = ({
375
399
  10: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
376
400
  }
377
401
 
378
- const applyColorToLegend = legendIdx => {
379
- // Default to "bluegreen" color scheme if the passed color isn't valid
380
- let mapColorPalette = obj.customColors || colorPalettes[obj.color] || colorPalettes['bluegreen']
381
-
382
- // Handle Region Maps need for a 10th color
383
- if (general.geoType === 'us-region' && mapColorPalette.length < 10 && mapColorPalette.length > 8) {
384
- if (!general.palette.isReversed) {
385
- mapColorPalette.push(chroma(mapColorPalette[8]).darken(0.75).hex())
386
- } else {
387
- mapColorPalette.unshift(chroma(mapColorPalette[0]).darken(0.75).hex())
388
- }
389
- }
390
-
391
- let colorIdx = legendIdx - specialClasses
392
-
393
- // Special Classes (No Data)
394
- if (result[legendIdx].special) {
395
- const specialClassColors = chroma.scale(['#D4D4D4', '#939393']).colors(specialClasses)
396
-
397
- return specialClassColors[legendIdx]
398
- }
399
-
400
- if (obj.color.includes('qualitative')) return mapColorPalette[colorIdx]
401
-
402
- let amt = Math.max(result.length - specialClasses, 1)
403
- let distributionArray = colorDistributions[amt]
404
-
405
- let specificColor
406
- if (distributionArray) {
407
- specificColor = distributionArray[colorIdx]
408
- } else if (mapColorPalette[colorIdx]) {
409
- specificColor = colorIdx
410
- } else {
411
- specificColor = mapColorPalette.length - 1
412
- }
413
-
414
- return mapColorPalette[specificColor]
415
- }
416
-
417
402
  let specialClasses = 0
418
403
  let specialClassesHash = {}
419
404
 
@@ -434,7 +419,7 @@ const CdcMap = ({
434
419
  label: specialClass.label
435
420
  })
436
421
 
437
- result[result.length - 1].color = applyColorToLegend(result.length - 1)
422
+ result[result.length - 1].color = applyColorToLegend(result.length - 1, state, result)
438
423
 
439
424
  specialClasses += 1
440
425
  }
@@ -466,7 +451,7 @@ const CdcMap = ({
466
451
  value: val
467
452
  })
468
453
 
469
- result[result.length - 1].color = applyColorToLegend(result.length - 1)
454
+ result[result.length - 1].color = applyColorToLegend(result.length - 1, state, result)
470
455
 
471
456
  specialClasses += 1
472
457
  }
@@ -548,7 +533,7 @@ const CdcMap = ({
548
533
 
549
534
  // Add color to new legend item
550
535
  for (let i = 0; i < result.length; i++) {
551
- result[i].color = applyColorToLegend(i)
536
+ result[i].color = applyColorToLegend(i, state, result)
552
537
  }
553
538
 
554
539
  legendMemo.current = newLegendMemo
@@ -573,7 +558,9 @@ const CdcMap = ({
573
558
  newLegendMemo.forEach(assignSpecialClassLastIndex)
574
559
  legendSpecialClassLastMemo.current = newLegendSpecialClassLastMemo
575
560
 
576
- return result
561
+ // filter special classes from results
562
+ const specialValues = result.filter(d => d.special).map(d => d.value)
563
+ return result.filter(d => d.special || !specialValues.includes(d.value))
577
564
  }
578
565
 
579
566
  let uniqueValues = {}
@@ -610,7 +597,7 @@ const CdcMap = ({
610
597
  let lastIdx = result.length - 1
611
598
 
612
599
  // Add color to new legend item
613
- result[lastIdx].color = applyColorToLegend(lastIdx)
600
+ result[lastIdx].color = applyColorToLegend(lastIdx, state, result)
614
601
  }
615
602
  }
616
603
 
@@ -662,7 +649,7 @@ const CdcMap = ({
662
649
  max
663
650
  })
664
651
 
665
- result[result.length - 1].color = applyColorToLegend(result.length - 1)
652
+ result[result.length - 1].color = applyColorToLegend(result.length - 1, state, result)
666
653
 
667
654
  changingNumber -= 1
668
655
  numberOfRows -= chunkAmt
@@ -820,16 +807,30 @@ const CdcMap = ({
820
807
 
821
808
  result.push(range)
822
809
 
823
- result[result.length - 1].color = applyColorToLegend(result.length - 1)
810
+ result[result.length - 1].color = applyColorToLegend(result.length - 1, state, result)
824
811
  }
825
812
  }
826
813
 
827
814
  result.forEach((legendItem, idx) => {
828
- legendItem.color = applyColorToLegend(idx, specialClasses, result)
815
+ legendItem.color = applyColorToLegend(idx, state, result)
829
816
  })
830
817
 
831
818
  legendMemo.current = newLegendMemo
832
819
 
820
+ if (state.general.geoType === 'world') {
821
+ const runtimeDataKeys = Object.keys(runtimeFilters)
822
+ const isCountriesWithNoDataState =
823
+ obj.data === undefined ? false : !countryKeys.every(countryKey => runtimeDataKeys.includes(countryKey))
824
+
825
+ if (result.length > 0 && isCountriesWithNoDataState) {
826
+ result.push({
827
+ min: null,
828
+ max: null,
829
+ color: getGeoFillColor(state)
830
+ })
831
+ }
832
+ }
833
+
833
834
  //----------
834
835
  // DEV-784
835
836
  // before returning the legend result
@@ -882,32 +883,21 @@ const CdcMap = ({
882
883
  ) => {
883
884
  let newFilter = runtimeFilters[idx]
884
885
 
885
- const sortAsc = (a, b) => {
886
- return a.toString().localeCompare(b.toString(), 'en', { numeric: true })
887
- }
888
-
889
- const sortDesc = (a, b) => {
890
- return b.toString().localeCompare(a.toString(), 'en', { numeric: true })
886
+ const sort = (a, b) => {
887
+ const asc = obj.filters[idx].order !== 'desc'
888
+ return String(asc ? a : b).localeCompare(String(asc ? b : a), 'en', { numeric: true })
891
889
  }
892
890
 
893
891
  if (type !== 'url') {
894
892
  values = getUniqueValues(state.data, columnName)
895
893
 
896
- if (obj.filters[idx].order === 'asc') {
897
- values = values.sort(sortAsc)
898
- }
899
-
900
- if (obj.filters[idx].order === 'desc') {
901
- values = values.sort(sortDesc)
902
- }
903
-
904
894
  if (obj.filters[idx].order === 'cust') {
905
895
  if (obj.filters[idx]?.values.length > 0) {
906
896
  values = obj.filters[idx].values
907
897
  }
898
+ } else {
899
+ values = values.sort(sort)
908
900
  }
909
- } else {
910
- values = values
911
901
  }
912
902
 
913
903
  if (undefined === newFilter) {
@@ -927,6 +917,7 @@ const CdcMap = ({
927
917
  newFilter.active = active ?? values[0] // Default to first found value
928
918
  newFilter.filterStyle = obj.filters[idx].filterStyle ? obj.filters[idx].filterStyle : 'dropdown'
929
919
  newFilter.showDropdown = showDropdown
920
+ newFilter.subGrouping = obj.filters[idx].subGrouping
930
921
 
931
922
  filters.push(newFilter)
932
923
  }
@@ -975,17 +966,23 @@ const CdcMap = ({
975
966
  // Filters
976
967
  if (filters?.length) {
977
968
  for (let i = 0; i < filters.length; i++) {
978
- const { columnName, active, type } = filters[i]
979
- if (type !== 'url' && String(row[columnName]) !== String(active)) return false // Bail out, not part of filter
969
+ const { columnName, active, type, filterStyle, subGrouping } = filters[i]
970
+ const isDataFilter = type !== 'url'
971
+ const matchingValue = String(active) === String(row[columnName]) // Group
972
+ if (isDataFilter && !matchingValue) return false // Bail out, data doesn't match the filter selection
973
+ if (filterStyle == 'nested-dropdown') {
974
+ const matchingSubValue = String(row[subGrouping?.columnName]) === String(subGrouping?.active)
975
+ if (subGrouping?.active && !matchingSubValue) {
976
+ return false // Bail out, data doesn't match the subgroup selection
977
+ }
978
+ }
980
979
  }
981
980
  }
982
-
983
981
  // Don't add additional rows with same UID
984
- if (undefined === result[row.uid]) {
982
+ if (result[row.uid] === undefined) {
985
983
  result[row.uid] = row
986
984
  }
987
985
  })
988
-
989
986
  return result
990
987
  } catch (e) {
991
988
  console.error('COVE: ', e) // eslint-disable-line
@@ -1571,7 +1568,7 @@ const CdcMap = ({
1571
1568
  const hashFilters = hashObj(state.filters)
1572
1569
  let filters
1573
1570
 
1574
- if (state.filters && hashFilters !== runtimeFilters.fromHash) {
1571
+ if (state.filters && (config || hashFilters !== runtimeFilters.fromHash)) {
1575
1572
  filters = generateRuntimeFilters(state, hashFilters, runtimeFilters)
1576
1573
 
1577
1574
  if (filters) {
@@ -1600,12 +1597,12 @@ const CdcMap = ({
1600
1597
  })
1601
1598
 
1602
1599
  // Data
1603
- if (hashData !== runtimeData.fromHash && state.data?.fromColumn) {
1600
+ if (hashData !== runtimeData?.fromHash && state.data?.fromColumn) {
1604
1601
  const newRuntimeData = generateRuntimeData(state, filters || runtimeFilters, hashData)
1605
1602
 
1606
1603
  setRuntimeData(newRuntimeData)
1607
1604
  } else {
1608
- if (hashLegend !== runtimeLegend.fromHash && undefined === runtimeData.init) {
1605
+ if (hashLegend !== runtimeLegend?.fromHash && undefined === runtimeData.init) {
1609
1606
  const legend = generateRuntimeLegend(state, runtimeData, hashLegend)
1610
1607
  setRuntimeLegend(legend)
1611
1608
  }
@@ -1702,6 +1699,7 @@ const CdcMap = ({
1702
1699
  isDebug,
1703
1700
  isEditor,
1704
1701
  loadConfig,
1702
+ logo,
1705
1703
  navigationHandler,
1706
1704
  position,
1707
1705
  resetLegendToggles,
@@ -1772,7 +1770,12 @@ const CdcMap = ({
1772
1770
  )
1773
1771
 
1774
1772
  const sectionClassNames = () => {
1775
- const classes = ['cove-component__content', 'cdc-map-inner-container', `${currentViewport}`]
1773
+ const classes = [
1774
+ 'cove-component__content',
1775
+ 'cdc-map-inner-container',
1776
+ `${currentViewport}`,
1777
+ `${state?.general?.headerColor}`
1778
+ ]
1776
1779
  if (config?.runtime?.editorErrorMessage.length > 0) classes.push('type-map--has-error')
1777
1780
  return classes.join(' ')
1778
1781
  }
@@ -1816,10 +1819,10 @@ const CdcMap = ({
1816
1819
  <Filters
1817
1820
  config={state}
1818
1821
  setConfig={setState}
1819
- getUniqueValues={getUniqueValues}
1820
1822
  filteredData={runtimeFilters}
1821
- setFilteredData={setRuntimeFilters}
1823
+ setFilteredData={_setRuntimeData}
1822
1824
  dimensions={dimensions}
1825
+ standaloneMap={!config}
1823
1826
  />
1824
1827
  )}
1825
1828
 
@@ -1833,7 +1836,7 @@ const CdcMap = ({
1833
1836
  closeModal(e)
1834
1837
  }
1835
1838
  }}
1836
- style={{ padding: '15px 25px', margin: '0px' }}
1839
+ style={{ padding: '15px 0px', margin: '0px' }}
1837
1840
  >
1838
1841
  {/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */}
1839
1842
  <section className='outline-none geography-container w-100' ref={mapSvg} tabIndex='0'>
@@ -1845,7 +1848,8 @@ const CdcMap = ({
1845
1848
  {'us-region' === geoType && <UsaMap.Region />}
1846
1849
  {'us-county' === geoType && <UsaMap.County />}
1847
1850
  {'world' === geoType && <WorldMap />}
1848
- {'data' === general.type && logo && (
1851
+ {/* logo is handled in UsaMap.State when applicable */}
1852
+ {'data' === general.type && logo && ('us' !== geoType || 'us-geocode' === state.general.type) && (
1849
1853
  <img src={logo} alt='' className='map-logo' style={{ maxWidth: '50px' }} />
1850
1854
  )}
1851
1855
  </>
@@ -1853,7 +1857,13 @@ const CdcMap = ({
1853
1857
  </section>
1854
1858
 
1855
1859
  {general.showSidebar && 'navigation' !== general.type && (
1856
- <Legend dimensions={dimensions} currentViewport={currentViewport} ref={legendRef} skipId={tabId} />
1860
+ <Legend
1861
+ dimensions={dimensions}
1862
+ ref={legendRef}
1863
+ skipId={tabId}
1864
+ containerWidthPadding={0}
1865
+ currentViewport={currentViewport}
1866
+ />
1857
1867
  )}
1858
1868
  </div>
1859
1869
 
@@ -0,0 +1,67 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import CdcMap from '../CdcMap'
3
+ import UsGradient from './_mock/usa-state-gradient.json'
4
+ import WastewaterMap from './_mock/wastewater-map.json'
5
+ import { editConfigKeys } from '@cdc/chart/src/helpers/configHelpers'
6
+
7
+ const meta: Meta<typeof CdcMap> = {
8
+ title: 'Components/Templates/Map/Legend/Gradient',
9
+ component: CdcMap
10
+ }
11
+
12
+ type Story = StoryObj<typeof CdcMap>
13
+
14
+ export default meta
15
+
16
+ export const Gradient: Story = {
17
+ args: {
18
+ config: UsGradient
19
+ }
20
+ }
21
+
22
+ export const Gradient_Smooth: Story = {
23
+ args: {
24
+ config: editConfigKeys(UsGradient, [{ path: ['legend', 'subStyle'], value: 'smooth' }])
25
+ }
26
+ }
27
+ export const Gradient_With_Box: Story = {
28
+ args: {
29
+ config: editConfigKeys(UsGradient, [
30
+ { path: ['legend', 'subStyle'], value: 'linear blocks' },
31
+ { path: ['legend', 'hideBorder'], value: false }
32
+ ])
33
+ }
34
+ }
35
+
36
+ export const Gradient_With_Text: Story = {
37
+ args: {
38
+ config: editConfigKeys(UsGradient, [
39
+ { path: ['legend', 'title'], value: 'Title' },
40
+ { path: ['legend', 'description'], value: 'Description' },
41
+ { path: ['legend', 'hideBorder'], value: true }
42
+ ])
43
+ }
44
+ }
45
+
46
+ export const Gradient_With_Patterns: Story = {
47
+ args: {
48
+ config: WastewaterMap
49
+ }
50
+ }
51
+ export const Gradient_Reversed: Story = {
52
+ args: {
53
+ config: editConfigKeys(WastewaterMap, [
54
+ {
55
+ path: ['customColors'],
56
+ value: undefined
57
+ },
58
+ { path: ['legend', 'specialClasses'], value: ['No Data'] },
59
+ { path: ['legend', 'showSpecialClassesLast'], value: false },
60
+ {
61
+ path: ['legend', 'categoryValuesOrder'],
62
+ value: ['No Data', 'Minimal', 'Low', 'Moderate', 'High', 'Very High']
63
+ },
64
+ { path: ['color'], value: 'greenblue' }
65
+ ])
66
+ }
67
+ }
@@ -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