@cdc/map 4.24.7 → 4.24.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.
- package/dist/cdcmap.js +40720 -38422
- package/examples/county-year.csv +10 -0
- package/examples/default-geocode.json +44 -10
- package/examples/default-patterns.json +0 -2
- package/examples/default-single-state.json +279 -108
- package/examples/map-issue-3.json +646 -0
- package/examples/single-state-filter.json +153 -0
- package/index.html +9 -6
- package/package.json +3 -3
- package/src/CdcMap.tsx +322 -126
- package/src/_stories/CdcMap.stories.tsx +7 -0
- package/src/_stories/_mock/DEV-8942.json +270 -0
- package/src/components/Annotation/AnnotationDropdown.tsx +1 -0
- package/src/components/{BubbleList.jsx → BubbleList.tsx} +1 -1
- package/src/components/{CityList.jsx → CityList.tsx} +28 -2
- package/src/components/{DataTable.jsx → DataTable.tsx} +2 -2
- package/src/components/EditorPanel/components/EditorPanel.tsx +647 -127
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +0 -22
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +61 -11
- package/src/components/Legend/components/Legend.tsx +125 -36
- package/src/components/Legend/components/index.scss +42 -42
- package/src/components/Modal.tsx +25 -0
- package/src/components/UsaMap/components/SingleState/SingleState.CountyOutput.tsx +74 -0
- package/src/components/UsaMap/components/SingleState/SingleState.StateOutput.tsx +29 -0
- package/src/components/UsaMap/components/SingleState/index.tsx +9 -0
- package/src/components/UsaMap/components/UsaMap.County.tsx +84 -33
- package/src/components/UsaMap/components/UsaMap.SingleState.tsx +173 -206
- package/src/components/UsaMap/components/UsaMap.State.tsx +161 -26
- package/src/components/UsaMap/data/us-extended-geography.json +1 -0
- package/src/components/UsaMap/helpers/map.ts +111 -0
- package/src/components/WorldMap/WorldMap.tsx +17 -32
- package/src/components/ZoomControls.tsx +41 -0
- package/src/data/initial-state.js +7 -1
- package/src/data/supported-geos.js +15 -4
- package/src/helpers/generateRuntimeLegendHash.ts +2 -2
- package/src/hooks/useStateZoom.tsx +157 -0
- package/src/hooks/{useZoomPan.js → useZoomPan.ts} +6 -5
- package/src/scss/editor-panel.scss +0 -4
- package/src/scss/main.scss +23 -1
- package/src/scss/map.scss +8 -0
- package/src/types/MapConfig.ts +9 -1
- package/src/types/MapContext.ts +14 -2
- package/src/components/Modal.jsx +0 -22
- /package/src/components/{Geo.jsx → Geo.tsx} +0 -0
- /package/src/components/{NavigationMenu.jsx → NavigationMenu.tsx} +0 -0
- /package/src/components/{ZoomableGroup.jsx → ZoomableGroup.tsx} +0 -0
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import React, { useState, useEffect, useCallback, memo, useContext } from 'react'
|
|
2
2
|
|
|
3
3
|
// Third Party
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
Accordion,
|
|
6
|
+
AccordionItem,
|
|
7
|
+
AccordionItemHeading,
|
|
8
|
+
AccordionItemPanel,
|
|
9
|
+
AccordionItemButton
|
|
10
|
+
} from 'react-accessible-accordion'
|
|
5
11
|
import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd'
|
|
6
12
|
import { useDebounce } from 'use-debounce'
|
|
7
13
|
// import ReactTags from 'react-tag-autocomplete'
|
|
@@ -35,7 +41,7 @@ import { useFilters } from '@cdc/core/components/Filters'
|
|
|
35
41
|
import HexSetting from './HexShapeSettings.jsx'
|
|
36
42
|
import ConfigContext from '../../../context.ts'
|
|
37
43
|
import { MapContext } from '../../../types/MapContext.js'
|
|
38
|
-
import {
|
|
44
|
+
import { TextField } from './Inputs'
|
|
39
45
|
|
|
40
46
|
// Todo: move to useReducer, seperate files out.
|
|
41
47
|
const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
@@ -53,7 +59,13 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
53
59
|
setRuntimeFilters,
|
|
54
60
|
setState,
|
|
55
61
|
state,
|
|
56
|
-
tooltipId
|
|
62
|
+
tooltipId,
|
|
63
|
+
runtimeData,
|
|
64
|
+
setRuntimeData,
|
|
65
|
+
generateRuntimeData,
|
|
66
|
+
position,
|
|
67
|
+
topoData,
|
|
68
|
+
|
|
57
69
|
} = useContext<MapContext>(ConfigContext)
|
|
58
70
|
|
|
59
71
|
const { general, columns, legend, table, tooltips } = state
|
|
@@ -66,9 +78,26 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
66
78
|
|
|
67
79
|
const [activeFilterValueForDescription, setActiveFilterValueForDescription] = useState([0, 0])
|
|
68
80
|
|
|
69
|
-
const { handleFilterOrder, filterOrderOptions, filterStyleOptions } = useFilters({
|
|
81
|
+
const { handleFilterOrder, filterOrderOptions, filterStyleOptions } = useFilters({
|
|
82
|
+
config: state,
|
|
83
|
+
setConfig: setState,
|
|
84
|
+
filteredData: runtimeFilters,
|
|
85
|
+
setFilteredData: setRuntimeFilters
|
|
86
|
+
})
|
|
70
87
|
|
|
71
|
-
const headerColors = [
|
|
88
|
+
const headerColors = [
|
|
89
|
+
'theme-blue',
|
|
90
|
+
'theme-purple',
|
|
91
|
+
'theme-brown',
|
|
92
|
+
'theme-teal',
|
|
93
|
+
'theme-pink',
|
|
94
|
+
'theme-orange',
|
|
95
|
+
'theme-slate',
|
|
96
|
+
'theme-indigo',
|
|
97
|
+
'theme-cyan',
|
|
98
|
+
'theme-green',
|
|
99
|
+
'theme-amber'
|
|
100
|
+
]
|
|
72
101
|
|
|
73
102
|
const {
|
|
74
103
|
// prettier-ignore
|
|
@@ -120,7 +149,9 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
120
149
|
switch (target) {
|
|
121
150
|
case 'value': {
|
|
122
151
|
const values = ['Circle', 'Square', 'Triangle', 'Diamond', 'Star', 'Pin']
|
|
123
|
-
const filteredValues = values.filter(
|
|
152
|
+
const filteredValues = values.filter(
|
|
153
|
+
val => String(state.visual.cityStyle).toLocaleLowerCase() !== val.toLocaleLowerCase()
|
|
154
|
+
)
|
|
124
155
|
|
|
125
156
|
return (
|
|
126
157
|
<>
|
|
@@ -268,6 +299,10 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
268
299
|
general: {
|
|
269
300
|
...state.general,
|
|
270
301
|
allowMapZoom: value
|
|
302
|
+
},
|
|
303
|
+
mapPosition: {
|
|
304
|
+
coordinates: state.general.geoType === 'world' ? [0, 30] : [0, 0],
|
|
305
|
+
zoom: 1
|
|
271
306
|
}
|
|
272
307
|
})
|
|
273
308
|
break
|
|
@@ -340,6 +375,42 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
340
375
|
}
|
|
341
376
|
})
|
|
342
377
|
break
|
|
378
|
+
case 'legendStyle':
|
|
379
|
+
setState({
|
|
380
|
+
...state,
|
|
381
|
+
legend: {
|
|
382
|
+
...state.legend,
|
|
383
|
+
style: value
|
|
384
|
+
}
|
|
385
|
+
})
|
|
386
|
+
break
|
|
387
|
+
case 'legendSubStyle':
|
|
388
|
+
setState({
|
|
389
|
+
...state,
|
|
390
|
+
legend: {
|
|
391
|
+
...state.legend,
|
|
392
|
+
subStyle: value
|
|
393
|
+
}
|
|
394
|
+
})
|
|
395
|
+
break
|
|
396
|
+
case 'legendTickRotation':
|
|
397
|
+
setState({
|
|
398
|
+
...state,
|
|
399
|
+
legend: {
|
|
400
|
+
...state.legend,
|
|
401
|
+
tickRotation: value
|
|
402
|
+
}
|
|
403
|
+
})
|
|
404
|
+
break
|
|
405
|
+
case 'legendBorder':
|
|
406
|
+
setState({
|
|
407
|
+
...state,
|
|
408
|
+
legend: {
|
|
409
|
+
...state.legend,
|
|
410
|
+
hideBorder: value
|
|
411
|
+
}
|
|
412
|
+
})
|
|
413
|
+
break
|
|
343
414
|
case 'handleCityStyle':
|
|
344
415
|
setState({
|
|
345
416
|
...state,
|
|
@@ -394,11 +465,15 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
394
465
|
let messages = []
|
|
395
466
|
|
|
396
467
|
if (!hasValue) {
|
|
397
|
-
messages.push(
|
|
468
|
+
messages.push(
|
|
469
|
+
`There appears to be values missing for data in the primary column ${state.columns.primary.name}`
|
|
470
|
+
)
|
|
398
471
|
}
|
|
399
472
|
|
|
400
473
|
if (testForType === 'string' && isNaN(testForType) && value !== 'category') {
|
|
401
|
-
messages.push(
|
|
474
|
+
messages.push(
|
|
475
|
+
'Error with legend. Primary columns that are text must use a categorical legend type. Try changing the legend type to DEV-12345categorical.'
|
|
476
|
+
)
|
|
402
477
|
} else {
|
|
403
478
|
messages = []
|
|
404
479
|
}
|
|
@@ -772,6 +847,11 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
772
847
|
statePicked: stateData
|
|
773
848
|
}
|
|
774
849
|
})
|
|
850
|
+
|
|
851
|
+
if (state) {
|
|
852
|
+
const newData = generateRuntimeData(state)
|
|
853
|
+
setRuntimeData(newData)
|
|
854
|
+
}
|
|
775
855
|
break
|
|
776
856
|
case 'classificationType':
|
|
777
857
|
setState({
|
|
@@ -809,6 +889,15 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
809
889
|
}
|
|
810
890
|
})
|
|
811
891
|
break
|
|
892
|
+
case 'filterControlsStatePicked':
|
|
893
|
+
setState({
|
|
894
|
+
...state,
|
|
895
|
+
general: {
|
|
896
|
+
...state.general,
|
|
897
|
+
filterControlsStatePicked: value
|
|
898
|
+
}
|
|
899
|
+
})
|
|
900
|
+
break
|
|
812
901
|
case 'filterBehavior':
|
|
813
902
|
setState({
|
|
814
903
|
...state,
|
|
@@ -1140,22 +1229,6 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1140
1229
|
}
|
|
1141
1230
|
}, [runtimeLegend]) // eslint-disable-line
|
|
1142
1231
|
|
|
1143
|
-
// if no state choice by default show alabama
|
|
1144
|
-
// useEffect(() => {
|
|
1145
|
-
// if (!state.general.statePicked) {
|
|
1146
|
-
// setState({
|
|
1147
|
-
// ...state,
|
|
1148
|
-
// general: {
|
|
1149
|
-
// ...general,
|
|
1150
|
-
// statePicked: {
|
|
1151
|
-
// fipsCode: '01',
|
|
1152
|
-
// stateName: 'Alabama'
|
|
1153
|
-
// }
|
|
1154
|
-
// }
|
|
1155
|
-
// })
|
|
1156
|
-
// }
|
|
1157
|
-
// }, []) // eslint-disable-line
|
|
1158
|
-
|
|
1159
1232
|
const columnsOptions = [
|
|
1160
1233
|
<option value='' key={'Select Option'}>
|
|
1161
1234
|
- Select Option -
|
|
@@ -1245,7 +1318,14 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1245
1318
|
>
|
|
1246
1319
|
Remove
|
|
1247
1320
|
</button>
|
|
1248
|
-
<TextField
|
|
1321
|
+
<TextField
|
|
1322
|
+
value={state.filters[index].label}
|
|
1323
|
+
section='filters'
|
|
1324
|
+
subsection={index}
|
|
1325
|
+
fieldName='label'
|
|
1326
|
+
label='Label'
|
|
1327
|
+
updateField={updateField}
|
|
1328
|
+
/>
|
|
1249
1329
|
<label>
|
|
1250
1330
|
<span className='edit-label column-heading'>
|
|
1251
1331
|
Filter Column
|
|
@@ -1254,7 +1334,10 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1254
1334
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1255
1335
|
</Tooltip.Target>
|
|
1256
1336
|
<Tooltip.Content>
|
|
1257
|
-
<p>
|
|
1337
|
+
<p>
|
|
1338
|
+
Selecting a column will add a dropdown menu below the map legend and allow users to filter based on
|
|
1339
|
+
the values in this column.
|
|
1340
|
+
</p>
|
|
1258
1341
|
</Tooltip.Content>
|
|
1259
1342
|
</Tooltip>
|
|
1260
1343
|
</span>
|
|
@@ -1316,19 +1399,45 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1316
1399
|
</select>
|
|
1317
1400
|
</label>
|
|
1318
1401
|
|
|
1319
|
-
<TextField
|
|
1402
|
+
<TextField
|
|
1403
|
+
value={state.filters[index].setByQueryParameter}
|
|
1404
|
+
section='filters'
|
|
1405
|
+
subsection={index}
|
|
1406
|
+
fieldName='setByQueryParameter'
|
|
1407
|
+
label='Default Value Set By Query String Parameter'
|
|
1408
|
+
updateField={updateField}
|
|
1409
|
+
/>
|
|
1320
1410
|
|
|
1321
1411
|
{filter.order === 'cust' && (
|
|
1322
|
-
<DragDropContext
|
|
1412
|
+
<DragDropContext
|
|
1413
|
+
onDragEnd={({ source, destination }) =>
|
|
1414
|
+
handleFilterOrder(source.index, destination.index, index, state.filters[index])
|
|
1415
|
+
}
|
|
1416
|
+
>
|
|
1323
1417
|
<Droppable droppableId='filter_order'>
|
|
1324
1418
|
{provided => (
|
|
1325
|
-
<ul
|
|
1419
|
+
<ul
|
|
1420
|
+
{...provided.droppableProps}
|
|
1421
|
+
className='sort-list'
|
|
1422
|
+
ref={provided.innerRef}
|
|
1423
|
+
style={{ marginTop: '1em' }}
|
|
1424
|
+
>
|
|
1326
1425
|
{state.filters[index]?.values.map((value, index) => {
|
|
1327
1426
|
return (
|
|
1328
1427
|
<Draggable key={value} draggableId={`draggableFilter-${value}`} index={index}>
|
|
1329
1428
|
{(provided, snapshot) => (
|
|
1330
1429
|
<li>
|
|
1331
|
-
<div
|
|
1430
|
+
<div
|
|
1431
|
+
className={snapshot.isDragging ? 'currently-dragging' : ''}
|
|
1432
|
+
style={getItemStyle(
|
|
1433
|
+
snapshot.isDragging,
|
|
1434
|
+
provided.draggableProps.style,
|
|
1435
|
+
sortableItemStyles
|
|
1436
|
+
)}
|
|
1437
|
+
ref={provided.innerRef}
|
|
1438
|
+
{...provided.draggableProps}
|
|
1439
|
+
{...provided.dragHandleProps}
|
|
1440
|
+
>
|
|
1332
1441
|
{value}
|
|
1333
1442
|
</div>
|
|
1334
1443
|
</li>
|
|
@@ -1370,7 +1479,7 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1370
1479
|
|
|
1371
1480
|
if (runtimeFilters.length > 0) {
|
|
1372
1481
|
runtimeFilters.forEach((filter, index) => {
|
|
1373
|
-
runtimeFilters[index]
|
|
1482
|
+
runtimeFilters[index]?.values?.forEach((value, valueNum) => {
|
|
1374
1483
|
filterValueOptionList.push([index, valueNum])
|
|
1375
1484
|
})
|
|
1376
1485
|
})
|
|
@@ -1403,7 +1512,13 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1403
1512
|
<Draggable key={value} draggableId={`item-${value}`} index={index}>
|
|
1404
1513
|
{(provided, snapshot) => (
|
|
1405
1514
|
<li style={{ position: 'relative' }}>
|
|
1406
|
-
<div
|
|
1515
|
+
<div
|
|
1516
|
+
className={snapshot.isDragging ? 'currently-dragging' : ''}
|
|
1517
|
+
style={getItemStyle(snapshot.isDragging, provided.draggableProps.style, sortableItemStyles)}
|
|
1518
|
+
ref={provided.innerRef}
|
|
1519
|
+
{...provided.draggableProps}
|
|
1520
|
+
{...provided.dragHandleProps}
|
|
1521
|
+
>
|
|
1407
1522
|
{value}
|
|
1408
1523
|
</div>
|
|
1409
1524
|
</li>
|
|
@@ -1426,7 +1541,12 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1426
1541
|
let mapcols = columnsInData[0]
|
|
1427
1542
|
if (mapcols !== '') editColumn('geo', 'name', mapcols)
|
|
1428
1543
|
|
|
1429
|
-
if (
|
|
1544
|
+
if (
|
|
1545
|
+
!state.columns.hasOwnProperty('primary') ||
|
|
1546
|
+
undefined === state.columns.primary.name ||
|
|
1547
|
+
'' === state.columns.primary.name ||
|
|
1548
|
+
!state.columns.primary.name
|
|
1549
|
+
) {
|
|
1430
1550
|
editColumn('primary', 'name', columnsInData[1]) // blindly picks first value col
|
|
1431
1551
|
}
|
|
1432
1552
|
}
|
|
@@ -1435,7 +1555,12 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1435
1555
|
|
|
1436
1556
|
return (
|
|
1437
1557
|
<ErrorBoundary component='EditorPanel'>
|
|
1438
|
-
<Layout.Sidebar
|
|
1558
|
+
<Layout.Sidebar
|
|
1559
|
+
isDashboard={isDashboard}
|
|
1560
|
+
displayPanel={displayPanel}
|
|
1561
|
+
title='Configure Map'
|
|
1562
|
+
onBackClick={onBackClick}
|
|
1563
|
+
>
|
|
1439
1564
|
<ReactTooltip multiline={true} />
|
|
1440
1565
|
<Accordion allowZeroExpanded={true}>
|
|
1441
1566
|
<AccordionItem>
|
|
@@ -1541,6 +1666,22 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1541
1666
|
</select>
|
|
1542
1667
|
</label>
|
|
1543
1668
|
)}
|
|
1669
|
+
|
|
1670
|
+
{state.general.geoType === 'single-state' && runtimeData && (
|
|
1671
|
+
<label>
|
|
1672
|
+
<span className='edit-label column-heading'>Filter Controlling State Picked</span>
|
|
1673
|
+
<select
|
|
1674
|
+
value={state.general.filterControlsStatePicked || ''}
|
|
1675
|
+
onChange={event => {
|
|
1676
|
+
handleEditorChanges('filterControlsStatePicked', event.target.value)
|
|
1677
|
+
}}
|
|
1678
|
+
>
|
|
1679
|
+
<option value=''>None</option>
|
|
1680
|
+
{runtimeData && columnsInData?.map(col => <option>{col}</option>)}
|
|
1681
|
+
</select>
|
|
1682
|
+
</label>
|
|
1683
|
+
)}
|
|
1684
|
+
|
|
1544
1685
|
{/* Type */}
|
|
1545
1686
|
{/* Select > Filter a state */}
|
|
1546
1687
|
{state.general.geoType === 'single-state' && (
|
|
@@ -1565,7 +1706,10 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1565
1706
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1566
1707
|
</Tooltip.Target>
|
|
1567
1708
|
<Tooltip.Content>
|
|
1568
|
-
<p>
|
|
1709
|
+
<p>
|
|
1710
|
+
Select "Data" to create a color-coded data map. To create a navigation-only map, select
|
|
1711
|
+
"Navigation."
|
|
1712
|
+
</p>
|
|
1569
1713
|
</Tooltip.Content>
|
|
1570
1714
|
</Tooltip>
|
|
1571
1715
|
</span>
|
|
@@ -1579,18 +1723,32 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1579
1723
|
{state.general.geoType === 'us-county' && <option value='us-geocode'>Geocode</option>}
|
|
1580
1724
|
{state.general.geoType === 'world' && <option value='world-geocode'>Geocode</option>}
|
|
1581
1725
|
{state.general.geoType !== 'us-county' && <option value='navigation'>Navigation</option>}
|
|
1582
|
-
{(state.general.geoType === 'world' || state.general.geoType === 'us') &&
|
|
1726
|
+
{(state.general.geoType === 'world' || state.general.geoType === 'us') && (
|
|
1727
|
+
<option value='bubble'>Bubble</option>
|
|
1728
|
+
)}
|
|
1583
1729
|
</select>
|
|
1584
1730
|
</label>
|
|
1585
1731
|
<label>
|
|
1586
1732
|
<span className='edit-label'>Data Classification Type</span>
|
|
1587
1733
|
<div>
|
|
1588
1734
|
<label>
|
|
1589
|
-
<input
|
|
1735
|
+
<input
|
|
1736
|
+
type='radio'
|
|
1737
|
+
name='equalnumber'
|
|
1738
|
+
value='equalnumber'
|
|
1739
|
+
checked={state.legend.type === 'equalnumber' || state.legend.type === 'equalinterval'}
|
|
1740
|
+
onChange={e => handleEditorChanges('classificationType', e.target.value)}
|
|
1741
|
+
/>
|
|
1590
1742
|
Numeric/Quantitative
|
|
1591
1743
|
</label>
|
|
1592
1744
|
<label>
|
|
1593
|
-
<input
|
|
1745
|
+
<input
|
|
1746
|
+
type='radio'
|
|
1747
|
+
name='category'
|
|
1748
|
+
value='category'
|
|
1749
|
+
checked={state.legend.type === 'category'}
|
|
1750
|
+
onChange={e => handleEditorChanges('classificationType', e.target.value)}
|
|
1751
|
+
/>
|
|
1594
1752
|
Categorical
|
|
1595
1753
|
</label>
|
|
1596
1754
|
</div>
|
|
@@ -1600,18 +1758,20 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1600
1758
|
<HexSetting.DisplayShapesOnHex state={state} setState={setState} />
|
|
1601
1759
|
<HexSetting.ShapeColumns state={state} setState={setState} columnsOptions={columnsOptions} />
|
|
1602
1760
|
|
|
1603
|
-
{'us' === state.general.geoType &&
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1761
|
+
{'us' === state.general.geoType &&
|
|
1762
|
+
'bubble' !== state.general.type &&
|
|
1763
|
+
false === state.general.displayAsHex && (
|
|
1764
|
+
<label className='checkbox'>
|
|
1765
|
+
<input
|
|
1766
|
+
type='checkbox'
|
|
1767
|
+
checked={state.general.displayStateLabels}
|
|
1768
|
+
onChange={event => {
|
|
1769
|
+
handleEditorChanges('displayStateLabels', event.target.checked)
|
|
1770
|
+
}}
|
|
1771
|
+
/>
|
|
1772
|
+
<span className='edit-label'>Show state labels</span>
|
|
1773
|
+
</label>
|
|
1774
|
+
)}
|
|
1615
1775
|
</AccordionItemPanel>
|
|
1616
1776
|
</AccordionItem>
|
|
1617
1777
|
<AccordionItem>
|
|
@@ -1636,7 +1796,9 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1636
1796
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1637
1797
|
</Tooltip.Target>
|
|
1638
1798
|
<Tooltip.Content>
|
|
1639
|
-
<p>
|
|
1799
|
+
<p>
|
|
1800
|
+
Title is required to set the name of the download file but can be hidden using the option below.
|
|
1801
|
+
</p>
|
|
1640
1802
|
</Tooltip.Content>
|
|
1641
1803
|
</Tooltip>
|
|
1642
1804
|
}
|
|
@@ -1699,7 +1861,10 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1699
1861
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1700
1862
|
</Tooltip.Target>
|
|
1701
1863
|
<Tooltip.Content>
|
|
1702
|
-
<p>
|
|
1864
|
+
<p>
|
|
1865
|
+
Enter supporting text to display below the data visualization, if applicable. The following HTML
|
|
1866
|
+
tags are supported: strong, em, sup, and sub.
|
|
1867
|
+
</p>
|
|
1703
1868
|
</Tooltip.Content>
|
|
1704
1869
|
</Tooltip>
|
|
1705
1870
|
}
|
|
@@ -1722,7 +1887,16 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1722
1887
|
</Tooltip>
|
|
1723
1888
|
}
|
|
1724
1889
|
/>
|
|
1725
|
-
{'us' === state.general.geoType &&
|
|
1890
|
+
{'us' === state.general.geoType && (
|
|
1891
|
+
<TextField
|
|
1892
|
+
value={general.territoriesLabel}
|
|
1893
|
+
updateField={updateField}
|
|
1894
|
+
section='general'
|
|
1895
|
+
fieldName='territoriesLabel'
|
|
1896
|
+
label='Territories Label'
|
|
1897
|
+
placeholder='Territories'
|
|
1898
|
+
/>
|
|
1899
|
+
)}
|
|
1726
1900
|
{'us' === state.general.geoType && (
|
|
1727
1901
|
<label className='checkbox'>
|
|
1728
1902
|
<input
|
|
@@ -1757,7 +1931,10 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1757
1931
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1758
1932
|
</Tooltip.Target>
|
|
1759
1933
|
<Tooltip.Content>
|
|
1760
|
-
<p>
|
|
1934
|
+
<p>
|
|
1935
|
+
Select the source column containing the map location names or, for county-level maps, the FIPS
|
|
1936
|
+
codes.
|
|
1937
|
+
</p>
|
|
1761
1938
|
</Tooltip.Content>
|
|
1762
1939
|
</Tooltip>
|
|
1763
1940
|
</span>
|
|
@@ -1871,9 +2048,32 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1871
2048
|
/>
|
|
1872
2049
|
<ul className='column-edit'>
|
|
1873
2050
|
<li className='three-col'>
|
|
1874
|
-
<TextField
|
|
1875
|
-
|
|
1876
|
-
|
|
2051
|
+
<TextField
|
|
2052
|
+
value={columns.primary.prefix}
|
|
2053
|
+
section='columns'
|
|
2054
|
+
subsection='primary'
|
|
2055
|
+
fieldName='prefix'
|
|
2056
|
+
label='Prefix'
|
|
2057
|
+
updateField={updateField}
|
|
2058
|
+
/>
|
|
2059
|
+
<TextField
|
|
2060
|
+
value={columns.primary.suffix}
|
|
2061
|
+
section='columns'
|
|
2062
|
+
subsection='primary'
|
|
2063
|
+
fieldName='suffix'
|
|
2064
|
+
label='Suffix'
|
|
2065
|
+
updateField={updateField}
|
|
2066
|
+
/>
|
|
2067
|
+
<TextField
|
|
2068
|
+
type='number'
|
|
2069
|
+
value={columns.primary.roundToPlace}
|
|
2070
|
+
section='columns'
|
|
2071
|
+
subsection='primary'
|
|
2072
|
+
fieldName='roundToPlace'
|
|
2073
|
+
label='Round'
|
|
2074
|
+
updateField={updateField}
|
|
2075
|
+
min={0}
|
|
2076
|
+
/>
|
|
1877
2077
|
</li>
|
|
1878
2078
|
<li>
|
|
1879
2079
|
<label className='checkbox'>
|
|
@@ -1973,7 +2173,10 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
1973
2173
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1974
2174
|
</Tooltip.Target>
|
|
1975
2175
|
<Tooltip.Content>
|
|
1976
|
-
<p>
|
|
2176
|
+
<p>
|
|
2177
|
+
For secondary values such as "NA", the system can automatically color-code them in shades of
|
|
2178
|
+
gray, one shade for each special class.
|
|
2179
|
+
</p>
|
|
1977
2180
|
</Tooltip.Content>
|
|
1978
2181
|
</Tooltip>
|
|
1979
2182
|
</span>
|
|
@@ -2006,11 +2209,20 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2006
2209
|
<select
|
|
2007
2210
|
value={specialClass.value}
|
|
2008
2211
|
onChange={e => {
|
|
2009
|
-
editColumn('primary', 'specialClassEdit', {
|
|
2212
|
+
editColumn('primary', 'specialClassEdit', {
|
|
2213
|
+
prop: 'value',
|
|
2214
|
+
index: i,
|
|
2215
|
+
value: e.target.value
|
|
2216
|
+
})
|
|
2010
2217
|
}}
|
|
2011
2218
|
>
|
|
2012
2219
|
<option value=''>- Select Value -</option>
|
|
2013
|
-
{columnsByKey[specialClass.key] &&
|
|
2220
|
+
{columnsByKey[specialClass.key] &&
|
|
2221
|
+
columnsByKey[specialClass.key]
|
|
2222
|
+
.sort()
|
|
2223
|
+
.map(option => (
|
|
2224
|
+
<option key={`special-class-value-option-${i}-${option}`}>{option}</option>
|
|
2225
|
+
))}
|
|
2014
2226
|
</select>
|
|
2015
2227
|
</label>
|
|
2016
2228
|
<label>
|
|
@@ -2019,7 +2231,11 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2019
2231
|
type='text'
|
|
2020
2232
|
value={specialClass.label}
|
|
2021
2233
|
onChange={e => {
|
|
2022
|
-
editColumn('primary', 'specialClassEdit', {
|
|
2234
|
+
editColumn('primary', 'specialClassEdit', {
|
|
2235
|
+
prop: 'label',
|
|
2236
|
+
index: i,
|
|
2237
|
+
value: e.target.value
|
|
2238
|
+
})
|
|
2023
2239
|
}}
|
|
2024
2240
|
/>
|
|
2025
2241
|
</label>
|
|
@@ -2045,7 +2261,10 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2045
2261
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2046
2262
|
</Tooltip.Target>
|
|
2047
2263
|
<Tooltip.Content>
|
|
2048
|
-
<p>
|
|
2264
|
+
<p>
|
|
2265
|
+
To provide end users with navigation functionality, select the source column containing the
|
|
2266
|
+
navigation URLs.
|
|
2267
|
+
</p>
|
|
2049
2268
|
</Tooltip.Content>
|
|
2050
2269
|
</Tooltip>
|
|
2051
2270
|
</span>
|
|
@@ -2068,7 +2287,10 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2068
2287
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2069
2288
|
</Tooltip.Target>
|
|
2070
2289
|
<Tooltip.Content>
|
|
2071
|
-
<p>
|
|
2290
|
+
<p>
|
|
2291
|
+
You can specify additional columns to display in tooltips and / or the supporting data
|
|
2292
|
+
table.
|
|
2293
|
+
</p>
|
|
2072
2294
|
</Tooltip.Content>
|
|
2073
2295
|
</Tooltip>
|
|
2074
2296
|
</span>
|
|
@@ -2095,12 +2317,41 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2095
2317
|
{columnsOptions}
|
|
2096
2318
|
</select>
|
|
2097
2319
|
</label>
|
|
2098
|
-
<TextField
|
|
2320
|
+
<TextField
|
|
2321
|
+
value={columns[val].label}
|
|
2322
|
+
section='columns'
|
|
2323
|
+
subsection={val}
|
|
2324
|
+
fieldName='label'
|
|
2325
|
+
label='Label'
|
|
2326
|
+
updateField={updateField}
|
|
2327
|
+
/>
|
|
2099
2328
|
<ul className='column-edit'>
|
|
2100
2329
|
<li className='three-col'>
|
|
2101
|
-
<TextField
|
|
2102
|
-
|
|
2103
|
-
|
|
2330
|
+
<TextField
|
|
2331
|
+
value={columns[val].prefix}
|
|
2332
|
+
section='columns'
|
|
2333
|
+
subsection={val}
|
|
2334
|
+
fieldName='prefix'
|
|
2335
|
+
label='Prefix'
|
|
2336
|
+
updateField={updateField}
|
|
2337
|
+
/>
|
|
2338
|
+
<TextField
|
|
2339
|
+
value={columns[val].suffix}
|
|
2340
|
+
section='columns'
|
|
2341
|
+
subsection={val}
|
|
2342
|
+
fieldName='suffix'
|
|
2343
|
+
label='Suffix'
|
|
2344
|
+
updateField={updateField}
|
|
2345
|
+
/>
|
|
2346
|
+
<TextField
|
|
2347
|
+
type='number'
|
|
2348
|
+
value={columns[val].roundToPlace}
|
|
2349
|
+
section='columns'
|
|
2350
|
+
subsection={val}
|
|
2351
|
+
fieldName='roundToPlace'
|
|
2352
|
+
label='Round'
|
|
2353
|
+
updateField={updateField}
|
|
2354
|
+
/>
|
|
2104
2355
|
</li>
|
|
2105
2356
|
<li>
|
|
2106
2357
|
<label className='checkbox'>
|
|
@@ -2247,20 +2498,111 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2247
2498
|
<span className='edit-label'>Show Legend</span>
|
|
2248
2499
|
</label>
|
|
2249
2500
|
)}
|
|
2501
|
+
{'navigation' !== state.general.type && (
|
|
2502
|
+
<>
|
|
2503
|
+
<label>
|
|
2504
|
+
<span className='edit-label'>Legend Position</span>
|
|
2505
|
+
<select
|
|
2506
|
+
value={legend.position || false}
|
|
2507
|
+
onChange={event => {
|
|
2508
|
+
handleEditorChanges('sidebarPosition', event.target.value)
|
|
2509
|
+
}}
|
|
2510
|
+
>
|
|
2511
|
+
<option value='side'>Side</option>
|
|
2512
|
+
<option value='bottom'>Bottom</option>
|
|
2513
|
+
<option value='top'>Top</option>
|
|
2514
|
+
</select>
|
|
2515
|
+
</label>
|
|
2516
|
+
{(state.legend.position === 'side' || !state.legend.position) &&
|
|
2517
|
+
state.legend.style === 'gradient' && (
|
|
2518
|
+
<span style={{ color: 'red', fontSize: '14px' }}>
|
|
2519
|
+
Position must be set to top or bottom to use gradient style.
|
|
2520
|
+
</span>
|
|
2521
|
+
)}
|
|
2522
|
+
</>
|
|
2523
|
+
)}
|
|
2250
2524
|
{'navigation' !== state.general.type && (
|
|
2251
2525
|
<label>
|
|
2252
|
-
<span className='edit-label'>
|
|
2526
|
+
<span className='edit-label column-heading'>
|
|
2527
|
+
Legend Style
|
|
2528
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2529
|
+
<Tooltip.Target>
|
|
2530
|
+
<Icon
|
|
2531
|
+
display='question'
|
|
2532
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
2533
|
+
/>
|
|
2534
|
+
</Tooltip.Target>
|
|
2535
|
+
<Tooltip.Content>
|
|
2536
|
+
<p>
|
|
2537
|
+
If using gradient style, limit the legend to five items for better mobile visibility, and
|
|
2538
|
+
position the legend at the top or bottom.
|
|
2539
|
+
</p>
|
|
2540
|
+
</Tooltip.Content>
|
|
2541
|
+
</Tooltip>
|
|
2542
|
+
</span>
|
|
2543
|
+
|
|
2253
2544
|
<select
|
|
2254
|
-
value={legend.
|
|
2545
|
+
value={legend.style || ''}
|
|
2255
2546
|
onChange={event => {
|
|
2256
|
-
handleEditorChanges('
|
|
2547
|
+
handleEditorChanges('legendStyle', event.target.value)
|
|
2257
2548
|
}}
|
|
2258
2549
|
>
|
|
2259
|
-
<option value='
|
|
2260
|
-
<option value='
|
|
2550
|
+
<option value='circles'>circles</option>
|
|
2551
|
+
<option value='boxes'>boxes</option>
|
|
2552
|
+
{legend.position !== 'side' && <option value='gradient'>gradient</option>}
|
|
2261
2553
|
</select>
|
|
2262
2554
|
</label>
|
|
2263
2555
|
)}
|
|
2556
|
+
{'navigation' !== state.general.type && state.legend.style === 'gradient' && (
|
|
2557
|
+
<label>
|
|
2558
|
+
<span className='edit-label'>Gradient Style</span>
|
|
2559
|
+
<select
|
|
2560
|
+
value={legend.subStyle || ''}
|
|
2561
|
+
onChange={event => {
|
|
2562
|
+
handleEditorChanges('legendSubStyle', event.target.value)
|
|
2563
|
+
}}
|
|
2564
|
+
>
|
|
2565
|
+
<option value='linear blocks'>linear blocks</option>
|
|
2566
|
+
<option value='smooth'>smooth</option>
|
|
2567
|
+
</select>
|
|
2568
|
+
</label>
|
|
2569
|
+
)}
|
|
2570
|
+
{'navigation' !== state.general.type && state.legend.style === 'gradient' && (
|
|
2571
|
+
<label>
|
|
2572
|
+
<span className='edit-label'>Tick Rotation (Degrees)</span>
|
|
2573
|
+
<input
|
|
2574
|
+
type='number'
|
|
2575
|
+
className='number-narrow'
|
|
2576
|
+
value={legend.tickRotation || ''}
|
|
2577
|
+
onChange={event => {
|
|
2578
|
+
handleEditorChanges('legendTickRotation', event.target.value)
|
|
2579
|
+
}}
|
|
2580
|
+
></input>
|
|
2581
|
+
</label>
|
|
2582
|
+
)}
|
|
2583
|
+
{
|
|
2584
|
+
<label className='checkbox'>
|
|
2585
|
+
<input
|
|
2586
|
+
type='checkbox'
|
|
2587
|
+
checked={legend.hideBorder}
|
|
2588
|
+
onChange={event => {
|
|
2589
|
+
handleEditorChanges('legendBorder', event.target.checked)
|
|
2590
|
+
}}
|
|
2591
|
+
/>
|
|
2592
|
+
<span className='edit-label column-heading'>Hide Legend Box</span>
|
|
2593
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2594
|
+
<Tooltip.Target>
|
|
2595
|
+
<Icon
|
|
2596
|
+
display='question'
|
|
2597
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
2598
|
+
/>
|
|
2599
|
+
</Tooltip.Target>
|
|
2600
|
+
<Tooltip.Content>
|
|
2601
|
+
<p> Default option for top and bottom legends is ‘No Box.’</p>
|
|
2602
|
+
</Tooltip.Content>
|
|
2603
|
+
</Tooltip>
|
|
2604
|
+
</label>
|
|
2605
|
+
}
|
|
2264
2606
|
{'side' === legend.position && (
|
|
2265
2607
|
<label className='checkbox'>
|
|
2266
2608
|
<input
|
|
@@ -2273,7 +2615,7 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2273
2615
|
<span className='edit-label'>Single Column Legend</span>
|
|
2274
2616
|
</label>
|
|
2275
2617
|
)}
|
|
2276
|
-
{'
|
|
2618
|
+
{'side' !== legend.position && legend.style !== 'gradient' && (
|
|
2277
2619
|
<label className='checkbox'>
|
|
2278
2620
|
<input
|
|
2279
2621
|
type='checkbox'
|
|
@@ -2285,16 +2627,19 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2285
2627
|
<span className='edit-label'>Single Row Legend</span>
|
|
2286
2628
|
</label>
|
|
2287
2629
|
)}
|
|
2288
|
-
|
|
2289
|
-
<
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2630
|
+
{state.legend.style !== 'gradient' && (
|
|
2631
|
+
<label className='checkbox'>
|
|
2632
|
+
<input
|
|
2633
|
+
type='checkbox'
|
|
2634
|
+
checked={legend.verticalSorted}
|
|
2635
|
+
onChange={event => {
|
|
2636
|
+
handleEditorChanges('verticalSortedLegend', event.target.checked)
|
|
2637
|
+
}}
|
|
2638
|
+
/>
|
|
2639
|
+
<span className='edit-label'>Vertical sorted legend</span>
|
|
2640
|
+
</label>
|
|
2641
|
+
)}
|
|
2642
|
+
|
|
2298
2643
|
{/* always show */}
|
|
2299
2644
|
{
|
|
2300
2645
|
<label className='checkbox'>
|
|
@@ -2310,12 +2655,19 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2310
2655
|
}
|
|
2311
2656
|
{'category' !== legend.type && (
|
|
2312
2657
|
<label className='checkbox'>
|
|
2313
|
-
<input
|
|
2658
|
+
<input
|
|
2659
|
+
type='checkbox'
|
|
2660
|
+
checked={legend.separateZero || false}
|
|
2661
|
+
onChange={event => handleEditorChanges('separateZero', event.target.checked)}
|
|
2662
|
+
/>
|
|
2314
2663
|
<span className='edit-label column-heading'>
|
|
2315
2664
|
Separate Zero
|
|
2316
2665
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
2317
2666
|
<Tooltip.Target>
|
|
2318
|
-
<Icon
|
|
2667
|
+
<Icon
|
|
2668
|
+
display='question'
|
|
2669
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
2670
|
+
/>
|
|
2319
2671
|
</Tooltip.Target>
|
|
2320
2672
|
<Tooltip.Content>
|
|
2321
2673
|
<p>For numeric data, you can separate the zero value as its own data class.</p>
|
|
@@ -2337,7 +2689,10 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2337
2689
|
<span className='edit-label column-heading'>Use new quantile legend</span>
|
|
2338
2690
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
2339
2691
|
<Tooltip.Target>
|
|
2340
|
-
<Icon
|
|
2692
|
+
<Icon
|
|
2693
|
+
display='question'
|
|
2694
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
2695
|
+
/>
|
|
2341
2696
|
</Tooltip.Target>
|
|
2342
2697
|
<Tooltip.Content>
|
|
2343
2698
|
<p>This prevents numbers from being used in more than one category (ie. 0-1, 1-2, 2-3) </p>
|
|
@@ -2354,7 +2709,10 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2354
2709
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2355
2710
|
</Tooltip.Target>
|
|
2356
2711
|
<Tooltip.Content>
|
|
2357
|
-
<p>
|
|
2712
|
+
<p>
|
|
2713
|
+
For numeric maps, select the number of data classes. Do not include designated special
|
|
2714
|
+
classes.
|
|
2715
|
+
</p>
|
|
2358
2716
|
</Tooltip.Content>
|
|
2359
2717
|
</Tooltip>
|
|
2360
2718
|
</span>
|
|
@@ -2390,7 +2748,9 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2390
2748
|
</span>
|
|
2391
2749
|
</label>
|
|
2392
2750
|
{/* 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. */}
|
|
2393
|
-
<DragDropContext
|
|
2751
|
+
<DragDropContext
|
|
2752
|
+
onDragEnd={({ source, destination }) => categoryMove(source.index, destination.index)}
|
|
2753
|
+
>
|
|
2394
2754
|
<Droppable droppableId='category_order'>
|
|
2395
2755
|
{provided => (
|
|
2396
2756
|
<ul {...provided.droppableProps} className='sort-list' ref={provided.innerRef}>
|
|
@@ -2404,14 +2764,33 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2404
2764
|
<section className='error-box my-2'>
|
|
2405
2765
|
<div>
|
|
2406
2766
|
<strong className='pt-1'>Warning</strong>
|
|
2407
|
-
<p>
|
|
2767
|
+
<p>
|
|
2768
|
+
The maximum number of categorical legend items is 10. If your data has more than 10
|
|
2769
|
+
categories your map will not display properly.
|
|
2770
|
+
</p>
|
|
2408
2771
|
</div>
|
|
2409
2772
|
</section>
|
|
2410
2773
|
)}
|
|
2411
2774
|
</React.Fragment>
|
|
2412
2775
|
)}
|
|
2413
|
-
<TextField
|
|
2414
|
-
|
|
2776
|
+
<TextField
|
|
2777
|
+
value={legend.title}
|
|
2778
|
+
updateField={updateField}
|
|
2779
|
+
section='legend'
|
|
2780
|
+
fieldName='title'
|
|
2781
|
+
label='Legend Title'
|
|
2782
|
+
placeholder='Legend Title'
|
|
2783
|
+
/>
|
|
2784
|
+
{false === legend.dynamicDescription && (
|
|
2785
|
+
<TextField
|
|
2786
|
+
type='textarea'
|
|
2787
|
+
value={legend.description}
|
|
2788
|
+
updateField={updateField}
|
|
2789
|
+
section='legend'
|
|
2790
|
+
fieldName='description'
|
|
2791
|
+
label='Legend Description'
|
|
2792
|
+
/>
|
|
2793
|
+
)}
|
|
2415
2794
|
{true === legend.dynamicDescription && (
|
|
2416
2795
|
<React.Fragment>
|
|
2417
2796
|
<label>
|
|
@@ -2450,10 +2829,16 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2450
2829
|
Dynamic Legend Description
|
|
2451
2830
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
2452
2831
|
<Tooltip.Target>
|
|
2453
|
-
<Icon
|
|
2832
|
+
<Icon
|
|
2833
|
+
display='question'
|
|
2834
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
2835
|
+
/>
|
|
2454
2836
|
</Tooltip.Target>
|
|
2455
2837
|
<Tooltip.Content>
|
|
2456
|
-
<p>
|
|
2838
|
+
<p>
|
|
2839
|
+
Check this option if the map has multiple filter controls and you want to specify a
|
|
2840
|
+
description for each filter selection.
|
|
2841
|
+
</p>
|
|
2457
2842
|
</Tooltip.Content>
|
|
2458
2843
|
</Tooltip>
|
|
2459
2844
|
</span>
|
|
@@ -2461,16 +2846,24 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2461
2846
|
)}
|
|
2462
2847
|
{(filtersJSX.length > 0 || state.general.type === 'bubble' || state.general.geoType === 'us') && (
|
|
2463
2848
|
<label className='checkbox'>
|
|
2464
|
-
<input
|
|
2849
|
+
<input
|
|
2850
|
+
type='checkbox'
|
|
2851
|
+
checked={legend.unified}
|
|
2852
|
+
onChange={event => handleEditorChanges('unifiedLegend', event.target.checked)}
|
|
2853
|
+
/>
|
|
2465
2854
|
<span className='edit-label column-heading'>
|
|
2466
2855
|
Unified Legend
|
|
2467
2856
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
2468
2857
|
<Tooltip.Target>
|
|
2469
|
-
<Icon
|
|
2858
|
+
<Icon
|
|
2859
|
+
display='question'
|
|
2860
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
2861
|
+
/>
|
|
2470
2862
|
</Tooltip.Target>
|
|
2471
2863
|
<Tooltip.Content>
|
|
2472
2864
|
<p>
|
|
2473
|
-
For a map with filters, check this option if you want the high and low values in the legend
|
|
2865
|
+
For a map with filters, check this option if you want the high and low values in the legend
|
|
2866
|
+
to be based on <em>all</em> mapped values.
|
|
2474
2867
|
</p>
|
|
2475
2868
|
</Tooltip.Content>
|
|
2476
2869
|
</Tooltip>
|
|
@@ -2488,7 +2881,11 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2488
2881
|
<AccordionItemButton>Filters</AccordionItemButton>
|
|
2489
2882
|
</AccordionItemHeading>
|
|
2490
2883
|
<AccordionItemPanel>
|
|
2491
|
-
{filtersJSX.length > 0 ?
|
|
2884
|
+
{filtersJSX.length > 0 ? (
|
|
2885
|
+
<MapFilters />
|
|
2886
|
+
) : (
|
|
2887
|
+
<p style={{ textAlign: 'center' }}>There are currently no filters.</p>
|
|
2888
|
+
)}
|
|
2492
2889
|
<button
|
|
2493
2890
|
className={'btn full-width'}
|
|
2494
2891
|
onClick={event => {
|
|
@@ -2556,10 +2953,16 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2556
2953
|
Show Data Table
|
|
2557
2954
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
2558
2955
|
<Tooltip.Target>
|
|
2559
|
-
<Icon
|
|
2956
|
+
<Icon
|
|
2957
|
+
display='question'
|
|
2958
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
2959
|
+
/>
|
|
2560
2960
|
</Tooltip.Target>
|
|
2561
2961
|
<Tooltip.Content>
|
|
2562
|
-
<p>
|
|
2962
|
+
<p>
|
|
2963
|
+
Data tables are required for 508 compliance. When choosing to hide this data table, replace
|
|
2964
|
+
with your own version.
|
|
2965
|
+
</p>
|
|
2563
2966
|
</Tooltip.Content>
|
|
2564
2967
|
</Tooltip>
|
|
2565
2968
|
</span>
|
|
@@ -2577,7 +2980,10 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2577
2980
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2578
2981
|
</Tooltip.Target>
|
|
2579
2982
|
<Tooltip.Content>
|
|
2580
|
-
<p>
|
|
2983
|
+
<p>
|
|
2984
|
+
To comply with 508 standards, if the first column in the data table has no header, enter a
|
|
2985
|
+
brief one here.
|
|
2986
|
+
</p>
|
|
2581
2987
|
</Tooltip.Content>
|
|
2582
2988
|
</Tooltip>
|
|
2583
2989
|
}
|
|
@@ -2611,7 +3017,19 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2611
3017
|
/>
|
|
2612
3018
|
<span className='edit-label'>Limit Table Height</span>
|
|
2613
3019
|
</label>
|
|
2614
|
-
{state.table.limitHeight &&
|
|
3020
|
+
{state.table.limitHeight && (
|
|
3021
|
+
<TextField
|
|
3022
|
+
value={table.height}
|
|
3023
|
+
updateField={updateField}
|
|
3024
|
+
section='table'
|
|
3025
|
+
fieldName='height'
|
|
3026
|
+
label='Data Table Height'
|
|
3027
|
+
placeholder='Height(px)'
|
|
3028
|
+
type='number'
|
|
3029
|
+
min='0'
|
|
3030
|
+
max='500'
|
|
3031
|
+
/>
|
|
3032
|
+
)}
|
|
2615
3033
|
<label className='checkbox'>
|
|
2616
3034
|
<input
|
|
2617
3035
|
type='checkbox'
|
|
@@ -2708,7 +3126,15 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2708
3126
|
<option value='click'>Click - Popover Modal</option>
|
|
2709
3127
|
</select>
|
|
2710
3128
|
</label>
|
|
2711
|
-
{'click' === state.tooltips.appearanceType &&
|
|
3129
|
+
{'click' === state.tooltips.appearanceType && (
|
|
3130
|
+
<TextField
|
|
3131
|
+
value={tooltips.linkLabel}
|
|
3132
|
+
section='tooltips'
|
|
3133
|
+
fieldName='linkLabel'
|
|
3134
|
+
label='Tooltips Link Label'
|
|
3135
|
+
updateField={updateField}
|
|
3136
|
+
/>
|
|
3137
|
+
)}
|
|
2712
3138
|
<label className='checkbox'>
|
|
2713
3139
|
<input
|
|
2714
3140
|
type='checkbox'
|
|
@@ -2784,7 +3210,16 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2784
3210
|
<span className='edit-label'>Map Color Palette</span>
|
|
2785
3211
|
</label>
|
|
2786
3212
|
{/* <InputCheckbox section="general" subsection="palette" fieldName='isReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} /> */}
|
|
2787
|
-
<InputToggle
|
|
3213
|
+
<InputToggle
|
|
3214
|
+
type='3d'
|
|
3215
|
+
section='general'
|
|
3216
|
+
subsection='palette'
|
|
3217
|
+
fieldName='isReversed'
|
|
3218
|
+
size='small'
|
|
3219
|
+
label='Use selected palette in reverse order'
|
|
3220
|
+
updateField={updateField}
|
|
3221
|
+
value={state.general.palette.isReversed}
|
|
3222
|
+
/>
|
|
2788
3223
|
<span>Sequential</span>
|
|
2789
3224
|
<ul className='color-palette'>
|
|
2790
3225
|
{sequential.map(palette => {
|
|
@@ -2853,16 +3288,39 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2853
3288
|
</ul>
|
|
2854
3289
|
<label>
|
|
2855
3290
|
Geocode Settings
|
|
2856
|
-
<TextField
|
|
3291
|
+
<TextField
|
|
3292
|
+
type='number'
|
|
3293
|
+
value={state.visual.geoCodeCircleSize}
|
|
3294
|
+
section='visual'
|
|
3295
|
+
max='10'
|
|
3296
|
+
fieldName='geoCodeCircleSize'
|
|
3297
|
+
label='Geocode Circle Size'
|
|
3298
|
+
updateField={updateField}
|
|
3299
|
+
/>
|
|
2857
3300
|
</label>
|
|
2858
3301
|
|
|
2859
3302
|
{state.general.type === 'bubble' && (
|
|
2860
3303
|
<>
|
|
2861
|
-
<TextField
|
|
2862
|
-
|
|
3304
|
+
<TextField
|
|
3305
|
+
type='number'
|
|
3306
|
+
value={state.visual.minBubbleSize}
|
|
3307
|
+
section='visual'
|
|
3308
|
+
fieldName='minBubbleSize'
|
|
3309
|
+
label='Minimum Bubble Size'
|
|
3310
|
+
updateField={updateField}
|
|
3311
|
+
/>
|
|
3312
|
+
<TextField
|
|
3313
|
+
type='number'
|
|
3314
|
+
value={state.visual.maxBubbleSize}
|
|
3315
|
+
section='visual'
|
|
3316
|
+
fieldName='maxBubbleSize'
|
|
3317
|
+
label='Maximum Bubble Size'
|
|
3318
|
+
updateField={updateField}
|
|
3319
|
+
/>
|
|
2863
3320
|
</>
|
|
2864
3321
|
)}
|
|
2865
|
-
{(state.general.geoType === 'world' ||
|
|
3322
|
+
{(state.general.geoType === 'world' ||
|
|
3323
|
+
(state.general.geoType === 'us' && state.general.type === 'bubble')) && (
|
|
2866
3324
|
<label className='checkbox'>
|
|
2867
3325
|
<input
|
|
2868
3326
|
type='checkbox'
|
|
@@ -2874,7 +3332,7 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2874
3332
|
<span className='edit-label'>Show Data with Zero's on Bubble Map</span>
|
|
2875
3333
|
</label>
|
|
2876
3334
|
)}
|
|
2877
|
-
{state.general.geoType === 'world' && (
|
|
3335
|
+
{(state.general.geoType === 'world' || state.general.geoType === 'single-state') && (
|
|
2878
3336
|
<label className='checkbox'>
|
|
2879
3337
|
<input
|
|
2880
3338
|
type='checkbox'
|
|
@@ -2898,7 +3356,9 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2898
3356
|
<span className='edit-label'>Bubble Map has extra border</span>
|
|
2899
3357
|
</label>
|
|
2900
3358
|
)}
|
|
2901
|
-
{(state.general.geoType === 'us' ||
|
|
3359
|
+
{(state.general.geoType === 'us' ||
|
|
3360
|
+
state.general.geoType === 'us-county' ||
|
|
3361
|
+
state.general.geoType === 'world') && (
|
|
2902
3362
|
<>
|
|
2903
3363
|
<label>
|
|
2904
3364
|
<span className='edit-label'>Default City Style</span>
|
|
@@ -2910,10 +3370,14 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2910
3370
|
>
|
|
2911
3371
|
<option value='circle'>Circle</option>
|
|
2912
3372
|
<option value='pin'>Pin</option>
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
3373
|
+
{'us-geocode' !== state.general.type && (
|
|
3374
|
+
<>
|
|
3375
|
+
<option value='square'>Square</option>
|
|
3376
|
+
<option value='triangle'>Triangle</option>
|
|
3377
|
+
<option value='diamond'>Diamond</option>
|
|
3378
|
+
<option value='star'>Star</option>
|
|
3379
|
+
</>
|
|
3380
|
+
)}
|
|
2917
3381
|
</select>
|
|
2918
3382
|
</label>
|
|
2919
3383
|
<TextField
|
|
@@ -2997,13 +3461,23 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
2997
3461
|
</div>
|
|
2998
3462
|
)
|
|
2999
3463
|
})}
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3464
|
+
{'us-geocode' !== state.general.type && (
|
|
3465
|
+
<button type='button' onClick={() => editCityStyles('add', 0, '', '')} className='btn full-width'>
|
|
3466
|
+
Add city style
|
|
3467
|
+
</button>
|
|
3468
|
+
)}
|
|
3004
3469
|
</>
|
|
3005
3470
|
<label htmlFor='opacity'>
|
|
3006
|
-
<TextField
|
|
3471
|
+
<TextField
|
|
3472
|
+
type='number'
|
|
3473
|
+
min={0}
|
|
3474
|
+
max={100}
|
|
3475
|
+
value={state.tooltips.opacity ? state.tooltips.opacity : 100}
|
|
3476
|
+
section='tooltips'
|
|
3477
|
+
fieldName='opacity'
|
|
3478
|
+
label='Tooltip Opacity (%)'
|
|
3479
|
+
updateField={updateField}
|
|
3480
|
+
/>
|
|
3007
3481
|
</label>
|
|
3008
3482
|
</AccordionItemPanel>
|
|
3009
3483
|
</AccordionItem>
|
|
@@ -3025,21 +3499,64 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
3025
3499
|
<AccordionItemPanel>
|
|
3026
3500
|
<div className='map-layers-panel'>
|
|
3027
3501
|
<label htmlFor='layerName'>Layer Name:</label>
|
|
3028
|
-
<input
|
|
3502
|
+
<input
|
|
3503
|
+
type='text'
|
|
3504
|
+
name='layerName'
|
|
3505
|
+
value={layer.name}
|
|
3506
|
+
onChange={e => handleMapLayer(e, index, 'name')}
|
|
3507
|
+
/>
|
|
3029
3508
|
<label htmlFor='layerFilename'>File:</label>
|
|
3030
|
-
<input
|
|
3509
|
+
<input
|
|
3510
|
+
type='text'
|
|
3511
|
+
name='layerFilename'
|
|
3512
|
+
value={layer.url}
|
|
3513
|
+
onChange={e => handleMapLayer(e, index, 'url')}
|
|
3514
|
+
/>
|
|
3031
3515
|
<label htmlFor='layerNamespace'>TOPOJSON Namespace:</label>
|
|
3032
|
-
<input
|
|
3516
|
+
<input
|
|
3517
|
+
type='text'
|
|
3518
|
+
name='layerNamespace'
|
|
3519
|
+
value={layer.namespace}
|
|
3520
|
+
onChange={e => handleMapLayer(e, index, 'namespace')}
|
|
3521
|
+
/>
|
|
3033
3522
|
<label htmlFor='layerFill'>Fill Color:</label>
|
|
3034
|
-
<input
|
|
3523
|
+
<input
|
|
3524
|
+
type='text'
|
|
3525
|
+
name='layerFill'
|
|
3526
|
+
value={layer.fill}
|
|
3527
|
+
onChange={e => handleMapLayer(e, index, 'fill')}
|
|
3528
|
+
/>
|
|
3035
3529
|
<label htmlFor='layerFill'>Fill Opacity (%):</label>
|
|
3036
|
-
<input
|
|
3530
|
+
<input
|
|
3531
|
+
type='number'
|
|
3532
|
+
min={0}
|
|
3533
|
+
max={100}
|
|
3534
|
+
name='layerFill'
|
|
3535
|
+
value={layer.fillOpacity ? layer.fillOpacity * 100 : ''}
|
|
3536
|
+
onChange={e => handleMapLayer(e, index, 'fillOpacity')}
|
|
3537
|
+
/>
|
|
3037
3538
|
<label htmlFor='layerStroke'>Stroke Color:</label>
|
|
3038
|
-
<input
|
|
3539
|
+
<input
|
|
3540
|
+
type='text'
|
|
3541
|
+
name='layerStroke'
|
|
3542
|
+
value={layer.stroke}
|
|
3543
|
+
onChange={e => handleMapLayer(e, index, 'stroke')}
|
|
3544
|
+
/>
|
|
3039
3545
|
<label htmlFor='layerStroke'>Stroke Width:</label>
|
|
3040
|
-
<input
|
|
3546
|
+
<input
|
|
3547
|
+
type='number'
|
|
3548
|
+
min={0}
|
|
3549
|
+
max={5}
|
|
3550
|
+
name='layerStrokeWidth'
|
|
3551
|
+
value={layer.strokeWidth}
|
|
3552
|
+
onChange={e => handleMapLayer(e, index, 'strokeWidth')}
|
|
3553
|
+
/>
|
|
3041
3554
|
<label htmlFor='layerTooltip'>Tooltip:</label>
|
|
3042
|
-
<textarea
|
|
3555
|
+
<textarea
|
|
3556
|
+
name='layerTooltip'
|
|
3557
|
+
value={layer.tooltip}
|
|
3558
|
+
onChange={e => handleMapLayer(e, index, 'tooltip')}
|
|
3559
|
+
></textarea>
|
|
3043
3560
|
<button onClick={e => handleRemoveLayer(e, index)}>Remove Layer</button>
|
|
3044
3561
|
</div>
|
|
3045
3562
|
</AccordionItemPanel>
|
|
@@ -3051,7 +3568,10 @@ const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
|
3051
3568
|
<button className={'btn full-width'} onClick={handleAddLayer}>
|
|
3052
3569
|
Add Map Layer
|
|
3053
3570
|
</button>
|
|
3054
|
-
<p className='layer-purpose-details'>
|
|
3571
|
+
<p className='layer-purpose-details'>
|
|
3572
|
+
Context should be added to your visualization or associated page to describe the significance of layers
|
|
3573
|
+
that are added to maps.
|
|
3574
|
+
</p>
|
|
3055
3575
|
</AccordionItemPanel>
|
|
3056
3576
|
</AccordionItem>
|
|
3057
3577
|
{state.general.geoType === 'us' && <Panels.PatternSettings name='Pattern Settings' />}
|