@cdc/map 4.24.10 → 4.24.12-2

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 (57) hide show
  1. package/dist/cdcmap.js +33447 -32769
  2. package/examples/default-geocode.json +13 -4
  3. package/examples/default-usa-regions.json +267 -117
  4. package/examples/example-city-state.json +6 -3
  5. package/examples/pattern.json +861 -0
  6. package/examples/private/DEV-9644.json +184 -0
  7. package/examples/private/DEV-9989.json +229 -0
  8. package/examples/private/ardi.json +180 -0
  9. package/examples/private/colors 2.json +416 -0
  10. package/examples/private/colors.json +416 -0
  11. package/examples/private/colors.json.zip +0 -0
  12. package/examples/private/customColors.json +45348 -0
  13. package/examples/private/default-patterns.json +867 -0
  14. package/examples/private/test.json +1632 -0
  15. package/index.html +4 -5
  16. package/package.json +3 -3
  17. package/src/CdcMap.tsx +93 -83
  18. package/src/_stories/CdcMap.Legend.Gradient.stories.tsx +67 -0
  19. package/src/_stories/CdcMap.Legend.stories.tsx +40 -0
  20. package/src/_stories/CdcMap.Patterns.stories.tsx +29 -0
  21. package/src/_stories/CdcMap.stories.tsx +59 -0
  22. package/src/_stories/UsaMap.NoData.stories.tsx +19 -0
  23. package/src/_stories/_mock/custom-layer-map.json +1117 -0
  24. package/src/_stories/_mock/default-patterns.json +865 -0
  25. package/src/_stories/_mock/example-city-state.json +858 -0
  26. package/src/_stories/_mock/usa-state-gradient.json +238 -0
  27. package/src/_stories/_mock/wastewater-map.json +208 -0
  28. package/src/components/CityList.tsx +5 -2
  29. package/src/components/EditorPanel/components/EditorPanel.tsx +68 -295
  30. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +27 -23
  31. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +75 -16
  32. package/src/components/Legend/components/Legend.tsx +42 -20
  33. package/src/components/Legend/components/index.scss +24 -24
  34. package/src/components/UsaMap/components/HexIcon.tsx +7 -1
  35. package/src/components/UsaMap/components/SingleState/SingleState.CountyOutput.tsx +40 -6
  36. package/src/components/UsaMap/components/SingleState/SingleState.StateOutput.tsx +10 -2
  37. package/src/components/UsaMap/components/Territory/Territory.Hexagon.tsx +57 -12
  38. package/src/components/UsaMap/components/Territory/Territory.Rectangle.tsx +95 -21
  39. package/src/components/UsaMap/components/Territory/TerritoryShape.ts +13 -0
  40. package/src/components/UsaMap/components/UsaMap.County.tsx +11 -13
  41. package/src/components/UsaMap/components/UsaMap.Region.tsx +59 -16
  42. package/src/components/UsaMap/components/UsaMap.SingleState.tsx +2 -1
  43. package/src/components/UsaMap/components/UsaMap.State.tsx +61 -63
  44. package/src/components/UsaMap/helpers/shapes.ts +5 -4
  45. package/src/components/WorldMap/WorldMap.tsx +77 -16
  46. package/src/data/initial-state.js +2 -1
  47. package/src/helpers/applyColorToLegend.ts +80 -0
  48. package/src/helpers/colors.ts +23 -0
  49. package/src/hooks/useTooltip.ts +9 -6
  50. package/src/scss/editor-panel.scss +0 -3
  51. package/src/scss/filters.scss +1 -9
  52. package/src/scss/main.scss +0 -5
  53. package/src/scss/map.scss +11 -63
  54. package/src/types/MapConfig.ts +8 -2
  55. package/src/types/MapContext.ts +1 -0
  56. package/examples/default-patterns.json +0 -579
  57. package/src/scss/datatable.scss +0 -6
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useCallback, memo, useContext } from 'react'
1
+ import React, { useState, useEffect, useContext } from 'react'
2
2
 
3
3
  // Third Party
