@cdc/map 2.6.3 → 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 (46) hide show
  1. package/dist/cdcmap.js +26 -18
  2. package/examples/bubble-us.json +363 -0
  3. package/examples/bubble-world.json +427 -0
  4. package/examples/default-hex.json +475 -0
  5. package/examples/default-usa-regions.json +118 -0
  6. package/examples/default-usa.json +1 -1
  7. package/examples/default-world-data.json +1450 -0
  8. package/examples/default-world.json +5 -3
  9. package/examples/example-city-state.json +36 -0
  10. package/examples/private/atsdr.json +439 -0
  11. package/examples/private/atsdr_new.json +436 -0
  12. package/examples/private/bubble.json +285 -0
  13. package/examples/private/default-world-data.json +1444 -0
  14. package/examples/private/default.json +968 -0
  15. package/examples/private/map.csv +60 -0
  16. package/examples/private/mdx.json +210 -0
  17. package/examples/private/regions.json +52 -0
  18. package/examples/private/wcmsrd-13881-data.json +2858 -0
  19. package/examples/private/wcmsrd-13881.json +5823 -0
  20. package/examples/private/wcmsrd-test.json +268 -0
  21. package/examples/private/world.json +1580 -0
  22. package/examples/private/worldmap.json +1490 -0
  23. package/package.json +51 -50
  24. package/src/CdcMap.js +340 -79
  25. package/src/components/BubbleList.js +240 -0
  26. package/src/components/CityList.js +19 -1
  27. package/src/components/CountyMap.js +3 -2
  28. package/src/components/DataTable.js +17 -10
  29. package/src/components/EditorPanel.js +741 -348
  30. package/src/components/Geo.js +1 -1
  31. package/src/components/SingleStateMap.js +1 -1
  32. package/src/components/UsaMap.js +22 -7
  33. package/src/components/UsaRegionMap.js +319 -0
  34. package/src/components/WorldMap.js +112 -35
  35. package/src/data/country-coordinates.js +250 -0
  36. package/src/data/initial-state.js +19 -2
  37. package/src/data/state-coordinates.js +55 -0
  38. package/src/data/supported-geos.js +91 -15
  39. package/src/data/us-regions-topo-2.json +360525 -0
  40. package/src/data/us-regions-topo.json +37894 -0
  41. package/src/hooks/useColorPalette.ts +96 -0
  42. package/src/index.html +10 -2
  43. package/src/scss/editor-panel.scss +76 -55
  44. package/src/scss/map.scss +108 -2
  45. package/src/data/color-palettes.js +0 -200
  46. package/src/images/map-folded.svg +0 -1
@@ -13,27 +13,25 @@ import { useDebounce } from 'use-debounce';
13
13
  import ErrorBoundary from '@cdc/core/components/ErrorBoundary';
14
14
  import Waiting from '@cdc/core/components/Waiting';
15
15
 
16
- import MapIcon from '../images/map-folded.svg';
17
16
  import UsaGraphic from '@cdc/core/assets/usa-graphic.svg';
18
17
  import WorldGraphic from '@cdc/core/assets/world-graphic.svg';
19
18
  import AlabamaGraphic from '@cdc/core/assets/alabama-graphic.svg';
20
- import colorPalettes from '../data/color-palettes';
19
+ import colorPalettes from '../../../core/data/colorPalettes';
21
20
  import worldDefaultConfig from '../../examples/default-world.json';
22
21
  import usaDefaultConfig from '../../examples/default-usa.json';
23
22
  import countyDefaultConfig from '../../examples/default-county.json';
24
23
  import QuestionIcon from '@cdc/core/assets/question-circle.svg';
25
24
 
26
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
+ import InputToggle from '@cdc/core/components/inputs/InputToggle';
29
+ import Tooltip from '@cdc/core/components/ui/Tooltip'
30
+ import Icon from '@cdc/core/components/ui/Icon'
27
31
 
28
- const ReactTags = require('react-tag-autocomplete'); // Future: Lazy
32
+ import AdvancedEditor from '@cdc/core/components/AdvancedEditor';
29
33
 
30
- const Helper = ({ text }) => {
31
- return (
32
- <span className='tooltip helper' data-tip={text}>
33
- <QuestionIcon />
34
- </span>
35
- );
36
- };
34
+ const ReactTags = require('react-tag-autocomplete'); // Future: Lazy
37
35
 
