@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
@@ -1,43 +1,26 @@
1
- import React, { useState, useEffect, memo } from 'react';
1
+ import React, { useState, useEffect, memo } from 'react'
2
2
  /** @jsx jsx */
3
3
  import { jsx } from '@emotion/react'
4
- import ErrorBoundary from '@cdc/core/components/ErrorBoundary';
5
- import { geoPath } from "d3-geo";
6
- import { feature, mesh } from "topojson-client";
7
- import { CustomProjection } from '@visx/geo';
8
- import colorPalettes from '../../../core/data/colorPalettes';
9
- import { geoAlbersUsaTerritories } from 'd3-composite-projections';
10
- import testJSON from '../data/county-map.json';
11
- import CityList from './CityList';
12
-
4
+ import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
5
+ import { geoPath } from 'd3-geo'
6
+ import { feature, mesh } from 'topojson-client'
7
+ import { CustomProjection } from '@visx/geo'
8
+ import colorPalettes from '../../../core/data/colorPalettes'
9
+ import { geoAlbersUsaTerritories } from 'd3-composite-projections'
10
+ import testJSON from '../data/county-map.json'
11
+ import CityList from './CityList'
13
12
 
14
13
  // SVG ITEMS
15
- const WIDTH = 880;
16
- const HEIGHT = 500;
17
- const PADDING = 25;
14
+ const WIDTH = 880
15
+ const HEIGHT = 500
16
+ const PADDING = 25
18
17
 
19
18
  // DATA
20
19
  let { features: counties } = feature(testJSON, testJSON.objects.counties)