4
4
  import {
@@ -10,6 +10,7 @@ import {
10
10
  } from 'react-accessible-accordion'
11
11
  import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd'
12
12
  import { useDebounce } from 'use-debounce'
13
+ import _ from 'lodash'
13
14
  // import ReactTags from 'react-tag-autocomplete'
14
15
  import { Tooltip as ReactTooltip } from 'react-tooltip'
15
16
  import Panels from './Panels'
@@ -25,6 +26,7 @@ import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
25
26
  import Icon from '@cdc/core/components/ui/Icon'
26
27
  import InputToggle from '@cdc/core/components/inputs/InputToggle'
27
28
  import Tooltip from '@cdc/core/components/ui/Tooltip'
29
+ import VizFilterEditor from '@cdc/core/components/EditorPanel/VizFilterEditor'
28
30
 
29
31
  // Assets
30
32
  import UsaGraphic from '@cdc/core/assets/icon-map-usa.svg'
@@ -36,35 +38,31 @@ import usaDefaultConfig from '../../../../examples/default-usa.json'
36
38
  import countyDefaultConfig from '../../../../examples/default-county.json'
37
39
  import useMapLayers from '../../../hooks/useMapLayers.tsx'
38
40
 
39
- import { useFilters } from '@cdc/core/components/Filters'
40
-
41
41
  import HexSetting from './HexShapeSettings.jsx'
42
42
  import ConfigContext from '../../../context.ts'
43
43
  import { MapContext } from '../../../types/MapContext.js'
44
44
  import { TextField } from './Inputs'
45
+ import Alert from '@cdc/core/components/Alert'
46
+ import { updateFieldFactory } from '@cdc/core/helpers/updateFieldFactory'
45
47
 
46
48
  // Todo: move to useReducer, seperate files out.
47
49
  const EditorPanel = ({ columnsRequiredChecker }) => {
48
50
  // prettier-ignore
49
51
  const {
50
- changeFilterActive,
51
52
  columnsInData = [],
52
53
  isDashboard,
53
54
  isDebug,
54
- isEditor,
55
55
  loadConfig,
56
56
  runtimeFilters,
57
57
  runtimeLegend,
58
58
  setParentConfig,
59
- setRuntimeFilters,
60
59
  setState,
61
60
  state,
62
61
  tooltipId,
63
62
  runtimeData,
64
63
  setRuntimeData,
65
64
  generateRuntimeData,
66
- position,
67
- topoData,
65
+
68
66
 
69
67
  } = useContext<MapContext>(ConfigContext)
70
68
 
@@ -78,13 +76,6 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
78
76
 
79
77
  const [activeFilterValueForDescription, setActiveFilterValueForDescription] = useState([0, 0])
80
78
 
81
- const { handleFilterOrder, filterOrderOptions, filterStyleOptions } = useFilters({
82
- config: state,
83
- setConfig: setState,
84
- filteredData: runtimeFilters,
85
- setFilteredData: setRuntimeFilters
86
- })
87
-
88
79
  const headerColors = [
89
80
  'theme-blue',
90
81
  'theme-purple',
@@ -109,12 +100,18 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
109
100
  } = useMapLayers(state, setState, false, tooltipId)
110
101
 
111
102
  const categoryMove = (idx1, idx2) => {
112
- let categoryValuesOrder = [...state.legend.categoryValuesOrder]
103
+ let categoryValuesOrder = getCategoryValuesOrder()
113
104
 
114
105
  let [movedItem] = categoryValuesOrder.splice(idx1, 1)
115
106
 
116
107
  categoryValuesOrder.splice(idx2, 0, movedItem)
117
108
 
109
+ state.legend.categoryValuesOrder?.forEach(value => {
110
+ if (categoryValuesOrder.indexOf(value) === -1) {
111
+ categoryValuesOrder.push(value)
112
+ }
113
+ })
114
+
118
115
  setState({
119
116
  ...state,
120
117
  legend: {
@@ -371,7 +368,8 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
371
368
  ...state,
372
369
  legend: {
373
370
  ...state.legend,
374
- position: value
371
+ position: value,
372
+ hideBorder: _.includes(['top', 'bottom'], value)
375
373
  }
376
374
  })
377
375
  break
@@ -1065,33 +1063,6 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
1065
1063
  })
1066
1064
  }
1067
1065
 
1068
- const MapFilters = () => {
1069
- return (
1070
- <>
1071
- <label>
1072
- Filter Behavior
1073
- <select
1074
- value={state.filterBehavior}
1075
- onChange={e => {
1076
- setState({
1077
- ...state,
1078
- filterBehavior: e.target.value
1079
- })
1080
- }}
1081
- >
1082
- <option key='Apply Button' value='Apply Button'>
1083
- Apply Button
1084
- </option>
1085
- <option key='Filter Change' value='Filter Change'>
1086
- Filter Change
1087
- </option>
1088
- </select>
1089
- </label>
1090
- {filtersJSX}
1091
- </>
1092
- )
1093
- }
1094
-
1095
1066
  const removeAdditionalColumn = columnName => {
1096
1067
  const newColumns = state.columns
1097
1068
 
@@ -1219,40 +1190,6 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
1219
1190
  columnsRequiredChecker()
1220
1191
  }, [state]) // eslint-disable-line
