@cdc/map 2.6.4 → 9.22.9

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 (46) hide show
  1. package/dist/cdcmap.js +22 -16
  2. package/examples/default-county.json +64 -12
  3. package/examples/default-hex.json +3 -1
  4. package/examples/example-city-state.json +10 -1
  5. package/examples/gallery/categorical-qualitative.json +797 -0
  6. package/examples/gallery/categorical-scale-based.json +739 -0
  7. package/examples/gallery/city-state.json +479 -0
  8. package/examples/gallery/county.json +22731 -0
  9. package/examples/gallery/equal-interval.json +1027 -0
  10. package/examples/gallery/equal-number.json +1027 -0
  11. package/examples/gallery/filterable.json +909 -0
  12. package/examples/gallery/hex-filtered.json +420 -0
  13. package/examples/gallery/hex.json +413 -0
  14. package/examples/gallery/single-state.json +21402 -0
  15. package/examples/gallery/world.json +1592 -0
  16. package/examples/private/city-state.json +428 -0
  17. package/examples/private/cty-issue.json +42768 -0
  18. package/examples/private/default-usa.json +460 -0
  19. package/examples/private/legend-issue.json +1 -0
  20. package/examples/private/map-rounding-error.json +42759 -0
  21. package/examples/private/monkeypox.json +376 -0
  22. package/examples/private/valid-data-map.csv +59 -0
  23. package/examples/private/wcmsrd-14492-data.json +292 -0
  24. package/examples/private/wcmsrd-14492.json +114 -0
  25. package/package.json +3 -3
  26. package/src/CdcMap.js +204 -127
  27. package/src/components/BubbleList.js +9 -5
  28. package/src/components/CityList.js +22 -4
  29. package/src/components/CountyMap.js +13 -4
  30. package/src/components/DataTable.js +9 -9
  31. package/src/components/EditorPanel.js +239 -121
  32. package/src/components/Modal.js +2 -1
  33. package/src/components/NavigationMenu.js +4 -3
  34. package/src/components/Sidebar.js +14 -19
  35. package/src/components/SingleStateMap.js +10 -4
  36. package/src/components/UsaMap.js +82 -30
  37. package/src/components/UsaRegionMap.js +3 -2
  38. package/src/components/WorldMap.js +7 -2
  39. package/src/data/{dfc-map.json → county-map.json} +0 -0
  40. package/src/data/initial-state.js +2 -1
  41. package/src/data/supported-geos.js +5 -0
  42. package/src/index.html +3 -8
  43. package/src/scss/editor-panel.scss +2 -2
  44. package/src/scss/main.scss +1 -1
  45. package/src/scss/map.scss +4 -0
  46. package/src/scss/sidebar.scss +2 -1
@@ -10,21 +10,21 @@ import ReactTooltip from 'react-tooltip';
10
10
  import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
11
11
  import { useDebounce } from 'use-debounce';
12
12
 
13
+ import colorPalettes from '@cdc/core/data/colorPalettes';
14
+ import { supportedStatesFipsCodes } from '../data/supported-geos';
15
+ import { GET_PALETTE,useColorPalette } from '../hooks/useColorPalette';
16
+
13
17
  import ErrorBoundary from '@cdc/core/components/ErrorBoundary';
14
18
  import Waiting from '@cdc/core/components/Waiting';
15
19
 
16
- import UsaGraphic from '@cdc/core/assets/usa-graphic.svg';
17
- import WorldGraphic from '@cdc/core/assets/world-graphic.svg';
18
- import AlabamaGraphic from '@cdc/core/assets/alabama-graphic.svg';
19
- import colorPalettes from '../../../core/data/colorPalettes';
20
+ import UsaGraphic from '@cdc/core/assets/icon-map-usa.svg';
21
+ import UsaRegionGraphic from '@cdc/core/assets/usa-region-graphic.svg';
22
+ import WorldGraphic from '@cdc/core/assets/icon-map-world.svg';
23
+ import AlabamaGraphic from '@cdc/core/assets/icon-map-alabama.svg';
20
24
  import worldDefaultConfig from '../../examples/default-world.json';
21
25
  import usaDefaultConfig from '../../examples/default-usa.json';
22
26
  import countyDefaultConfig from '../../examples/default-county.json';
23
- import QuestionIcon from '@cdc/core/assets/question-circle.svg';
24
27
 