38
36
  const TextField = ({
39
37
  label,
@@ -43,7 +41,7 @@ const TextField = ({
43
41
  updateField,
44
42
  value: stateValue,
45
43
  type = 'input',
46
- helper = null,
44
+ tooltip,
47
45
  ...attributes
48
46
  }) => {
49
47
  const [value, setValue] = useState(stateValue);
@@ -73,7 +71,7 @@ const TextField = ({
73
71
  return (
74
72
  <label>
75
73
  <span className='edit-label column-heading'>
76
- {label} {helper && <Helper text={helper} />}
74
+ {label}{tooltip}
77
75
  </span>
78
76
  {formElement}
79
77
  </label>
@@ -107,6 +105,9 @@ const EditorPanel = (props) => {
107
105
 
108
106
  const [activeFilterValueForDescription, setActiveFilterValueForDescription] = useState([0, 0]);
109
107
 
108
+ const {filteredPallets,filteredQualitative,isPaletteReversed,paletteName} = useColorPalette(colorPalettes,state);
109
+
110
+
110
111
  const [editorCatOrder, setEditorCatOrder] = useState(state.legend.categoryValuesOrder || []);
111
112
 
112
113
  const headerColors = [
@@ -162,7 +163,7 @@ const EditorPanel = (props) => {
162
163
  };
163
164
 
164
165
 
165
- const DynamicDesc = ({ label, fieldName, value: stateValue, type = 'input', helper = null, ...attributes }) => {
166
+ const DynamicDesc = ({ label, fieldName, value: stateValue, type = 'input', ...attributes }) => {
166
167
  const [value, setValue] = useState(stateValue);
167
168
 
168
169
  const [debouncedValue] = useDebounce(value, 500);
@@ -183,6 +184,67 @@ const EditorPanel = (props) => {
183
184
 
184
185
  const handleEditorChanges = async (property, value) => {
185
186
  switch (property) {
187
+
188
+ // change these to be more generic.
189
+ // updateVisualPropertyValue
190
+ // updateGeneralPropertyValue, etc.
191
+ case 'showBubbleZeros':
192
+ setState({
193
+ ...state,
194
+ visual: {
195
+ ...state.visual,
196
+ showBubbleZeros: value
197
+ }
198
+ })
199
+ break;
200
+
201
+ case 'showEqualNumber':
202
+ setState({
203
+ ...state,
204
+ general: {
205
+ ...state.general,
206
+ equalNumberOptIn: value
207
+ }
208
+ })
209
+ break;
210
+
211
+ case 'hideGeoColumnInTooltip':
212
+ setState({
213
+ ...state,
214
+ general: {
215
+ ...state.general,
216
+ [property]: value
217
+ }
218
+ })
219
+ break;
220
+
221
+ case 'toggleExtraBubbleBorder':
222
+ setState({
223
+ ...state,
224
+ visual: {
225
+ ...state.visual,
226
+ extraBubbleBorder: value
227
+ }
228
+ })
229
+ break;
230
+ case 'allowMapZoom':
231
+ setState({
232
+ ...state,
233
+ general: {
234
+ ...state.general,
235
+ [property]: value
236
+ }
237
+ })
238
+ break;
239
+ case 'hidePrimaryColumnInTooltip':
240
+ setState({
241
+ ...state,
242
+ general: {
243
+ ...state.general,
244
+ [property]: value
245
+ }
246
+ })
247
+ break;
186
248
  case 'showTitle':
187
249
  setState({
188
250
  ...state,
@@ -274,12 +336,31 @@ const EditorPanel = (props) => {
274
336
  });
275
337
  break;
276
338
  case 'legendType':
339
+
340
+ let testForType = typeof state.data[0][state.columns.primary.name];
341
+ let hasValue = state.data[0][state.columns.primary.name];
342
+ let messages = [];
343
+
344
+ if(!hasValue) {
345
+ messages.push(`There appears to be values missing for data in the primary column ${state.columns.primary.name}`);
346
+ }
347
+
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.' );
350
+ } else {
351
+ messages = []
352
+ }
353
+
277
354
  setState({
278
355
  ...state,
279
356
  legend: {
280
357
  ...state.legend,
281
358
  type: value,
282
359
  },
360
+ runtime: {
361
+ ...state.runtime,
362
+ editorErrorMessage: messages
363
+ }
283
364
  });
284
365
  break;
285
366
  case 'legendNumber':
@@ -367,6 +448,20 @@ const EditorPanel = (props) => {
367
448
  },
368
449
  });
369
450
  break;
451
+ case 'bubble':
452
+ setState({
453
+ ...state,
454
+ general: {
455
+ ...state.general,
456
+ showSidebar: false,
457
+ type: 'bubble',
458
+ },
459
+ tooltips: {
460
+ ...state.tooltips,
461
+ appearanceType: 'hover',
462
+ },
463
+ });
464
+ break;
370
465
  default:
371
466
  console.warn('Map type not set');
372
467
  break;
@@ -558,6 +653,15 @@ const EditorPanel = (props) => {
558
653
  },
559
654
  });
560
655
  break;
656
+ case "classificationType":
657
+ setState({
658
+ ...state,
659
+ legend: {
660
+ ...state.legend,
661
+ type: value,
662
+ },
663
+ });
664
+ break;
561
665
  default:
562
666
  console.warn(`Did not recognize editor property.`);
563
667
  break;
@@ -804,7 +908,7 @@ const EditorPanel = (props) => {
804
908
  }, [state]);
805
909
 
806
910
  useEffect(() => {
807
- if ('category' === state.legend.type && editorCatOrder.length === 0) {
911
+ if ('category' === state.legend.type) {
808
912
  let arr = runtimeLegend.filter((item) => !item.special).map(({ value }) => value);
809
913
 
810
914
  setEditorCatOrder(arr);
@@ -948,7 +1052,12 @@ const EditorPanel = (props) => {
948
1052
  <label>
949
1053
  <span className='edit-label column-heading'>
950
1054
  Filter Column{' '}
951
- <Helper text='Selecting a column will add a dropdown menu below the map legend and allow users to filter based on the values in this column.' />
1055
+ <Tooltip style={{textTransform: 'none'}}>
1056
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1057
+ <Tooltip.Content>
1058
+ <p>Selecting a column will add a dropdown menu below the map legend and allow users to filter based on the values in this column.</p>
1059
+ </Tooltip.Content>
1060
+ </Tooltip>
952
1061
  </span>
953
1062
  <select
954
1063
  value={filter.columnName}
@@ -961,7 +1070,7 @@ const EditorPanel = (props) => {
961
1070
  )}
962
1071
  </select>
963
1072
  </label>
964
-
1073
+
965
1074
  <label>
966
1075
  <span className="edit-filterOrder column-heading">Filter Order</span>
967
1076
  <select value={filter.order} onChange={ (e) => {
@@ -1009,7 +1118,7 @@ const EditorPanel = (props) => {
1009
1118
  </Droppable>
1010
1119
  </DragDropContext>
1011
1120
  }
1012
-
1121
+
1013
1122
  </fieldset>
1014
1123
  );
1015
1124
  });
@@ -1043,21 +1152,28 @@ const EditorPanel = (props) => {
1043
1152
  });
1044
1153
  }
1045
1154
 
1155
+
1156
+ useEffect(()=>{
1157
+ if(paletteName) handleEditorChanges('color',paletteName)
1158
+ },[paletteName]) // dont add handleEditorChanges as a dependency even if it requires
1159
+
1046
1160
  useEffect(() => {
1047
1161
  const parsedData = convertStateToConfig();
1048
1162
  const formattedData = JSON.stringify(parsedData, undefined, 2);
1049
1163
 
1050
1164
  setConfigTextbox(formattedData);
1165
+ }, [state]);
1051
1166
 
1167
+ useEffect(() => {
1052
1168
  // Pass up to Editor if needed
1053
1169
  if (setParentConfig) {
1054
1170
  const newConfig = convertStateToConfig();
1055
1171
  setParentConfig(newConfig);
1056
1172
  }
1057
1173
 
1058
- // eslint-disable-next-line react-hooks/exhaustive-deps
1059
1174
  }, [state]);
1060
1175
 
1176
+
1061
1177
  let numberOfItemsLimit = 8;
1062
1178
 
1063
1179
  const getItemStyle = (isDragging, draggableStyle) => ({
@@ -1084,8 +1200,20 @@ const EditorPanel = (props) => {
1084
1200
  ));
1085
1201
  };
1086
1202
 
1203
+ const Error = () => {
1204
+ return (
1205
+ <section className="waiting">
1206
+ <section className="waiting-container">
1207
+ <h3>Error With Configuration</h3>
1208
+ <p>{state.runtime.editorErrorMessage}</p>
1209
+ </section>
1210
+ </section>
1211
+ );
1212
+ }
1213
+
1087
1214
  return (
1088
1215
  <ErrorBoundary component='EditorPanel'>
1216
+ {state?.runtime?.editorErrorMessage.length > 0 && <Error />}
1089
1217
  {requiredColumns && (
1090
1218
  <Waiting requiredColumns={requiredColumns} className={displayPanel ? `waiting` : `waiting collapsed`} />
1091
1219
  )}
@@ -1095,7 +1223,8 @@ const EditorPanel = (props) => {
1095
1223
  onClick={onBackClick}
1096
1224
  data-html2canvas-ignore
1097
1225
  ></button>
1098
- <section className={displayPanel ? 'editor-panel' : 'hidden editor-panel'} data-html2canvas-ignore>
1226
+
1227
+ <section className={displayPanel ? 'editor-panel cove' : 'hidden editor-panel cove'} data-html2canvas-ignore>
1099
1228
  <ReactTooltip html={true} multiline={true} />
1100
1229
  <span className='base-label'>Configure Map</span>
1101
1230
  <section className='form-container'>
@@ -1145,7 +1274,15 @@ const EditorPanel = (props) => {
1145
1274
  {/* Select > State or County Map */}
1146
1275
  {(state.general.geoType === 'us' || state.general.geoType === 'us-county') && (
1147
1276
  <label>
1148
- <span className='edit-label column-heading'>Map Type</span>
1277
+ <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>
1285
+ </span>
1149
1286
  <select
1150
1287
  value={state.general.geoType}
1151
1288
  onChange={(event) => {
@@ -1187,6 +1324,7 @@ const EditorPanel = (props) => {
1187
1324
  >
1188
1325
  <option value='data'>Data</option>
1189
1326
  <option value='navigation'>Navigation</option>
1327
+ { (state.general.geoType === 'world' || state.general.geoType === 'us') && <option value="bubble">Bubble</option>}
1190
1328
  </select>
1191
1329
  </label>
1192
1330
  {/* SubType */}
@@ -1232,7 +1370,14 @@ const EditorPanel = (props) => {
1232
1370
  fieldName='title'
1233
1371
  label='Title'
1234
1372
  placeholder='Map Title'
1235
- helper='For accessibility reasons, you should enter a title even if you are not planning on displaying it.'
1373
+ 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>
1380
+ }
1236
1381
  />
1237
1382
  <TextField
1238
1383
  type='textarea'
@@ -1241,6 +1386,14 @@ const EditorPanel = (props) => {
1241
1386
  section='general'
1242
1387
  fieldName='subtext'
1243
1388
  label='Subtext'
1389
+ tooltip={
1390
+ <Tooltip style={{textTransform: 'none'}}>
1391
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1392
+ <Tooltip.Content>
1393
+ <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>
1395
+ </Tooltip>
1396
+ }
1244
1397
  />
1245
1398
  {'us' === state.general.geoType && (
1246
1399
  <TextField
@@ -1252,6 +1405,41 @@ const EditorPanel = (props) => {
1252
1405
  placeholder='Territories'
1253
1406
  />
1254
1407
  )}
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>
1255
1443
  {/* <label className="checkbox mt-4">
1256
1444
  <input type="checkbox" checked={ state.general.showDownloadMediaButton } onChange={(event) => { handleEditorChanges("toggleDownloadMediaButton", event.target.checked) }} />
1257
1445
  <span className="edit-label">Enable Media Download</span>
@@ -1266,7 +1454,15 @@ const EditorPanel = (props) => {
1266
1454
  </AccordionItemHeading>
1267
1455
  <AccordionItemPanel>
1268
1456
  <label className='edit-block geo'>
1269
- <span className='edit-label column-heading'>Geography</span>
1457
+ <span className='edit-label column-heading'>
1458
+ Geography
1459
+ <Tooltip style={{textTransform: 'none'}}>
1460
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1461
+ <Tooltip.Content>
1462
+ <p>Select the source column containing the map location names or, for county-level maps, the FIPS codes.</p>
1463
+ </Tooltip.Content>
1464
+ </Tooltip>
1465
+ </span>
1270
1466
  <select
1271
1467
  value={state.columns.geo ? state.columns.geo.name : columnsOptions[0]}
1272
1468
  onChange={(event) => {
@@ -1276,155 +1472,222 @@ const EditorPanel = (props) => {
1276
1472
  {columnsOptions}
1277
1473
  </select>
1278
1474
  </label>
1279
- {'navigation' !== state.general.type && (
1280
- <fieldset className='primary-fieldset edit-block'>
1281
- <label>
1282
- <span className='edit-label column-heading'>Primary</span>
1283
- <select
1284
- value={
1285
- state.columns.primary
1286
- ? state.columns.primary.name
1287
- : columnsOptions[0]
1288
- }
1289
- onChange={(event) => {
1290
- editColumn('primary', 'name', event.target.value);
1291
- }}
1292
- >
1293
- {columnsOptions}
1294
- </select>
1295
- </label>
1296
- <TextField
1297
- value={columns.primary.label}
1298
- section='columns'
1299
- subsection='primary'
1300
- fieldName='label'
1301
- label='Label'
1302
- updateField={updateField}
1303
- />
1304
- <ul className='column-edit'>
1305
- <li className='three-col'>
1306
- <TextField
1307
- value={columns.primary.prefix}
1308
- section='columns'
1309
- subsection='primary'
1310
- fieldName='prefix'
1311
- label='Prefix'
1312
- updateField={updateField}
1313
- />
1314
- <TextField
1315
- value={columns.primary.suffix}
1316
- section='columns'
1317
- subsection='primary'
1318
- fieldName='suffix'
1319
- label='Suffix'
1320
- updateField={updateField}
1321
- />
1322
- <TextField
1323
- type='number'
1324
- value={columns.primary.roundToPlace}
1325
- section='columns'
1326
- subsection='primary'
1327
- fieldName='roundToPlace'
1328
- label='Round'
1329
- updateField={updateField}
1330
- />
1331
- </li>
1332
- <li>
1333
- <label className='checkbox'>
1334
- <input
1335
- type='checkbox'
1336
- checked={state.columns.primary.useCommas}
1337
- onChange={(event) => {
1338
- editColumn(
1339
- 'primary',
1340
- 'useCommas',
1341
- event.target.checked
1342
- );
1343
- }}
1344
- />
1345
- <span className='edit-label'>Add Commas to Numbers</span>
1346
- </label>
1347
- </li>
1348
- <li>
1349
- <label className='checkbox'>
1350
- <input
1351
- type='checkbox'
1352
- checked={state.columns.primary.dataTable || false}
1353
- onChange={(event) => {
1354
- editColumn(
1355
- 'primary',
1356
- 'dataTable',
1357
- event.target.checked
1358
- );
1359
- }}
1360
- />
1361
- <span className='edit-label'>Display in Data Table</span>
1362
- </label>
1363
- </li>
1364
- <li>
1365
- <label className='checkbox'>
1366
- <input
1367
- type='checkbox'
1368
- checked={state.columns.primary.tooltip || false}
1369
- onChange={(event) => {
1370
- editColumn('primary', 'tooltip', event.target.checked);
1371
- }}
1372
- />
1373
- <span className='edit-label'>Display in Tooltips</span>
1374
- </label>
1375
- </li>
1376
- <li>
1377
- <label>
1378
- <span className='edit-label'>Special Classes</span>
1379
- </label>
1380
- {specialClasses.map((specialClass, i) => (
1381
- <div className="edit-block" key={`special-class-${i}`}>
1382
- <button className="remove-column"
1383
- onClick={(e) => {
1384
- e.preventDefault();
1385
- editColumn('primary', 'specialClassDelete', i);
1386
- }}
1387
- >Remove</button>
1388
- <p>Special Class {i + 1}</p>
1389
- <label>
1390
- <span className="edit-label column-heading">Data Key</span>
1391
- <select value={specialClass.key} onChange={(e) => {
1392
- editColumn('primary', 'specialClassEdit', {prop: 'key', index: i, value: e.target.value});
1393
- }}>
1394
- {columnsOptions}
1395
- </select>
1396
- </label>
1397
- <label>
1398
- <span className="edit-label column-heading">Value</span>
1399
- <select value={specialClass.value} onChange={(e) => {
1400
- editColumn('primary', 'specialClassEdit', {prop: 'value', index: i, value: e.target.value});
1401
- }}>
1402
- <option value="">- Select Value -</option>
1403
- {columnsByKey[specialClass.key] && columnsByKey[specialClass.key].sort().map(option => (
1404
- <option key={`special-class-value-option-${i}-${option}`}>{option}</option>
1405
- ))}
1406
- </select>
1407
- </label>
1408
- <label>
1409
- <span className="edit-label column-heading">Label</span>
1410
- <input type="text" value={specialClass.label} onChange={(e) => {
1411
- editColumn('primary', 'specialClassEdit', {prop: 'label', index: i, value: e.target.value});
1412
- }} />
1413
- </label>
1414
- </div>
1415
- ))}
1416
- <button className="btn full-width"
1417
- onClick={(e) => {
1418
- e.preventDefault();
1419
- editColumn('primary', 'specialClassAdd', {});
1420
- }}
1421
- >Add SpecialClass</button>
1422
- </li>
1423
- </ul>
1424
- </fieldset>
1425
- )}
1475
+
1476
+ {'navigation' !== state.general.type && (
1477
+ <fieldset className='primary-fieldset edit-block'>
1478
+ <label>
1479
+ <span className='edit-label column-heading'>
1480
+ Data Column
1481
+ <Tooltip style={{textTransform: 'none'}}>
1482
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1483
+ <Tooltip.Content>
1484
+ <p>Select the source column containing the categorical or numeric values to be mapped.</p>
1485
+ </Tooltip.Content>
1486
+ </Tooltip>
1487
+ </span>
1488
+ <select
1489
+ value={
1490
+ state.columns.primary
1491
+ ? state.columns.primary.name
1492
+ : columnsOptions[0]
1493
+ }
1494
+ onChange={(event) => {
1495
+ editColumn('primary', 'name', event.target.value);
1496
+ }}
1497
+ >
1498
+ {columnsOptions}
1499
+ </select>
1500
+ </label>
1501
+ <TextField
1502
+ value={columns.primary.label}
1503
+ section='columns'
1504
+ subsection='primary'
1505
+ fieldName='label'
1506
+ label='Label'
1507
+ updateField={updateField}
1508
+ tooltip={
1509
+ <Tooltip style={{textTransform: 'none'}}>
1510
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1511
+ <Tooltip.Content>
1512
+ <p>Enter a data label for use in tooltips and the data table.</p>
1513
+ </Tooltip.Content>
1514
+ </Tooltip>
1515
+ }
1516
+ />
1517
+ <ul className='column-edit'>
1518
+ <li className='three-col'>
1519
+ <TextField
1520
+ value={columns.primary.prefix}
1521
+ section='columns'
1522
+ subsection='primary'
1523
+ fieldName='prefix'
1524
+ label='Prefix'
1525
+ updateField={updateField}
1526
+ />
1527
+ <TextField
1528
+ value={columns.primary.suffix}
1529
+ section='columns'
1530
+ subsection='primary'
1531
+ fieldName='suffix'
1532
+ label='Suffix'
1533
+ updateField={updateField}
1534
+ />
1535
+ <TextField
1536
+ type='number'
1537
+ value={columns.primary.roundToPlace}
1538
+ section='columns'
1539
+ subsection='primary'
1540
+ fieldName='roundToPlace'
1541
+ label='Round'
1542
+ updateField={updateField}
1543
+ />
1544
+ </li>
1545
+ <li>
1546
+ <label className='checkbox'>
1547
+ <input
1548
+ type='checkbox'
1549
+ checked={state.columns.primary.useCommas}
1550
+ onChange={(event) => {
1551
+ editColumn(
1552
+ 'primary',
1553
+ 'useCommas',
1554
+ event.target.checked
1555
+ );
1556
+ }}
1557
+ />
1558
+ <span className='edit-label'>Add Commas to Numbers</span>
1559
+ </label>
1560
+ </li>
1561
+ <li>
1562
+ <label className='checkbox'>
1563
+ <input
1564
+ type='checkbox'
1565
+ checked={state.columns.primary.dataTable || false}
1566
+ onChange={(event) => {
1567
+ editColumn(
1568
+ 'primary',
1569
+ 'dataTable',
1570
+ event.target.checked
1571
+ );
1572
+ }}
1573
+ />
1574
+ <span className='edit-label'>Display in Data Table</span>
1575
+ </label>
1576
+ </li>
1577
+ <li>
1578
+ <label className='checkbox'>
1579
+ <input
1580
+ type='checkbox'
1581
+ checked={state.columns.primary.tooltip || false}
1582
+ onChange={(event) => {
1583
+ editColumn('primary', 'tooltip', event.target.checked);
1584
+ }}
1585
+ />
1586
+ <span className='edit-label'>Display in Tooltips</span>
1587
+ </label>
1588
+ </li>
1589
+ </ul>
1590
+ </fieldset>
1591
+ )}
1592
+
1593
+
1594
+
1595
+ { (state.general.type === 'bubble') && state.legend.type === 'category' && (
1596
+ <fieldset className='primary-fieldset edit-block'>
1597
+ <label>
1598
+ <span className='edit-label column-heading'>
1599
+ Category Column
1600
+ <Tooltip style={{textTransform: 'none'}}>
1601
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1602
+ <Tooltip.Content>
1603
+ <p>Select the source column containing the categorical bubble values to be mapped.</p>
1604
+ </Tooltip.Content>
1605
+ </Tooltip>
1606
+ </span>
1607
+ <select
1608
+ value={
1609
+ state.columns.categorical
1610
+ ? state.columns.categorical.name
1611
+ : columnsOptions[0]
1612
+ }
1613
+ onChange={(event) => {
1614
+ editColumn('categorical', 'name', event.target.value);
1615
+ }}
1616
+ >
1617
+ {columnsOptions}
1618
+ </select>
1619
+ </label>
1620
+ </fieldset>
1621
+ )}
1622
+
1623
+ {'navigation' !== state.general.type && (
1624
+ <fieldset className="primary-fieldset edit-block">
1625
+ <label>
1626
+ <span className='edit-label'>
1627
+ Special Classes
1628
+ <Tooltip style={{textTransform: 'none'}}>
1629
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1630
+ <Tooltip.Content>
1631
+ <p>For secondary values such as "NA", the system can automatically color-code them in shades of gray, one shade for each special class.</p>
1632
+ </Tooltip.Content>
1633
+ </Tooltip>
1634
+ </span>
1635
+ </label>
1636
+ {specialClasses.map((specialClass, i) => (
1637
+ <div className="edit-block" key={`special-class-${i}`}>
1638
+ <button className="remove-column"
1639
+ onClick={(e) => {
1640
+ e.preventDefault();
1641
+ editColumn('primary', 'specialClassDelete', i);
1642
+ }}
1643
+ >Remove</button>
1644
+ <p>Special Class {i + 1}</p>
1645
+ <label>
1646
+ <span className="edit-label column-heading">Data Key</span>
1647
+ <select value={specialClass.key} onChange={(e) => {
1648
+ editColumn('primary', 'specialClassEdit', {prop: 'key', index: i, value: e.target.value});
1649
+ }}>
1650
+ {columnsOptions}
1651
+ </select>
1652
+ </label>
1653
+ <label>
1654
+ <span className="edit-label column-heading">Value</span>
1655
+ <select value={specialClass.value} onChange={(e) => {
1656
+ editColumn('primary', 'specialClassEdit', {prop: 'value', index: i, value: e.target.value});
1657
+ }}>
1658
+ <option value="">- Select Value -</option>
1659
+ {columnsByKey[specialClass.key] && columnsByKey[specialClass.key].sort().map(option => (
1660
+ <option key={`special-class-value-option-${i}-${option}`}>{option}</option>
1661
+ ))}
1662
+ </select>
1663
+ </label>
1664
+ <label>
1665
+ <span className="edit-label column-heading">Label</span>
1666
+ <input type="text" value={specialClass.label} onChange={(e) => {
1667
+ editColumn('primary', 'specialClassEdit', {prop: 'label', index: i, value: e.target.value});
1668
+ }} />
1669
+ </label>
1670
+ </div>
1671
+ ))}
1672
+ <button className="btn full-width" onClick={(e) => {
1673
+ e.preventDefault();
1674
+ editColumn('primary', 'specialClassAdd', {});
1675
+ }}>
1676
+ Add Special Class
1677
+ </button>
1678
+ </fieldset>
1679
+ )}
1680
+
1426
1681
  <label className='edit-block navigate column-heading'>
1427
- <span className='edit-label column-heading'>Navigation</span>
1682
+ <span className='edit-label column-heading'>
1683
+ Navigation
1684
+ <Tooltip style={{textTransform: 'none'}}>
1685
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1686
+ <Tooltip.Content>
1687
+ <p>To provide end users with navigation functionality, select the source column containing the navigation URLs.</p>
1688
+ </Tooltip.Content>
1689
+ </Tooltip>
1690
+ </span>
1428
1691
  <select
1429
1692
  value={
1430
1693
  state.columns.navigate ? state.columns.navigate.name : columnsOptions[0]
@@ -1437,118 +1700,130 @@ const EditorPanel = (props) => {
1437
1700
  </select>
1438
1701
  </label>
1439
1702
  {'navigation' !== state.general.type &&
1440
- additionalColumns.map((val) => (
1441
- <fieldset className='edit-block' key={val}>
1442
- <button
1443
- className='remove-column'
1444
- onClick={(event) => {
1445
- event.preventDefault();
1446
- removeAdditionalColumn(val);
1447
- }}
1448
- >
1449
- Remove
1450
- </button>
1451
- <label>
1452
- <span className='edit-label column-heading'>Column</span>
1453
- <select
1454
- value={
1455
- state.columns[val]
1456
- ? state.columns[val].name
1457
- : columnsOptions[0]
1458
- }
1459
- onChange={(event) => {
1460
- editColumn(val, 'name', event.target.value);
1461
- }}
1462
- >
1463
- {columnsOptions}
1464
- </select>
1465
- </label>
1466
- <TextField
1467
- value={columns[val].label}
1468
- section='columns'
1469
- subsection={val}
1470
- fieldName='label'
1471
- label='Label'
1472
- updateField={updateField}
1473
- />
1474
- <ul className='column-edit'>
1475
- <li className='three-col'>
1476
- <TextField
1477
- value={columns[val].prefix}
1478
- section='columns'
1479
- subsection={val}
1480
- fieldName='prefix'
1481
- label='Prefix'
1482
- updateField={updateField}
1483
- />
1484
- <TextField
1485
- value={columns[val].suffix}
1486
- section='columns'
1487
- subsection={val}
1488
- fieldName='suffix'
1489
- label='Suffix'
1490
- updateField={updateField}
1491
- />
1492
- <TextField
1493
- type='number'
1494
- value={columns[val].roundToPlace}
1495
- section='columns'
1496
- subsection={val}
1497
- fieldName='roundToPlace'
1498
- label='Round'
1499
- updateField={updateField}
1500
- />
1501
- </li>
1502
- <li>
1503
- <label className='checkbox'>
1504
- <input
1505
- type='checkbox'
1506
- checked={state.columns[val].useCommas}
1507
- onChange={(event) => {
1508
- editColumn(val, 'useCommas', event.target.checked);
1509
- }}
1510
- />
1511
- <span className='edit-label'>Add Commas to Numbers</span>
1512
- </label>
1513
- </li>
1514
- <li>
1515
- <label className='checkbox'>
1516
- <input
1517
- type='checkbox'
1518
- checked={state.columns[val].dataTable}
1519
- onChange={(event) => {
1520
- editColumn(val, 'dataTable', event.target.checked);
1521
- }}
1522
- />
1523
- <span className='edit-label'>Display in Data Table</span>
1524
- </label>
1525
- </li>
1526
- <li>
1527
- <label className='checkbox'>
1528
- <input
1529
- type='checkbox'
1530
- checked={state.columns[val].tooltip}
1531
- onChange={(event) => {
1532
- editColumn(val, 'tooltip', event.target.checked);
1533
- }}
1534
- />
1535
- <span className='edit-label'>Display in Tooltips</span>
1536
- </label>
1537
- </li>
1538
- </ul>
1539
- </fieldset>
1540
- ))}
1541
- {'navigation' !== state.general.type && (
1542
- <button
1543
- className={'btn full-width'}
1544
- onClick={(event) => {
1545
- event.preventDefault();
1546
- addAdditionalColumn(additionalColumns.length + 1);
1547
- }}
1548
- >
1549
- Add Column
1550
- </button>
1551
- )}
1703
+ <fieldset className="primary-fieldset edit-block">
1704
+ <label>
1705
+ <span className="edit-label">
1706
+ Additional Columns
1707
+ <Tooltip style={{textTransform: 'none'}}>
1708
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1709
+ <Tooltip.Content>
1710
+ <p>You can specify additional columns to display in tooltips and / or the supporting data table.</p>
1711
+ </Tooltip.Content>
1712
+ </Tooltip>
1713
+ </span>
1714
+ </label>
1715
+ {additionalColumns.map((val) => (
1716
+ <fieldset className="edit-block" key={val}>
1717
+ <button
1718
+ className="remove-column"
1719
+ onClick={(event) => {
1720
+ event.preventDefault()
1721
+ removeAdditionalColumn(val)
1722
+ }}
1723
+ >
1724
+ Remove
1725
+ </button>
1726
+ <label>
1727
+ <span className="edit-label column-heading">Column</span>
1728
+ <select
1729
+ value={
1730
+ state.columns[val]
1731
+ ? state.columns[val].name
1732
+ : columnsOptions[0]
1733
+ }
1734
+ onChange={(event) => {
1735
+ editColumn(val, 'name', event.target.value)
1736
+ }}
1737
+ >
1738
+ {columnsOptions}
1739
+ </select>
1740
+ </label>
1741
+ <TextField
1742
+ value={columns[val].label}
1743
+ section="columns"
1744
+ subsection={val}
1745
+ fieldName="label"
1746
+ label="Label"
1747
+ updateField={updateField}
1748
+ />
1749
+ <ul className="column-edit">
1750
+ <li className="three-col">
1751
+ <TextField
1752
+ value={columns[val].prefix}
1753
+ section="columns"
1754
+ subsection={val}
1755
+ fieldName="prefix"
1756
+ label="Prefix"
1757
+ updateField={updateField}
1758
+ />
1759
+ <TextField
1760
+ value={columns[val].suffix}
1761
+ section="columns"
1762
+ subsection={val}
1763
+ fieldName="suffix"
1764
+ label="Suffix"
1765
+ updateField={updateField}
1766
+ />
1767
+ <TextField
1768
+ type="number"
1769
+ value={columns[val].roundToPlace}
1770
+ section="columns"
1771
+ subsection={val}
1772
+ fieldName="roundToPlace"
1773
+ label="Round"
1774
+ updateField={updateField}
1775
+ />
1776
+ </li>
1777
+ <li>
1778
+ <label className="checkbox">
1779
+ <input
1780
+ type="checkbox"
1781
+ checked={state.columns[val].useCommas}
1782
+ onChange={(event) => {
1783
+ editColumn(val, 'useCommas', event.target.checked)
1784
+ }}
1785
+ />
1786
+ <span className="edit-label">Add Commas to Numbers</span>
1787
+ </label>
1788
+ </li>
1789
+ <li>
1790
+ <label className="checkbox">
1791
+ <input
1792
+ type="checkbox"
1793
+ checked={state.columns[val].dataTable}
1794
+ onChange={(event) => {
1795
+ editColumn(val, 'dataTable', event.target.checked)
1796
+ }}
1797
+ />
1798
+ <span className="edit-label">Display in Data Table</span>
1799
+ </label>
1800
+ </li>
1801
+ <li>
1802
+ <label className="checkbox">
1803
+ <input
1804
+ type="checkbox"
1805
+ checked={state.columns[val].tooltip}
1806
+ onChange={(event) => {
1807
+ editColumn(val, 'tooltip', event.target.checked)
1808
+ }}
1809
+ />
1810
+ <span className="edit-label">Display in Tooltips</span>
1811
+ </label>
1812
+ </li>
1813
+ </ul>
1814
+ </fieldset>
1815
+ ))}
1816
+ <button
1817
+ className={'btn full-width'}
1818
+ onClick={(event) => {
1819
+ event.preventDefault();
1820
+ addAdditionalColumn(additionalColumns.length + 1);
1821
+ }}
1822
+ >
1823
+ Add Column
1824
+ </button>
1825
+ </fieldset>
1826
+ }
1552
1827
  </AccordionItemPanel>
1553
1828
  </AccordionItem>{' '}
1554
1829
  {/* Columns */}
@@ -1560,6 +1835,7 @@ const EditorPanel = (props) => {
1560
1835
  <AccordionItemButton>Legend</AccordionItemButton>
1561
1836
  </AccordionItemHeading>
1562
1837
  <AccordionItemPanel>
1838
+ {(state.legend.type === "equalnumber" || state.legend.type === 'equalinterval') && (
1563
1839
  <label>
1564
1840
  <span className='edit-label'>Legend Type</span>
1565
1841
  <select
@@ -1572,7 +1848,8 @@ const EditorPanel = (props) => {
1572
1848
  <option value='equalinterval'>Equal Interval</option>
1573
1849
  <option value='category'>Categorical</option>
1574
1850
  </select>
1575
- </label>
1851
+ </label>
1852
+ )}
1576
1853
  {'category' !== legend.type && (
1577
1854
  <label className='checkbox'>
1578
1855
  <input
@@ -1582,12 +1859,42 @@ const EditorPanel = (props) => {
1582
1859
  handleEditorChanges('separateZero', event.target.checked)
1583
1860
  }
1584
1861
  />
1585
- <span className='edit-label'>Separate Zero</span>
1862
+ <span className='edit-label'>
1863
+ Separate Zero
1864
+ <Tooltip style={{textTransform: 'none'}}>
1865
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1866
+ <Tooltip.Content>
1867
+ <p>For numeric data, you can separate the zero value as its own data class.</p>
1868
+ </Tooltip.Content>
1869
+ </Tooltip>
1870
+ </span>
1871
+
1586
1872
  </label>
1587
1873
  )}
1874
+ {/* Temp Checkbox */}
1875
+ {state.legend.type === 'equalnumber' &&
1876
+ <label className="checkbox mt-4">
1877
+ <input type="checkbox" checked={ state.general.equalNumberOptIn } onChange={(event) => { handleEditorChanges("showEqualNumber", event.target.checked) }} />
1878
+ <span className="edit-label">Use new quantile legend</span>
1879
+ <Tooltip style={{textTransform: 'none'}}>
1880
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1881
+ <Tooltip.Content>
1882
+ <p>This prevents numbers from being used in more than one category (ie. 0-1, 1-2, 2-3) </p>
1883
+ </Tooltip.Content>
1884
+ </Tooltip>
1885
+ </label>
1886
+ }
1588
1887
  {'category' !== legend.type && (
1589
1888
  <label>
1590
- <span className='edit-label'>Number of Items</span>
1889
+ <span className='edit-label'>
1890
+ Number of Items
1891
+ <Tooltip style={{textTransform: 'none'}}>
1892
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1893
+ <Tooltip.Content>
1894
+ <p>For numeric maps, select the number of data classes. Do not include designated special classes.</p>
1895
+ </Tooltip.Content>
1896
+ </Tooltip>
1897
+ </span>
1591
1898
  <select
1592
1899
  value={legend.numberOfItems}
1593
1900
  onChange={(event) => {
@@ -1607,7 +1914,15 @@ const EditorPanel = (props) => {
1607
1914
  {'category' === legend.type && (
1608
1915
  <React.Fragment>
1609
1916
  <label>
1610
- <span className='edit-label'>Category Order</span>
1917
+ <span className='edit-label'>
1918
+ Category Order
1919
+ <Tooltip style={{textTransform: 'none'}}>
1920
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
1921
+ <Tooltip.Content>
1922
+ <p>Drag map categories into preferred legend order. </p>
1923
+ </Tooltip.Content>
1924
+ </Tooltip>
1925
+ </span>
1611
1926
  </label>
1612
1927
  {/* TODO: Swap out this drag and drop library back to something simpler. I had to remove the old one because it hadn't been updated and wouldn't work with Webpack 5. This is overkill for our needs. */}
1613
1928
  <DragDropContext
@@ -1628,13 +1943,13 @@ const EditorPanel = (props) => {
1628
1943
  )}
1629
1944
  </Droppable>
1630
1945
  </DragDropContext>
1631
- {editorCatOrder.length >= 9 && (
1946
+ {editorCatOrder.length >= 10 && (
1632
1947
  <section className='error-box my-2'>
1633
1948
  <div>
1634
1949
  <strong className='pt-1'>Warning</strong>
1635
1950
  <p>
1636
- The maximum number of categorical legend items is 9. If
1637
- your data has more than 9 categories your map will not
1951
+ The maximum number of categorical legend items is 10. If
1952
+ your data has more than 10 categories your map will not
1638
1953
  display properly.
1639
1954
  </p>
1640
1955
  </div>
@@ -1706,10 +2021,18 @@ const EditorPanel = (props) => {
1706
2021
  );
1707
2022
  }}
1708
2023
  />
1709
- <span className='edit-label'>Dynamic Legend Description</span>
2024
+ <span className='edit-label'>
2025
+ Dynamic Legend Description
2026
+ <Tooltip style={{textTransform: 'none'}}>
2027
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
2028
+ <Tooltip.Content>
2029
+ <p>Check this option if the map has multiple filter controls and you want to specify a description for each filter selection.</p>
2030
+ </Tooltip.Content>
2031
+ </Tooltip>
2032
+ </span>
1710
2033
  </label>
1711
2034
  )}
1712
- {filtersJSX.length > 0 && (
2035
+ {filtersJSX.length > 0 || state.general.type === 'bubble' && (
1713
2036
  <label className='checkbox'>
1714
2037
  <input
1715
2038
  type='checkbox'
@@ -1718,7 +2041,15 @@ const EditorPanel = (props) => {
1718
2041
  handleEditorChanges('unifiedLegend', event.target.checked)
1719
2042
  }
1720
2043
  />
1721
- <span className='edit-label'>Unified Legend</span>
2044
+ <span className='edit-label'>
2045
+ Unified Legend
2046
+ <Tooltip style={{textTransform: 'none'}}>
2047
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
2048
+ <Tooltip.Content>
2049
+ <p>For a map with filters, check this option if you want the high and low values in the legend to be based on <em>all</em> mapped values.</p>
2050
+ </Tooltip.Content>
2051
+ </Tooltip>
2052
+ </span>
1722
2053
  </label>
1723
2054
  )}
1724
2055
  </AccordionItemPanel>
@@ -1766,12 +2097,20 @@ const EditorPanel = (props) => {
1766
2097
  placeholder='Data Table'
1767
2098
  />
1768
2099
  <TextField
1769
- value={dataTable.indexTitle}
2100
+ value={dataTable.indexLabel || ''}
1770
2101
  updateField={updateField}
1771
2102
  section='dataTable'
1772
- fieldName='indexTitle'
1773
- label='Index Column Title'
2103
+ fieldName='indexLabel'
2104
+ label='Index Column Header'
1774
2105
  placeholder='Location'
2106
+ tooltip={
2107
+ <Tooltip style={{textTransform: 'none'}}>
2108
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
2109
+ <Tooltip.Content>
2110
+ <p>To comply with 508 standards, if the first column in the data table has no header, enter a brief one here.</p>
2111
+ </Tooltip.Content>
2112
+ </Tooltip>
2113
+ }
1775
2114
  />
1776
2115
  <TextField
1777
2116
  value={dataTable.caption}
@@ -1780,7 +2119,14 @@ const EditorPanel = (props) => {
1780
2119
  fieldName='caption'
1781
2120
  label='Data Table Caption'
1782
2121
  placeholder='Data Table'
1783
- helper='Text that describes the data table for screen'
2122
+ tooltip={
2123
+ <Tooltip style={{textTransform: 'none'}}>
2124
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
2125
+ <Tooltip.Content>
2126
+ <p>Enter a description of the data table to be read by screen readers.</p>
2127
+ </Tooltip.Content>
2128
+ </Tooltip>
2129
+ }
1784
2130
  type="textarea"
1785
2131
  />
1786
2132
  <label className='checkbox'>
@@ -1795,8 +2141,15 @@ const EditorPanel = (props) => {
1795
2141
  handleEditorChanges('showDataTable', event.target.checked);
1796
2142
  }}
1797
2143
  />
1798
- <span className='edit-label'>Show Table</span>
1799
- <Helper text='Data tables are required for 508 compliance. When choosing to hide this data table, replace with your own version.' />
2144
+ <span className='edit-label'>
2145
+ Show Table
2146
+ <Tooltip style={{textTransform: 'none'}}>
2147
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
2148
+ <Tooltip.Content>
2149
+ <p>Data tables are required for 508 compliance. When choosing to hide this data table, replace with your own version.</p>
2150
+ </Tooltip.Content>
2151
+ </Tooltip>
2152
+ </span>
1800
2153
  </label>
1801
2154
  <label className='checkbox'>
1802
2155
  <input
@@ -1854,7 +2207,12 @@ const EditorPanel = (props) => {
1854
2207
  <label>
1855
2208
  <span className='edit-label'>
1856
2209
  Detail displays on{' '}
1857
- <Helper text='At mobile sizes, information always appears in a popover modal when a user taps on an item.' />
2210
+ <Tooltip style={{textTransform: 'none'}}>
2211
+ <Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
2212
+ <Tooltip.Content>
2213
+ <p>At mobile sizes, information always appears in a popover modal when a user taps on an item.</p>
2214
+ </Tooltip.Content>
2215
+ </Tooltip>
1858
2216
  </span>
1859
2217
  <select
1860
2218
  value={state.tooltips.appearanceType}
@@ -1894,7 +2252,7 @@ const EditorPanel = (props) => {
1894
2252
  <AccordionItemButton>Visual</AccordionItemButton>
1895
2253
  </AccordionItemHeading>
1896
2254
  <AccordionItemPanel>
1897
- <label className='header'>
2255
+ <label>
1898
2256
  <span className='edit-label'>Header Theme</span>
1899
2257
  <ul className='color-palette'>
1900
2258
  {headerColors.map((palette) => {
@@ -1925,6 +2283,29 @@ const EditorPanel = (props) => {
1925
2283
  />
1926
2284
  <span className='edit-label'>Show Title</span>
1927
2285
  </label>
2286
+
2287
+ <label className='checkbox'>
2288
+ <input
2289
+ type='checkbox'
2290
+ checked={state.general.hideGeoColumnInTooltip || false}
2291
+ onChange={(event) => {
2292
+ handleEditorChanges('hideGeoColumnInTooltip', event.target.checked);
2293
+ }}
2294
+ />
2295
+ <span className='edit-label'>Hide Geography Column Name in Tooltip</span>
2296
+ </label>
2297
+
2298
+ <label className='checkbox'>
2299
+ <input
2300
+ type='checkbox'
2301
+ checked={state.general.hidePrimaryColumnInTooltip || false}
2302
+ onChange={(event) => {
2303
+ handleEditorChanges('hidePrimaryColumnInTooltip', event.target.checked);
2304
+ }}
2305
+ />
2306
+ <span className='edit-label'>Hide Primary Column Name in Tooltip</span>
2307
+ </label>
2308
+
1928
2309
  {'navigation' !== state.general.type && (
1929
2310
  <label className='checkbox'>
1930
2311
  <input
@@ -1990,10 +2371,11 @@ const EditorPanel = (props) => {
1990
2371
  <label>
1991
2372
  <span className='edit-label'>Map Color Palette</span>
1992
2373
  </label>
1993
- <span className='h5'>Sequential</span>
2374
+ {/* <InputCheckbox section="general" subsection="palette" fieldName='isReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} /> */}
2375
+ <InputToggle type='3d' section="general" subsection="palette" fieldName='isReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} />
2376
+ <span>Sequential</span>
1994
2377
  <ul className='color-palette'>
1995
- {Object.keys(colorPalettes)
1996
- .filter((name) => !name.includes('qualitative'))
2378
+ {filteredPallets
1997
2379
  .map((palette) => {
1998
2380
  const colorOne = {
1999
2381
  backgroundColor: colorPalettes[palette][2],
@@ -2023,10 +2405,9 @@ const EditorPanel = (props) => {
2023
2405
  );
2024
2406
  })}
2025
2407
  </ul>
2026
- <span className='h5'>Non-Sequential</span>
2408
+ <span>Non-Sequential</span>
2027
2409
  <ul className='color-palette'>
2028
- {Object.keys(colorPalettes)
2029
- .filter((name) => name.includes('qualitative'))
2410
+ {filteredQualitative
2030
2411
  .map((palette) => {
2031
2412
  const colorOne = {
2032
2413
  backgroundColor: colorPalettes[palette][2],
@@ -2056,52 +2437,64 @@ const EditorPanel = (props) => {
2056
2437
  );
2057
2438
  })}
2058
2439
  </ul>
2440
+ <TextField
2441
+ type='number'
2442
+ value={state.visual.minBubbleSize}
2443
+ section='visual'
2444
+ fieldName='minBubbleSize'
2445
+ label='Minimum Bubble Size'
2446
+ updateField={updateField}
2447
+ />
2448
+ <TextField
2449
+ type='number'
2450
+ value={state.visual.maxBubbleSize}
2451
+ section='visual'
2452
+ fieldName='maxBubbleSize'
2453
+ label='Maximum Bubble Size'
2454
+ updateField={updateField}
2455
+ />
2456
+ { (state.general.geoType === 'world' || state.general.geoType === 'us') &&
2457
+ <label className='checkbox'>
2458
+ <input
2459
+ type='checkbox'
2460
+ checked={state.visual.showBubbleZeros}
2461
+ onChange={(event) => {
2462
+ handleEditorChanges('showBubbleZeros', event.target.checked);
2463
+ }}
2464
+ />
2465
+ <span className='edit-label'>Show Data with Zero's on Bubble Map</span>
2466
+ </label>
2467
+ }
2468
+ {state.general.geoType === 'world' &&
2469
+ <label className='checkbox'>
2470
+ <input
2471
+ type='checkbox'
2472
+ checked={state.general.allowMapZoom}
2473
+ onChange={(event) => {
2474
+ handleEditorChanges('allowMapZoom', event.target.checked);
2475
+ }}
2476
+ />
2477
+ <span className='edit-label'>Allow Map Zooming</span>
2478
+ </label>
2479
+ }
2480
+ {state.general.type === 'bubble' &&
2481
+ <label className='checkbox'>
2482
+ <input
2483
+ type='checkbox'
2484
+ checked={state.visual.extraBubbleBorder}
2485
+ onChange={(event) => {
2486
+ handleEditorChanges('toggleExtraBubbleBorder', event.target.checked);
2487
+ }}
2488
+ />
2489
+ <span className='edit-label'>Bubble Map has extra border</span>
2490
+ </label>
2491
+ }
2059
2492
  </AccordionItemPanel>
2060
2493
  </AccordionItem>
2061
2494
  </Accordion>
2062
2495
  </form>
2063
- <a
2064
- href='https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/data-map.html'
2065
- target='_blank'
2066
- rel='noopener noreferrer'
2067
- className='guidance-link'
2068
- >
2069
- <MapIcon />
2070
- <div>
2071
- <span className='heading-3'>Get Maps Help</span>
2072
- <p>Examples and documentation</p>
2073
- </div>
2074
- </a>
2075
- <div className='advanced'>
2076
- <span className='advanced-toggle-link' onClick={() => setAdvancedToggle(!advancedToggle)}>
2077
- <span>{advancedToggle ? `— ` : `+ `}</span>Advanced Options
2078
- </span>
2079
- {advancedToggle && (
2080
- <React.Fragment>
2081
- <section className='error-box py-2 px-3 my-2'>
2082
- <div>
2083
- <strong className='pt-1'>Warning</strong>
2084
- <p>This can cause serious errors in your map.</p>
2085
- </div>
2086
- </section>
2087
- <p className='pb-2'>
2088
- This tool displays the actual map configuration{' '}
2089
- <acronym title='JavaScript Object Notation'>JSON</acronym> that is generated by this
2090
- editor and allows you to edit properties directly and apply them.
2091
- </p>
2092
- <textarea
2093
- value={configTextboxValue}
2094
- onChange={(event) => setConfigTextbox(event.target.value)}
2095
- />
2096
- <button
2097
- className='btn full-width'
2098
- onClick={() => loadConfig(JSON.parse(configTextboxValue))}
2099
- >
2100
- Apply
2101
- </button>
2102
- </React.Fragment>
2103
- )}
2104
- </div>
2496
+ <AdvancedEditor loadConfig={loadConfig} state={state} convertStateToConfig={convertStateToConfig} />
2497
+
2105
2498
  </section>
2106
2499
  </section>
2107
2500
  </ErrorBoundary>