1221
1192
 
1222
- useEffect(() => {
1223
- //If a categorical map is used and the order is either not defined or incorrect, fix it
1224
- if ('category' === state.legend.type && runtimeLegend && runtimeLegend.runtimeDataHash) {
1225
- let valid = true
1226
- if (state.legend.categoryValuesOrder) {
1227
- runtimeLegend.forEach(item => {
1228
- if (!item.special && state.legend.categoryValuesOrder.indexOf(item.value) === -1) {
1229
- valid = false
1230
- }
1231
- })
1232
- let runtimeLegendKeys = runtimeLegend.map(item => item.value)
1233
- state.legend.categoryValuesOrder.forEach(category => {
1234
- if (runtimeLegendKeys.indexOf(category) === -1) {
1235
- valid = false
1236
- }
1237
- })
1238
- } else {
1239
- valid = false
1240
- }
1241
-
1242
- if (!valid) {
1243
- let arr = runtimeLegend.filter(item => !item.special).map(({ value }) => value)
1244
-
1245
- setState({
1246
- ...state,
1247
- legend: {
1248
- ...state.legend,
1249
- categoryValuesOrder: arr
1250
- }
1251
- })
1252
- }
1253
- }
1254
- }, [runtimeLegend]) // eslint-disable-line
1255
-
1256
1193
  const columnsOptions = [
1257
1194
  <option value='' key={'Select Option'}>
1258
1195
  - Select Option -
@@ -1288,30 +1225,7 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
1288
1225
  return true
1289
1226
  })
1290
1227
 
1291
- const updateField = (section, subsection, fieldName, newValue) => {
1292
- const isArray = Array.isArray(state[section])
1293
-
1294
- let sectionValue = isArray ? [...state[section], newValue] : { ...state[section], [fieldName]: newValue }
1295
-
1296
- if (null !== subsection) {
1297
- if (isArray) {
1298
- sectionValue = [...state[section]]
1299
- sectionValue[subsection] = { ...sectionValue[subsection], [fieldName]: newValue }
1300
- } else {
1301
- sectionValue = {
1302
- ...state[section],
1303
- [subsection]: { ...state[section][subsection], [fieldName]: newValue }
1304
- }
1305
- }
1306
- }
1307
-
1308
- let updatedState = {
1309
- ...state,
1310
- [section]: sectionValue
1311
- }
1312
-
1313
- setState(updatedState)
1314
- }
1228
+ const updateField = updateFieldFactory(state, setState)
1315
1229
 
