@cdc/map 2.6.2 → 2.6.4

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 (67) hide show
  1. package/dist/cdcmap.js +37 -29
  2. package/examples/bubble-us.json +363 -0
  3. package/examples/bubble-world.json +427 -0
  4. package/examples/default-county.json +105 -0
  5. package/examples/default-hex.json +475 -0
  6. package/examples/default-single-state.json +109 -0
  7. package/examples/default-usa-regions.json +118 -0
  8. package/examples/default-usa.json +744 -603
  9. package/examples/default-world-data.json +1450 -0
  10. package/examples/default-world.json +5 -3
  11. package/examples/example-city-state.json +510 -0
  12. package/examples/example-world-map.json +1596 -0
  13. package/examples/gender-rate-map.json +1 -0
  14. package/examples/private/atsdr.json +439 -0
  15. package/examples/private/atsdr_new.json +436 -0
  16. package/examples/private/bubble.json +285 -0
  17. package/examples/private/default-world-data.json +1444 -0
  18. package/examples/private/default.json +968 -0
  19. package/examples/private/map.csv +60 -0
  20. package/examples/private/mdx.json +210 -0
  21. package/examples/private/regions.json +52 -0
  22. package/examples/private/wcmsrd-13881-data.json +2858 -0
  23. package/examples/private/wcmsrd-13881.json +5823 -0
  24. package/examples/private/wcmsrd-test.json +268 -0
  25. package/examples/private/world.json +1580 -0
  26. package/examples/private/worldmap.json +1490 -0
  27. package/package.json +11 -7
  28. package/src/CdcMap.js +726 -202
  29. package/src/components/BubbleList.js +240 -0
  30. package/src/components/CityList.js +22 -3
  31. package/src/components/CountyMap.js +557 -0
  32. package/src/components/DataTable.js +85 -24
  33. package/src/components/EditorPanel.js +2455 -1204
  34. package/src/components/Geo.js +1 -1
  35. package/src/components/Sidebar.js +5 -5
  36. package/src/components/SingleStateMap.js +326 -0
  37. package/src/components/UsaMap.js +41 -9
  38. package/src/components/UsaRegionMap.js +319 -0
  39. package/src/components/WorldMap.js +112 -35
  40. package/src/data/abbreviations.js +57 -0
  41. package/src/data/country-coordinates.js +250 -0
  42. package/src/data/county-map-halfquality.json +58453 -0
  43. package/src/data/county-map-quarterquality.json +1 -0
  44. package/src/data/county-topo.json +1 -0
  45. package/src/data/dfc-map.json +1 -0
  46. package/src/data/initial-state.js +21 -4
  47. package/src/data/newtest.json +1 -0
  48. package/src/data/state-abbreviations.js +60 -0
  49. package/src/data/state-coordinates.js +55 -0
  50. package/src/data/supported-geos.js +3592 -163
  51. package/src/data/test.json +1 -0
  52. package/src/data/us-regions-topo-2.json +360525 -0
  53. package/src/data/us-regions-topo.json +37894 -0
  54. package/src/hooks/useActiveElement.js +19 -0
  55. package/src/hooks/useColorPalette.ts +96 -0
  56. package/src/index.html +35 -20
  57. package/src/index.js +8 -4
  58. package/src/scss/datatable.scss +2 -1
  59. package/src/scss/editor-panel.scss +76 -55
  60. package/src/scss/main.scss +10 -1
  61. package/src/scss/map.scss +257 -121
  62. package/src/scss/sidebar.scss +0 -1
  63. package/uploads/upload-example-city-state.json +392 -0
  64. package/uploads/upload-example-world-data.json +1490 -0
  65. package/LICENSE +0 -201
  66. package/src/data/color-palettes.js +0 -191
  67. package/src/images/map-folded.svg +0 -1
@@ -10,8 +10,12 @@ import ExternalIcon from '../images/external-link.svg';
10
10
  import ErrorBoundary from '@cdc/core/components/ErrorBoundary';
11
11
  import LegendCircle from '@cdc/core/components/LegendCircle';
12
12
 
