@cdc/map 4.22.10-alpha.1 → 4.22.11

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 (47) hide show
  1. package/dist/cdcmap.js +10 -10
  2. package/examples/private/atsdr.json +19 -29
  3. package/examples/private/atsdr_new.json +1 -1
  4. package/examples/private/bubble.json +282 -284
  5. package/examples/private/city-state.json +427 -427
  6. package/examples/private/city-state2.json +433 -433
  7. package/examples/private/cty-issue.json +42765 -42768
  8. package/examples/private/default-usa.json +2 -5
  9. package/examples/private/default-world-data.json +1443 -1443
  10. package/examples/private/default.json +965 -965
  11. package/examples/private/diff.json +226 -0
  12. package/examples/private/filters.json +1 -0
  13. package/examples/private/legend-issue.json +3271 -1
  14. package/examples/private/map-issue.json +166 -0
  15. package/examples/private/map-rounding-error.json +42756 -42759
  16. package/examples/private/mdx.json +209 -209
  17. package/examples/private/monkeypox.json +375 -375
  18. package/examples/private/regions.json +51 -51
  19. package/examples/private/wcmsrd-13881-data.json +2856 -2856
  20. package/examples/private/wcmsrd-13881.json +5818 -5822
  21. package/examples/private/wcmsrd-14492-data.json +291 -291
  22. package/examples/private/wcmsrd-14492.json +103 -113
  23. package/examples/private/wcmsrd-test.json +264 -267
  24. package/examples/private/world.json +1579 -1579
  25. package/examples/private/worldmap.json +1489 -1489
  26. package/package.json +3 -3
  27. package/src/CdcMap.js +231 -315
  28. package/src/components/BubbleList.js +199 -240
  29. package/src/components/CityList.js +50 -96
  30. package/src/components/CountyMap.js +511 -600
  31. package/src/components/DataTable.js +218 -253
  32. package/src/components/EditorPanel.js +2338 -2551
  33. package/src/components/Geo.js +4 -14
  34. package/src/components/Modal.js +13 -23
  35. package/src/components/NavigationMenu.js +43 -39
  36. package/src/components/Sidebar.js +83 -93
  37. package/src/components/SingleStateMap.js +95 -151
  38. package/src/components/UsaMap.js +165 -214
  39. package/src/components/UsaRegionMap.js +122 -160
  40. package/src/components/WorldMap.js +96 -179
  41. package/src/components/ZoomableGroup.js +6 -26
  42. package/src/data/initial-state.js +1 -0
  43. package/src/hooks/useActiveElement.js +13 -13
  44. package/src/hooks/useColorPalette.ts +66 -74
  45. package/src/hooks/useZoomPan.js +22 -23
  46. package/src/index.html +1 -2
  47. package/src/scss/sidebar.scss +22 -0
package/src/CdcMap.js CHANGED
@@ -17,16 +17,7 @@ import Canvg from 'canvg'
17
17
  // Data
18
18
  import colorPalettes from '../../core/data/colorPalettes'
19
19
  import ExternalIcon from './images/external-link.svg'
20
- import {
21
- supportedStates,
22
- supportedTerritories,
23
- supportedCountries,
24
- supportedCounties,
25
- supportedCities,
26
- supportedStatesFipsCodes,
27
- stateFipsToTwoDigit,
28
- supportedRegions
29
- } from './data/supported-geos'
20
+ import { supportedStates, supportedTerritories, supportedCountries, supportedCounties, supportedCities, supportedStatesFipsCodes, stateFipsToTwoDigit, supportedRegions } from './data/supported-geos'
30
21
  import initialState from './data/initial-state'
31
22
  import { countryCoordinates } from './data/country-coordinates'
32
23
 
@@ -40,12 +31,12 @@ import DownloadImg from './images/icon-download-img.svg'
40
31
  import DownloadPdf from './images/icon-download-pdf.svg'
41
32
 
42
33
  // Core
43
- import Loading from '@cdc/core/components/Loading';
44
- import { DataTransform } from '@cdc/core/helpers/DataTransform';
45
- import getViewport from '@cdc/core/helpers/getViewport';
46
- import numberFromString from '@cdc/core/helpers/numberFromString';
47
- import fetchRemoteData from '@cdc/core/helpers/fetchRemoteData';
48
- import cacheBustingString from '@cdc/core/helpers/cacheBustingString';
34
+ import Loading from '@cdc/core/components/Loading'
35
+ import { DataTransform } from '@cdc/core/helpers/DataTransform'
36
+ import getViewport from '@cdc/core/helpers/getViewport'
37
+ import numberFromString from '@cdc/core/helpers/numberFromString'
38
+ import fetchRemoteData from '@cdc/core/helpers/fetchRemoteData'
39
+ import cacheBustingString from '@cdc/core/helpers/cacheBustingString'
49
40
 
50
41
  // Child Components
51
42
  import Sidebar from './components/Sidebar'
@@ -73,14 +64,10 @@ const generateColorsArray = (color = '#000000', special = false) => {
73
64
  let colorObj = chroma(color)
74
65
  let hoverColor = special ? colorObj.brighten(0.5).hex() : colorObj.saturate(1.3).hex()
75
66
 
76
- return [
77
- color,
78
- hoverColor,
79
- colorObj.darken(0.3).hex()
80
- ]
67
+ return [color, hoverColor, colorObj.darken(0.3).hex()]
81
68
  }
82
69
 