1316
1230
  const onBackClick = () => {
1317
1231
  setDisplayPanel(!displayPanel)
@@ -1323,163 +1237,6 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
1323
1237
 
1324
1238
  const usedFilterColumns = {}
1325
1239
 
1326
- const filtersJSX = state.filters.map((filter, index) => {
1327
- if (filter.type === 'url') return <></>
1328
-
1329
- if (filter.columnName) {
1330
- usedFilterColumns[filter.columnName] = true
1331
- }
1332
-
1333
- return (
1334
- <>
1335
- <fieldset className='edit-block' key={`filter-${index}`}>
1336
- <button
1337
- className='remove-column'
1338
- onClick={e => {
1339
- e.preventDefault()
1340
- changeFilter(index, 'remove')
1341
- }}
1342
- >
1343
- Remove
1344
- </button>
1345
- <TextField
1346
- value={state.filters[index].label}
1347
- section='filters'
1348
- subsection={index}
1349
- fieldName='label'
1350
- label='Label'
1351
- updateField={updateField}
1352
- />
1353
- <label>
1354
- <span className='edit-label column-heading'>
1355
- Filter Column
1356
- <Tooltip style={{ textTransform: 'none' }}>
1357
- <Tooltip.Target>
1358
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1359
- </Tooltip.Target>
1360
- <Tooltip.Content>
1361
- <p>
1362
- Selecting a column will add a dropdown menu below the map legend and allow users to filter based on
1363
- the values in this column.
1364
- </p>
1365
- </Tooltip.Content>
1366
- </Tooltip>
1367
- </span>
1368
- <select
1369
- value={filter.columnName}
1370
- onChange={event => {
1371
- changeFilter(index, 'columnName', event.target.value)
1372
- }}
1373
- >
1374
- {columnsOptions.filter(({ key }) => undefined === usedFilterColumns[key] || filter.columnName === key)}
1375
- </select>
1376
- </label>
1377
-
1378
- <label>
1379
- <span className='edit-showDropdown column-heading'>Show Filter Input</span>
1380
- <input
1381
- type='checkbox'
1382
- checked={filter.showDropdown === undefined ? true : filter.showDropdown}
1383
- onChange={e => {
1384
- changeFilter(index, 'showDropdown', e.target.checked)
1385
- }}
1386
- />
1387
- </label>
1388
-
1389
- <label>
1390
- <span className='edit-filterOrder column-heading'>Filter Style</span>
1391
- <select
1392
- value={filter.filterStyle}
1393
- onChange={e => {
1394
- changeFilter(index, 'filterStyle', e.target.value)
1395
- }}
1396
- >
1397
- {filterStyleOptions.map((option, index) => {
1398
- return (
1399
- <option value={option} key={`filter-${option}--${index}`}>
1400
- {option}
1401
- </option>
1402
- )
1403
- })}
1404
- </select>
1405
- </label>
1406
-
1407
- <label>
1408
- <span className='edit-filterOrder column-heading'>Filter Order</span>
1409
- <select
1410
- value={filter.order}
1411
- onChange={e => {
1412
- changeFilter(index, 'filterOrder', e.target.value)
1413
- changeFilterActive(index, filter.values[0])
1414
- }}
1415
- >
1416
- {filterOrderOptions.map((option, index) => {
1417
- return (
1418
- <option value={option.value} key={`filter-${index}`}>
1419
- {option.label}
1420
- </option>
1421
- )
1422
- })}
1423
- </select>
1424
- </label>
1425
-
1426
- <TextField
1427
- value={state.filters[index].setByQueryParameter}
1428
- section='filters'
1429
- subsection={index}
1430
- fieldName='setByQueryParameter'
1431
- label='Default Value Set By Query String Parameter'
1432
- updateField={updateField}
1433
- />
1434
-
1435
- {filter.order === 'cust' && (
1436
- <DragDropContext
1437
- onDragEnd={({ source, destination }) =>
1438
- handleFilterOrder(source.index, destination.index, index, state.filters[index])
1439
- }
1440
- >
1441
- <Droppable droppableId='filter_order'>
1442
- {provided => (
1443
- <ul
1444
- {...provided.droppableProps}
1445
- className='sort-list'
1446
- ref={provided.innerRef}
1447
- style={{ marginTop: '1em' }}
1448
- >
1449
- {state.filters[index]?.values.map((value, index) => {
1450
- return (
1451
- <Draggable key={value} draggableId={`draggableFilter-${value}`} index={index}>
1452
- {(provided, snapshot) => (
1453
- <li>
1454
- <div
1455
- className={snapshot.isDragging ? 'currently-dragging' : ''}
1456
- style={getItemStyle(
1457
- snapshot.isDragging,
1458
- provided.draggableProps.style,
1459
- sortableItemStyles
1460
- )}
1461
- ref={provided.innerRef}
1462
- {...provided.draggableProps}
1463
- {...provided.dragHandleProps}
1464
- >
1465
- {value}
1466
- </div>
1467
- </li>
1468
- )}
1469
- </Draggable>
1470
- )
1471
- })}
1472
- {provided.placeholder}
1473
- </ul>
1474
- )}
1475
- </Droppable>
1476
- </DragDropContext>
1477
- )}
1478
- </fieldset>
1479
- </>
1480
- )
1481
- })
1482
-
1483
1240
  const StateOptionList = () => {
1484
1241
  const arrOfArrays = Object.entries(supportedStatesFipsCodes)
1485
1242
 
@@ -1530,9 +1287,29 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
1530
1287
  ...draggableStyle
1531
1288
  })
