@cdc/map 2.6.3 → 4.22.10-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/LICENSE +201 -0
  2. package/dist/cdcmap.js +32 -18
  3. package/examples/bubble-us.json +363 -0
  4. package/examples/bubble-world.json +427 -0
  5. package/examples/default-county.json +64 -12
  6. package/examples/default-geocode.json +746 -0
  7. package/examples/default-hex.json +477 -0
  8. package/examples/default-usa-regions.json +118 -0
  9. package/examples/default-usa.json +1 -1
  10. package/examples/default-world-data.json +1450 -0
  11. package/examples/default-world.json +5 -3
  12. package/examples/example-city-state.json +46 -1
  13. package/examples/gallery/categorical-qualitative.json +797 -0
  14. package/examples/gallery/categorical-scale-based.json +739 -0
  15. package/examples/gallery/city-state.json +479 -0
  16. package/examples/gallery/county.json +22731 -0
  17. package/examples/gallery/equal-interval.json +1027 -0
  18. package/examples/gallery/equal-number.json +1027 -0
  19. package/examples/gallery/filterable.json +909 -0
  20. package/examples/gallery/hex-filtered.json +420 -0
  21. package/examples/gallery/hex.json +413 -0
  22. package/examples/gallery/single-state.json +21402 -0
  23. package/examples/gallery/world.json +1592 -0
  24. package/examples/private/atsdr.json +439 -0
  25. package/examples/private/atsdr_new.json +436 -0
  26. package/examples/private/bubble.json +285 -0
  27. package/examples/private/city-state.json +428 -0
  28. package/examples/private/city-state2.json +434 -0
  29. package/examples/private/cty-issue.json +42768 -0
  30. package/examples/private/default-usa.json +460 -0
  31. package/examples/private/default-world-data.json +1444 -0
  32. package/examples/private/default.json +968 -0
  33. package/examples/private/legend-issue.json +1 -0
  34. package/examples/private/map-rounding-error.json +42759 -0
  35. package/examples/private/map.csv +60 -0
  36. package/examples/private/mdx.json +210 -0
  37. package/examples/private/monkeypox.json +376 -0
  38. package/examples/private/regions.json +52 -0
  39. package/examples/private/valid-data-map.csv +59 -0
  40. package/examples/private/wcmsrd-13881-data.json +2858 -0
  41. package/examples/private/wcmsrd-13881.json +5823 -0
  42. package/examples/private/wcmsrd-14492-data.json +292 -0
  43. package/examples/private/wcmsrd-14492.json +114 -0
  44. package/examples/private/wcmsrd-test.json +268 -0
  45. package/examples/private/world.json +1580 -0
  46. package/examples/private/worldmap.json +1490 -0
  47. package/package.json +51 -50
  48. package/src/CdcMap.js +1384 -1075
  49. package/src/components/BubbleList.js +244 -0
  50. package/src/components/CityList.js +79 -17
  51. package/src/components/CountyMap.js +104 -44
  52. package/src/components/DataTable.js +32 -22
  53. package/src/components/EditorPanel.js +977 -414
  54. package/src/components/Geo.js +1 -1
  55. package/src/components/Modal.js +2 -1
  56. package/src/components/NavigationMenu.js +4 -3
  57. package/src/components/Sidebar.js +14 -19
  58. package/src/components/SingleStateMap.js +178 -249
  59. package/src/components/UsaMap.js +104 -36
  60. package/src/components/UsaRegionMap.js +320 -0
  61. package/src/components/WorldMap.js +117 -34
  62. package/src/data/country-coordinates.js +250 -0
  63. package/src/data/{dfc-map.json → county-map.json} +0 -0
  64. package/src/data/initial-state.js +23 -3
  65. package/src/data/state-coordinates.js +55 -0
  66. package/src/data/supported-geos.js +101 -15
  67. package/src/data/us-regions-topo-2.json +360525 -0
  68. package/src/data/us-regions-topo.json +37894 -0
  69. package/src/hooks/useColorPalette.ts +96 -0
  70. package/src/index.html +8 -4
  71. package/src/scss/editor-panel.scss +78 -57
  72. package/src/scss/main.scss +1 -6
  73. package/src/scss/map.scss +126 -2
  74. package/src/scss/sidebar.scss +2 -1
  75. package/src/data/color-palettes.js +0 -200
  76. package/src/images/map-folded.svg +0 -1