21
- let { features: states } = feature(testJSON, testJSON.objects.states);
22
-
23
- const SingleStateMap = (props) => {
24
-
25
- const {
26
- state,
27
- applyTooltipsToGeo,
28
- data,
29
- geoClickHandler,
30
- applyLegendToRow,
31
- displayGeoName,
32
- supportedTerritories,
33
- rebuildTooltips,
34
- runtimeLegend,
35
- generateColorsArray,
36
- handleMapAriaLabels,
37
- titleCase,
38
- setSharedFilterValue,
39
- isFilterValueSupported
40
- } = props;
20
+ let { features: states } = feature(testJSON, testJSON.objects.states)
21
+
22
+ const SingleStateMap = props => {
23
+ const { state, applyTooltipsToGeo, data, geoClickHandler, applyLegendToRow, displayGeoName, supportedTerritories, rebuildTooltips, runtimeLegend, generateColorsArray, handleMapAriaLabels, titleCase, setSharedFilterValue, isFilterValueSupported } = props
41
24
 
42
25
  const projection = geoAlbersUsaTerritories().translate([WIDTH / 2, HEIGHT / 2])
43
26
  const cityListProjection = geoAlbersUsaTerritories().translate([WIDTH / 2, HEIGHT / 2])
@@ -46,18 +29,18 @@ const SingleStateMap = (props) => {
46
29
  const [countiesToShow, setCountiesToShow] = useState(null)
47
30
  const [translate, setTranslate] = useState()
48
31
  const [scale, setScale] = useState()
49
- const [strokeWidth, setStrokeWidth] = useState(.75)
50
- let mapColorPalette = colorPalettes[state.color] || '#fff';
51
- let focusedBorderColor = mapColorPalette[3];
32
+ const [strokeWidth, setStrokeWidth] = useState(0.75)
33
+ let mapColorPalette = colorPalettes[state.color] || '#fff'
34
+ let focusedBorderColor = mapColorPalette[3]
52
35
 
53
- useEffect(() => rebuildTooltips());
36
+ useEffect(() => rebuildTooltips())
54
37
 
55
38
  const path = geoPath().projection(projection)
56
39
 
57
40
  // When choosing a state changes...
58
41
  useEffect(() => {
59
42
  if (state.general.hasOwnProperty('statePicked')) {
60
- let statePicked = state.general.statePicked.stateName;
43
+ let statePicked = state.general.statePicked.stateName
61
44
  let statePickedData = states.find(s => s.properties.name === statePicked)
62
45
  setStateToShow(statePickedData)
63
46
 
@@ -66,29 +49,33 @@ const SingleStateMap = (props) => {
66
49
  setCountiesToShow(countiesFound)
67
50
 
68
51
  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;
52
+ const newProjection = projection.fitExtent(
53
+ [
54
+ [PADDING, PADDING],
55
+ [WIDTH - PADDING, HEIGHT - PADDING]
56
+ ],
57
+ statePickedData
58
+ )
59
+ const newScale = newProjection.scale()
60
+ const newScaleWithHypot = newScale / 1070
72
61
 
73
62
  let [x, y] = newProjection.translate()
74
- x = (x - WIDTH / 2);
75
- y = (y - HEIGHT / 2);
63
+ x = x - WIDTH / 2
64
+ y = y - HEIGHT / 2
76
65
 
77
66
  setTranslate([x, y])
78
67
  setScale(newScaleWithHypot)
79
-
80
68
  }
81
- }, [state.general.statePicked]);
69
+ }, [state.general.statePicked])
82
70
 
83
71
  // Constructs and displays markup for all geos on the map (except territories right now)
84
72
  const constructGeoJsx = (geographies, projection) => {
85
- const statePassed = geographies[0].feature.states;
86
- const counties = geographies[0].feature.counties;
73
+ const statePassed = geographies[0].feature.states
74
+ const counties = geographies[0].feature.counties
87
75
 
88
- let geosJsx = [];
76
+ let geosJsx = []
89
77
 
90
78
  const StateOutput = () => {
91
-
92
79
  let geo = testJSON.objects.states.geometries.filter(s => {
93
80
  return s.id === statePassed.id
94
81
  })
@@ -96,59 +83,46 @@ const SingleStateMap = (props) => {
96
83
  // const stateLine = path(mesh(testJSON, lines ))
97
84
  let stateLines = path(mesh(testJSON, geo[0]))
98
85
  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
- />
86
+ <g key={'single-state'} className='single-state' style={{ fill: '#E6E6E6' }} stroke={geoStrokeColor} strokeWidth={0.95 / scale}>
87
+ <path tabIndex={-1} className='state-path' d={stateLines} />
111
88
  </g>
112
89
  )
113
- };
114
-
115
- const countyOutput = (counties.map((county) => {
90
+ }
116
91
 
92
+ const countyOutput = counties.map(county => {
117
93
  // Map the name from the geo data with the appropriate key for the processed data
118
- let geoKey = county.id;
94
+ let geoKey = county.id
119
95
 
120
- if (!geoKey) return;
96
+ if (!geoKey) return
121
97
 
122
- let countyPath = path(county);
98
+ let countyPath = path(county)
123
99
 
124
- let geoData = data[county.id];
125
- let legendColors;
100
+ let geoData = data[county.id]
101
+ let legendColors
126
102
 
127
103
  // Once we receive data for this geographic item, setup variables.
128
104
  if (geoData !== undefined) {
129
- legendColors = applyLegendToRow(geoData);
105
+ legendColors = applyLegendToRow(geoData)
130
106
  }
131
107
 
132
- const geoDisplayName = displayGeoName(geoKey);
108
+ const geoDisplayName = displayGeoName(geoKey)
133
109
 
134
110
  // For some reason, these two geos are breaking the display.
135
- if (geoDisplayName === 'Franklin City' || geoDisplayName === 'Waynesboro') return null;
111
+ if (geoDisplayName === 'Franklin City' || geoDisplayName === 'Waynesboro') return null
136
112
 
137
- const tooltip = applyTooltipsToGeo(geoDisplayName, geoData);
113
+ const tooltip = applyTooltipsToGeo(geoDisplayName, geoData)
138
114
 
139
115
  if (legendColors && legendColors[0] !== '#000000') {
140
-
141
-
142
116
  let styles = {
143
117
  fill: legendColors[0],
144
118
  cursor: 'default',
145
119
  '&:hover': {
146
- fill: legendColors[1],
120
+ fill: legendColors[1]
147
121
  },
148
122
  '&:active': {
149
- fill: legendColors[2],
150
- },
151
- };
123
+ fill: legendColors[2]
124
+ }
125
+ }
152
126
 
153
127
  // When to add pointer cursor
154
128
  if ((state.columns.navigate && geoData[state.columns.navigate.name]) || state.tooltips.appearanceType === 'hover') {
@@ -156,100 +130,70 @@ const SingleStateMap = (props) => {
156
130
  }
157
131
 
158
132
  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
- />
133
+ <g data-for='tooltip' data-tip={tooltip} key={`key--${county.id}`} className={`county county--${geoDisplayName.split(' ').join('')} county--${geoData[state.columns.geo.name]}`} css={styles} onClick={() => geoClickHandler(geoDisplayName, geoData)}>
134
+ <path tabIndex={-1} className={`county`} stroke={geoStrokeColor} d={countyPath} strokeWidth={0.75 / scale} />
174
135
  </g>
175
136
  )
176
137
  } else {
177
138
  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
- />
139
+ <g data-for='tooltip' data-tip={tooltip} key={`key--${county.id}`} className={`county county--${geoDisplayName.split(' ').join('')}`} style={{ fill: '#e6e6e6' }}>
140
+ <path tabIndex={-1} className={`county`} stroke={geoStrokeColor} d={countyPath} strokeWidth={0.75 / scale} />
192
141
  </g>
193
142
  )
194
143
  }
195
-
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
- />)
215
-
216
- return geosJsx;
217
- };
144
+ })
145
+
146
+ geosJsx.push(<StateOutput />)
147
+ geosJsx.push(countyOutput)
148
+ geosJsx.push(
149
+ <CityList
150
+ projection={cityListProjection}
151
+ key='cities'
152
+ data={data}
153
+ state={state}
154
+ geoClickHandler={geoClickHandler}
155
+ applyTooltipsToGeo={applyTooltipsToGeo}
156
+ displayGeoName={displayGeoName}
157
+ applyLegendToRow={applyLegendToRow}
158
+ titleCase={titleCase}
159
+ setSharedFilterValue={setSharedFilterValue}
160
+ isFilterValueSupported={isFilterValueSupported}
161
+ isGeoCodeMap={state.general.type === 'us-geocode'}
162
+ />
163
+ )
164
+
165
+ return geosJsx
166
+ }
218
167
 