1532
1289
 
1290
+ const getCategoryValuesOrder = () => {
1291
+ let values = runtimeLegend
1292
+ ? runtimeLegend.filter(item => !item.special).map(runtimeLegendItem => runtimeLegendItem.value)
1293
+ : []
1294
+
1295
+ if (state.legend.cateogryValuesOrder) {
1296
+ return values.sort((a, b) => {
1297
+ let aVal = state.legend.cateogryValuesOrder.indexOf(a)
1298
+ let bVal = state.legend.cateogryValuesOrder.indexOf(b)
1299
+ if (aVal === bVal) return 0
1300
+ if (aVal === -1) return 1
1301
+ if (bVal === -1) return -1
1302
+ return aVal - bVal
1303
+ })
1304
+ } else {
1305
+ return values
1306
+ }
1307
+ }
1308
+
1533
1309
  const CategoryList = () => {
1534
- return state.legend.categoryValuesOrder ? (
1535
- state.legend.categoryValuesOrder.map((value, index) => (
1310
+ return getCategoryValuesOrder()
1311
+ .filter(item => !item?.special)
1312
+ .map((value, index) => (
1536
1313
  <Draggable key={value} draggableId={`item-${value}`} index={index}>
1537
1314
  {(provided, snapshot) => (
1538
1315
  <li style={{ position: 'relative' }}>
@@ -1549,9 +1326,6 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
1549
1326
  )}
1550
1327
  </Draggable>
1551
1328
  ))
1552
- ) : (
1553
- <></>
1554
- )
1555
1329
  }
1556
1330
 
1557
1331
  const isLoadedFromUrl = state?.dataKey?.includes('http://') || state?.dataKey?.includes('https://')
@@ -2205,6 +1979,13 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
2205
1979
  </Tooltip>
2206
1980
  </span>
2207
1981
  </label>
1982
+ {state.legend.specialClasses.length === 2 && (
1983
+ <Alert
1984
+ type='info'
1985
+ message='If a third special class is needed you can apply a pattern to set it apart.'
1986
+ showCloseButton={false}
1987
+ />
1988
+ )}
2208
1989
  {specialClasses.map((specialClass, i) => (
2209
1990
  <div className='edit-block' key={`special-class-${i}`}>
2210
1991
  <button
@@ -2265,15 +2046,17 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
2265
2046
  </label>
2266
2047
  </div>
2267
2048
  ))}
2268
- <button
2269
- className='btn full-width'
2270
- onClick={e => {
2271
- e.preventDefault()
2272
- editColumn('primary', 'specialClassAdd', {})
2273
- }}
2274
- >
2275
- Add Special Class
2276
- </button>
2049
+ {state.legend.specialClasses.length < 2 && (
2050
+ <button
2051
+ className='btn btn-primary full-width'
2052
+ onClick={e => {
2053
+ e.preventDefault()
2054
+ editColumn('primary', 'specialClassAdd', {})
2055
+ }}
2056
+ >
2057
+ Add Special Class
2058
+ </button>
2059
+ )}
2277
2060
  </fieldset>
2278
2061
  )}
2279
2062
 
@@ -2417,7 +2200,7 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
2417
2200
  </fieldset>
2418
2201
  ))}
2419
2202
  <button