@@ -18,4 +18,4 @@ const Geo = ({path, styles, stroke, strokeWidth, ...props}) => {
18
18
  )
19
19
  }
20
20
 
21
- export default memo(Geo)
21
+ export default memo(Geo)
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import closeIcon from '../images/close.svg?inline';
3
3
  import LegendCircle from '@cdc/core/components/LegendCircle';
4
4
 
5
+ //TODO: Where is this being used? Transfer to new Modal component?
5
6
  const Modal = (props) => {
6
7
  const {
7
8
  applyTooltipsToGeo,
@@ -28,4 +29,4 @@ const Modal = (props) => {
28
29
  };
29
30
 
30
31
 
31
- export default Modal;
32
+ export default Modal;
@@ -1,7 +1,7 @@
1
1
  import React, { useEffect, useState } from 'react';
2
2
 
3
3
  const NavigationMenu = ({
4
- data, navigationHandler, options, columns, displayGeoName
4
+ data, navigationHandler, options, columns, displayGeoName, mapTabbingID
5
5
  }) => {
6
6
  const [activeGeo, setActiveGeo] = useState('');
7
7
 
@@ -15,6 +15,7 @@ const NavigationMenu = ({
15
15
  navigationHandler(urlString);
16
16
  }
17
17
  };
18
+
18
19
  let navSelect; let
19
20
  navGo;
20
21
 
@@ -51,9 +52,9 @@ const NavigationMenu = ({
51
52
  return (
52
53
  <section className="navigation-menu">
53
54
  <form onSubmit={handleSubmit} type="get">
54
- <label htmlFor="dropdown">
55
+ <label htmlFor={mapTabbingID.replace('#', '')}>
55
56
  <div className="select-heading">{navSelect}</div>
56
- <select value={activeGeo} id="dropdown" onChange={(e) => setActiveGeo(e.target.value)}>
57
+ <select value={activeGeo} id={mapTabbingID.replace('#', '')} onChange={(e) => setActiveGeo(e.target.value)}>
57
58
  {Object.keys(dropdownItems).map((key, i) => <option key={key} value={key}>{key}</option>)}
58
59
  </select>
59
60
  </label>
@@ -16,18 +16,10 @@ const Sidebar = (props) => {
16
16
  setRuntimeLegend,
17
17
  prefix,
18
18
  suffix,
19
- viewport
19
+ viewport,
20
+ displayDataAsText
20
21
  } = props;
21
22
 
22
- const addCommas = (value) => {
23
- // If value is a number, apply specific formattings
24
- if (value && columns.primary.hasOwnProperty('useCommas') && columns.primary.useCommas === true) {
25
- return value.toLocaleString('en-US', { style: 'decimal' });
26
- }
27
-
28
- return value;
29
- };
30
-
31
23
  // Toggles if a legend is active and being applied to the map and data table.
32
24
  const toggleLegendActive = (i, legendLabel) => {
33
25
  const newValue = !runtimeLegend[i].disabled;
@@ -48,21 +40,22 @@ const Sidebar = (props) => {
48
40
  };
49
41
 
50
42
  const legendList = runtimeLegend.map((entry, idx) => {
51
- const entryMax = addCommas(entry.max);
52
43
 
53
- const entryMin = addCommas(entry.min);
44
+ const entryMax = displayDataAsText(entry.max, 'primary');
54
45
 
55
- let formattedText = `${prefix + entryMin + suffix}${entryMax !== entryMin ? ` - ${prefix + entryMax + suffix}` : ''}`;
46
+ const entryMin = displayDataAsText(entry.min, 'primary');
47
+
48
+ let formattedText = `${entryMin}${entryMax !== entryMin ? ` - ${entryMax}` : ''}`;
56
49
 
57
50
  // If interval, add some formatting
58
51
  if (legend.type === 'equalinterval' && idx !== runtimeLegend.length - 1) {
59
- formattedText = `${prefix + entryMin + suffix} - < ${prefix + entryMax + suffix}`;
52
+ formattedText = `${entryMin} - < ${entryMax}`;
60
53
  }
61
54
 
62
55
  const { disabled } = entry;
63
56
 
64
57
  if (legend.type === 'category') {
65
- formattedText = prefix + entry.value + suffix;
58
+ formattedText = displayDataAsText(entry.value, 'primary');
66
59
  }
67
60
 
68
61
  if (entry.max === 0 && entry.min === 0) {
@@ -76,12 +69,13 @@ const Sidebar = (props) => {
76
69
  }
77
70
 
78
71
  return (
79
- <li
72
+ <li
73
+ className={disabled ? 'disabled single-legend' : 'single-legend'}
80
74
  key={idx}
81
75
  title={`Legend item ${legendLabel} - Click to disable`}
82
- onClick={() => { toggleLegendActive(idx, legendLabel); }}
83
- className={disabled ? 'disabled single-legend' : 'single-legend'}
84
- ><LegendCircle fill={entry.color} /> <span className="label">{legendLabel}</span>
76
+ onClick={() => { toggleLegendActive(idx, legendLabel); } }
77
+ >
78
+ <LegendCircle fill={entry.color} /> <span className="label">{legendLabel}</span>
85
79
  </li>
86
80
  );
87
81
  });
@@ -105,6 +99,7 @@ const Sidebar = (props) => {
105
99
  <select
106
100
  id={`filter-${idx}`}
107
101
  className="filter-select"
102
+ aria-label="select filter"
108
103
  value={singleFilter.active}
109
104
  onChange={(val) => {
110
105
  changeFilterActive(idx, val.target.value);
@@ -1,72 +1,14 @@
1
- import React, { useState, useEffect, memo, useRef } from 'react';
1
+ import React, { useState, useEffect, memo } from 'react';
2
2
  /** @jsx jsx */
3
3
  import { jsx } from '@emotion/react'
4
4
  import ErrorBoundary from '@cdc/core/components/ErrorBoundary';
5
- import { geoCentroid, geoPath } from "d3-geo";
5
+ import { geoPath } from "d3-geo";
6
6
  import { feature, mesh } from "topojson-client";
7
7
  import { CustomProjection } from '@visx/geo';
8
- import colorPalettes from '../data/color-palettes';
8
+ import colorPalettes from '../../../core/data/colorPalettes';
9
9
  import { geoAlbersUsaTerritories } from 'd3-composite-projections';
10
- import testJSON from '../data/dfc-map.json';
11
-
12
- const abbrs = {
13
- Alabama: 'AL',
14
- Alaska: 'AK',
15
- Arizona: 'AZ',
16
- Arkansas: 'AR',
17
- California: 'CA',
18
- Colorado: 'CO',
19
- Connecticut: 'CT',
20
- Delaware: 'DE',
21
- Florida: 'FL',
22
- Georgia: 'GA',
23
- Hawaii: 'HI',
24
- Idaho: 'ID',
25
- Illinois: 'IL',
26
- Indiana: 'IN',
27
- Iowa: 'IA',
28
- Kansas: 'KS',
29
- Kentucky: 'KY',
30
- Louisiana: 'LA',
31
- Maine: 'ME',
32
- Maryland: 'MD',
33
- Massachusetts: 'MA',
34
- Michigan: 'MI',
35
- Minnesota: 'MN',
36
- Mississippi: 'MS',
37
- Missouri: 'MO',
38
- Montana: 'MT',
39
- Nebraska: 'NE',
40
- Nevada: 'NV',
41
- 'New Hampshire': 'NH',
42
- 'New Jersey': 'NJ',
43
- 'New Mexico': 'NM',
44
- 'New York': 'NY',
45
- 'North Carolina': 'NC',
46
- 'North Dakota': 'ND',
47
- Ohio: 'OH',
48
- Oklahoma: 'OK',
49
- Oregon: 'OR',
50
- Pennsylvania: 'PA',
51
- 'Rhode Island': 'RI',
52
- 'South Carolina': 'SC',
53
- 'South Dakota': 'SD',
54
- Tennessee: 'TN',
55
- Texas: 'TX',
56
- Utah: 'UT',
57
- Vermont: 'VT',
58
- Virginia: 'VA',
59
- Washington: 'WA',
60
- 'West Virginia': 'WV',
61
- Wisconsin: 'WI',
62
- Wyoming: 'WY',
63
- 'District of Columbia': 'DC',
64
- Guam: 'GU',
65
- 'Virgin Islands': 'VI',
66
- 'Puerto Rico': 'PR',
67
- 'American Samoa': 'AS'
68
- }
69
-
10
+ import testJSON from '../data/county-map.json';
11
+ import CityList from './CityList';
70
12
 
71
13
 
72
14
  // SVG ITEMS
@@ -78,15 +20,6 @@ const PADDING = 25;
78
20
  let { features: counties } = feature(testJSON, testJSON.objects.counties)
79
21
  let { features: states } = feature(testJSON, testJSON.objects.states);
80
22
 
81
- // CONSTANTS
82
- const STATE_BORDER = '#c0cad4';
83
- const STATE_INACTIVE_FILL = '#F4F7FA';
84
-
85
- // CREATE STATE LINES
86
- // const projection = geoAlbersUsaTerritories().translate([WIDTH/2,HEIGHT/2])
87
-
88
-
89
-
90
23
  const SingleStateMap = (props) => {
91
24
 
92
25
  const {
@@ -99,226 +32,222 @@ const SingleStateMap = (props) => {
99
32
  supportedTerritories,
100
33
  rebuildTooltips,
101
34
  runtimeLegend,
102
- generateColorsArray
35
+ generateColorsArray,
36
+ handleMapAriaLabels,
37
+ titleCase,
38
+ setSharedFilterValue,
39
+ isFilterValueSupported
103
40
  } = props;
104
41
 
105
-
106
-
107
- const projection = geoAlbersUsaTerritories().translate([WIDTH/2, HEIGHT/2])
108
-
42
+ const projection = geoAlbersUsaTerritories().translate([WIDTH / 2, HEIGHT / 2])
43
+ const cityListProjection = geoAlbersUsaTerritories().translate([WIDTH / 2, HEIGHT / 2])
109
44
  const geoStrokeColor = state.general.geoBorderColor === 'darkGray' ? 'rgba(0, 0, 0, 0.2)' : 'rgba(255,255,255,0.7)'
110
-
111
- const [stateToShow, setStateToShow ] = useState( null )
112
- const [countiesToShow, setCountiesToShow] = useState( null )
45
+ const [stateToShow, setStateToShow] = useState(null)
46
+ const [countiesToShow, setCountiesToShow] = useState(null)
113
47
  const [translate, setTranslate] = useState()
114
48
  const [scale, setScale] = useState()
115
- const [strokeWidth, setStrokeWidth ] = useState(.75)
116
-
49
+ const [strokeWidth, setStrokeWidth] = useState(.75)
117
50
  let mapColorPalette = colorPalettes[state.color] || '#fff';
118
51
  let focusedBorderColor = mapColorPalette[3];
52
+
119
53
  useEffect(() => rebuildTooltips());
120
54
 
121
55
  const path = geoPath().projection(projection)
122
56
 
123
57
  // When choosing a state changes...
124
58
  useEffect(() => {
125
- if(state.general.hasOwnProperty('statePicked')) {
126
- let statePicked = state.general.statePicked.stateName;
127
- let statePickedData = states.find(s => s.properties.name === statePicked)
128
- setStateToShow(statePickedData)
129
-
130
- let countiesFound = counties.filter( c => c.id.substring(0,2) === state.general.statePicked.fipsCode)
131
-
132
- setCountiesToShow(countiesFound)
133
-
134
- const projection = geoAlbersUsaTerritories().translate([WIDTH/2,HEIGHT/2])
135
- const newProjection = projection.fitExtent([[PADDING, PADDING], [WIDTH - PADDING, HEIGHT - PADDING]], statePickedData)
136
- const newScale = newProjection.scale();
137
- const newScaleWithHypot = newScale / 1070;
138
-
139
- let [x, y] = newProjection.translate()
140
- x = (x - WIDTH/2);
141
- y = (y - HEIGHT/2);
142
-
143
- setTranslate([x,y])
144
- setScale(newScaleWithHypot)
145
-
146
- }
147
- }, [state.general.statePicked]);
59
+ if (state.general.hasOwnProperty('statePicked')) {
60
+ let statePicked = state.general.statePicked.stateName;
61
+ let statePickedData = states.find(s => s.properties.name === statePicked)
62
+ setStateToShow(statePickedData)
148
63
 
149
- const geoLabel = (geo, projection) => {
150
- //projection = geoAlbersUsaTerritories().translate([WIDTH/2,HEIGHT/2])
151
- //const newProjection = projection.fitExtent([[PADDING, PADDING], [WIDTH - PADDING, HEIGHT - PADDING]], geo)
152
- let [x, y] = projection( geoCentroid(geo) )
153
- let abbr = abbrs[geo.properties.name]
154
- if (abbr === 'NJ') x += 3
155
- if(undefined === abbr) return null
156
- let [dx, dy] = offsets[geo.properties.name]
157
-
158
- return (
159
- <>
160
- <line className="abbrLine" x1={x} y1={y} x2={x + dx} y2={y + dy} stroke="black" strokeWidth={1} />
161
- <text className="abbrText" x={4} strokeWidth="0" fontSize={13} style={{fill: "#202020"}} alignmentBaseline="middle" transform={`translate(${x + dx}, ${y + dy})`}>
162
- {abbr}
163
- </text>
164
- </>
165
- )
166
- }
64
+ let countiesFound = counties.filter(c => c.id.substring(0, 2) === state.general.statePicked.fipsCode)
65
+
66
+ setCountiesToShow(countiesFound)
67
+
68
+ const projection = geoAlbersUsaTerritories().translate([WIDTH / 2, HEIGHT / 2])
69
+ const newProjection = projection.fitExtent([[PADDING, PADDING], [WIDTH - PADDING, HEIGHT - PADDING]], statePickedData)
70
+ const newScale = newProjection.scale();
71
+ const newScaleWithHypot = newScale / 1070;
72
+
73
+ let [x, y] = newProjection.translate()
74
+ x = (x - WIDTH / 2);
75
+ y = (y - HEIGHT / 2);
76
+
77
+ setTranslate([x, y])
78
+ setScale(newScaleWithHypot)
79
+
80
+ }
81
+ }, [state.general.statePicked]);
167
82
 
168
83
  // Constructs and displays markup for all geos on the map (except territories right now)
169
84
  const constructGeoJsx = (geographies, projection) => {
170
- const statePassed = geographies[0].feature.states;
171
- const counties = geographies[0].feature.counties;
172
-
173
- let geosJsx = [];
85
+ const statePassed = geographies[0].feature.states;
86
+ const counties = geographies[0].feature.counties;
174
87
 
88
+ let geosJsx = [];
175
89
 
176
90
  const StateOutput = () => {
177
91
 
178
- let geo = testJSON.objects.states.geometries.filter( s => {
179
- return s.id === statePassed.id
180
- })
181
-
182
-
183
- // const stateLine = path(mesh(testJSON, lines ))
184
- let stateLines = path(mesh(testJSON, geo[0]))
185
- return (
186
- <g
187
- key={'single-state'}
188
- className="single-state"
189
- style={{ fill: '#E6E6E6'}}
190
- stroke={geoStrokeColor}
191
- strokeWidth={ .95 / scale }
192
- >
193
- <path
194
- tabIndex={-1}
195
- className='state-path'
196
- d={stateLines}
197
- />
198
- </g>
199
- )
92
+ let geo = testJSON.objects.states.geometries.filter(s => {
93
+ return s.id === statePassed.id
94
+ })
95
+
96
+ // const stateLine = path(mesh(testJSON, lines ))
97
+ let stateLines = path(mesh(testJSON, geo[0]))
98
+ return (
99
+ <g
100
+ key={'single-state'}
101
+ className="single-state"
102
+ style={{ fill: '#E6E6E6' }}
103
+ stroke={geoStrokeColor}
104
+ strokeWidth={.95 / scale}
105
+ >
106
+ <path
107
+ tabIndex={-1}
108
+ className='state-path'
109
+ d={stateLines}
110
+ />
111
+ </g>
112
+ )
200
113
  };
201
114
 
202
- const countyOutput = ( counties.map(( county ) => {
203
-
115
+ const countyOutput = (counties.map((county) => {
204
116
 
205
- // Map the name from the geo data with the appropriate key for the processed data
206
- let geoKey = county.id;
117
+ // Map the name from the geo data with the appropriate key for the processed data
118
+ let geoKey = county.id;
207
119
 
208
- if(!geoKey) return;
120
+ if (!geoKey) return;
209
121
 
210
- let countyPath = path(county);
211
-
212
- let geoData = data[county.id];
213
- let legendColors;
122
+ let countyPath = path(county);
214
123
 
215
- // Once we receive data for this geographic item, setup variables.
216
- if (geoData !== undefined ) {
217
- legendColors = applyLegendToRow(geoData);
218
- }
124
+ let geoData = data[county.id];
125
+ let legendColors;
219
126
 
220
- const geoDisplayName = displayGeoName(geoKey);
127
+ // Once we receive data for this geographic item, setup variables.
128
+ if (geoData !== undefined) {
129
+ legendColors = applyLegendToRow(geoData);
130
+ }
221
131
 
222
- // For some reason, these two geos are breaking the display.
223
- if (geoDisplayName === 'Franklin City' || geoDisplayName === 'Waynesboro') return null;
132
+ const geoDisplayName = displayGeoName(geoKey);
224
133
 
225
- const tooltip = applyTooltipsToGeo(geoDisplayName, geoData);
226
-
227
- if (legendColors && legendColors[0] !== '#000000') {
134
+ // For some reason, these two geos are breaking the display.
135
+ if (geoDisplayName === 'Franklin City' || geoDisplayName === 'Waynesboro') return null;
228
136
 
137
+ const tooltip = applyTooltipsToGeo(geoDisplayName, geoData);
229
138
 
230
- let styles = {
231
- fill: legendColors[0],
232
- cursor: 'default',
233
- '&:hover': {
234
- fill: legendColors[1],
235
- },
236
- '&:active': {
237
- fill: legendColors[2],
238
- },
239
- };
139
+ if (legendColors && legendColors[0] !== '#000000') {
240
140
 
241
- // When to add pointer cursor
242
- if ((state.columns.navigate && geoData[state.columns.navigate.name]) || state.tooltips.appearanceType === 'hover') {
243
- styles.cursor = 'pointer'
244
- }
245
141
 
246
- return (
247
- <g
248
- data-for="tooltip"
249
- data-tip={tooltip}
250
- key={`key--${county.id}`}
251
- className={`county county--${geoDisplayName.split(" ").join("")} county--${geoData[state.columns.geo.name]}`}
252
- css={styles}
253
- onClick={() => geoClickHandler(geoDisplayName, geoData)}
254
- >
255
- <path
256
- tabIndex={-1}
257
- className={`county`}
258
- stroke={geoStrokeColor}
259
- d={countyPath}
260
- strokeWidth={ .75 / scale }
261
- />
262
- </g>
263
- )
264
- } else {
265
- return (
266
- <g
267
- data-for="tooltip"
268
- data-tip={tooltip}
269
- key={`key--${county.id}`}
270
- className={`county county--${geoDisplayName.split(" ").join("")}`}
271
- style={{ fill : '#e6e6e6'}}
272
- >
273
- <path
274
- tabIndex={-1}
275
- className={`county`}
276
- stroke={geoStrokeColor}
277
- d={countyPath}
278
- strokeWidth={ .75 / scale }
279
- />
280
- </g>
281
- )
282
- }
142
+ let styles = {
143
+ fill: legendColors[0],
144
+ cursor: 'default',
145
+ '&:hover': {
146
+ fill: legendColors[1],
147
+ },
148
+ '&:active': {
149
+ fill: legendColors[2],
150
+ },
151
+ };
283
152
 
284
- }));
153
+ // When to add pointer cursor
154
+ if ((state.columns.navigate && geoData[state.columns.navigate.name]) || state.tooltips.appearanceType === 'hover') {
155
+ styles.cursor = 'pointer'
156
+ }
285
157
 
158
+ return (
159
+ <g
160
+ data-for="tooltip"
161
+ data-tip={tooltip}
162
+ key={`key--${county.id}`}
163
+ className={`county county--${geoDisplayName.split(" ").join("")} county--${geoData[state.columns.geo.name]}`}
164
+ css={styles}
165
+ onClick={() => geoClickHandler(geoDisplayName, geoData)}
166
+ >
167
+ <path
168
+ tabIndex={-1}
169
+ className={`county`}
170
+ stroke={geoStrokeColor}
171
+ d={countyPath}
172
+ strokeWidth={.75 / scale}
173
+ />
174
+ </g>
175
+ )
176
+ } else {
177
+ return (
178
+ <g
179
+ data-for="tooltip"
180
+ data-tip={tooltip}
181
+ key={`key--${county.id}`}
182
+ className={`county county--${geoDisplayName.split(" ").join("")}`}
183
+ style={{ fill: '#e6e6e6' }}
184
+ >
185
+ <path
186
+ tabIndex={-1}
187
+ className={`county`}
188
+ stroke={geoStrokeColor}
189
+ d={countyPath}
190
+ strokeWidth={.75 / scale}
191
+ />
192
+ </g>
193
+ )
194
+ }
286
195
 
287
- geosJsx.push( <StateOutput /> );
288
- geosJsx.push( countyOutput );
196
+ }));
197
+
198
+
199
+ geosJsx.push(<StateOutput />);
200
+ geosJsx.push(countyOutput);
201
+ geosJsx.push(<CityList
202
+ projection={cityListProjection}
203
+ key="cities"
204
+ data={data}
205
+ state={state}
206
+ geoClickHandler={geoClickHandler}
207
+ applyTooltipsToGeo={applyTooltipsToGeo}
208
+ displayGeoName={displayGeoName}
209
+ applyLegendToRow={applyLegendToRow}
210
+ titleCase={titleCase}
211
+ setSharedFilterValue={setSharedFilterValue}
212
+ isFilterValueSupported={isFilterValueSupported}
213
+ isGeoCodeMap={state.general.type === 'us-geocode'}
214
+ />)
289
215
 
290
216
  return geosJsx;
291
217
  };
292
218
 
293
-
294
219
  return (
295
220
  <ErrorBoundary component="SingleStateMap">
296
- {stateToShow &&
297
- <svg viewBox={`0 0 ${WIDTH} ${HEIGHT}`} preserveAspectRatio="xMinYMin" className="svg-container">
298
- <rect className="background center-container ocean" width={WIDTH} height={HEIGHT} fillOpacity={1} fill="white"></rect>
299
- <CustomProjection
300
- data={ [{states: stateToShow, counties: countiesToShow }] }
301
- // translate={translate}
302
- // scale={scale}
303
- projection={geoAlbersUsaTerritories}
304
- fitExtent={[[[PADDING, PADDING], [WIDTH - PADDING, HEIGHT - PADDING]], stateToShow]}
305
- >
306
- { ({ features, projection }) => {
307
- return (
308
- <g
309
- id="mapGroup"
310
- className="countyMapGroup"
311
- transform={`translate(${translate}) scale(${scale})`}
312
- data-scale=""
313
- key="countyMapGroup">
314
- { constructGeoJsx(features, geoAlbersUsaTerritories) }
315
- </g>
316
- )
317
- }}
318
- </CustomProjection>
319
- </svg>
320
- }
321
- {!stateToShow && 'No State Picked'}
221
+ {stateToShow &&
222
+ <svg
223
+ viewBox={`0 0 ${WIDTH} ${HEIGHT}`}
224
+ preserveAspectRatio="xMinYMin"
225
+ className="svg-container"
226
+ role="img"
227
+ aria-label={handleMapAriaLabels(state)}
228
+ >
229
+ <rect className="background center-container ocean" width={WIDTH} height={HEIGHT} fillOpacity={1} fill="white"></rect>
230
+ <CustomProjection
231
+ data={[{ states: stateToShow, counties: countiesToShow }]}
232
+ projection={geoAlbersUsaTerritories}
233
+ fitExtent={[[[PADDING, PADDING], [WIDTH - PADDING, HEIGHT - PADDING]], stateToShow]}
234
+ >
235
+ {({ features, projection }) => {
236
+ return (
237
+ <g
238
+ id="mapGroup"
239
+ className="countyMapGroup"
240
+ transform={`translate(${translate}) scale(${scale})`}
241
+ data-scale=""
242
+ key="countyMapGroup">
243
+ {constructGeoJsx(features, projection)}
244
+ </g>
245
+ )
246
+ }}
247
+ </CustomProjection>
248
+ </svg>
249
+ }
250
+ {!stateToShow && 'No State Picked'}
322
251
  </ErrorBoundary>
323
252
  );
324
253
  };