83
- const hashObj = (row) => {
70
+ const hashObj = row => {
84
71
  try {
85
72
  if (!row) throw new Error('No row supplied to hashObj')
86
73
 
@@ -91,7 +78,7 @@ const hashObj = (row) => {
91
78
 
92
79
  for (let i = 0; i < str.length; i++) {
93
80
  let char = str.charCodeAt(i)
94
- hash = ((hash << 5) - hash) + char
81
+ hash = (hash << 5) - hash + char
95
82
  hash = hash & hash
96
83
  }
97
84
 
@@ -119,20 +106,20 @@ const getUniqueValues = (data, columnName) => {
119
106
  }
120
107
 
121
108
  const CdcMap = ({ className, config, navigationHandler: customNavigationHandler, isDashboard = false, isEditor = false, configUrl, logo = null, setConfig, setSharedFilter, setSharedFilterValue, hostname = 'localhost:8080', link }) => {
122
- const [ showLoadingMessage, setShowLoadingMessage ] = useState(false)
109
+ const [showLoadingMessage, setShowLoadingMessage] = useState(false)
123
110
  const transform = new DataTransform()
124
- const [ state, setState ] = useState({ ...initialState })
125
- const [ loading, setLoading ] = useState(true)
126
- const [ currentViewport, setCurrentViewport ] = useState()
127
- const [ runtimeFilters, setRuntimeFilters ] = useState([])
128
- const [ runtimeLegend, setRuntimeLegend ] = useState([])
129
- const [ runtimeData, setRuntimeData ] = useState({ init: true })
130
- const [ modal, setModal ] = useState(null)
131
- const [ accessibleStatus, setAccessibleStatus ] = useState('')
132
- const [ filteredCountryCode, setFilteredCountryCode ] = useState()
133
- const [ position, setPosition ] = useState(state.mapPosition)
134
- const [ coveLoadedHasRan, setCoveLoadedHasRan ] = useState(false)
135
- const [ container, setContainer ] = useState()
111
+ const [state, setState] = useState({ ...initialState })
112
+ const [loading, setLoading] = useState(true)
113
+ const [currentViewport, setCurrentViewport] = useState()
114
+ const [runtimeFilters, setRuntimeFilters] = useState([])
115
+ const [runtimeLegend, setRuntimeLegend] = useState([])
116
+ const [runtimeData, setRuntimeData] = useState({ init: true })
117
+ const [modal, setModal] = useState(null)
118
+ const [accessibleStatus, setAccessibleStatus] = useState('')
119
+ const [filteredCountryCode, setFilteredCountryCode] = useState()
120
+ const [position, setPosition] = useState(state.mapPosition)
121
+ const [coveLoadedHasRan, setCoveLoadedHasRan] = useState(false)
122
+ const [container, setContainer] = useState()
136
123
 
137
124
  let legendMemo = useRef(new Map())
138
125
 
@@ -143,7 +130,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
143
130
  const coordinates = countryCoordinates[filteredCountryCode]
144
131
  const long = coordinates[1]
145
132
  const lat = coordinates[0]
146
- const reversedCoordinates = [ long, lat ]
133
+ const reversedCoordinates = [long, lat]
147
134
 
148
135
  setState({
149
136
  ...state,
@@ -153,7 +140,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
153
140
  } catch (e) {
154
141
  console.error('Failed to set world map zoom.')
155
142
  }
156
- }, [ filteredCountryCode ])
143
+ }, [filteredCountryCode])
157
144
 
158
145
  useEffect(() => {
159
146
  setTimeout(() => {
@@ -165,15 +152,15 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
165
152
  setRuntimeData(tmpData)
166
153
  }
167
154
  }, 100)
168
- }, [ filteredCountryCode ])
155
+ }, [filteredCountryCode])
169
156
 
170
157
  useEffect(() => {
171
158
  if (state.mapPosition) {
172
159
  setPosition(state.mapPosition)
173
160
  }
174
- }, [ state.mapPosition, setPosition ])
161
+ }, [state.mapPosition, setPosition])
175
162
 
176
- const setZoom = (reversedCoordinates) => {
163
+ const setZoom = reversedCoordinates => {
177
164
  setState({
178
165
  ...state,
179
166
  mapPosition: { coordinates: reversedCoordinates, zoom: 3 }
@@ -207,16 +194,16 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
207
194
  }
208
195
 
209
196
  // States
210
- uid = stateKeys.find((key) => supportedStates[key].includes(geoName))
197
+ uid = stateKeys.find(key => supportedStates[key].includes(geoName))
211
198
 
212
199
  // Territories
213
200
  if (!uid) {
214
- uid = territoryKeys.find((key) => supportedTerritories[key].includes(geoName))
201
+ uid = territoryKeys.find(key => supportedTerritories[key].includes(geoName))
215
202
  }
216
203
 
217
204
  // Cities
218
205
  if (!uid) {
219
- uid = cityKeys.find((key) => key === geoName)
206
+ uid = cityKeys.find(key => key === geoName)
220
207
  }
221
208
  }
222
209
 
@@ -230,20 +217,20 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
230
217
  }
231
218
 
232
219
  // Regions
233
- uid = regionKeys.find((key) => supportedRegions[key].includes(geoName))
220
+ uid = regionKeys.find(key => supportedRegions[key].includes(geoName))
234
221
  }
235
222
 
236
223
  // World Check
237
224
  if ('world' === obj.general.geoType) {
238
225
  const geoName = row[obj.columns.geo.name]
239
226
 
240
- uid = countryKeys.find((key) => supportedCountries[key].includes(geoName))
227
+ uid = countryKeys.find(key => supportedCountries[key].includes(geoName))
241
228
  }
242
229
 
243
230
  // County Check
244
231
  if (('us-county' === obj.general.geoType || 'single-state' === obj.general.geoType) && 'us-geocode' !== obj.general.type) {
245
232
  const fips = row[obj.columns.geo.name]
246
- uid = countyKeys.find((key) => key === fips)
233
+ uid = countyKeys.find(key => key === fips)
247
234
  }
248
235
 