219
168
  return (
220
- <ErrorBoundary component="SingleStateMap">
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>
169
+ <ErrorBoundary component='SingleStateMap'>
170
+ {stateToShow && (
171
+ <svg viewBox={`0 0 ${WIDTH} ${HEIGHT}`} preserveAspectRatio='xMinYMin' className='svg-container' role='img' aria-label={handleMapAriaLabels(state)}>
172
+ <rect className='background center-container ocean' width={WIDTH} height={HEIGHT} fillOpacity={1} fill='white'></rect>
230
173
  <CustomProjection
231
174
  data={[{ states: stateToShow, counties: countiesToShow }]}
232
175
  projection={geoAlbersUsaTerritories}
233
- fitExtent={[[[PADDING, PADDING], [WIDTH - PADDING, HEIGHT - PADDING]], stateToShow]}
176
+ fitExtent={[
177
+ [
178
+ [PADDING, PADDING],
179
+ [WIDTH - PADDING, HEIGHT - PADDING]
180
+ ],
181
+ stateToShow
182
+ ]}
234
183
  >
235
184
  {({ features, projection }) => {
236
185
  return (
237
- <g
238
- id="mapGroup"
239
- className="countyMapGroup"
240
- transform={`translate(${translate}) scale(${scale})`}
241
- data-scale=""
242
- key="countyMapGroup">
186
+ <g id='mapGroup' className='countyMapGroup' transform={`translate(${translate}) scale(${scale})`} data-scale='' key='countyMapGroup'>
243
187
  {constructGeoJsx(features, projection)}
244
188
  </g>
245
189
  )
246
190
  }}
247
191
  </CustomProjection>
248
192
  </svg>
249
- }
193
+ )}
250
194
  {!stateToShow && 'No State Picked'}
251
195
  </ErrorBoundary>
252
- );
253
- };
196
+ )
197
+ }
254
198
 
255
199
  export default memo(SingleStateMap)