2420
- className={'btn full-width'}
2203
+ className={'btn btn-primary full-width'}
2421
2204
  onClick={event => {
2422
2205
  event.preventDefault()
2423
2206
  addAdditionalColumn(additionalColumns.length + 1)
@@ -2473,7 +2256,7 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
2473
2256
  </fieldset>
2474
2257
  ))}
2475
2258
  <button
2476
- className={'btn full-width'}
2259
+ className={'btn btn-primary full-width'}
2477
2260
  onClick={event => {
2478
2261
  event.preventDefault()
2479
2262
  const updatedAdditionaCategories = [...(state.legend.additionalCategories || [])]
@@ -2784,7 +2567,7 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
2784
2567
  )}
2785
2568
  </Droppable>
2786
2569
  </DragDropContext>
2787
- {state.legend.categoryValuesOrder && state.legend.categoryValuesOrder.length >= 10 && (
2570
+ {runtimeLegend && runtimeLegend.length >= 10 && (
2788
2571
  <section className='error-box my-2'>
2789
2572
  <div>
2790
2573
  <strong className='pt-1'>Warning</strong>
@@ -2840,7 +2623,7 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
2840
2623
  </label>
2841
2624
  </React.Fragment>
2842
2625
  )}
2843
- {filtersJSX.length > 0 && (
2626
+ {state.filters.length > 0 && (
2844
2627
  <label className='checkbox'>
2845
2628
  <input
2846
2629
  type='checkbox'
@@ -2868,7 +2651,7 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
2868
2651
  </span>
2869
2652
  </label>
2870
2653
  )}
2871
- {(filtersJSX.length > 0 || state.general.type === 'bubble' || state.general.geoType === 'us') && (
2654
+ {(state.filters.length > 0 || state.general.type === 'bubble' || state.general.geoType === 'us') && (
2872
2655
  <label className='checkbox'>
2873
2656
  <input
2874
2657
  type='checkbox'
@@ -2905,20 +2688,7 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
2905
2688
  <AccordionItemButton>Filters</AccordionItemButton>
2906
2689
  </AccordionItemHeading>
2907
2690
  <AccordionItemPanel>
2908
- {filtersJSX.length > 0 ? (
2909
- <MapFilters />
2910
- ) : (
2911
- <p style={{ textAlign: 'center' }}>There are currently no filters.</p>
2912
- )}
2913
- <button
2914
- className={'btn full-width'}
2915
- onClick={event => {
2916
- event.preventDefault()
2917
- changeFilter(null, 'addNew')
2918
- }}
2919
- >
2920
- Add Filter
2921
- </button>
2691
+ <VizFilterEditor config={state} updateField={updateField} rawData={state.data} />
2922
2692
  </AccordionItemPanel>
2923
2693
  </AccordionItem>
2924
2694
  )}
@@ -3243,7 +3013,6 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
3243
3013
  <label>
3244
3014
  <span className='edit-label'>Map Color Palette</span>
3245
3015
  </label>
3246
- {/* <InputCheckbox section="general" subsection="palette" fieldName='isReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} /> */}
3247
3016
  <InputToggle
3248
3017
  type='3d'
3249
3018
  section='general'
@@ -3527,7 +3296,11 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
3527
3296
  )
3528
3297
  })}
3529
3298
 
3530
- <button type='button' onClick={() => editCityStyles('add', 0, '', '')} className='btn full-width'>
3299
+ <button
3300
+ type='button'
3301
+ onClick={() => editCityStyles('add', 0, '', '')}
3302
+ className='btn btn-primary full-width'
3303
+ >
3531
3304
  Add city style
3532
3305
  </button>
3533
3306
  </>
@@ -3629,7 +3402,7 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
3629
3402
  </>
3630
3403
  )
3631
3404
  })}
3632
- <button className={'btn full-width'} onClick={handleAddLayer}>
3405
+ <button className={'btn btn-primary full-width'} onClick={handleAddLayer}>
3633
3406
  Add Map Layer
3634
3407
  </button>
3635
3408
  <p className='layer-purpose-details'>
@@ -11,7 +11,12 @@ import ConfigContext from '../../../../context'
11
11
  // styles
12
12
 