249
236
  if ('us-geocode' === state.general.type) {
@@ -263,8 +250,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
263
250
 
264
251
  const generateRuntimeLegend = useCallback((obj, runtimeData, hash) => {
265
252
  const newLegendMemo = new Map() // Reset memoization
266
- const
267
- primaryCol = obj.columns.primary.name,
253
+ const primaryCol = obj.columns.primary.name,
268
254
  isData = obj.general.type === 'data',
269
255
  isBubble = obj.general.type === 'bubble',
270
256
  categoricalCol = obj.columns.categorical ? obj.columns.categorical.name : undefined,
@@ -281,19 +267,19 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
281
267
  let dataSet = obj.legend.unified ? obj.data : Object.values(runtimeData)
282
268
 
283
269
  const colorDistributions = {
284
- 1: [ 1 ],
285
- 2: [ 1, 3 ],
286
- 3: [ 1, 3, 5 ],
287
- 4: [ 0, 2, 4, 6 ],
288
- 5: [ 0, 2, 4, 6, 7 ],
289
- 6: [ 0, 2, 3, 4, 5, 7 ],
290
- 7: [ 0, 2, 3, 4, 5, 6, 7 ],
291
- 8: [ 0, 2, 3, 4, 5, 6, 7, 8 ],
292
- 9: [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ],
293
- 10: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
270
+ 1: [1],
271
+ 2: [1, 3],
272
+ 3: [1, 3, 5],
273
+ 4: [0, 2, 4, 6],
274
+ 5: [0, 2, 4, 6, 7],
275
+ 6: [0, 2, 3, 4, 5, 7],
276
+ 7: [0, 2, 3, 4, 5, 6, 7],
277
+ 8: [0, 2, 3, 4, 5, 6, 7, 8],
278
+ 9: [0, 1, 2, 3, 4, 5, 6, 7, 8],
279
+ 10: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
294
280
  }
295
281
 
296
- const applyColorToLegend = (legendIdx) => {
282
+ const applyColorToLegend = legendIdx => {
297
283
  // Default to "bluegreen" color scheme if the passed color isn't valid
298
284
  let mapColorPalette = obj.customColors || colorPalettes[obj.color] || colorPalettes['bluegreen']
299
285
 
@@ -310,7 +296,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
310
296
 
311
297
  // Special Classes (No Data)
312
298
  if (result[legendIdx].special) {
313
- const specialClassColors = chroma.scale([ '#D4D4D4', '#939393' ]).colors(specialClasses)
299
+ const specialClassColors = chroma.scale(['#D4D4D4', '#939393']).colors(specialClasses)
314
300
 
315
301
  return specialClassColors[legendIdx]
316
302
  }
@@ -410,7 +396,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
410
396
  if (undefined === value) continue
411
397
 
412
398
  if (false === uniqueValues.has(value)) {
413
- uniqueValues.set(value, [ hashObj(row) ])
399
+ uniqueValues.set(value, [hashObj(row)])
414
400
  count++
415
401
  } else {
416
402
  uniqueValues.get(value).push(hashObj(row))
@@ -419,15 +405,11 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
419
405
  if (count === 10) break // Can only have 10 categorical items for now
420
406
  }
421
407
 
422
- let sorted = [ ...uniqueValues.keys() ]
408
+ let sorted = [...uniqueValues.keys()]
423
409
 
424
410
  // Apply custom sorting or regular sorting
425
411
  let configuredOrder = obj.legend.categoryValuesOrder ?? []
426
412
 
427
- // Coerce strings to numbers inside configuredOrder property
428
- for(let i = 0; i < configuredOrder.length; i++) {
429
- configuredOrder[i] = numberFromString(configuredOrder[i])
430
- }
431
413
 
432
414
  if (configuredOrder.length) {
433
415
  sorted.sort((a, b) => {
@@ -438,9 +420,9 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
438
420
  }
439
421
 
440
422
  // Add legend item for each
441
- sorted.forEach((val) => {
423
+ sorted.forEach(val => {
442
424
  result.push({
443
- value: val,
425
+ value: val
444
426
  })
445
427
 
446
428
  let lastIdx = result.length - 1
@@ -500,12 +482,14 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
500
482
 
501
483
  // Sort data for use in equalnumber or equalinterval
502
484
  if (state.general.type !== 'us-geocode') {
503
- dataSet = dataSet.filter(row => typeof row[primaryCol] === 'number').sort((a, b) => {
504
- let aNum = a[primaryCol]
505
- let bNum = b[primaryCol]
485
+ dataSet = dataSet
486
+ .filter(row => typeof row[primaryCol] === 'number')
487
+ .sort((a, b) => {
488
+ let aNum = a[primaryCol]
489
+ let bNum = b[primaryCol]
506
490
 
507
- return aNum - bNum
508
- })
491
+ return aNum - bNum
492
+ })
509
493
  }
510
494
 
511
495
  // Equal Number
@@ -558,8 +542,9 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
558
542
  let colors = colorPalettes[state.color]
559
543
  let colorRange = colors.slice(0, state.legend.numberOfItems)
560
544
 
561
- let scale = d3.scaleQuantile()
562
- .domain([ ...new Set(dataSet.map(item => Math.round(item[state.columns.primary.name]))) ]) // min/max values
545
+ let scale = d3
546
+ .scaleQuantile()
547
+ .domain([...new Set(dataSet.map(item => Math.round(item[state.columns.primary.name])))]) // min/max values
563
548
  .range(colorRange) // set range to our colors array
564
549
 
565
550
  let breaks = scale.quantiles()
@@ -572,7 +557,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
572
557
  }
573
558
 
574
559
  breaks.map((item, index) => {
575
- const setMin = (index) => {
560
+ const setMin = index => {
576
561
  //debugger;
577
562
  let min = breaks[index]
578
563
 
@@ -665,7 +650,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
665
650
  for (let i = 0; i < legendNumber; i++) {
666
651
  let interval = Math.abs(dataMax - dataMin) / legendNumber
667
652
 
668
- let min = dataMin + (interval * i)
653
+ let min = dataMin + interval * i
669
654
  let max = min + interval
670
655
 
671
656
  // If this is the last loop, assign actual max of data as the end point
@@ -679,7 +664,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
679
664
 
680
665
  let range = {
681
666
  min: Math.round(min * 100) / 100,
682
- max: Math.round(max * 100) / 100,
667
+ max: Math.round(max * 100) / 100
683
668
  }
684
669
 
685
670
  result.push(range)
@@ -768,11 +753,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
768
753
  if (undefined === row.uid) return false // No UID for this row, we can't use for mapping
769
754
 
770
755
  // When on a single state map filter runtime data by state
771
- if (
772
- !(String(row[obj.columns.geo.name]).substring(0, 2) === obj.general?.statePicked?.fipsCode) &&
773
- obj.general.geoType === 'single-state' &&
774
- obj.general.type !== 'us-geocode'
775
- ) {
756
+ if (!(String(row[obj.columns.geo.name]).substring(0, 2) === obj.general?.statePicked?.fipsCode) && obj.general.geoType === 'single-state' && obj.general.type !== 'us-geocode') {
776
757
  return false
777
758
  }
778
759
 
@@ -832,10 +813,10 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
832
813
  const ie = navigator.userAgent.match(/MSIE\s([\d.]+)/)
833
814
  const ie11 = navigator.userAgent.match(/Trident\/7.0/) && navigator.userAgent.match(/rv:11/)
834
815
  const ieEdge = navigator.userAgent.match(/Edge/g)
835
- const ieVer = (ie ? ie[1] : (ie11 ? 11 : (ieEdge ? 12 : -1)))
816
+ const ieVer = ie ? ie[1] : ie11 ? 11 : ieEdge ? 12 : -1
836
817
 
837
818
  if (ieVer > -1) {
838
- const fileAsBlob = new Blob([ uri ], {
819
+ const fileAsBlob = new Blob([uri], {
839
820
  type: 'image/png'
840
821
  })
841
822
  window.navigator.msSaveBlob(fileAsBlob, filename)
@@ -844,7 +825,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
844
825
  if (typeof link.download === 'string') {
845
826
  link.href = uri
846
827
  link.download = filename
847
- link.onclick = (e) => document.body.removeChild(e.target)
828
+ link.onclick = e => document.body.removeChild(e.target)
848
829
  document.body.appendChild(link)
849
830
  link.click()
850
831
  } else {
@@ -891,12 +872,14 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
891
872
  windowWidth: 1440,
892
873
  scale: 1,
893
874
  logging: false
894
- }).then(canvas => {
895
- saveImageAs(canvas.toDataURL(), filename + '.png')
896
- }).then(() => {
897
- generatedImage.remove() // Remove generated png
898
- baseSvg.style.display = null // Re-display initial svg map
899
875
  })
876
+ .then(canvas => {
877
+ saveImageAs(canvas.toDataURL(), filename + '.png')
878
+ })
879
+ .then(() => {
880
+ generatedImage.remove() // Remove generated png
881
+ baseSvg.style.display = null // Re-display initial svg map
882
+ })
900
883
  case 'pdf':
901
884
  let opt = {
902
885
  margin: 0.2,
@@ -906,13 +889,17 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
906
889
  jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }
907
890
  }
908
891
 
909
- html2pdf().set(opt).from(target).save().then(() => {
910
- generatedImage.remove() // Remove generated png
911
- baseSvg.style.display = null // Re-display initial svg map
912
- })
892
+ html2pdf()
893
+ .set(opt)
894
+ .from(target)
895
+ .save()
896
+ .then(() => {
897
+ generatedImage.remove() // Remove generated png
898
+ baseSvg.style.display = null // Re-display initial svg map
899
+ })
913
900
  break
914
901
  default:
915
- console.warn('generateMedia param 2 type must be \'image\' or \'pdf\'')
902
+ console.warn("generateMedia param 2 type must be 'image' or 'pdf'")
916
903
  break
917
904
  }
918
905
  }
@@ -922,11 +909,11 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
922
909
  resetLegendToggles()
923
910
 
924
911
  try {
925
- const isEmpty = (obj) => {
912
+ const isEmpty = obj => {
926
913
  return Object.keys(obj).length === 0
927
914
  }
928
915
 
929
- let filters = [ ...runtimeFilters ]
916
+ let filters = [...runtimeFilters]
930
917
 
931
918
  filters[idx] = { ...filters[idx] }
932
919
  filters[idx].active = activeValue
@@ -988,7 +975,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
988
975
  return formattedValue
989
976
  }
990
977
 
991
- const applyLegendToRow = (rowObj) => {
978
+ const applyLegendToRow = rowObj => {
992
979
  try {
993
980
  if (!rowObj) throw new Error('COVE: No rowObj in applyLegendToRow')
994
981
  // Navigation map
@@ -1013,16 +1000,11 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1013
1000
  }
1014
1001
 
1015
1002
  const applyTooltipsToGeo = (geoName, row, returnType = 'string') => {
1016
-
1017
- if(!row) return;
1003
+ if (!row) return
1018
1004
  let toolTipText = ''
1019
1005
 
1020
1006
  // Adds geo label, ie State: Georgia
1021
- let stateOrCounty = state.general.geoType === 'us'
1022
- ? 'State: '
1023
- : (state.general.geoType === 'us-county' || state.general.geoType === 'single-state')
1024
- ? 'County: '
1025
- : ''
1007
+ let stateOrCounty = state.general.geoType === 'us' ? 'State: ' : state.general.geoType === 'us-county' || state.general.geoType === 'single-state' ? 'County: ' : ''
1026
1008
 
1027
1009
  if (state.general.geoType === 'us-county' && state.general.type !== 'us-geocode') {
1028
1010
  let stateFipsCode = row[state.columns.geo.name].substring(0, 2)
@@ -1036,7 +1018,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1036
1018
  if (('data' === state.general.type || state.general.type === 'bubble' || state.general.type === 'us-geocode') && undefined !== row) {
1037
1019
  toolTipText += `<dl>`
1038
1020
 
1039
- Object.keys(state.columns).forEach((columnKey) => {
1021
+ Object.keys(state.columns).forEach(columnKey => {
1040
1022
  const column = state.columns[columnKey]
1041
1023
 
1042
1024
  if (true === column.tooltip) {
@@ -1057,7 +1039,8 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1057
1039
  value = displayDataAsText(row[column.name], columnKey)
1058
1040
  }
1059
1041
 
1060
- if (0 < value.length) { // Only spit out the tooltip if there's a value there
1042
+ if (0 < value.length) {
1043
+ // Only spit out the tooltip if there's a value there
1061
1044
  toolTipText += state.general.hidePrimaryColumnInTooltip ? `<div><dd>${value}</dd></div>` : `<div><dt>${label}</dt><dd>${value}</dd></div>`
1062
1045
  }
1063
1046
  }
@@ -1067,23 +1050,31 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1067
1050
 
1068
1051
  // We convert the markup into JSX and add a navigation link if it's going into a modal.
1069
1052
  if ('jsx' === returnType) {
1070
- toolTipText = [ (<div key="modal-content">{parse(toolTipText)}</div>) ]
1053
+ toolTipText = [<div key='modal-content'>{parse(toolTipText)}</div>]
1071
1054
 
1072
1055
  if (state.columns.hasOwnProperty('navigate') && row[state.columns.navigate.name]) {
1073
- toolTipText.push((<span className="navigation-link" key="modal-navigation-link" onClick={() => navigationHandler(row[state.columns.navigate.name])}>{state.tooltips.linkLabel}<ExternalIcon className="inline-icon ml-1"/></span>))
1056
+ toolTipText.push(
1057
+ <span className='navigation-link' key='modal-navigation-link' onClick={() => navigationHandler(row[state.columns.navigate.name])}>
1058
+ {state.tooltips.linkLabel}
1059
+ <ExternalIcon className='inline-icon ml-1' />
1060
+ </span>
1061
+ )
1074
1062
  }
1075
1063
  }
1076
1064
 
1077
1065
  return toolTipText
1078
1066
  }
1079
1067
 
1080
- const titleCase = (string) => {
1081
- return string.split(' ').map(word => word.charAt(0).toUpperCase() + word.substring(1).toLowerCase()).join(' ')
1068
+ const titleCase = string => {
1069
+ return string
1070
+ .split(' ')
1071
+ .map(word => word.charAt(0).toUpperCase() + word.substring(1).toLowerCase())
1072
+ .join(' ')
1082
1073
  }
1083
1074
 
1084
1075
  // This resets all active legend toggles.
1085
1076
  const resetLegendToggles = async () => {
1086
- let newLegend = [ ...runtimeLegend ]
1077
+ let newLegend = [...runtimeLegend]
1087
1078
 
1088
1079
  newLegend.forEach(legendItem => {
1089
1080
  delete legendItem.disabled
@@ -1092,7 +1083,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1092
1083
  setRuntimeLegend(newLegend)
1093
1084
  }
1094
1085
 
1095
- const formatLegendLocation = (key) => {
1086
+ const formatLegendLocation = key => {
1096
1087
  let value = key
1097
1088
  let formattedName = ''
1098
1089
  let stateName = stateFipsToTwoDigit[key.substring(0, 2)]
@@ -1109,7 +1100,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1109
1100
  }
1110
1101
 
1111
1102
  // Attempts to find the corresponding value
1112
- const displayGeoName = (key) => {
1103
+ const displayGeoName = key => {
1113
1104
  let value = key
1114
1105
 
1115
1106
  // Map to first item in values array which is the preferred label
@@ -1132,9 +1123,9 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1132
1123
  const dict = {
1133
1124
  'Washington D.C.': 'District of Columbia',
1134
1125
  'WASHINGTON DC': 'District of Columbia',
1135
- 'DC': 'District of Columbia',
1126
+ DC: 'District of Columbia',
1136
1127
  'WASHINGTON DC.': 'District of Columbia',
1137
- 'Congo': 'Republic of the Congo'
1128
+ Congo: 'Republic of the Congo'
1138
1129
  }
1139
1130
 
1140
1131
  if (true === Object.keys(dict).includes(value)) {
@@ -1143,7 +1134,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1143
1134
  return titleCase(value)
1144
1135
  }
1145
1136
 
1146
- const navigationHandler = (urlString) => {
1137
+ const navigationHandler = urlString => {
1147
1138
  // Call custom navigation method if passed
1148
1139
  if (customNavigationHandler) {
1149
1140
  customNavigationHandler(urlString)
@@ -1182,12 +1173,10 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1182
1173
  }
1183
1174
  }
1184
1175
 
1185
- const validateFipsCodeLength = (newState) => {
1186
- if (newState.general.geoType === 'us-county' || newState.general.geoType === 'single-state' || newState.general.geoType === 'us' && newState?.data) {
1187
-
1176
+ const validateFipsCodeLength = newState => {
1177
+ if (newState.general.geoType === 'us-county' || newState.general.geoType === 'single-state' || (newState.general.geoType === 'us' && newState?.data)) {
1188
1178
  newState?.data.forEach(dataPiece => {
1189
1179
  if (dataPiece[newState.columns.geo.name]) {
1190
-
1191
1180
  if (!isNaN(parseInt(dataPiece[newState.columns.geo.name])) && dataPiece[newState.columns.geo.name].length === 4) {
1192
1181
  dataPiece[newState.columns.geo.name] = 0 + dataPiece[newState.columns.geo.name]
1193
1182
  }
@@ -1234,7 +1223,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1234
1223
  }
1235
1224
  }
1236
1225
 
1237
- const loadConfig = async (configObj) => {
1226
+ const loadConfig = async configObj => {
1238
1227
  // Set loading flag
1239
1228
  if (!loading) setLoading(true)
1240
1229
 
@@ -1244,16 +1233,15 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1244
1233
  ...configObj
1245
1234
  }
1246
1235
 
1236
+ // If a dataUrl property exists, always pull from that.
1237
+ if (newState.dataUrl) {
1238
+ if (newState.dataUrl[0] === '/') {
1239
+ newState.dataUrl = 'http://' + hostname + newState.dataUrl
1240
+ }
1247
1241
 
1248
- // If a dataUrl property exists, always pull from that.
1249
- if (newState.dataUrl) {
1250
- if(newState.dataUrl[0] === '/') {
1251
- newState.dataUrl = 'http://' + hostname + newState.dataUrl
1252
- }
1253
-
1254
- // handle urls with spaces in the name.
1255
- if (newState.dataUrl) newState.dataUrl = encodeURI(`${newState.dataUrl}?v=${cacheBustingString()}`)
1256
- let newData = await fetchRemoteData(newState.dataUrl )
1242
+ // handle urls with spaces in the name.
1243
+ if (newState.dataUrl) newState.dataUrl = encodeURI(`${newState.dataUrl}?v=${cacheBustingString()}`)
1244
+ let newData = await fetchRemoteData(newState.dataUrl)
1257
1245
 
1258
1246
  if (newData && newState.dataDescription) {
1259
1247
  newData = transform.autoStandardize(newData)
@@ -1268,10 +1256,10 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1268
1256
  // This code goes through and adds the defaults for every property declaring in the initial state at the top.
1269
1257
  // This allows you to easily add new properties to the config without having to worry about accounting for backwards compatibility.
1270
1258
  // Right now this does not work recursively -- only on first and second level properties. So state -> prop1 -> childprop1
1271
- Object.keys(newState).forEach((key) => {
1259
+ Object.keys(newState).forEach(key => {
1272
1260
  if ('object' === typeof newState[key] && false === Array.isArray(newState[key])) {
1273
1261
  if (initialState[key]) {
1274
- Object.keys(initialState[key]).forEach((property) => {
1262
+ Object.keys(initialState[key]).forEach(property => {
1275
1263
  if (undefined === newState[key][property]) {
1276
1264
  newState[key][property] = initialState[key][property]
1277
1265
  }
@@ -1323,14 +1311,14 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1323
1311
  publish('cove_loaded', { config: state })
1324
1312
  setCoveLoadedHasRan(true)
1325
1313
  }
1326
- }, [ state, container ])
1314
+ }, [state, container])
1327
1315
 
1328
1316
  useEffect(() => {
1329
1317
  if (state.data) {
1330
1318
  let newData = generateRuntimeData(state)
1331
1319
  setRuntimeData(newData)
1332
1320
  }
1333
- }, [ state.general.statePicked ])
1321
+ }, [state.general.statePicked])
1334
1322
 
1335
1323
  // When geotype changes
1336
1324
  useEffect(() => {
@@ -1338,7 +1326,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1338
1326
  if (state.data && state.columns.geo.name) {
1339
1327
  addUIDs(state, state.columns.geo.name)
1340
1328
  }
1341
- }, [ state ])
1329
+ }, [state])
1342
1330
 
1343
1331
  useEffect(() => {
1344
1332
  // UID
@@ -1394,8 +1382,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1394
1382
  const legend = generateRuntimeLegend(state, newRuntimeData || runtimeData, hashLegend)
1395
1383
  setRuntimeLegend(legend)
1396
1384
  }
1397
-
1398
- }, [ state ])
1385
+ }, [state])
1399
1386
 
1400
1387
  useEffect(() => {
1401
1388
  const hashLegend = hashObj({
@@ -1415,13 +1402,12 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1415
1402
  const legend = generateRuntimeLegend(state, runtimeData)
1416
1403
  setRuntimeLegend(legend)
1417
1404
  }
1418
-
1419
- }, [ runtimeData ])
1405
+ }, [runtimeData])
1420
1406
 
1421
1407
  if (config) {
1422
1408
  useEffect(() => {
1423
1409
  loadConfig(config)
1424
- }, [ config.data ])
1410
+ }, [config.data])
1425
1411
  }
1426
1412
 
1427
1413
  // Destructuring for more readable JSX
@@ -1429,24 +1415,14 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1429
1415
  const { title = '', subtext = '' } = general
1430
1416
 
1431
1417
  // Outer container classes
1432
- let outerContainerClasses = [
1433
- 'cdc-open-viz-module',
1434
- 'cdc-map-outer-container',
1435
- currentViewport
1436
- ]
1418
+ let outerContainerClasses = ['cdc-open-viz-module', 'cdc-map-outer-container', currentViewport]
1437
1419
 
1438
1420
  if (className) {
1439
1421
  outerContainerClasses.push(className)
1440
1422
  }
1441
1423
 
1442
1424
  // Map container classes
1443
- let mapContainerClasses = [
1444
- 'map-container',
1445
- state.legend.position,
1446
- state.general.type,
1447
- state.general.geoType,
1448
- 'outline-none'
1449
- ]
1425
+ let mapContainerClasses = ['map-container', state.legend.position, state.general.type, state.general.geoType, 'outline-none']
1450
1426
 
1451
1427
  if (modal) {
1452
1428
  mapContainerClasses.push('modal-background')
@@ -1482,7 +1458,7 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1482
1458
  handleMapAriaLabels
1483
1459
  }
1484
1460
 
1485
- if (!mapProps.data || !state.data) return <Loading/>
1461
+ if (!mapProps.data || !state.data) return <Loading />
1486
1462
 
1487
1463
  const hasDataTable = state.runtime.editorErrorMessage.length === 0 && true === dataTable.forceDisplay && general.type !== 'navigation' && false === loading
1488
1464
 
@@ -1512,178 +1488,118 @@ const CdcMap = ({ className, config, navigationHandler: customNavigationHandler,
1512
1488
 
1513
1489
  return (
1514
1490
  <div className={outerContainerClasses.join(' ')} ref={outerContainerRef}>
1515
- {isEditor && (
1516
- <EditorPanel
1517
- isDashboard={isDashboard}
1518
- state={state}
1519
- setState={setState}
1520
- loadConfig={loadConfig}
1521
- setParentConfig={setConfig}
1522
- setRuntimeFilters={setRuntimeFilters}
1523
- runtimeFilters={runtimeFilters}
1524
- runtimeLegend={runtimeLegend}
1525
- columnsInData={Object.keys(state.data[0])}
1526
- />
1527
- )}
1528
- {!runtimeData.init && (general.type === 'navigation' || runtimeLegend) && <section className={`cdc-map-inner-container ${currentViewport}`} aria-label={'Map: ' + title}>
1529
- {!window.matchMedia('(any-hover: none)').matches && 'hover' === tooltips.appearanceType && (
1530
- <ReactTooltip
1531
- id="tooltip"
1532
- place="right"
1533
- type="light"
1534
- html={true}
1535
- className={tooltips.capitalizeLabels ? 'capitalize tooltip' : 'tooltip'}
1536
- />
1537
- )}
1538
- {state.general.title &&
1539
- <header className={general.showTitle === true ? 'visible' : 'hidden'} {...(!general.showTitle || !state.general.title ? { 'aria-hidden': true } : { 'aria-hidden': false })}>
1540
- <div role="heading" className={'map-title ' + general.headerColor} tabIndex="0" aria-level="2">
1541
- <sup>{general.superTitle}</sup>
1542
- <div>{parse(title)}</div>
1543
- </div>
1544
- </header>
1545
- }
1546
-
1547
- <div>
1548
- {general.introText && <section className="introText">{parse(general.introText)}</section>}
1549
- </div>
1550
-
1551
- <section
1552
- role="button"
1553
- tabIndex="0"
1554
- className={mapContainerClasses.join(' ')}
1555
- onClick={(e) => closeModal(e)}
1556
- onKeyDown={(e) => {
1557
- if (e.keyCode === 13) {
1558
- closeModal(e)
1559
- }
1560
- }}
1561
- >
1562
- {general.showDownloadMediaButton === true && (
1563
- <div className="map-downloads" data-html2canvas-ignore>
1564
- <div className="map-downloads__ui btn-group">
1565
- <button
1566
- className="btn"
1567
- title="Download Map as Image"
1568
- onClick={() => generateMedia(outerContainerRef.current, 'image')}
1569
- >
1570
- <DownloadImg className="btn__icon" title="Download Map as Image"/>
1571
- </button>
1572
- <button
1573
- className="btn"
1574
- title="Download Map as PDF"
1575
- onClick={() => generateMedia(outerContainerRef.current, 'pdf')}
1576
- >
1577
- <DownloadPdf className="btn__icon" title="Download Map as PDF"/>
1578
- </button>
1491
+ {isEditor && <EditorPanel isDashboard={isDashboard} state={state} setState={setState} loadConfig={loadConfig} setParentConfig={setConfig} setRuntimeFilters={setRuntimeFilters} runtimeFilters={runtimeFilters} runtimeLegend={runtimeLegend} columnsInData={Object.keys(state.data[0])} />}
1492
+ {!runtimeData.init && (general.type === 'navigation' || runtimeLegend) && (
1493
+ <section className={`cdc-map-inner-container ${currentViewport}`} aria-label={'Map: ' + title}>
1494
+ {!window.matchMedia('(any-hover: none)').matches && 'hover' === tooltips.appearanceType && <ReactTooltip id='tooltip' place='right' type='light' html={true} className={tooltips.capitalizeLabels ? 'capitalize tooltip' : 'tooltip'} />}
1495
+ {state.general.title && (
1496
+ <header className={general.showTitle === true ? 'visible' : 'hidden'} {...(!general.showTitle || !state.general.title ? { 'aria-hidden': true } : { 'aria-hidden': false })}>
1497
+ <div role='heading' className={'map-title ' + general.headerColor} tabIndex='0' aria-level='2'>
1498
+ <sup>{general.superTitle}</sup>
1499
+ <div>{parse(title)}</div>
1579
1500
  </div>
1580
- </div>
1501
+ </header>
1581
1502
  )}
1582
1503
 
1583
- <a id="skip-geo-container" className="cdcdataviz-sr-only-focusable" href={tabId}>
1584
- Skip Over Map Container
1585
- </a>
1586
-
1587
- <section className="geography-container outline-none" ref={mapSvg} tabIndex="0">
1588
- {currentViewport && (
1589
- <section className="geography-container" ref={mapSvg}>
1590
- {modal && (
1591
- <Modal
1592
- type={general.type}
1593
- viewport={currentViewport}
1594
- applyTooltipsToGeo={applyTooltipsToGeo}
1595
- applyLegendToRow={applyLegendToRow}
1596
- capitalize={state.tooltips.capitalizeLabels}
1597
- content={modal}
1598
- />
1599
- )}
1600
- {'single-state' === general.geoType && (
1601
- <SingleStateMap supportedTerritories={supportedTerritories} {...mapProps} />
1602
- )}
1603
- {('us' === general.geoType && 'us-geocode' !== state.general.type) && (
1604
- <UsaMap supportedTerritories={supportedTerritories} {...mapProps} />
1605
- )}
1606
- {'us-region' === general.geoType && (
1607
- <UsaRegionMap supportedTerritories={supportedTerritories} {...mapProps} />
1608
- )}
1609
- {'world' === general.geoType && (
1610
- <WorldMap supportedCountries={supportedCountries} {...mapProps} />
1611
- )}
1612
- {('us-county' === general.geoType) && (
1613
- <CountyMap
1614
- supportedCountries={supportedCountries}
1615
- {...mapProps}
1616
- />
1617
- )}
1618
- {'data' === general.type && logo && <img src={logo} alt="" className="map-logo"/>}
1619
- </section>
1504
+ <div>{general.introText && <section className='introText'>{parse(general.introText)}</section>}</div>
1505
+
1506
+ <section
1507
+ role='button'
1508
+ tabIndex='0'
1509
+ className={mapContainerClasses.join(' ')}
1510
+ onClick={e => closeModal(e)}
1511
+ onKeyDown={e => {
1512
+ if (e.keyCode === 13) {
1513
+ closeModal(e)
1514
+ }
1515
+ }}
1516
+ >
1517
+ {general.showDownloadMediaButton === true && (
1518
+ <div className='map-downloads' data-html2canvas-ignore>
1519
+ <div className='map-downloads__ui btn-group'>
1520
+ <button className='btn' title='Download Map as Image' onClick={() => generateMedia(outerContainerRef.current, 'image')}>
1521
+ <DownloadImg className='btn__icon' title='Download Map as Image' />
1522
+ </button>
1523
+ <button className='btn' title='Download Map as PDF' onClick={() => generateMedia(outerContainerRef.current, 'pdf')}>
1524
+ <DownloadPdf className='btn__icon' title='Download Map as PDF' />
1525
+ </button>
1526
+ </div>
1527
+ </div>
1528
+ )}
1620
1529
 
1530
+ <a id='skip-geo-container' className='cdcdataviz-sr-only-focusable' href={tabId}>
1531
+ Skip Over Map Container
1532
+ </a>
1533
+
1534
+ <section className='geography-container outline-none' ref={mapSvg} tabIndex='0'>
1535
+ {currentViewport && (
1536
+ <section className='geography-container' ref={mapSvg}>
1537
+ {modal && <Modal type={general.type} viewport={currentViewport} applyTooltipsToGeo={applyTooltipsToGeo} applyLegendToRow={applyLegendToRow} capitalize={state.tooltips.capitalizeLabels} content={modal} />}
1538
+ {'single-state' === general.geoType && <SingleStateMap supportedTerritories={supportedTerritories} {...mapProps} />}
1539
+ {'us' === general.geoType && 'us-geocode' !== state.general.type && <UsaMap supportedTerritories={supportedTerritories} {...mapProps} />}
1540
+ {'us-region' === general.geoType && <UsaRegionMap supportedTerritories={supportedTerritories} {...mapProps} />}
1541
+ {'world' === general.geoType && <WorldMap supportedCountries={supportedCountries} {...mapProps} />}
1542
+ {'us-county' === general.geoType && <CountyMap supportedCountries={supportedCountries} {...mapProps} />}
1543
+ {'data' === general.type && logo && <img src={logo} alt='' className='map-logo' />}
1544
+ </section>
1545
+ )}
1546
+ </section>
1547
+
1548
+ {general.showSidebar && 'navigation' !== general.type && (
1549
+ <Sidebar
1550
+ viewport={currentViewport}
1551
+ legend={state.legend}
1552
+ runtimeLegend={runtimeLegend}
1553
+ setRuntimeLegend={setRuntimeLegend}
1554
+ runtimeFilters={runtimeFilters}
1555
+ columns={state.columns}
1556
+ sharing={state.sharing}
1557
+ prefix={state.columns.primary.prefix}
1558
+ suffix={state.columns.primary.suffix}
1559
+ setState={setState}
1560
+ resetLegendToggles={resetLegendToggles}
1561
+ changeFilterActive={changeFilterActive}
1562
+ setAccessibleStatus={setAccessibleStatus}
1563
+ displayDataAsText={displayDataAsText}
1564
+ />
1621
1565
  )}
1622
1566
  </section>
1623
1567
 
1624
- {general.showSidebar && 'navigation' !== general.type && (
1625
- <Sidebar
1626
- viewport={currentViewport}
1627
- legend={state.legend}
1628
- runtimeLegend={runtimeLegend}
1629
- setRuntimeLegend={setRuntimeLegend}
1630
- runtimeFilters={runtimeFilters}
1568
+ {'navigation' === general.type && <NavigationMenu mapTabbingID={tabId} displayGeoName={displayGeoName} data={runtimeData} options={general} columns={state.columns} navigationHandler={val => navigationHandler(val)} />}
1569
+
1570
+ {link && link}
1571
+
1572
+ {subtext.length > 0 && <p className='subtext'>{parse(subtext)}</p>}
1573
+
1574
+ {state.runtime.editorErrorMessage.length === 0 && true === dataTable.forceDisplay && general.type !== 'navigation' && false === loading && (
1575
+ <DataTable
1576
+ state={state}
1577
+ rawData={state.data}
1578
+ navigationHandler={navigationHandler}
1579
+ expandDataTable={general.expandDataTable}
1580
+ headerColor={general.headerColor}
1631
1581
  columns={state.columns}
1632
- sharing={state.sharing}
1633
- prefix={state.columns.primary.prefix}
1634
- suffix={state.columns.primary.suffix}
1635
- setState={setState}
1636
- resetLegendToggles={resetLegendToggles}
1637
- changeFilterActive={changeFilterActive}
1638
- setAccessibleStatus={setAccessibleStatus}
1582
+ showDownloadButton={general.showDownloadButton}
1583
+ runtimeLegend={runtimeLegend}
1584
+ runtimeData={runtimeData}
1639
1585
  displayDataAsText={displayDataAsText}
1586
+ displayGeoName={displayGeoName}
1587
+ applyLegendToRow={applyLegendToRow}
1588
+ tableTitle={dataTable.title}
1589
+ indexTitle={dataTable.indexLabel}
1590
+ mapTitle={general.title}
1591
+ viewport={currentViewport}
1592
+ formatLegendLocation={formatLegendLocation}
1593
+ setFilteredCountryCode={setFilteredCountryCode}
1594
+ tabbingId={tabId}
1640
1595
  />
1641
1596
  )}
1597
+
1598
+ {general.footnotes && <section className='footnotes'>{parse(general.footnotes)}</section>}
1642
1599
  </section>
1600
+ )}
1643
1601
 
1644
- {'navigation' === general.type && (
1645
- <NavigationMenu
1646
- mapTabbingID={tabId}
1647
- displayGeoName={displayGeoName}
1648
- data={runtimeData}
1649
- options={general}
1650
- columns={state.columns}
1651
- navigationHandler={(val) => navigationHandler(val)}
1652
- />
1653
- )}
1654
-
1655
- {link && link}
1656
-
1657
- {subtext.length > 0 && <p className="subtext">{parse(subtext)}</p>}
1658
-
1659
- {state.runtime.editorErrorMessage.length === 0 && true === dataTable.forceDisplay && general.type !== 'navigation' && false === loading && (
1660
- <DataTable
1661
- state={state}
1662
- rawData={state.data}
1663
- navigationHandler={navigationHandler}
1664
- expandDataTable={general.expandDataTable}
1665
- headerColor={general.headerColor}
1666
- columns={state.columns}
1667
- showDownloadButton={general.showDownloadButton}
1668
- runtimeLegend={runtimeLegend}
1669
- runtimeData={runtimeData}
1670
- displayDataAsText={displayDataAsText}
1671
- displayGeoName={displayGeoName}
1672
- applyLegendToRow={applyLegendToRow}
1673
- tableTitle={dataTable.title}
1674
- indexTitle={dataTable.indexLabel}
1675
- mapTitle={general.title}
1676
- viewport={currentViewport}
1677
- formatLegendLocation={formatLegendLocation}
1678
- setFilteredCountryCode={setFilteredCountryCode}
1679
- tabbingId={tabId}
1680
- />
1681
- )}
1682
-
1683
- {general.footnotes && <section className="footnotes">{parse(general.footnotes)}</section>}
1684
- </section>}
1685
-
1686
- <div aria-live="assertive" className="cdcdataviz-sr-only">
1602
+ <div aria-live='assertive' className='cdcdataviz-sr-only'>
1687
1603
  {accessibleStatus}
1688
1604
  </div>
1689
1605
  </div>