13
+
14
+ import Loading from '@cdc/core/components/Loading';
15
+
13
16
  const DataTable = (props) => {
14
17
  const {
18
+ state,
15
19
  tableTitle,
16
20
  indexTitle,
17
21
  mapTitle,
@@ -27,12 +31,20 @@ const DataTable = (props) => {
27
31
  displayGeoName,
28
32
  navigationHandler,
29
33
  viewport,
34
+ formatLegendLocation,
35
+ tabbingId,
36
+ setFilteredCountryCode
30
37
  } = props;
31
38
 
32
39
  const [expanded, setExpanded] = useState(expandDataTable);
33
40
 
34
41
  const [accessibilityLabel, setAccessibilityLabel] = useState('');
35
42
 
43
+ const [ready, setReady] = useState(false)
44
+
45
+ const fileName = `${mapTitle || 'data-table'}.csv`;
46
+
47
+
36
48
  // Catch all sorting method used on load by default but also on user click
37
49
  // Having a custom method means we can add in any business logic we want going forward
38
50
  const customSort = useCallback((a, b) => {
@@ -132,28 +144,32 @@ const DataTable = (props) => {
132
144
  }, [columns.navigate, navigationHandler]);
133
145
 
134
146
  const DownloadButton = memo(() => {
135
- const fileName = `${mapTitle}.csv`;
136
147
  const csvData = Papa.unparse(rawData);
137
148
 
138
149
  const blob = new Blob([csvData], {type: "text/csv;charset=utf-8;"});
139
150
 
140
151
  const saveBlob = () => {
141
- if (navigator.msSaveBlob) {
152
+ //@ts-ignore
153
+ if (typeof window.navigator.msSaveBlob === 'function') {
154
+ //@ts-ignore
142
155
  navigator.msSaveBlob(blob, fileName);
143
156
  }
144
157
  }
145
158
 
146
159
  return (
147
- <a
148
- download={fileName}
149
- onClick={saveBlob}
150
- href={URL.createObjectURL(blob)}
151
- aria-label="Download this data in a CSV file format."
152
- className={`${headerColor} btn btn-download no-border`}
153
- data-html2canvas-ignore
154
- >
155
- Download Data (CSV)
156
- </a>
160
+ <a
161
+ download={fileName}
162
+ type="button"
163
+ onClick={saveBlob}
164
+ href={URL.createObjectURL(blob)}
165
+ aria-label="Download this data in a CSV file format."
166
+ className={`${headerColor} btn btn-download no-border`}
167
+ id={`${skipId}`}
168
+ data-html2canvas-ignore
169
+ role="button"
170
+ >
171
+ Download Data (CSV)
172
+ </a>
157
173
  )
158
174
  }, [rawData]);
159
175
 
@@ -162,12 +178,19 @@ const DataTable = (props) => {
162
178
  const newTableColumns = [];
163
179
 
164
180
  Object.keys(columns).forEach((column) => {
165
- if (columns[column].dataTable === true && '' !== columns[column].name) {
181
+ if (columns[column].dataTable === true && columns[column].name) {
166
182
  const newCol = {
167
- Header: columns[column].label || columns[column].name,
183
+ Header: columns[column].label ? columns[column].label : columns[column].name,
168
184
  id: column,
169
185
  accessor: (row) => {
170
186
  if (runtimeData) {
187
+ if(state.legend.specialClasses && state.legend.specialClasses.length && typeof state.legend.specialClasses[0] === 'object'){
188
+ for(let i = 0; i < state.legend.specialClasses.length; i++){
189
+ if(String(runtimeData[row][state.legend.specialClasses[i].key]) === state.legend.specialClasses[i].value){
190
+ return state.legend.specialClasses[i].label;
191
+ }
192
+ }
193
+ }
171
194
  return runtimeData[row][columns[column].name] ?? null;
172
195
  }
173
196
 
@@ -183,7 +206,11 @@ const DataTable = (props) => {
183
206
 
184
207
  const legendColor = applyLegendToRow(rowObj);
185
208
 
186
- let labelValue = displayGeoName(row.original);
209
+ if(state.general.geoType !== 'us-county') {
210
+ var labelValue = displayGeoName(row.original);
211
+ } else {
212
+ var labelValue = formatLegendLocation(row.original)
213
+ }
187
214
 
188
215
  labelValue = getCellAnchor(labelValue, rowObj);
189
216
 
@@ -209,11 +236,11 @@ const DataTable = (props) => {
209
236
  });
210
237
 
211
238
  return newTableColumns;
212
- }, [indexTitle, columns, runtimeData, runtimeLegend]);
239
+ }, [indexTitle, columns, runtimeData,getCellAnchor,displayDataAsText,applyLegendToRow,customSort,displayGeoName,state.legend.specialClasses]);
213
240
 
214
241
  const tableData = useMemo(
215
242
  () => Object.keys(runtimeData).filter((key) => applyLegendToRow(runtimeData[key])).sort((a, b) => customSort(a, b)),
216
- [runtimeLegend, runtimeData, applyLegendToRow, customSort]
243
+ [ runtimeData, applyLegendToRow, customSort]
217
244
  );
218
245
 
219
246
  // Change accessibility label depending on expanded status
@@ -240,6 +267,13 @@ const DataTable = (props) => {
240
267
  []
241
268
  );
242
269
 
270
+ const mapLookup = {
271
+ 'us-county': 'United States County Map',
272
+ 'single-state': 'State Map',
273
+ 'us': 'United States Map',
274
+ 'world': 'World Map'
275
+ }
276
+
243
277
  const {
244
278
  getTableProps,
245
279
  getTableBodyProps,
@@ -248,30 +282,57 @@ const DataTable = (props) => {
248
282
  prepareRow,
249
283
  } = useTable({ columns: tableColumns, data: tableData, defaultColumn }, useSortBy, useBlockLayout, useResizeColumns);
250
284
 
285
+ const rand = Math.random().toString(16).substr(2, 8);
286
+ const skipId = `btn__${rand}`
287
+
288
+ if(!state.data) return <Loading />
251
289
  return (
252
290
  <ErrorBoundary component="DataTable">
253
- <section className={`data-table-container ${viewport}`} aria-label={accessibilityLabel}>
291
+ <section id={state.general.title ? `dataTableSection__${state.general.title.replace(/\s/g, '')}` : `dataTableSection`} className={`data-table-container ${viewport}`} aria-label={accessibilityLabel}>
292
+ <a id='skip-nav' className='cdcdataviz-sr-only-focusable' href={`#${skipId}`}>
293
+ Skip Navigation or Skip to Content
294
+ </a>
254
295
  <div
255
296
  className={expanded ? 'data-table-heading' : 'collapsed data-table-heading'}
256
297
  onClick={() => { setExpanded(!expanded); }}
257
298
  tabIndex="0"
258
299
  onKeyDown={(e) => { if (e.keyCode === 13) { setExpanded(!expanded); } }}
259
300
  >
301
+
260
302
  {tableTitle}
261
303
  </div>
262
- <div className="table-container">
263
- <table className={expanded ? 'data-table' : 'data-table cdcdataviz-sr-only'} height={expanded ? null : 0} {...getTableProps()} aria-live="assertive" >
264
- <thead>
304
+ <div
305
+ className="table-container"
306
+ style={ { maxHeight: state.dataTable.limitHeight && `${state.dataTable.height}px`, overflowY: 'scroll' } }
307
+ >
308
+ <table
309
+ height={expanded ? null : 0} {...getTableProps()}
310
+ aria-live="assertive"
311
+ className={expanded ? 'data-table' : 'data-table cdcdataviz-sr-only'}
312
+ hidden={!expanded}
313
+ aria-rowcount={state?.data.length ? state.data.length : '-1' }
314
+ >
315
+ <caption className='cdcdataviz-sr-only'>{state.dataTable.caption ? state.dataTable.caption : `Datatable showing data for the ${mapLookup[state.general.geoType]} figure.`}</caption>
316
+ <thead style={{position: 'sticky', top: 0, zIndex: 999}}>
265
317
  {headerGroups.map((headerGroup) => (
266
318
  <tr {...headerGroup.getHeaderGroupProps()}>
267
319
  {headerGroup.headers.map((column) => (
268
- <th tabIndex="0"
320
+ <th
321
+ tabIndex="0"
269
322
  title={column.Header}
323
+ role="columnheader"
324
+ scope="col"
270
325
  {...column.getHeaderProps(column.getSortByToggleProps())}
271
326
  className={column.isSorted ? column.isSortedDesc ? 'sort sort-desc' : 'sort sort-asc' : 'sort'}
272
327
  onKeyDown={(e) => { if (e.keyCode === 13) { column.toggleSortBy(); } }}
328
+ //aria-sort={column.isSorted ? column.isSortedDesc ? 'descending' : 'ascending' : 'none' }
329
+ {...(column.isSorted ? column.isSortedDesc ? { 'aria-sort': 'descending' } : { 'aria-sort': 'ascending' } : null)}
330
+
273
331
  >
274
332
  {column.render('Header')}
333
+ <button>
334
+ <span className="cdcdataviz-sr-only">{`Sort by ${(column.render('Header')).toLowerCase() } in ${ column.isSorted ? column.isSortedDesc ? 'descending' : 'ascending' : 'no'} `} order</span>
335
+ </button>
275
336
  <div {...column.getResizerProps()} className="resizer" />
276
337
  </th>
277
338
  ))}
@@ -282,9 +343,9 @@ const DataTable = (props) => {
282
343
  {rows.map((row) => {
283
344
  prepareRow(row);
284
345
  return (
285
- <tr {...row.getRowProps()}>
346
+ <tr {...row.getRowProps()} role="row">
286
347
  {row.cells.map((cell) => (
287
- <td tabIndex="0" {...cell.getCellProps()}>
348
+ <td tabIndex="0" {...cell.getCellProps()} role="gridcell" onClick={ (e) => (state.general.type === 'bubble' && state.general.allowMapZoom && state.general.geoType === 'world') ? setFilteredCountryCode(cell.row.original) : true }>
288
349
  {cell.render('Cell')}
289
350
  </td>
290
351
  ))}