13
13
  const PanelAnnotate: React.FC = props => {
14
- const { state: config, setState: updateConfig, dimensions, isDraggingAnnotation } = useContext<MapContext>(ConfigContext)
14
+ const {
15
+ state: config,
16
+ setState: updateConfig,
17
+ dimensions,
18
+ isDraggingAnnotation
19
+ } = useContext<MapContext>(ConfigContext)
15
20
  const getColumns = (filter = true) => {
16
21
  const columns = {}
17
22
  config.data.forEach(row => {
@@ -20,7 +25,10 @@ const PanelAnnotate: React.FC = props => {
20
25
 
21
26
  if (filter) {
22
27
  Object.keys(columns).forEach(key => {
23
- if ((config.series && config.series.filter(series => series.dataKey === key).length > 0) || (config.confidenceKeys && Object.keys(config.confidenceKeys).includes(key))) {
28
+ if (
29
+ (config.series && config.series.filter(series => series.dataKey === key).length > 0) ||
30
+ (config.confidenceKeys && Object.keys(config.confidenceKeys).includes(key))
31
+ ) {
24
32
  delete columns[key]
25
33
  }
26
34
  })
@@ -41,7 +49,9 @@ const PanelAnnotate: React.FC = props => {
41
49
  }
42
50
 
43
51
  const handleAddAnnotation = () => {
44
- const svgContainer = document.querySelector('.map-container > section > svg, .map-container > section > canvas')?.getBoundingClientRect()
52
+ const svgContainer = document
53
+ .querySelector('.map-container > section > svg, .map-container > section > canvas')
54
+ ?.getBoundingClientRect()
45
55
  const newSvgDims = [svgContainer.width, svgContainer.height]
46
56
 
47
57
  const newAnnotation = {
@@ -139,11 +149,17 @@ const PanelAnnotate: React.FC = props => {
139
149
  {config?.annotations &&
140
150
  config?.annotations.map((annotation, index) => (
141
151
  <Accordion>
142
- <Accordion.Section title={annotation.text ? annotation.text.substring(0, 15) + '...' : `Annotation ${index + 1}`}>
152
+ <Accordion.Section
153
+ title={annotation.text ? annotation.text.substring(0, 15) + '...' : `Annotation ${index + 1}`}
154
+ >
143
155
  <div className='annotation-group'>
144
156
  <label>
145
157
  Annotation Text:
146
- <textarea rows={5} value={annotation.text} onChange={e => handleAnnotationUpdate(e.target.value, 'text', index)} />
158
+ <textarea
159
+ rows={5}
160
+ value={annotation.text}
161
+ onChange={e => handleAnnotationUpdate(e.target.value, 'text', index)}
162
+ />
147
163
  </label>
148
164
  {/* <label>
149
165
  Vertical Anchor
@@ -304,30 +320,18 @@ const PanelAnnotate: React.FC = props => {
304
320
  </select>
305
321
  </label>
306
322
 
307
- {/* <label>
308
- Snap to Nearest Point
309
- <input
310
- type='checkbox'
311
- checked={config?.annotations[index]?.snapToNearestPoint}
312
- onClick={e => {
313
- const updatedAnnotations = [...config?.annotations]
314
- updatedAnnotations[index].snapToNearestPoint = e.target.checked
315
- updateConfig({
316
- ...config,
317
- annotations: updatedAnnotations
318
- })
319
- }}
320
- />
321
- </label> */}
322
-
323
- <Button className='warn btn-warn btn btn-remove delete' onClick={() => handleRemoveAnnotation(index)}>
323
+ <Button className='btn btn-danger' onClick={() => handleRemoveAnnotation(index)}>
324
324
  Delete Annotation
325
325
  </Button>
326
326
  </div>
327
327
  </Accordion.Section>
328
328
  </Accordion>
329
329
  ))}
330
- {config?.annotations?.length < 3 && <Button onClick={handleAddAnnotation}>Add Annotation</Button>}
330
+ {config?.annotations?.length < 3 && (
331
+ <button className='btn btn-primary full-width' onClick={handleAddAnnotation}>
332
+ Add Annotation
333
+ </button>
334
+ )}
331
335
  </Accordion.Section>
332
336
  </Accordion>
333
337
  )