25
- import { supportedStatesFipsCodes } from '../data/supported-geos';
26
- import { GET_PALETTE,useColorPalette } from '../hooks/useColorPalette';
27
- import InputCheckbox from '@cdc/core/components/inputs/InputCheckbox';
28
28
  import InputToggle from '@cdc/core/components/inputs/InputToggle';
29
29
  import Tooltip from '@cdc/core/components/ui/Tooltip'
30
30
  import Icon from '@cdc/core/components/ui/Icon'
@@ -107,7 +107,6 @@ const EditorPanel = (props) => {
107
107
 
108
108
  const {filteredPallets,filteredQualitative,isPaletteReversed,paletteName} = useColorPalette(colorPalettes,state);
109
109
 
110
-
111
110
  const [editorCatOrder, setEditorCatOrder] = useState(state.legend.categoryValuesOrder || []);
112
111
 
113
112
  const headerColors = [
@@ -183,6 +182,7 @@ const EditorPanel = (props) => {
183
182
  };
184
183
 
185
184
  const handleEditorChanges = async (property, value) => {
185
+
186
186
  switch (property) {
187
187
 
188
188
  // change these to be more generic.
@@ -232,10 +232,16 @@ const EditorPanel = (props) => {
232
232
  ...state,
233
233
  general: {
234
234
  ...state.general,
235
- [property]: value
235
+ allowMapZoom: value
236
236
  }
237
237
  })
238
238
  break;
239
+ case 'hideGeoColumnInTooltip':
240
+ setState({
241
+ ...state,
242
+ [property]: value
243
+ })
244
+ break;
239
245
  case 'hidePrimaryColumnInTooltip':
240
246
  setState({
241
247
  ...state,
@@ -296,6 +302,14 @@ const EditorPanel = (props) => {
296
302
  },
297
303
  });
298
304
  break;
305
+ case 'handleCityStyle':
306
+ setState({
307
+ ...state,
308
+ visual: {
309
+ cityStyle: value,
310
+ },
311
+ });
312
+ break;
299
313
  case 'geoBorderColor':
300
314
  setState({
301
315
  ...state,
@@ -337,7 +351,7 @@ const EditorPanel = (props) => {
337
351
  break;
338
352
  case 'legendType':
339
353
 
340
- let testForType = typeof state.data[0][state.columns.primary.name];
354
+ let testForType = Number(typeof state.data[0][state.columns.primary.name]);
341
355
  let hasValue = state.data[0][state.columns.primary.name];
342
356
  let messages = [];
343
357
 
@@ -345,8 +359,10 @@ const EditorPanel = (props) => {
345
359
  messages.push(`There appears to be values missing for data in the primary column ${state.columns.primary.name}`);
346
360
  }
347
361
 
348
- if (testForType === 'string' && value !== 'category') {
349
- messages.push( 'Error with legend. Primary columns that are text must use a categorical legend type. Try changing the legend type to categorical.' );
362
+ if (testForType === 'string' && isNaN(testForType) && value !== 'category') {
363
+ messages.push(
364
+ "Error with legend. Primary columns that are text must use a categorical legend type. Try changing the legend type to DEV-12345categorical."
365
+ );
350
366
  } else {
351
367
  messages = []
352
368
  }
@@ -502,6 +518,20 @@ const EditorPanel = (props) => {
502
518
  });
503
519
  ReactTooltip.rebuild();
504
520
  break;
521
+ case 'us-region':
522
+ setState({
523
+ ...state,
524
+ general: {
525
+ ...state.general,
526
+ geoType: 'us-region',
527
+ },
528
+ dataTable: {
529
+ ...state.dataTable,
530
+ forceDisplay: true,
531
+ },
532
+ });
533
+ ReactTooltip.rebuild();
534
+ break;
505
535
  case 'world':
506
536
  setState({
507
537
  ...state,
@@ -1243,45 +1273,60 @@ const EditorPanel = (props) => {
1243
1273
  <span>Geography</span>
1244
1274
  </span>
1245
1275
  <ul className='geo-buttons'>
1246
- <li
1276
+ <button
1247
1277
  className={
1248
1278
  state.general.geoType === 'us' ||
1249
1279
  state.general.geoType === 'us-county'
1250
1280
  ? 'active'
1251
1281
  : ''
1252
1282
  }
1253
- onClick={() => handleEditorChanges('geoType', 'us')}
1283
+ onClick={ (e) => {
1284
+ e.preventDefault();
1285
+ handleEditorChanges('geoType', 'us')
1286
+ }}
1254
1287
  >
1255
1288
  <UsaGraphic />
1256
1289
  <span>United States</span>
1257
- </li>
1258
- <li
1290
+ </button>
1291
+ <button
1292
+ className={state.general.geoType === 'us-region' ? 'active' : ''}
1293
+ onClick={ (e) => {
1294
+ e.preventDefault();
1295
+ handleEditorChanges('geoType', 'us-region')
1296
+ }}
1297
+ >
1298
+ <UsaRegionGraphic />
1299
+ <span>U.S. Region</span>
1300
+ </button>
1301
+ <button
1259
1302
  className={state.general.geoType === 'world' ? 'active' : ''}
1260
- onClick={() => handleEditorChanges('geoType', 'world')}
1303
+ onClick={ (e) => {
1304
+ e.preventDefault();
1305
+ handleEditorChanges('geoType', 'world')
1306
+ }
1307
+ }
1261
1308
  >
1262
1309
  <WorldGraphic />
1263
1310
  <span>World</span>
1264
- </li>
1265
- <li
1311
+ </button>
1312
+ <button
1266
1313
  className={state.general.geoType === 'single-state' ? 'active' : ''}
1267
- onClick={() => handleEditorChanges('geoType', 'single-state')}
1314
+ onClick={(e) => {
1315
+ e.preventDefault();
1316
+ handleEditorChanges('geoType', 'single-state')
1317
+ }}
1268
1318
  >
1269
1319
  <AlabamaGraphic />
1270
1320
  <span>U.S. State</span>
1271
- </li>
1321
+ </button>
1272
1322
  </ul>
1273
1323
  </label>
1274
1324
  {/* Select > State or County Map */}
1275
1325
  {(state.general.geoType === 'us' || state.general.geoType === 'us-county') && (
1276
1326
  <label>
1277
1327
  <span className='edit-label column-heading'>
1278
- Map Type
1279
- <Tooltip style={{textTransform: 'none'}}>
1280
- <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1281
- <Tooltip.Content>
1282
- <p>Select "Data" to create a color-coded data map. To create a navigation-only map, select "Navigation."</p>
1283
- </Tooltip.Content>
1284
- </Tooltip>
1328
+ Geography Subtype
1329
+
1285
1330
  </span>
1286
1331
  <select
1287
1332
  value={state.general.geoType}
@@ -1315,7 +1360,15 @@ const EditorPanel = (props) => {
1315
1360
  )}
1316
1361
  {/* Type */}
1317
1362
  <label>
1318
- <span className='edit-label column-heading'>Map Type</span>
1363
+ <span className='edit-label column-heading'>
1364
+ Map Type
1365
+ <Tooltip style={{textTransform: 'none'}}>
1366
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1367
+ <Tooltip.Content>
1368
+ <p>Select "Data" to create a color-coded data map. To create a navigation-only map, select "Navigation."</p>
1369
+ </Tooltip.Content>
1370
+ </Tooltip>
1371
+ </span>
1319
1372
  <select
1320
1373
  value={state.general.type}
1321
1374
  onChange={(event) => {
@@ -1327,6 +1380,41 @@ const EditorPanel = (props) => {
1327
1380
  { (state.general.geoType === 'world' || state.general.geoType === 'us') && <option value="bubble">Bubble</option>}
1328
1381
  </select>
1329
1382
  </label>
1383
+ <label>
1384
+ <span className="edit-label">Data Classification Type</span>
1385
+ <div>
1386
+ <label>
1387
+ <input
1388
+ type="radio"
1389
+ name="equalnumber"
1390
+ value="equalnumber"
1391
+ checked={state.legend.type === "equalnumber"}
1392
+ onChange={(e) =>
1393
+ handleEditorChanges(
1394
+ "classificationType",
1395
+ e.target.value
1396
+ )
1397
+ }
1398
+ />
1399
+ Numeric/Quantitative
1400
+ </label>
1401
+ <label>
1402
+ <input
1403
+ type="radio"
1404
+ name="category"
1405
+ value="category"
1406
+ checked={state.legend.type === "category"}
1407
+ onChange={(e) =>
1408
+ handleEditorChanges(
1409
+ "classificationType",
1410
+ e.target.value
1411
+ )
1412
+ }
1413
+ />
1414
+ Categorical
1415
+ </label>
1416
+ </div>
1417
+ </label>
1330
1418
  {/* SubType */}
1331
1419
  {'us' === state.general.geoType && 'data' === state.general.type && (
1332
1420
  <label className='checkbox mt-4'>
@@ -1341,7 +1429,7 @@ const EditorPanel = (props) => {
1341
1429
  </label>
1342
1430
  )}
1343
1431
  {'us' === state.general.geoType &&
1344
- 'data' === state.general.type &&
1432
+ 'bubble' !== state.general.type &&
1345
1433
  false === state.general.displayAsHex && (
1346
1434
  <label className='checkbox'>
1347
1435
  <input
@@ -1364,19 +1452,50 @@ const EditorPanel = (props) => {
1364
1452
  </AccordionItemHeading>
1365
1453
  <AccordionItemPanel>
1366
1454
  <TextField
1367
- value={state.general.title}
1455
+ value={general.title}
1368
1456
  updateField={updateField}
1369
1457
  section='general'
1370
1458
  fieldName='title'
1371
1459
  label='Title'
1372
1460
  placeholder='Map Title'
1373
1461
  tooltip={
1374
- <Tooltip style={{textTransform: 'none'}}>
1375
- <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1376
- <Tooltip.Content>
1377
- <p>For accessibility reasons, you should enter a title even if you are not planning on displaying it.</p>
1378
- </Tooltip.Content>
1379
- </Tooltip>
1462
+ <Tooltip style={{textTransform: 'none'}}>
1463
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1464
+ <Tooltip.Content>
1465
+ <p>For accessibility reasons, you should enter a title even if you are not planning on displaying it.</p>
1466
+ </Tooltip.Content>
1467
+ </Tooltip>
1468
+ }
1469
+ />
1470
+ <TextField
1471
+ value={general.superTitle || ''}
1472
+ updateField={updateField}
1473
+ section='general'
1474
+ fieldName='superTitle'
1475
+ label='Super Title'
1476
+ tooltip={
1477
+ <Tooltip style={{textTransform: 'none'}}>
1478
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1479
+ <Tooltip.Content>
1480
+ <p>Super Title</p>
1481
+ </Tooltip.Content>
1482
+ </Tooltip>
1483
+ }
1484
+ />
1485
+ <TextField
1486
+ type='textarea'
1487
+ value={general.introText}
1488
+ updateField={updateField}
1489
+ section='general'
1490
+ fieldName='introText'
1491
+ label='Intro Text'
1492
+ tooltip={
1493
+ <Tooltip style={{textTransform: 'none'}}>
1494
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1495
+ <Tooltip.Content>
1496
+ <p>Intro Text</p>
1497
+ </Tooltip.Content>
1498
+ </Tooltip>
1380
1499
  }
1381
1500
  />
1382
1501
  <TextField
@@ -1388,10 +1507,26 @@ const EditorPanel = (props) => {
1388
1507
  label='Subtext'
1389
1508
  tooltip={
1390
1509
  <Tooltip style={{textTransform: 'none'}}>
1391
- <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1392
- <Tooltip.Content>
1510
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1511
+ <Tooltip.Content>
1393
1512
  <p>Enter supporting text to display below the data visualization, if applicable. The following HTML tags are supported: strong, em, sup, and sub.</p>
1394
- </Tooltip.Content>
1513
+ </Tooltip.Content>
1514
+ </Tooltip>
1515
+ }
1516
+ />
1517
+ <TextField
1518
+ type='textarea'
1519
+ value={general.footnotes}
1520
+ updateField={updateField}
1521
+ section='general'
1522
+ fieldName='footnotes'
1523
+ label='Footnotes'
1524
+ tooltip={
1525
+ <Tooltip style={{textTransform: 'none'}}>
1526
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1527
+ <Tooltip.Content>
1528
+ <p>Footnotes</p>
1529
+ </Tooltip.Content>
1395
1530
  </Tooltip>
1396
1531
  }
1397
1532
  />
@@ -1405,41 +1540,6 @@ const EditorPanel = (props) => {
1405
1540
  placeholder='Territories'
1406
1541
  />
1407
1542
  )}
1408
- <label>
1409
- <span className="edit-label">Data Classification Type</span>
1410
- <div>
1411
- <label>
1412
- <input
1413
- type="radio"
1414
- name="equalnumber"
1415
- value="equalnumber"
1416
- checked={state.legend.type === "equalnumber"}
1417
- onChange={(e) =>
1418
- handleEditorChanges(
1419
- "classificationType",
1420
- e.target.value
1421
- )
1422
- }
1423
- />
1424
- Numeric/Quantitative
1425
- </label>
1426
- <label>
1427
- <input
1428
- type="radio"
1429
- name="category"
1430
- value="category"
1431
- checked={state.legend.type === "category"}
1432
- onChange={(e) =>
1433
- handleEditorChanges(
1434
- "classificationType",
1435
- e.target.value
1436
- )
1437
- }
1438
- />
1439
- Categorical
1440
- </label>
1441
- </div>
1442
- </label>
1443
1543
  {/* <label className="checkbox mt-4">
1444
1544
  <input type="checkbox" checked={ state.general.showDownloadMediaButton } onChange={(event) => { handleEditorChanges("toggleDownloadMediaButton", event.target.checked) }} />
1445
1545
  <span className="edit-label">Enable Media Download</span>
@@ -1540,6 +1640,7 @@ const EditorPanel = (props) => {
1540
1640
  fieldName='roundToPlace'
1541
1641
  label='Round'
1542
1642
  updateField={updateField}
1643
+ min={0}
1543
1644
  />
1544
1645
  </li>
1545
1646
  <li>
@@ -1844,12 +1945,49 @@ const EditorPanel = (props) => {
1844
1945
  handleEditorChanges('legendType', event.target.value);
1845
1946
  }}
1846
1947
  >
1847
- <option value='equalnumber'>Equal Number</option>
1948
+ <option value='equalnumber'>Equal Number (Quantiles)</option>
1848
1949
  <option value='equalinterval'>Equal Interval</option>
1849
- <option value='category'>Categorical</option>
1850
1950
  </select>
1851
1951
  </label>
1852
1952
  )}
1953
+ {'navigation' !== state.general.type && (
1954
+ <label className='checkbox'>
1955
+ <input
1956
+ type='checkbox'
1957
+ checked={state.general.showSidebar || false}
1958
+ onChange={(event) => {
1959
+ handleEditorChanges('showSidebar', event.target.checked);
1960
+ }}
1961
+ />
1962
+ <span className='edit-label'>Show Legend</span>
1963
+ </label>
1964
+ )}
1965
+ {'navigation' !== state.general.type && (
1966
+ <label>
1967
+ <span className='edit-label'>Legend Position</span>
1968
+ <select
1969
+ value={legend.position || false}
1970
+ onChange={(event) => {
1971
+ handleEditorChanges('sidebarPosition', event.target.value);
1972
+ }}
1973
+ >
1974
+ <option value='side'>Side</option>
1975
+ <option value='bottom'>Bottom</option>
1976
+ </select>
1977
+ </label>
1978
+ )}
1979
+ {'side' === legend.position && (
1980
+ <label className='checkbox'>
1981
+ <input
1982
+ type='checkbox'
1983
+ checked={legend.singleColumn}
1984
+ onChange={(event) => {
1985
+ handleEditorChanges('singleColumnLegend', event.target.checked);
1986
+ }}
1987
+ />
1988
+ <span className='edit-label'>Single Column Legend</span>
1989
+ </label>
1990
+ )}
1853
1991
  {'category' !== legend.type && (
1854
1992
  <label className='checkbox'>
1855
1993
  <input
@@ -1872,6 +2010,7 @@ const EditorPanel = (props) => {
1872
2010
  </label>
1873
2011
  )}
1874
2012
  {/* Temp Checkbox */}
2013
+
1875
2014
  {state.legend.type === 'equalnumber' &&
1876
2015
  <label className="checkbox mt-4">
1877
2016
  <input type="checkbox" checked={ state.general.equalNumberOptIn } onChange={(event) => { handleEditorChanges("showEqualNumber", event.target.checked) }} />
@@ -2032,7 +2171,7 @@ const EditorPanel = (props) => {
2032
2171
  </span>
2033
2172
  </label>
2034
2173
  )}
2035
- {filtersJSX.length > 0 || state.general.type === 'bubble' && (
2174
+ {(filtersJSX.length > 0 || state.general.type === 'bubble' || state.general.geoType === 'us') && (
2036
2175
  <label className='checkbox'>
2037
2176
  <input
2038
2177
  type='checkbox'
@@ -2305,45 +2444,6 @@ const EditorPanel = (props) => {
2305
2444
  />
2306
2445
  <span className='edit-label'>Hide Primary Column Name in Tooltip</span>
2307
2446
  </label>
2308
-
2309
- {'navigation' !== state.general.type && (
2310
- <label className='checkbox'>
2311
- <input
2312
- type='checkbox'
2313
- checked={state.general.showSidebar || false}
2314
- onChange={(event) => {
2315
- handleEditorChanges('showSidebar', event.target.checked);
2316
- }}
2317
- />
2318
- <span className='edit-label'>Show Legend</span>
2319
- </label>
2320
- )}
2321
- {'navigation' !== state.general.type && (
2322
- <label>
2323
- <span className='edit-label'>Legend Position</span>
2324
- <select
2325
- value={legend.position || false}
2326
- onChange={(event) => {
2327
- handleEditorChanges('sidebarPosition', event.target.value);
2328
- }}
2329
- >
2330
- <option value='side'>Side</option>
2331
- <option value='bottom'>Bottom</option>
2332
- </select>
2333
- </label>
2334
- )}
2335
- {'side' === legend.position && (
2336
- <label className='checkbox'>
2337
- <input
2338
- type='checkbox'
2339
- checked={legend.singleColumn}
2340
- onChange={(event) => {
2341
- handleEditorChanges('singleColumnLegend', event.target.checked);
2342
- }}
2343
- />
2344
- <span className='edit-label'>Single Column Legend</span>
2345
- </label>
2346
- )}
2347
2447
  {'navigation' === state.general.type && (
2348
2448
  <label className='checkbox'>
2349
2449
  <input
@@ -2421,6 +2521,10 @@ const EditorPanel = (props) => {
2421
2521
  backgroundColor: colorPalettes[palette][6],
2422
2522
  };
2423
2523
 
2524
+ // hide palettes with too few colors for region maps
2525
+ if ( colorPalettes[palette].length <= 8 && state.general.geoType === 'us-region' ) {
2526
+ return('');
2527
+ }
2424
2528
  return (
2425
2529
  <li
2426
2530
  title={palette}
@@ -2437,7 +2541,7 @@ const EditorPanel = (props) => {
2437
2541
  );
2438
2542
  })}
2439
2543
  </ul>
2440
- <TextField
2544
+ {(state.general.type === 'bubble') && <><TextField
2441
2545
  type='number'
2442
2546
  value={state.visual.minBubbleSize}
2443
2547
  section='visual'
@@ -2452,8 +2556,8 @@ const EditorPanel = (props) => {
2452
2556
  fieldName='maxBubbleSize'
2453
2557
  label='Maximum Bubble Size'
2454
2558
  updateField={updateField}
2455
- />
2456
- { (state.general.geoType === 'world' || state.general.geoType === 'us') &&
2559
+ /></>}
2560
+ { (state.general.geoType === 'world' || state.general.geoType === 'us' && state.general.type === 'bubble') &&
2457
2561
  <label className='checkbox'>
2458
2562
  <input
2459
2563
  type='checkbox'
@@ -2489,6 +2593,20 @@ const EditorPanel = (props) => {
2489
2593
  <span className='edit-label'>Bubble Map has extra border</span>
2490
2594
  </label>
2491
2595
  }
2596
+ {state.general.geoType === 'us' &&
2597
+ <label>
2598
+ <span className='edit-label'>City Style</span>
2599
+ <select
2600
+ value={state.visual.cityStyle || false}
2601
+ onChange={(event) => {
2602
+ handleEditorChanges('handleCityStyle', event.target.value);
2603
+ }}
2604
+ >
2605
+ <option value='circle'>Circle</option>
2606
+ <option value='pin'>Pin</option>
2607
+ </select>
2608
+ </label>
2609
+ }
2492
2610
  </AccordionItemPanel>
2493
2611
  </AccordionItem>
2494
2612
  </Accordion>
@@ -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);