@cdc/map 4.24.2 → 4.24.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.
- package/dist/cdcmap.js +33089 -32197
- package/examples/508.json +548 -0
- package/examples/default-county.json +0 -28
- package/examples/default-hex.json +110 -13
- package/examples/default-usa.json +69 -28
- package/examples/example-city-state.json +51 -17
- package/examples/hex-colors.json +507 -0
- package/examples/usa-special-class-legend.json +501 -0
- package/index.html +10 -9
- package/package.json +3 -3
- package/src/CdcMap.tsx +200 -125
- package/src/components/BubbleList.jsx +16 -6
- package/src/components/CityList.jsx +64 -12
- package/src/components/DataTable.jsx +7 -7
- package/src/components/EditorPanel/components/EditorPanel.tsx +1457 -1367
- package/src/components/EditorPanel/components/Error.tsx +12 -0
- package/src/components/EditorPanel/components/HexShapeSettings.tsx +16 -1
- package/src/components/EditorPanel/components/Panel.PatternSettings-style.css +5 -0
- package/src/components/EditorPanel/components/Panel.PatternSettings.tsx +18 -1
- package/src/components/Legend/components/Legend.tsx +80 -15
- package/src/components/Legend/components/LegendItem.Hex.tsx +1 -1
- package/src/components/Legend/components/index.scss +31 -5
- package/src/components/UsaMap/components/HexIcon.tsx +41 -0
- package/src/components/UsaMap/components/Territory/Territory.Hexagon.tsx +38 -19
- package/src/components/UsaMap/components/Territory/Territory.Rectangle.tsx +11 -22
- package/src/components/UsaMap/components/UsaMap.County.tsx +7 -4
- package/src/components/UsaMap/components/UsaMap.Region.tsx +13 -38
- package/src/components/UsaMap/components/UsaMap.SingleState.tsx +5 -3
- package/src/components/UsaMap/components/UsaMap.State.tsx +77 -60
- package/src/components/UsaMap/helpers/patternSizes.tsx +5 -0
- package/src/components/WorldMap/components/WorldMap.jsx +20 -3
- package/src/data/initial-state.js +3 -0
- package/src/data/supported-geos.js +2 -1
- package/src/hooks/useMapLayers.tsx +2 -2
- package/src/scss/editor-panel.scss +4 -12
- package/src/scss/main.scss +3 -1
- package/src/scss/map.scss +1 -1
- package/src/types/MapConfig.ts +7 -0
|
@@ -7,6 +7,7 @@ import { useDebounce } from 'use-debounce'
|
|
|
7
7
|
// import ReactTags from 'react-tag-autocomplete'
|
|
8
8
|
import { Tooltip as ReactTooltip } from 'react-tooltip'
|
|
9
9
|
import Panels from './Panels.tsx'
|
|
10
|
+
import Layout from '@cdc/core/components/Layout'
|
|
10
11
|
|
|
11
12
|
// Data
|
|
12
13
|
import colorPalettes from '@cdc/core/data/colorPalettes'
|
|
@@ -18,7 +19,6 @@ import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
|
|
|
18
19
|
import Icon from '@cdc/core/components/ui/Icon'
|
|
19
20
|
import InputToggle from '@cdc/core/components/inputs/InputToggle'
|
|
20
21
|
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
21
|
-
import Waiting from '@cdc/core/components/Waiting'
|
|
22
22
|
|
|
23
23
|
// Assets
|
|
24
24
|
import UsaGraphic from '@cdc/core/assets/icon-map-usa.svg'
|
|
@@ -38,7 +38,7 @@ import { MapContext } from '../../../types/MapContext.js'
|
|
|
38
38
|
import { Checkbox, TextField } from './Inputs'
|
|
39
39
|
|
|
40
40
|
// Todo: move to useReducer, seperate files out.
|
|
41
|
-
const EditorPanel =
|
|
41
|
+
const EditorPanel = ({ columnsRequiredChecker }) => {
|
|
42
42
|
// prettier-ignore
|
|
43
43
|
const {
|
|
44
44
|
changeFilterActive,
|
|
@@ -53,12 +53,11 @@ const EditorPanel = props => {
|
|
|
53
53
|
setRuntimeFilters,
|
|
54
54
|
setState,
|
|
55
55
|
state,
|
|
56
|
+
tooltipId
|
|
56
57
|
} = useContext<MapContext>(ConfigContext)
|
|
57
58
|
|
|
58
59
|
const { general, columns, legend, table, tooltips } = state
|
|
59
60
|
|
|
60
|
-
const [requiredColumns, setRequiredColumns] = useState(null) // Simple state so we know if we need more information before parsing the map
|
|
61
|
-
|
|
62
61
|
const [configTextboxValue, setConfigTextbox] = useState({}) // eslint-disable-line
|
|
63
62
|
|
|
64
63
|
const [loadedDefault, setLoadedDefault] = useState(false)
|
|
@@ -78,7 +77,7 @@ const EditorPanel = props => {
|
|
|
78
77
|
handleAddLayer,
|
|
79
78
|
handleRemoveLayer
|
|
80
79
|
}
|
|
81
|
-
} = useMapLayers(state, setState, false,
|
|
80
|
+
} = useMapLayers(state, setState, false, tooltipId)
|
|
82
81
|
|
|
83
82
|
const categoryMove = (idx1, idx2) => {
|
|
84
83
|
let categoryValuesOrder = [...state.legend.categoryValuesOrder]
|
|
@@ -117,6 +116,75 @@ const EditorPanel = props => {
|
|
|
117
116
|
specialClasses = legend.specialClasses || []
|
|
118
117
|
}
|
|
119
118
|
|
|
119
|
+
const getCityStyleOptions = target => {
|
|
120
|
+
switch (target) {
|
|
121
|
+
case 'value': {
|
|
122
|
+
const values = ['Circle', 'Square', 'Triangle', 'Diamond', 'Star', 'Pin']
|
|
123
|
+
const filteredValues = values.filter(val => String(state.visual.cityStyle).toLocaleLowerCase() !== val.toLocaleLowerCase())
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<>
|
|
127
|
+
<option value='' key={'Select Option'}>
|
|
128
|
+
- Select Option -
|
|
129
|
+
</option>
|
|
130
|
+
{filteredValues.map((val, i) => {
|
|
131
|
+
return (
|
|
132
|
+
<option key={i} value={val}>
|
|
133
|
+
{val}
|
|
134
|
+
</option>
|
|
135
|
+
)
|
|
136
|
+
})}
|
|
137
|
+
</>
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const editCityStyles = (target, index, fieldName, value) => {
|
|
144
|
+
switch (target) {
|
|
145
|
+
case 'add': {
|
|
146
|
+
const additionalCityStyles = state.visual.additionalCityStyles ? [...state.visual.additionalCityStyles] : []
|
|
147
|
+
additionalCityStyles.push({ label: '', column: '', value: '', shape: '' })
|
|
148
|
+
setState({
|
|
149
|
+
...state,
|
|
150
|
+
visual: {
|
|
151
|
+
...state.visual,
|
|
152
|
+
additionalCityStyles: additionalCityStyles
|
|
153
|
+
}
|
|
154
|
+
})
|
|
155
|
+
break
|
|
156
|
+
}
|
|
157
|
+
case 'remove': {
|
|
158
|
+
let additionalCityStyles = []
|
|
159
|
+
if (state.visual.additionalCityStyles) {
|
|
160
|
+
additionalCityStyles = [...state.visual.additionalCityStyles]
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
additionalCityStyles.splice(index, 1)
|
|
164
|
+
setState({
|
|
165
|
+
...state,
|
|
166
|
+
visual: {
|
|
167
|
+
...state.visual,
|
|
168
|
+
additionalCityStyles: additionalCityStyles
|
|
169
|
+
}
|
|
170
|
+
})
|
|
171
|
+
break
|
|
172
|
+
}
|
|
173
|
+
case 'update': {
|
|
174
|
+
let additionalCityStyles = []
|
|
175
|
+
additionalCityStyles = [...state.visual.additionalCityStyles]
|
|
176
|
+
additionalCityStyles[index][fieldName] = value
|
|
177
|
+
setState({
|
|
178
|
+
...state,
|
|
179
|
+
visual: {
|
|
180
|
+
...state.visual,
|
|
181
|
+
additionalCityStyles: additionalCityStyles
|
|
182
|
+
}
|
|
183
|
+
})
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
120
188
|
const DynamicDesc = ({ label, fieldName, value: stateValue, type = 'input', ...attributes }) => {
|
|
121
189
|
const [value, setValue] = useState(stateValue)
|
|
122
190
|
|
|
@@ -379,20 +447,6 @@ const EditorPanel = props => {
|
|
|
379
447
|
}
|
|
380
448
|
})
|
|
381
449
|
break
|
|
382
|
-
case 'toggleDownloadButton':
|
|
383
|
-
setState({
|
|
384
|
-
...state,
|
|
385
|
-
general: {
|
|
386
|
-
...state.general,
|
|
387
|
-
showDownloadButton: !state.general.showDownloadButton
|
|
388
|
-
},
|
|
389
|
-
table: {
|
|
390
|
-
// setting both bc DataTable new core needs it here
|
|
391
|
-
...state.table,
|
|
392
|
-
download: !state.general.showDownloadButton
|
|
393
|
-
}
|
|
394
|
-
})
|
|
395
|
-
break
|
|
396
450
|
case 'toggleShowFullGeoNameInCSV':
|
|
397
451
|
setState({
|
|
398
452
|
...state,
|
|
@@ -767,37 +821,6 @@ const EditorPanel = props => {
|
|
|
767
821
|
}
|
|
768
822
|
}
|
|
769
823
|
|
|
770
|
-
const columnsRequiredChecker = useCallback(() => {
|
|
771
|
-
let columnList = []
|
|
772
|
-
|
|
773
|
-
// Geo is always required
|
|
774
|
-
if ('' === state.columns.geo.name) {
|
|
775
|
-
columnList.push('Geography')
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
// Primary is required if we're on a data map or a point map
|
|
779
|
-
if ('navigation' !== state.general.type && '' === state.columns.primary.name) {
|
|
780
|
-
columnList.push('Primary')
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
// Navigate is required for navigation maps
|
|
784
|
-
if ('navigation' === state.general.type && ('' === state.columns.navigate.name || undefined === state.columns.navigate)) {
|
|
785
|
-
columnList.push('Navigation')
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
if (('us-geocode' === state.general.type || 'world-geocode' === state.general.type) && '' === state.columns.latitude.name) {
|
|
789
|
-
columnList.push('Latitude')
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
if (('us-geocode' === state.general.type || 'world-geocode' === state.general.type) && '' === state.columns.longitude.name) {
|
|
793
|
-
columnList.push('Longitude')
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
if (columnList.length === 0) columnList = null
|
|
797
|
-
|
|
798
|
-
setRequiredColumns(columnList)
|
|
799
|
-
}, [state.columns, state.general.type])
|
|
800
|
-
|
|
801
824
|
const editColumn = async (columnName, editTarget, value) => {
|
|
802
825
|
let newSpecialClasses
|
|
803
826
|
switch (editTarget) {
|
|
@@ -1195,6 +1218,10 @@ const EditorPanel = props => {
|
|
|
1195
1218
|
|
|
1196
1219
|
const onBackClick = () => {
|
|
1197
1220
|
setDisplayPanel(!displayPanel)
|
|
1221
|
+
setState({
|
|
1222
|
+
...state,
|
|
1223
|
+
showEditorPanel: !displayPanel
|
|
1224
|
+
})
|
|
1198
1225
|
}
|
|
1199
1226
|
|
|
1200
1227
|
const usedFilterColumns = {}
|
|
@@ -1289,6 +1316,8 @@ const EditorPanel = props => {
|
|
|
1289
1316
|
</select>
|
|
1290
1317
|
</label>
|
|
1291
1318
|
|
|
1319
|
+
<TextField value={state.filters[index].setByQueryParameter} section='filters' subsection={index} fieldName='setByQueryParameter' label='Default Value Set By Query String Parameter' updateField={updateField} />
|
|
1320
|
+
|
|
1292
1321
|
{filter.order === 'cust' && (
|
|
1293
1322
|
<DragDropContext onDragEnd={({ source, destination }) => handleFilterOrder(source.index, destination.index, index, state.filters[index])}>
|
|
1294
1323
|
<Droppable droppableId='filter_order'>
|
|
@@ -1386,17 +1415,6 @@ const EditorPanel = props => {
|
|
|
1386
1415
|
)
|
|
1387
1416
|
}
|
|
1388
1417
|
|
|
1389
|
-
const Error = () => {
|
|
1390
|
-
return (
|
|
1391
|
-
<section className='waiting'>
|
|
1392
|
-
<section className='waiting-container'>
|
|
1393
|
-
<h3>Error With Configuration</h3>
|
|
1394
|
-
<p>{state.runtime.editorErrorMessage}</p>
|
|
1395
|
-
</section>
|
|
1396
|
-
</section>
|
|
1397
|
-
)
|
|
1398
|
-
}
|
|
1399
|
-
|
|
1400
1418
|
const isLoadedFromUrl = state?.dataKey?.includes('http://') || state?.dataKey?.includes('https://')
|
|
1401
1419
|
|
|
1402
1420
|
// if isDebug = true, then try to set the Geography Col and Data col to reduce clicking
|
|
@@ -1417,382 +1435,428 @@ const EditorPanel = props => {
|
|
|
1417
1435
|
|
|
1418
1436
|
return (
|
|
1419
1437
|
<ErrorBoundary component='EditorPanel'>
|
|
1420
|
-
|
|
1421
|
-
{requiredColumns && <Waiting requiredColumns={requiredColumns} className={displayPanel ? `waiting` : `waiting collapsed`} />}
|
|
1422
|
-
<button className={displayPanel ? `editor-toggle` : `editor-toggle collapsed`} title={displayPanel ? `Collapse Editor` : `Expand Editor`} onClick={onBackClick} data-html2canvas-ignore></button>
|
|
1423
|
-
|
|
1424
|
-
<section className={displayPanel ? 'editor-panel cove' : 'hidden editor-panel cove'} data-html2canvas-ignore>
|
|
1438
|
+
<Layout.Sidebar isDashboard={isDashboard} displayPanel={displayPanel} title='Configure Map' onBackClick={onBackClick}>
|
|
1425
1439
|
<ReactTooltip multiline={true} />
|
|
1426
|
-
<
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1440
|
+
<Accordion allowZeroExpanded={true}>
|
|
1441
|
+
<AccordionItem>
|
|
1442
|
+
{' '}
|
|
1443
|
+
{/* Type */}
|
|
1444
|
+
<AccordionItemHeading>
|
|
1445
|
+
<AccordionItemButton>Type</AccordionItemButton>
|
|
1446
|
+
</AccordionItemHeading>
|
|
1447
|
+
<AccordionItemPanel>
|
|
1448
|
+
{/* Geography */}
|
|
1449
|
+
<label>
|
|
1450
|
+
<span className='edit-label column-heading'>
|
|
1451
|
+
<span>Geography</span>
|
|
1452
|
+
</span>
|
|
1453
|
+
<ul className='geo-buttons'>
|
|
1454
|
+
<button
|
|
1455
|
+
className={state.general.geoType === 'us' || state.general.geoType === 'us-county' ? 'active' : ''}
|
|
1456
|
+
onClick={e => {
|
|
1457
|
+
e.preventDefault()
|
|
1458
|
+
handleEditorChanges('geoType', 'us')
|
|
1459
|
+
}}
|
|
1460
|
+
>
|
|
1461
|
+
<UsaGraphic />
|
|
1462
|
+
<span>United States</span>
|
|
1463
|
+
</button>
|
|
1464
|
+
<button
|
|
1465
|
+
className={state.general.geoType === 'us-region' ? 'active' : ''}
|
|
1466
|
+
onClick={e => {
|
|
1467
|
+
e.preventDefault()
|
|
1468
|
+
handleEditorChanges('geoType', 'us-region')
|
|
1469
|
+
}}
|
|
1470
|
+
>
|
|
1471
|
+
<UsaRegionGraphic />
|
|
1472
|
+
<span>U.S. Region</span>
|
|
1473
|
+
</button>
|
|
1474
|
+
<button
|
|
1475
|
+
className={state.general.geoType === 'world' ? 'active' : ''}
|
|
1476
|
+
onClick={e => {
|
|
1477
|
+
e.preventDefault()
|
|
1478
|
+
handleEditorChanges('geoType', 'world')
|
|
1479
|
+
}}
|
|
1480
|
+
>
|
|
1481
|
+
<WorldGraphic />
|
|
1482
|
+
<span>World</span>
|
|
1483
|
+
</button>
|
|
1484
|
+
<button
|
|
1485
|
+
className={state.general.geoType === 'single-state' ? 'active' : ''}
|
|
1486
|
+
onClick={e => {
|
|
1487
|
+
e.preventDefault()
|
|
1488
|
+
handleEditorChanges('geoType', 'single-state')
|
|
1489
|
+
}}
|
|
1490
|
+
>
|
|
1491
|
+
<AlabamaGraphic />
|
|
1492
|
+
<span>U.S. State</span>
|
|
1493
|
+
</button>
|
|
1494
|
+
</ul>
|
|
1495
|
+
</label>
|
|
1496
|
+
{/* Select > State or County Map */}
|
|
1497
|
+
{(state.general.geoType === 'us' || state.general.geoType === 'us-county') && (
|
|
1498
|
+
<label>
|
|
1499
|
+
<span className='edit-label column-heading'>Geography Subtype</span>
|
|
1500
|
+
<select
|
|
1501
|
+
value={state.general.geoType}
|
|
1502
|
+
onChange={event => {
|
|
1503
|
+
handleEditorChanges('geoType', event.target.value)
|
|
1504
|
+
}}
|
|
1505
|
+
>
|
|
1506
|
+
<option value='us'>US State-Level</option>
|
|
1507
|
+
<option value='us-county'>US County-Level</option>
|
|
1508
|
+
</select>
|
|
1509
|
+
</label>
|
|
1510
|
+
)}
|
|
1511
|
+
{(state.general.geoType === 'us-county' || state.general.geoType === 'single-state') && (
|
|
1512
|
+
<label>
|
|
1513
|
+
<span className='edit-label column-heading'>County Census Year</span>
|
|
1514
|
+
<select
|
|
1515
|
+
value={state.general.countyCensusYear || '2019'}
|
|
1516
|
+
onChange={event => {
|
|
1517
|
+
handleEditorChanges('countyCensusYear', event.target.value)
|
|
1518
|
+
}}
|
|
1519
|
+
>
|
|
1520
|
+
<option value='2022'>2022</option>
|
|
1521
|
+
<option value='2021'>2021</option>
|
|
1522
|
+
<option value='2020'>2020</option>
|
|
1523
|
+
<option value='2019'>2019</option>
|
|
1524
|
+
<option value='2015'>2015</option>
|
|
1525
|
+
<option value='2014'>2014</option>
|
|
1526
|
+
<option value='2013'>2013</option>
|
|
1527
|
+
</select>
|
|
1528
|
+
</label>
|
|
1529
|
+
)}
|
|
1530
|
+
{(state.general.geoType === 'us-county' || state.general.geoType === 'single-state') && (
|
|
1531
|
+
<label>
|
|
1532
|
+
<span className='edit-label column-heading'>Filter Controlling County Census Year</span>
|
|
1533
|
+
<select
|
|
1534
|
+
value={state.general.filterControlsCountyYear || ''}
|
|
1535
|
+
onChange={event => {
|
|
1536
|
+
handleEditorChanges('filterControlsCountyYear', event.target.value)
|
|
1537
|
+
}}
|
|
1538
|
+
>
|
|
1539
|
+
<option value=''>None</option>
|
|
1540
|
+
{state.filters && state.filters.map(filter => <option>{filter.columnName}</option>)}
|
|
1541
|
+
</select>
|
|
1542
|
+
</label>
|
|
1543
|
+
)}
|
|
1431
1544
|
{/* Type */}
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
</AccordionItemHeading>
|
|
1435
|
-
<AccordionItemPanel>
|
|
1436
|
-
{/* Geography */}
|
|
1545
|
+
{/* Select > Filter a state */}
|
|
1546
|
+
{state.general.geoType === 'single-state' && (
|
|
1437
1547
|
<label>
|
|
1438
|
-
<span className='edit-label column-heading'>
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
}}
|
|
1448
|
-
>
|
|
1449
|
-
<UsaGraphic />
|
|
1450
|
-
<span>United States</span>
|
|
1451
|
-
</button>
|
|
1452
|
-
<button
|
|
1453
|
-
className={state.general.geoType === 'us-region' ? 'active' : ''}
|
|
1454
|
-
onClick={e => {
|
|
1455
|
-
e.preventDefault()
|
|
1456
|
-
handleEditorChanges('geoType', 'us-region')
|
|
1457
|
-
}}
|
|
1458
|
-
>
|
|
1459
|
-
<UsaRegionGraphic />
|
|
1460
|
-
<span>U.S. Region</span>
|
|
1461
|
-
</button>
|
|
1462
|
-
<button
|
|
1463
|
-
className={state.general.geoType === 'world' ? 'active' : ''}
|
|
1464
|
-
onClick={e => {
|
|
1465
|
-
e.preventDefault()
|
|
1466
|
-
handleEditorChanges('geoType', 'world')
|
|
1467
|
-
}}
|
|
1468
|
-
>
|
|
1469
|
-
<WorldGraphic />
|
|
1470
|
-
<span>World</span>
|
|
1471
|
-
</button>
|
|
1472
|
-
<button
|
|
1473
|
-
className={state.general.geoType === 'single-state' ? 'active' : ''}
|
|
1474
|
-
onClick={e => {
|
|
1475
|
-
e.preventDefault()
|
|
1476
|
-
handleEditorChanges('geoType', 'single-state')
|
|
1477
|
-
}}
|
|
1478
|
-
>
|
|
1479
|
-
<AlabamaGraphic />
|
|
1480
|
-
<span>U.S. State</span>
|
|
1481
|
-
</button>
|
|
1482
|
-
</ul>
|
|
1548
|
+
<span className='edit-label column-heading'>State Selector</span>
|
|
1549
|
+
<select
|
|
1550
|
+
value={state.general.statePicked.stateName}
|
|
1551
|
+
onChange={event => {
|
|
1552
|
+
handleEditorChanges('chooseState', event.target.value)
|
|
1553
|
+
}}
|
|
1554
|
+
>
|
|
1555
|
+
<StateOptionList />
|
|
1556
|
+
</select>
|
|
1483
1557
|
</label>
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
>
|
|
1494
|
-
<
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
<option value='2013'>2013</option>
|
|
1515
|
-
</select>
|
|
1516
|
-
</label>
|
|
1517
|
-
)}
|
|
1518
|
-
{(state.general.geoType === 'us-county' || state.general.geoType === 'single-state') && (
|
|
1558
|
+
)}
|
|
1559
|
+
{/* Type */}
|
|
1560
|
+
<label>
|
|
1561
|
+
<span className='edit-label column-heading'>
|
|
1562
|
+
Map Type
|
|
1563
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1564
|
+
<Tooltip.Target>
|
|
1565
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1566
|
+
</Tooltip.Target>
|
|
1567
|
+
<Tooltip.Content>
|
|
1568
|
+
<p>Select "Data" to create a color-coded data map. To create a navigation-only map, select "Navigation."</p>
|
|
1569
|
+
</Tooltip.Content>
|
|
1570
|
+
</Tooltip>
|
|
1571
|
+
</span>
|
|
1572
|
+
<select
|
|
1573
|
+
value={state.general.type}
|
|
1574
|
+
onChange={event => {
|
|
1575
|
+
handleEditorChanges('editorMapType', event.target.value)
|
|
1576
|
+
}}
|
|
1577
|
+
>
|
|
1578
|
+
<option value='data'>Data</option>
|
|
1579
|
+
{state.general.geoType === 'us-county' && <option value='us-geocode'>Geocode</option>}
|
|
1580
|
+
{state.general.geoType === 'world' && <option value='world-geocode'>Geocode</option>}
|
|
1581
|
+
{state.general.geoType !== 'us-county' && <option value='navigation'>Navigation</option>}
|
|
1582
|
+
{(state.general.geoType === 'world' || state.general.geoType === 'us') && <option value='bubble'>Bubble</option>}
|
|
1583
|
+
</select>
|
|
1584
|
+
</label>
|
|
1585
|
+
<label>
|
|
1586
|
+
<span className='edit-label'>Data Classification Type</span>
|
|
1587
|
+
<div>
|
|
1519
1588
|
<label>
|
|
1520
|
-
<
|
|
1521
|
-
|
|
1522
|
-
value={state.general.filterControlsCountyYear || ''}
|
|
1523
|
-
onChange={event => {
|
|
1524
|
-
handleEditorChanges('filterControlsCountyYear', event.target.value)
|
|
1525
|
-
}}
|
|
1526
|
-
>
|
|
1527
|
-
<option value=''>None</option>
|
|
1528
|
-
{state.filters && state.filters.map(filter => <option>{filter.columnName}</option>)}
|
|
1529
|
-
</select>
|
|
1589
|
+
<input type='radio' name='equalnumber' value='equalnumber' checked={state.legend.type === 'equalnumber'} onChange={e => handleEditorChanges('classificationType', e.target.value)} />
|
|
1590
|
+
Numeric/Quantitative
|
|
1530
1591
|
</label>
|
|
1531
|
-
)}
|
|
1532
|
-
{/* Type */}
|
|
1533
|
-
{/* Select > Filter a state */}
|
|
1534
|
-
{state.general.geoType === 'single-state' && (
|
|
1535
1592
|
<label>
|
|
1536
|
-
<
|
|
1537
|
-
|
|
1538
|
-
value={state.general.statePicked.stateName}
|
|
1539
|
-
onChange={event => {
|
|
1540
|
-
handleEditorChanges('chooseState', event.target.value)
|
|
1541
|
-
}}
|
|
1542
|
-
>
|
|
1543
|
-
<StateOptionList />
|
|
1544
|
-
</select>
|
|
1593
|
+
<input type='radio' name='category' value='category' checked={state.legend.type === 'category'} onChange={e => handleEditorChanges('classificationType', e.target.value)} />
|
|
1594
|
+
Categorical
|
|
1545
1595
|
</label>
|
|
1546
|
-
|
|
1547
|
-
|
|
1596
|
+
</div>
|
|
1597
|
+
</label>
|
|
1598
|
+
|
|
1599
|
+
<HexSetting.DisplayAsHexMap state={state} setState={setState} handleEditorChanges={handleEditorChanges} />
|
|
1600
|
+
<HexSetting.DisplayShapesOnHex state={state} setState={setState} />
|
|
1601
|
+
<HexSetting.ShapeColumns state={state} setState={setState} columnsOptions={columnsOptions} />
|
|
1602
|
+
|
|
1603
|
+
{'us' === state.general.geoType && 'bubble' !== state.general.type && false === state.general.displayAsHex && (
|
|
1604
|
+
<label className='checkbox'>
|
|
1605
|
+
<input
|
|
1606
|
+
type='checkbox'
|
|
1607
|
+
checked={state.general.displayStateLabels}
|
|
1608
|
+
onChange={event => {
|
|
1609
|
+
handleEditorChanges('displayStateLabels', event.target.checked)
|
|
1610
|
+
}}
|
|
1611
|
+
/>
|
|
1612
|
+
<span className='edit-label'>Show state labels</span>
|
|
1613
|
+
</label>
|
|
1614
|
+
)}
|
|
1615
|
+
</AccordionItemPanel>
|
|
1616
|
+
</AccordionItem>
|
|
1617
|
+
<AccordionItem>
|
|
1618
|
+
{' '}
|
|
1619
|
+
{/* General */}
|
|
1620
|
+
<AccordionItemHeading>
|
|
1621
|
+
<AccordionItemButton>General</AccordionItemButton>
|
|
1622
|
+
</AccordionItemHeading>
|
|
1623
|
+
<AccordionItemPanel>
|
|
1624
|
+
<TextField
|
|
1625
|
+
value={general.title}
|
|
1626
|
+
data-testid='title-input'
|
|
1627
|
+
updateField={updateField}
|
|
1628
|
+
section='general'
|
|
1629
|
+
fieldName='title'
|
|
1630
|
+
id='title'
|
|
1631
|
+
label='Title'
|
|
1632
|
+
placeholder='Map Title'
|
|
1633
|
+
tooltip={
|
|
1634
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1635
|
+
<Tooltip.Target>
|
|
1636
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1637
|
+
</Tooltip.Target>
|
|
1638
|
+
<Tooltip.Content>
|
|
1639
|
+
<p>Title is required to set the name of the download file but can be hidden using the option below.</p>
|
|
1640
|
+
</Tooltip.Content>
|
|
1641
|
+
</Tooltip>
|
|
1642
|
+
}
|
|
1643
|
+
/>
|
|
1644
|
+
<label className='checkbox'>
|
|
1645
|
+
<input
|
|
1646
|
+
type='checkbox'
|
|
1647
|
+
checked={state.general.showTitle || false}
|
|
1648
|
+
onChange={event => {
|
|
1649
|
+
handleEditorChanges('showTitle', event.target.checked)
|
|
1650
|
+
}}
|
|
1651
|
+
/>
|
|
1652
|
+
<span className='edit-label'>Show Title</span>
|
|
1653
|
+
</label>
|
|
1654
|
+
<TextField
|
|
1655
|
+
value={general.superTitle || ''}
|
|
1656
|
+
updateField={updateField}
|
|
1657
|
+
section='general'
|
|
1658
|
+
fieldName='superTitle'
|
|
1659
|
+
label='Super Title'
|
|
1660
|
+
tooltip={
|
|
1661
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1662
|
+
<Tooltip.Target>
|
|
1663
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1664
|
+
</Tooltip.Target>
|
|
1665
|
+
<Tooltip.Content>
|
|
1666
|
+
<p>Super Title</p>
|
|
1667
|
+
</Tooltip.Content>
|
|
1668
|
+
</Tooltip>
|
|
1669
|
+
}
|
|
1670
|
+
/>
|
|
1671
|
+
<TextField
|
|
1672
|
+
type='textarea'
|
|
1673
|
+
value={general.introText}
|
|
1674
|
+
updateField={updateField}
|
|
1675
|
+
section='general'
|
|
1676
|
+
fieldName='introText'
|
|
1677
|
+
label='Message'
|
|
1678
|
+
tooltip={
|
|
1679
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1680
|
+
<Tooltip.Target>
|
|
1681
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1682
|
+
</Tooltip.Target>
|
|
1683
|
+
<Tooltip.Content>
|
|
1684
|
+
<p>Intro Text</p>
|
|
1685
|
+
</Tooltip.Content>
|
|
1686
|
+
</Tooltip>
|
|
1687
|
+
}
|
|
1688
|
+
/>
|
|
1689
|
+
<TextField
|
|
1690
|
+
type='textarea'
|
|
1691
|
+
value={general.subtext}
|
|
1692
|
+
updateField={updateField}
|
|
1693
|
+
section='general'
|
|
1694
|
+
fieldName='subtext'
|
|
1695
|
+
label='Subtext'
|
|
1696
|
+
tooltip={
|
|
1697
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1698
|
+
<Tooltip.Target>
|
|
1699
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1700
|
+
</Tooltip.Target>
|
|
1701
|
+
<Tooltip.Content>
|
|
1702
|
+
<p>Enter supporting text to display below the data visualization, if applicable. The following HTML tags are supported: strong, em, sup, and sub.</p>
|
|
1703
|
+
</Tooltip.Content>
|
|
1704
|
+
</Tooltip>
|
|
1705
|
+
}
|
|
1706
|
+
/>
|
|
1707
|
+
<TextField
|
|
1708
|
+
type='textarea'
|
|
1709
|
+
value={general.footnotes}
|
|
1710
|
+
updateField={updateField}
|
|
1711
|
+
section='general'
|
|
1712
|
+
fieldName='footnotes'
|
|
1713
|
+
label='Footnotes'
|
|
1714
|
+
tooltip={
|
|
1715
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1716
|
+
<Tooltip.Target>
|
|
1717
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1718
|
+
</Tooltip.Target>
|
|
1719
|
+
<Tooltip.Content>
|
|
1720
|
+
<p>Footnotes</p>
|
|
1721
|
+
</Tooltip.Content>
|
|
1722
|
+
</Tooltip>
|
|
1723
|
+
}
|
|
1724
|
+
/>
|
|
1725
|
+
{'us' === state.general.geoType && <TextField value={general.territoriesLabel} updateField={updateField} section='general' fieldName='territoriesLabel' label='Territories Label' placeholder='Territories' />}
|
|
1726
|
+
{'us' === state.general.geoType && (
|
|
1727
|
+
<label className='checkbox'>
|
|
1728
|
+
<input
|
|
1729
|
+
type='checkbox'
|
|
1730
|
+
checked={general.territoriesAlwaysShow || false}
|
|
1731
|
+
onChange={event => {
|
|
1732
|
+
handleEditorChanges('territoriesAlwaysShow', event.target.checked)
|
|
1733
|
+
}}
|
|
1734
|
+
/>
|
|
1735
|
+
<span className='edit-label'>Show All Territories</span>
|
|
1736
|
+
</label>
|
|
1737
|
+
)}
|
|
1738
|
+
{/* <label className="checkbox mt-4">
|
|
1739
|
+
<input type="checkbox" checked={ state.general.showDownloadMediaButton } onChange={(event) => { handleEditorChanges("toggleDownloadMediaButton", event.target.checked) }} />
|
|
1740
|
+
<span className="edit-label">Enable Media Download</span>
|
|
1741
|
+
</label> */}
|
|
1742
|
+
</AccordionItemPanel>
|
|
1743
|
+
</AccordionItem>
|
|
1744
|
+
<AccordionItem>
|
|
1745
|
+
{' '}
|
|
1746
|
+
{/* Columns */}
|
|
1747
|
+
<AccordionItemHeading>
|
|
1748
|
+
<AccordionItemButton>Columns</AccordionItemButton>
|
|
1749
|
+
</AccordionItemHeading>
|
|
1750
|
+
<AccordionItemPanel>
|
|
1751
|
+
<fieldset className='primary-fieldset edit-block'>
|
|
1548
1752
|
<label>
|
|
1549
1753
|
<span className='edit-label column-heading'>
|
|
1550
|
-
|
|
1754
|
+
Geography
|
|
1551
1755
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
1552
1756
|
<Tooltip.Target>
|
|
1553
1757
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1554
1758
|
</Tooltip.Target>
|
|
1555
1759
|
<Tooltip.Content>
|
|
1556
|
-
<p>Select
|
|
1760
|
+
<p>Select the source column containing the map location names or, for county-level maps, the FIPS codes.</p>
|
|
1557
1761
|
</Tooltip.Content>
|
|
1558
1762
|
</Tooltip>
|
|
1559
1763
|
</span>
|
|
1560
1764
|
<select
|
|
1561
|
-
value={state.
|
|
1765
|
+
value={state.columns.geo ? state.columns.geo.name : columnsOptions[0]}
|
|
1562
1766
|
onChange={event => {
|
|
1563
|
-
|
|
1767
|
+
editColumn('geo', 'name', event.target.value)
|
|
1564
1768
|
}}
|
|
1565
1769
|
>
|
|
1566
|
-
|
|
1567
|
-
{state.general.geoType === 'us-county' && <option value='us-geocode'>Geocode</option>}
|
|
1568
|
-
{state.general.geoType === 'world' && <option value='world-geocode'>Geocode</option>}
|
|
1569
|
-
{state.general.geoType !== 'us-county' && <option value='navigation'>Navigation</option>}
|
|
1570
|
-
{(state.general.geoType === 'world' || state.general.geoType === 'us') && <option value='bubble'>Bubble</option>}
|
|
1770
|
+
{columnsOptions}
|
|
1571
1771
|
</select>
|
|
1572
1772
|
</label>
|
|
1573
|
-
|
|
1574
|
-
<span className='edit-label'>Data Classification Type</span>
|
|
1575
|
-
<div>
|
|
1576
|
-
<label>
|
|
1577
|
-
<input type='radio' name='equalnumber' value='equalnumber' checked={state.legend.type === 'equalnumber'} onChange={e => handleEditorChanges('classificationType', e.target.value)} />
|
|
1578
|
-
Numeric/Quantitative
|
|
1579
|
-
</label>
|
|
1580
|
-
<label>
|
|
1581
|
-
<input type='radio' name='category' value='category' checked={state.legend.type === 'category'} onChange={e => handleEditorChanges('classificationType', e.target.value)} />
|
|
1582
|
-
Categorical
|
|
1583
|
-
</label>
|
|
1584
|
-
</div>
|
|
1585
|
-
</label>
|
|
1586
|
-
|
|
1587
|
-
<HexSetting.DisplayAsHexMap state={state} setState={setState} handleEditorChanges={handleEditorChanges} />
|
|
1588
|
-
<HexSetting.DisplayShapesOnHex state={state} setState={setState} />
|
|
1589
|
-
<HexSetting.ShapeColumns state={state} setState={setState} columnsOptions={columnsOptions} />
|
|
1590
|
-
|
|
1591
|
-
{'us' === state.general.geoType && 'bubble' !== state.general.type && false === state.general.displayAsHex && (
|
|
1773
|
+
{state.general.type === 'us-geocode' && (
|
|
1592
1774
|
<label className='checkbox'>
|
|
1593
1775
|
<input
|
|
1594
1776
|
type='checkbox'
|
|
1595
|
-
checked={state.general.
|
|
1777
|
+
checked={state.general.convertFipsCodes}
|
|
1596
1778
|
onChange={event => {
|
|
1597
|
-
|
|
1779
|
+
setState({
|
|
1780
|
+
...state,
|
|
1781
|
+
general: {
|
|
1782
|
+
...state.general,
|
|
1783
|
+
convertFipsCodes: event.target.checked
|
|
1784
|
+
}
|
|
1785
|
+
})
|
|
1598
1786
|
}}
|
|
1599
1787
|
/>
|
|
1600
|
-
<span className='edit-label'>
|
|
1788
|
+
<span className='edit-label'>Convert FIPS Codes to Geography Name</span>
|
|
1601
1789
|
</label>
|
|
1602
1790
|
)}
|
|
1603
|
-
|
|
1604
|
-
</AccordionItem>
|
|
1605
|
-
<AccordionItem>
|
|
1606
|
-
{' '}
|
|
1607
|
-
{/* General */}
|
|
1608
|
-
<AccordionItemHeading>
|
|
1609
|
-
<AccordionItemButton>General</AccordionItemButton>
|
|
1610
|
-
</AccordionItemHeading>
|
|
1611
|
-
<AccordionItemPanel>
|
|
1612
|
-
<TextField
|
|
1613
|
-
value={general.title}
|
|
1614
|
-
data-testid='title-input'
|
|
1615
|
-
updateField={updateField}
|
|
1616
|
-
section='general'
|
|
1617
|
-
fieldName='title'
|
|
1618
|
-
id='title'
|
|
1619
|
-
label='Title'
|
|
1620
|
-
placeholder='Map Title'
|
|
1621
|
-
tooltip={
|
|
1622
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
1623
|
-
<Tooltip.Target>
|
|
1624
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1625
|
-
</Tooltip.Target>
|
|
1626
|
-
<Tooltip.Content>
|
|
1627
|
-
<p>Title is required to set the name of the download file but can be hidden using the option below.</p>
|
|
1628
|
-
</Tooltip.Content>
|
|
1629
|
-
</Tooltip>
|
|
1630
|
-
}
|
|
1631
|
-
/>
|
|
1791
|
+
|
|
1632
1792
|
<label className='checkbox'>
|
|
1633
1793
|
<input
|
|
1634
1794
|
type='checkbox'
|
|
1635
|
-
checked={state.general.
|
|
1795
|
+
checked={state.general.hideGeoColumnInTooltip || false}
|
|
1636
1796
|
onChange={event => {
|
|
1637
|
-
handleEditorChanges('
|
|
1797
|
+
handleEditorChanges('hideGeoColumnInTooltip', event.target.checked)
|
|
1638
1798
|
}}
|
|
1639
1799
|
/>
|
|
1640
|
-
<span className='edit-label'>
|
|
1800
|
+
<span className='edit-label'>Hide Geography Column Name in Tooltip</span>
|
|
1641
1801
|
</label>
|
|
1642
1802
|
<TextField
|
|
1643
|
-
value={general.
|
|
1644
|
-
updateField={updateField}
|
|
1645
|
-
section='general'
|
|
1646
|
-
fieldName='superTitle'
|
|
1647
|
-
label='Super Title'
|
|
1648
|
-
tooltip={
|
|
1649
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
1650
|
-
<Tooltip.Target>
|
|
1651
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1652
|
-
</Tooltip.Target>
|
|
1653
|
-
<Tooltip.Content>
|
|
1654
|
-
<p>Super Title</p>
|
|
1655
|
-
</Tooltip.Content>
|
|
1656
|
-
</Tooltip>
|
|
1657
|
-
}
|
|
1658
|
-
/>
|
|
1659
|
-
<TextField
|
|
1660
|
-
type='textarea'
|
|
1661
|
-
value={general.introText}
|
|
1662
|
-
updateField={updateField}
|
|
1663
|
-
section='general'
|
|
1664
|
-
fieldName='introText'
|
|
1665
|
-
label='Message'
|
|
1666
|
-
tooltip={
|
|
1667
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
1668
|
-
<Tooltip.Target>
|
|
1669
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1670
|
-
</Tooltip.Target>
|
|
1671
|
-
<Tooltip.Content>
|
|
1672
|
-
<p>Intro Text</p>
|
|
1673
|
-
</Tooltip.Content>
|
|
1674
|
-
</Tooltip>
|
|
1675
|
-
}
|
|
1676
|
-
/>
|
|
1677
|
-
<TextField
|
|
1678
|
-
type='textarea'
|
|
1679
|
-
value={general.subtext}
|
|
1680
|
-
updateField={updateField}
|
|
1803
|
+
value={state.general.geoLabelOverride}
|
|
1681
1804
|
section='general'
|
|
1682
|
-
fieldName='
|
|
1683
|
-
label='
|
|
1684
|
-
|
|
1685
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
1686
|
-
<Tooltip.Target>
|
|
1687
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1688
|
-
</Tooltip.Target>
|
|
1689
|
-
<Tooltip.Content>
|
|
1690
|
-
<p>Enter supporting text to display below the data visualization, if applicable. The following HTML tags are supported: strong, em, sup, and sub.</p>
|
|
1691
|
-
</Tooltip.Content>
|
|
1692
|
-
</Tooltip>
|
|
1693
|
-
}
|
|
1694
|
-
/>
|
|
1695
|
-
<TextField
|
|
1696
|
-
type='textarea'
|
|
1697
|
-
value={general.footnotes}
|
|
1805
|
+
fieldName='geoLabelOverride'
|
|
1806
|
+
label='Geography Label'
|
|
1807
|
+
className='edit-label'
|
|
1698
1808
|
updateField={updateField}
|
|
1699
|
-
section='general'
|
|
1700
|
-
fieldName='footnotes'
|
|
1701
|
-
label='Footnotes'
|
|
1702
1809
|
tooltip={
|
|
1703
1810
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
1704
1811
|
<Tooltip.Target>
|
|
1705
1812
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1706
1813
|
</Tooltip.Target>
|
|
1707
1814
|
<Tooltip.Content>
|
|
1708
|
-
<p>
|
|
1815
|
+
<p>Enter a geography label for use in tooltips.</p>
|
|
1709
1816
|
</Tooltip.Content>
|
|
1710
1817
|
</Tooltip>
|
|
1711
1818
|
}
|
|
1712
1819
|
/>
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
<label className='checkbox'>
|
|
1716
|
-
<input
|
|
1717
|
-
type='checkbox'
|
|
1718
|
-
checked={general.territoriesAlwaysShow || false}
|
|
1719
|
-
onChange={event => {
|
|
1720
|
-
handleEditorChanges('territoriesAlwaysShow', event.target.checked)
|
|
1721
|
-
}}
|
|
1722
|
-
/>
|
|
1723
|
-
<span className='edit-label'>Show All Territories</span>
|
|
1724
|
-
</label>
|
|
1725
|
-
)}
|
|
1726
|
-
{/* <label className="checkbox mt-4">
|
|
1727
|
-
<input type="checkbox" checked={ state.general.showDownloadMediaButton } onChange={(event) => { handleEditorChanges("toggleDownloadMediaButton", event.target.checked) }} />
|
|
1728
|
-
<span className="edit-label">Enable Media Download</span>
|
|
1729
|
-
</label> */}
|
|
1730
|
-
</AccordionItemPanel>
|
|
1731
|
-
</AccordionItem>
|
|
1732
|
-
<AccordionItem>
|
|
1733
|
-
{' '}
|
|
1734
|
-
{/* Columns */}
|
|
1735
|
-
<AccordionItemHeading>
|
|
1736
|
-
<AccordionItemButton>Columns</AccordionItemButton>
|
|
1737
|
-
</AccordionItemHeading>
|
|
1738
|
-
<AccordionItemPanel>
|
|
1820
|
+
</fieldset>
|
|
1821
|
+
{'navigation' !== state.general.type && (
|
|
1739
1822
|
<fieldset className='primary-fieldset edit-block'>
|
|
1740
1823
|
<label>
|
|
1741
1824
|
<span className='edit-label column-heading'>
|
|
1742
|
-
|
|
1825
|
+
Data Column
|
|
1743
1826
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
1744
1827
|
<Tooltip.Target>
|
|
1745
1828
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1746
1829
|
</Tooltip.Target>
|
|
1747
1830
|
<Tooltip.Content>
|
|
1748
|
-
<p>Select the source column containing the
|
|
1831
|
+
<p>Select the source column containing the categorical or numeric values to be mapped.</p>
|
|
1749
1832
|
</Tooltip.Content>
|
|
1750
1833
|
</Tooltip>
|
|
1751
1834
|
</span>
|
|
1752
1835
|
<select
|
|
1753
|
-
value={state.columns.
|
|
1836
|
+
value={state.columns.primary ? state.columns.primary.name : columnsOptions[0]}
|
|
1754
1837
|
onChange={event => {
|
|
1755
|
-
editColumn('
|
|
1838
|
+
editColumn('primary', 'name', event.target.value)
|
|
1756
1839
|
}}
|
|
1757
1840
|
>
|
|
1758
1841
|
{columnsOptions}
|
|
1759
1842
|
</select>
|
|
1760
1843
|
</label>
|
|
1761
|
-
{state.general.type === 'us-geocode' && (
|
|
1762
|
-
<label className='checkbox'>
|
|
1763
|
-
<input
|
|
1764
|
-
type='checkbox'
|
|
1765
|
-
checked={state.general.convertFipsCodes}
|
|
1766
|
-
onChange={event => {
|
|
1767
|
-
setState({
|
|
1768
|
-
...state,
|
|
1769
|
-
general: {
|
|
1770
|
-
...state.general,
|
|
1771
|
-
convertFipsCodes: event.target.checked
|
|
1772
|
-
}
|
|
1773
|
-
})
|
|
1774
|
-
}}
|
|
1775
|
-
/>
|
|
1776
|
-
<span className='edit-label'>Convert FIPS Codes to Geography Name</span>
|
|
1777
|
-
</label>
|
|
1778
|
-
)}
|
|
1779
|
-
|
|
1780
1844
|
<label className='checkbox'>
|
|
1781
1845
|
<input
|
|
1782
1846
|
type='checkbox'
|
|
1783
|
-
checked={state.general.
|
|
1847
|
+
checked={state.general.hidePrimaryColumnInTooltip || false}
|
|
1784
1848
|
onChange={event => {
|
|
1785
|
-
handleEditorChanges('
|
|
1849
|
+
handleEditorChanges('hidePrimaryColumnInTooltip', event.target.checked)
|
|
1786
1850
|
}}
|
|
1787
1851
|
/>
|
|
1788
|
-
<span className='edit-label'>Hide
|
|
1852
|
+
<span className='edit-label'>Hide Data Column Name in Tooltip</span>
|
|
1789
1853
|
</label>
|
|
1790
1854
|
<TextField
|
|
1791
|
-
value={
|
|
1792
|
-
section='
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1855
|
+
value={columns.primary.label}
|
|
1856
|
+
section='columns'
|
|
1857
|
+
subsection='primary'
|
|
1858
|
+
fieldName='label'
|
|
1859
|
+
label='Data Label'
|
|
1796
1860
|
updateField={updateField}
|
|
1797
1861
|
tooltip={
|
|
1798
1862
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
@@ -1800,1107 +1864,1044 @@ const EditorPanel = props => {
|
|
|
1800
1864
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1801
1865
|
</Tooltip.Target>
|
|
1802
1866
|
<Tooltip.Content>
|
|
1803
|
-
<p>Enter a
|
|
1867
|
+
<p>Enter a data label for use in tooltips and the data table.</p>
|
|
1804
1868
|
</Tooltip.Content>
|
|
1805
1869
|
</Tooltip>
|
|
1806
1870
|
}
|
|
1807
1871
|
/>
|
|
1872
|
+
<ul className='column-edit'>
|
|
1873
|
+
<li className='three-col'>
|
|
1874
|
+
<TextField value={columns.primary.prefix} section='columns' subsection='primary' fieldName='prefix' label='Prefix' updateField={updateField} />
|
|
1875
|
+
<TextField value={columns.primary.suffix} section='columns' subsection='primary' fieldName='suffix' label='Suffix' updateField={updateField} />
|
|
1876
|
+
<TextField type='number' value={columns.primary.roundToPlace} section='columns' subsection='primary' fieldName='roundToPlace' label='Round' updateField={updateField} min={0} />
|
|
1877
|
+
</li>
|
|
1878
|
+
<li>
|
|
1879
|
+
<label className='checkbox'>
|
|
1880
|
+
<input
|
|
1881
|
+
type='checkbox'
|
|
1882
|
+
checked={state.columns.primary.useCommas}
|
|
1883
|
+
onChange={event => {
|
|
1884
|
+
editColumn('primary', 'useCommas', event.target.checked)
|
|
1885
|
+
}}
|
|
1886
|
+
/>
|
|
1887
|
+
<span className='edit-label'>Add Commas to Numbers</span>
|
|
1888
|
+
</label>
|
|
1889
|
+
</li>
|
|
1890
|
+
<li>
|
|
1891
|
+
<label className='checkbox'>
|
|
1892
|
+
<input
|
|
1893
|
+
type='checkbox'
|
|
1894
|
+
checked={state.columns.primary.dataTable || false}
|
|
1895
|
+
onChange={event => {
|
|
1896
|
+
editColumn('primary', 'dataTable', event.target.checked)
|
|
1897
|
+
}}
|
|
1898
|
+
/>
|
|
1899
|
+
<span className='edit-label'>Show in Data Table</span>
|
|
1900
|
+
</label>
|
|
1901
|
+
</li>
|
|
1902
|
+
<li>
|
|
1903
|
+
<label className='checkbox'>
|
|
1904
|
+
<input
|
|
1905
|
+
type='checkbox'
|
|
1906
|
+
checked={state.columns.primary.tooltip || false}
|
|
1907
|
+
onChange={event => {
|
|
1908
|
+
editColumn('primary', 'tooltip', event.target.checked)
|
|
1909
|
+
}}
|
|
1910
|
+
/>
|
|
1911
|
+
<span className='edit-label'>Show in Tooltips</span>
|
|
1912
|
+
</label>
|
|
1913
|
+
</li>
|
|
1914
|
+
</ul>
|
|
1808
1915
|
</fieldset>
|
|
1809
|
-
|
|
1810
|
-
<fieldset className='primary-fieldset edit-block'>
|
|
1811
|
-
<label>
|
|
1812
|
-
<span className='edit-label column-heading'>
|
|
1813
|
-
Data Column
|
|
1814
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
1815
|
-
<Tooltip.Target>
|
|
1816
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1817
|
-
</Tooltip.Target>
|
|
1818
|
-
<Tooltip.Content>
|
|
1819
|
-
<p>Select the source column containing the categorical or numeric values to be mapped.</p>
|
|
1820
|
-
</Tooltip.Content>
|
|
1821
|
-
</Tooltip>
|
|
1822
|
-
</span>
|
|
1823
|
-
<select
|
|
1824
|
-
value={state.columns.primary ? state.columns.primary.name : columnsOptions[0]}
|
|
1825
|
-
onChange={event => {
|
|
1826
|
-
editColumn('primary', 'name', event.target.value)
|
|
1827
|
-
}}
|
|
1828
|
-
>
|
|
1829
|
-
{columnsOptions}
|
|
1830
|
-
</select>
|
|
1831
|
-
</label>
|
|
1832
|
-
<label className='checkbox'>
|
|
1833
|
-
<input
|
|
1834
|
-
type='checkbox'
|
|
1835
|
-
checked={state.general.hidePrimaryColumnInTooltip || false}
|
|
1836
|
-
onChange={event => {
|
|
1837
|
-
handleEditorChanges('hidePrimaryColumnInTooltip', event.target.checked)
|
|
1838
|
-
}}
|
|
1839
|
-
/>
|
|
1840
|
-
<span className='edit-label'>Hide Data Column Name in Tooltip</span>
|
|
1841
|
-
</label>
|
|
1842
|
-
<TextField
|
|
1843
|
-
value={columns.primary.label}
|
|
1844
|
-
section='columns'
|
|
1845
|
-
subsection='primary'
|
|
1846
|
-
fieldName='label'
|
|
1847
|
-
label='Data Label'
|
|
1848
|
-
updateField={updateField}
|
|
1849
|
-
tooltip={
|
|
1850
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
1851
|
-
<Tooltip.Target>
|
|
1852
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1853
|
-
</Tooltip.Target>
|
|
1854
|
-
<Tooltip.Content>
|
|
1855
|
-
<p>Enter a data label for use in tooltips and the data table.</p>
|
|
1856
|
-
</Tooltip.Content>
|
|
1857
|
-
</Tooltip>
|
|
1858
|
-
}
|
|
1859
|
-
/>
|
|
1860
|
-
<ul className='column-edit'>
|
|
1861
|
-
<li className='three-col'>
|
|
1862
|
-
<TextField value={columns.primary.prefix} section='columns' subsection='primary' fieldName='prefix' label='Prefix' updateField={updateField} />
|
|
1863
|
-
<TextField value={columns.primary.suffix} section='columns' subsection='primary' fieldName='suffix' label='Suffix' updateField={updateField} />
|
|
1864
|
-
<TextField type='number' value={columns.primary.roundToPlace} section='columns' subsection='primary' fieldName='roundToPlace' label='Round' updateField={updateField} min={0} />
|
|
1865
|
-
</li>
|
|
1866
|
-
<li>
|
|
1867
|
-
<label className='checkbox'>
|
|
1868
|
-
<input
|
|
1869
|
-
type='checkbox'
|
|
1870
|
-
checked={state.columns.primary.useCommas}
|
|
1871
|
-
onChange={event => {
|
|
1872
|
-
editColumn('primary', 'useCommas', event.target.checked)
|
|
1873
|
-
}}
|
|
1874
|
-
/>
|
|
1875
|
-
<span className='edit-label'>Add Commas to Numbers</span>
|
|
1876
|
-
</label>
|
|
1877
|
-
</li>
|
|
1878
|
-
<li>
|
|
1879
|
-
<label className='checkbox'>
|
|
1880
|
-
<input
|
|
1881
|
-
type='checkbox'
|
|
1882
|
-
checked={state.columns.primary.dataTable || false}
|
|
1883
|
-
onChange={event => {
|
|
1884
|
-
editColumn('primary', 'dataTable', event.target.checked)
|
|
1885
|
-
}}
|
|
1886
|
-
/>
|
|
1887
|
-
<span className='edit-label'>Show in Data Table</span>
|
|
1888
|
-
</label>
|
|
1889
|
-
</li>
|
|
1890
|
-
<li>
|
|
1891
|
-
<label className='checkbox'>
|
|
1892
|
-
<input
|
|
1893
|
-
type='checkbox'
|
|
1894
|
-
checked={state.columns.primary.tooltip || false}
|
|
1895
|
-
onChange={event => {
|
|
1896
|
-
editColumn('primary', 'tooltip', event.target.checked)
|
|
1897
|
-
}}
|
|
1898
|
-
/>
|
|
1899
|
-
<span className='edit-label'>Show in Tooltips</span>
|
|
1900
|
-
</label>
|
|
1901
|
-
</li>
|
|
1902
|
-
</ul>
|
|
1903
|
-
</fieldset>
|
|
1904
|
-
)}
|
|
1916
|
+
)}
|
|
1905
1917
|
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
<select
|
|
1921
|
-
value={state.columns.categorical ? state.columns.categorical.name : columnsOptions[0]}
|
|
1922
|
-
onChange={event => {
|
|
1923
|
-
editColumn('categorical', 'name', event.target.value)
|
|
1924
|
-
}}
|
|
1925
|
-
>
|
|
1926
|
-
{columnsOptions}
|
|
1927
|
-
</select>
|
|
1928
|
-
</label>
|
|
1929
|
-
</fieldset>
|
|
1930
|
-
)}
|
|
1931
|
-
{(
|
|
1932
|
-
<>
|
|
1933
|
-
<label>Latitude Column</label>
|
|
1934
|
-
<select
|
|
1935
|
-
value={state.columns.latitude.name ? state.columns.latitude.name : ''}
|
|
1936
|
-
onChange={e => {
|
|
1937
|
-
editColumn('latitude', 'name', e.target.value)
|
|
1938
|
-
}}
|
|
1939
|
-
>
|
|
1940
|
-
{columnsOptions}
|
|
1941
|
-
</select>
|
|
1942
|
-
<label>Longitude Column</label>
|
|
1918
|
+
{state.general.type === 'bubble' && state.legend.type === 'category' && (
|
|
1919
|
+
<fieldset className='primary-fieldset edit-block'>
|
|
1920
|
+
<label>
|
|
1921
|
+
<span className='edit-label column-heading'>
|
|
1922
|
+
Category Column
|
|
1923
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1924
|
+
<Tooltip.Target>
|
|
1925
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1926
|
+
</Tooltip.Target>
|
|
1927
|
+
<Tooltip.Content>
|
|
1928
|
+
<p>Select the source column containing the categorical bubble values to be mapped.</p>
|
|
1929
|
+
</Tooltip.Content>
|
|
1930
|
+
</Tooltip>
|
|
1931
|
+
</span>
|
|
1943
1932
|
<select
|
|
1944
|
-
value={state.columns.
|
|
1945
|
-
onChange={
|
|
1946
|
-
editColumn('
|
|
1933
|
+
value={state.columns.categorical ? state.columns.categorical.name : columnsOptions[0]}
|
|
1934
|
+
onChange={event => {
|
|
1935
|
+
editColumn('categorical', 'name', event.target.value)
|
|
1947
1936
|
}}
|
|
1948
1937
|
>
|
|
1949
1938
|
{columnsOptions}
|
|
1950
1939
|
</select>
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
<span className='edit-label'>
|
|
1958
|
-
Special Classes
|
|
1959
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
1960
|
-
<Tooltip.Target>
|
|
1961
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1962
|
-
</Tooltip.Target>
|
|
1963
|
-
<Tooltip.Content>
|
|
1964
|
-
<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>
|
|
1965
|
-
</Tooltip.Content>
|
|
1966
|
-
</Tooltip>
|
|
1967
|
-
</span>
|
|
1968
|
-
</label>
|
|
1969
|
-
{specialClasses.map((specialClass, i) => (
|
|
1970
|
-
<div className='edit-block' key={`special-class-${i}`}>
|
|
1971
|
-
<button
|
|
1972
|
-
className='remove-column'
|
|
1973
|
-
onClick={e => {
|
|
1974
|
-
e.preventDefault()
|
|
1975
|
-
editColumn('primary', 'specialClassDelete', i)
|
|
1976
|
-
}}
|
|
1977
|
-
>
|
|
1978
|
-
Remove
|
|
1979
|
-
</button>
|
|
1980
|
-
<p>Special Class {i + 1}</p>
|
|
1981
|
-
<label>
|
|
1982
|
-
<span className='edit-label column-heading'>Data Key</span>
|
|
1983
|
-
<select
|
|
1984
|
-
value={specialClass.key}
|
|
1985
|
-
onChange={e => {
|
|
1986
|
-
editColumn('primary', 'specialClassEdit', { prop: 'key', index: i, value: e.target.value })
|
|
1987
|
-
}}
|
|
1988
|
-
>
|
|
1989
|
-
{columnsOptions}
|
|
1990
|
-
</select>
|
|
1991
|
-
</label>
|
|
1992
|
-
<label>
|
|
1993
|
-
<span className='edit-label column-heading'>Value</span>
|
|
1994
|
-
<select
|
|
1995
|
-
value={specialClass.value}
|
|
1996
|
-
onChange={e => {
|
|
1997
|
-
editColumn('primary', 'specialClassEdit', { prop: 'value', index: i, value: e.target.value })
|
|
1998
|
-
}}
|
|
1999
|
-
>
|
|
2000
|
-
<option value=''>- Select Value -</option>
|
|
2001
|
-
{columnsByKey[specialClass.key] && columnsByKey[specialClass.key].sort().map(option => <option key={`special-class-value-option-${i}-${option}`}>{option}</option>)}
|
|
2002
|
-
</select>
|
|
2003
|
-
</label>
|
|
2004
|
-
<label>
|
|
2005
|
-
<span className='edit-label column-heading'>Label</span>
|
|
2006
|
-
<input
|
|
2007
|
-
type='text'
|
|
2008
|
-
value={specialClass.label}
|
|
2009
|
-
onChange={e => {
|
|
2010
|
-
editColumn('primary', 'specialClassEdit', { prop: 'label', index: i, value: e.target.value })
|
|
2011
|
-
}}
|
|
2012
|
-
/>
|
|
2013
|
-
</label>
|
|
2014
|
-
</div>
|
|
2015
|
-
))}
|
|
2016
|
-
<button
|
|
2017
|
-
className='btn full-width'
|
|
2018
|
-
onClick={e => {
|
|
2019
|
-
e.preventDefault()
|
|
2020
|
-
editColumn('primary', 'specialClassAdd', {})
|
|
2021
|
-
}}
|
|
2022
|
-
>
|
|
2023
|
-
Add Special Class
|
|
2024
|
-
</button>
|
|
2025
|
-
</fieldset>
|
|
2026
|
-
)}
|
|
2027
|
-
|
|
2028
|
-
<label className='edit-block navigate column-heading'>
|
|
2029
|
-
<span className='edit-label column-heading'>
|
|
2030
|
-
Navigation
|
|
2031
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2032
|
-
<Tooltip.Target>
|
|
2033
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2034
|
-
</Tooltip.Target>
|
|
2035
|
-
<Tooltip.Content>
|
|
2036
|
-
<p>To provide end users with navigation functionality, select the source column containing the navigation URLs.</p>
|
|
2037
|
-
</Tooltip.Content>
|
|
2038
|
-
</Tooltip>
|
|
2039
|
-
</span>
|
|
1940
|
+
</label>
|
|
1941
|
+
</fieldset>
|
|
1942
|
+
)}
|
|
1943
|
+
{
|
|
1944
|
+
<>
|
|
1945
|
+
<label>Latitude Column</label>
|
|
2040
1946
|
<select
|
|
2041
|
-
value={state.columns.
|
|
2042
|
-
onChange={
|
|
2043
|
-
editColumn('
|
|
1947
|
+
value={state.columns.latitude.name ? state.columns.latitude.name : ''}
|
|
1948
|
+
onChange={e => {
|
|
1949
|
+
editColumn('latitude', 'name', e.target.value)
|
|
2044
1950
|
}}
|
|
2045
1951
|
>
|
|
2046
1952
|
{columnsOptions}
|
|
2047
1953
|
</select>
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
<fieldset className='edit-block' key={val}>
|
|
2066
|
-
<button
|
|
2067
|
-
className='remove-column'
|
|
2068
|
-
onClick={event => {
|
|
2069
|
-
event.preventDefault()
|
|
2070
|
-
removeAdditionalColumn(val)
|
|
2071
|
-
}}
|
|
2072
|
-
>
|
|
2073
|
-
Remove
|
|
2074
|
-
</button>
|
|
2075
|
-
<label>
|
|
2076
|
-
<span className='edit-label column-heading'>Column</span>
|
|
2077
|
-
<select
|
|
2078
|
-
value={state.columns[val] ? state.columns[val].name : columnsOptions[0]}
|
|
2079
|
-
onChange={event => {
|
|
2080
|
-
editColumn(val, 'name', event.target.value)
|
|
2081
|
-
}}
|
|
2082
|
-
>
|
|
2083
|
-
{columnsOptions}
|
|
2084
|
-
</select>
|
|
2085
|
-
</label>
|
|
2086
|
-
<TextField value={columns[val].label} section='columns' subsection={val} fieldName='label' label='Label' updateField={updateField} />
|
|
2087
|
-
<ul className='column-edit'>
|
|
2088
|
-
<li className='three-col'>
|
|
2089
|
-
<TextField value={columns[val].prefix} section='columns' subsection={val} fieldName='prefix' label='Prefix' updateField={updateField} />
|
|
2090
|
-
<TextField value={columns[val].suffix} section='columns' subsection={val} fieldName='suffix' label='Suffix' updateField={updateField} />
|
|
2091
|
-
<TextField type='number' value={columns[val].roundToPlace} section='columns' subsection={val} fieldName='roundToPlace' label='Round' updateField={updateField} />
|
|
2092
|
-
</li>
|
|
2093
|
-
<li>
|
|
2094
|
-
<label className='checkbox'>
|
|
2095
|
-
<input
|
|
2096
|
-
type='checkbox'
|
|
2097
|
-
checked={state.columns[val].useCommas}
|
|
2098
|
-
onChange={event => {
|
|
2099
|
-
editColumn(val, 'useCommas', event.target.checked)
|
|
2100
|
-
}}
|
|
2101
|
-
/>
|
|
2102
|
-
<span className='edit-label'>Add Commas to Numbers</span>
|
|
2103
|
-
</label>
|
|
2104
|
-
</li>
|
|
2105
|
-
<li>
|
|
2106
|
-
<label className='checkbox'>
|
|
2107
|
-
<input
|
|
2108
|
-
type='checkbox'
|
|
2109
|
-
checked={state.columns[val].dataTable}
|
|
2110
|
-
onChange={event => {
|
|
2111
|
-
editColumn(val, 'dataTable', event.target.checked)
|
|
2112
|
-
}}
|
|
2113
|
-
/>
|
|
2114
|
-
<span className='edit-label'>Show in Data Table</span>
|
|
2115
|
-
</label>
|
|
2116
|
-
</li>
|
|
2117
|
-
<li>
|
|
2118
|
-
<label className='checkbox'>
|
|
2119
|
-
<input
|
|
2120
|
-
type='checkbox'
|
|
2121
|
-
checked={state.columns[val].tooltip}
|
|
2122
|
-
onChange={event => {
|
|
2123
|
-
editColumn(val, 'tooltip', event.target.checked)
|
|
2124
|
-
}}
|
|
2125
|
-
/>
|
|
2126
|
-
<span className='edit-label'>Show in Tooltips</span>
|
|
2127
|
-
</label>
|
|
2128
|
-
</li>
|
|
2129
|
-
</ul>
|
|
2130
|
-
</fieldset>
|
|
2131
|
-
))}
|
|
2132
|
-
<button
|
|
2133
|
-
className={'btn full-width'}
|
|
2134
|
-
onClick={event => {
|
|
2135
|
-
event.preventDefault()
|
|
2136
|
-
addAdditionalColumn(additionalColumns.length + 1)
|
|
2137
|
-
}}
|
|
2138
|
-
>
|
|
2139
|
-
Add Column
|
|
2140
|
-
</button>
|
|
2141
|
-
</fieldset>
|
|
2142
|
-
)}
|
|
2143
|
-
{'category' === state.legend.type && (
|
|
2144
|
-
<fieldset className='primary-fieldset edit-block'>
|
|
2145
|
-
<label>
|
|
2146
|
-
<span className='edit-label'>
|
|
2147
|
-
Additional Category
|
|
2148
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2149
|
-
<Tooltip.Target>
|
|
2150
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2151
|
-
</Tooltip.Target>
|
|
2152
|
-
<Tooltip.Content>
|
|
2153
|
-
<p>You can provide additional categories to ensure they appear in the legend</p>
|
|
2154
|
-
</Tooltip.Content>
|
|
2155
|
-
</Tooltip>
|
|
2156
|
-
</span>
|
|
2157
|
-
</label>
|
|
2158
|
-
{state.legend.additionalCategories &&
|
|
2159
|
-
state.legend.additionalCategories.map((val, i) => (
|
|
2160
|
-
<fieldset className='edit-block' key={val}>
|
|
2161
|
-
<button
|
|
2162
|
-
className='remove-column'
|
|
2163
|
-
onClick={event => {
|
|
2164
|
-
event.preventDefault()
|
|
2165
|
-
const updatedAdditionaCategories = [...state.legend.additionalCategories]
|
|
2166
|
-
updatedAdditionaCategories.splice(i, 1)
|
|
2167
|
-
updateField('legend', null, 'additionalCategories', updatedAdditionaCategories)
|
|
2168
|
-
}}
|
|
2169
|
-
>
|
|
2170
|
-
Remove
|
|
2171
|
-
</button>
|
|
2172
|
-
<label>
|
|
2173
|
-
<span className='edit-label column-heading'>Category</span>
|
|
2174
|
-
<TextField
|
|
2175
|
-
value={val}
|
|
2176
|
-
section='legend'
|
|
2177
|
-
subsection={null}
|
|
2178
|
-
fieldName='additionalCategories'
|
|
2179
|
-
updateField={(section, subsection, fieldName, value) => {
|
|
2180
|
-
const updatedAdditionaCategories = [...state.legend.additionalCategories]
|
|
2181
|
-
updatedAdditionaCategories[i] = value
|
|
2182
|
-
updateField(section, subsection, fieldName, updatedAdditionaCategories)
|
|
2183
|
-
}}
|
|
2184
|
-
/>
|
|
2185
|
-
</label>
|
|
2186
|
-
</fieldset>
|
|
2187
|
-
))}
|
|
2188
|
-
<button
|
|
2189
|
-
className={'btn full-width'}
|
|
2190
|
-
onClick={event => {
|
|
2191
|
-
event.preventDefault()
|
|
2192
|
-
const updatedAdditionaCategories = [...(state.legend.additionalCategories || [])]
|
|
2193
|
-
updatedAdditionaCategories.push('')
|
|
2194
|
-
updateField('legend', null, 'additionalCategories', updatedAdditionaCategories)
|
|
2195
|
-
}}
|
|
2196
|
-
>
|
|
2197
|
-
Add Category
|
|
2198
|
-
</button>
|
|
2199
|
-
</fieldset>
|
|
2200
|
-
)}
|
|
2201
|
-
</AccordionItemPanel>
|
|
2202
|
-
</AccordionItem>{' '}
|
|
2203
|
-
{/* Columns */}
|
|
2204
|
-
{'navigation' !== state.general.type && (
|
|
2205
|
-
<AccordionItem>
|
|
2206
|
-
{' '}
|
|
2207
|
-
{/* Legend */}
|
|
2208
|
-
<AccordionItemHeading>
|
|
2209
|
-
<AccordionItemButton>Legend</AccordionItemButton>
|
|
2210
|
-
</AccordionItemHeading>
|
|
2211
|
-
<AccordionItemPanel>
|
|
2212
|
-
{(state.legend.type === 'equalnumber' || state.legend.type === 'equalinterval') && (
|
|
2213
|
-
<label>
|
|
2214
|
-
<span className='edit-label'>Legend Type</span>
|
|
2215
|
-
<select
|
|
2216
|
-
value={legend.type}
|
|
2217
|
-
onChange={event => {
|
|
2218
|
-
handleEditorChanges('legendType', event.target.value)
|
|
2219
|
-
}}
|
|
2220
|
-
>
|
|
2221
|
-
<option value='equalnumber'>Equal Number (Quantiles)</option>
|
|
2222
|
-
<option value='equalinterval'>Equal Interval</option>
|
|
2223
|
-
</select>
|
|
2224
|
-
</label>
|
|
2225
|
-
)}
|
|
2226
|
-
{'navigation' !== state.general.type && (
|
|
2227
|
-
<label className='checkbox'>
|
|
2228
|
-
<input
|
|
2229
|
-
type='checkbox'
|
|
2230
|
-
checked={state.general.showSidebar || false}
|
|
2231
|
-
onChange={event => {
|
|
2232
|
-
handleEditorChanges('showSidebar', event.target.checked)
|
|
2233
|
-
}}
|
|
2234
|
-
/>
|
|
2235
|
-
<span className='edit-label'>Show Legend</span>
|
|
2236
|
-
</label>
|
|
2237
|
-
)}
|
|
2238
|
-
{'navigation' !== state.general.type && (
|
|
2239
|
-
<label>
|
|
2240
|
-
<span className='edit-label'>Legend Position</span>
|
|
2241
|
-
<select
|
|
2242
|
-
value={legend.position || false}
|
|
2243
|
-
onChange={event => {
|
|
2244
|
-
handleEditorChanges('sidebarPosition', event.target.value)
|
|
2245
|
-
}}
|
|
2246
|
-
>
|
|
2247
|
-
<option value='side'>Side</option>
|
|
2248
|
-
<option value='bottom'>Bottom</option>
|
|
2249
|
-
</select>
|
|
2250
|
-
</label>
|
|
2251
|
-
)}
|
|
2252
|
-
{'side' === legend.position && (
|
|
2253
|
-
<label className='checkbox'>
|
|
2254
|
-
<input
|
|
2255
|
-
type='checkbox'
|
|
2256
|
-
checked={legend.singleColumn}
|
|
2257
|
-
onChange={event => {
|
|
2258
|
-
handleEditorChanges('singleColumnLegend', event.target.checked)
|
|
2259
|
-
}}
|
|
2260
|
-
/>
|
|
2261
|
-
<span className='edit-label'>Single Column Legend</span>
|
|
2262
|
-
</label>
|
|
2263
|
-
)}
|
|
2264
|
-
{'bottom' === legend.position && (
|
|
2265
|
-
<label className='checkbox'>
|
|
2266
|
-
<input
|
|
2267
|
-
type='checkbox'
|
|
2268
|
-
checked={legend.singleRow}
|
|
2269
|
-
onChange={event => {
|
|
2270
|
-
handleEditorChanges('singleRowLegend', event.target.checked)
|
|
2271
|
-
}}
|
|
2272
|
-
/>
|
|
2273
|
-
<span className='edit-label'>Single Row Legend</span>
|
|
2274
|
-
</label>
|
|
2275
|
-
)}
|
|
2276
|
-
<label className='checkbox'>
|
|
2277
|
-
<input
|
|
2278
|
-
type='checkbox'
|
|
2279
|
-
checked={legend.verticalSorted}
|
|
2280
|
-
onChange={event => {
|
|
2281
|
-
handleEditorChanges('verticalSortedLegend', event.target.checked)
|
|
2282
|
-
}}
|
|
2283
|
-
/>
|
|
2284
|
-
<span className='edit-label'>Vertical sorted legend</span>
|
|
2285
|
-
</label>
|
|
2286
|
-
{/* always show */}
|
|
2287
|
-
{
|
|
2288
|
-
<label className='checkbox'>
|
|
2289
|
-
<input
|
|
2290
|
-
type='checkbox'
|
|
2291
|
-
checked={legend.showSpecialClassesLast}
|
|
2292
|
-
onChange={event => {
|
|
2293
|
-
handleEditorChanges('legendShowSpecialClassesLast', event.target.checked)
|
|
2294
|
-
}}
|
|
2295
|
-
/>
|
|
2296
|
-
<span className='edit-label'>Show Special Classes Last</span>
|
|
2297
|
-
</label>
|
|
2298
|
-
}
|
|
2299
|
-
{'category' !== legend.type && (
|
|
2300
|
-
<label className='checkbox'>
|
|
2301
|
-
<input type='checkbox' checked={legend.separateZero || false} onChange={event => handleEditorChanges('separateZero', event.target.checked)} />
|
|
2302
|
-
<span className='edit-label column-heading'>
|
|
2303
|
-
Separate Zero
|
|
2304
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2305
|
-
<Tooltip.Target>
|
|
2306
|
-
<Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
|
|
2307
|
-
</Tooltip.Target>
|
|
2308
|
-
<Tooltip.Content>
|
|
2309
|
-
<p>For numeric data, you can separate the zero value as its own data class.</p>
|
|
2310
|
-
</Tooltip.Content>
|
|
2311
|
-
</Tooltip>
|
|
2312
|
-
</span>
|
|
2313
|
-
</label>
|
|
2314
|
-
)}
|
|
2315
|
-
{/* Temp Checkbox */}
|
|
2316
|
-
{state.legend.type === 'equalnumber' && (
|
|
2317
|
-
<label className='checkbox'>
|
|
2318
|
-
<input
|
|
2319
|
-
type='checkbox'
|
|
2320
|
-
checked={state.general.equalNumberOptIn}
|
|
2321
|
-
onChange={event => {
|
|
2322
|
-
handleEditorChanges('showEqualNumber', event.target.checked)
|
|
2323
|
-
}}
|
|
2324
|
-
/>
|
|
2325
|
-
<span className='edit-label column-heading'>Use new quantile legend</span>
|
|
1954
|
+
<label>Longitude Column</label>
|
|
1955
|
+
<select
|
|
1956
|
+
value={state.columns.longitude.name ? state.columns.longitude.name : ''}
|
|
1957
|
+
onChange={e => {
|
|
1958
|
+
editColumn('longitude', 'name', e.target.value)
|
|
1959
|
+
}}
|
|
1960
|
+
>
|
|
1961
|
+
{columnsOptions}
|
|
1962
|
+
</select>
|
|
1963
|
+
</>
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
{'navigation' !== state.general.type && (
|
|
1967
|
+
<fieldset className='primary-fieldset edit-block'>
|
|
1968
|
+
<label>
|
|
1969
|
+
<span className='edit-label'>
|
|
1970
|
+
Special Classes
|
|
2326
1971
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
2327
1972
|
<Tooltip.Target>
|
|
2328
|
-
<Icon display='question' style={{ marginLeft: '0.5rem'
|
|
1973
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2329
1974
|
</Tooltip.Target>
|
|
2330
1975
|
<Tooltip.Content>
|
|
2331
|
-
<p>
|
|
1976
|
+
<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>
|
|
2332
1977
|
</Tooltip.Content>
|
|
2333
1978
|
</Tooltip>
|
|
2334
|
-
</
|
|
2335
|
-
|
|
2336
|
-
{
|
|
2337
|
-
<
|
|
2338
|
-
<
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
</Tooltip.Target>
|
|
2344
|
-
<Tooltip.Content>
|
|
2345
|
-
<p>For numeric maps, select the number of data classes. Do not include designated special classes.</p>
|
|
2346
|
-
</Tooltip.Content>
|
|
2347
|
-
</Tooltip>
|
|
2348
|
-
</span>
|
|
2349
|
-
<select
|
|
2350
|
-
value={legend.numberOfItems}
|
|
2351
|
-
onChange={event => {
|
|
2352
|
-
handleEditorChanges('legendNumber', event.target.value)
|
|
1979
|
+
</span>
|
|
1980
|
+
</label>
|
|
1981
|
+
{specialClasses.map((specialClass, i) => (
|
|
1982
|
+
<div className='edit-block' key={`special-class-${i}`}>
|
|
1983
|
+
<button
|
|
1984
|
+
className='remove-column'
|
|
1985
|
+
onClick={e => {
|
|
1986
|
+
e.preventDefault()
|
|
1987
|
+
editColumn('primary', 'specialClassDelete', i)
|
|
2353
1988
|
}}
|
|
2354
1989
|
>
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
{num + 1}
|
|
2359
|
-
</option>
|
|
2360
|
-
)
|
|
2361
|
-
})}
|
|
2362
|
-
</select>
|
|
2363
|
-
</label>
|
|
2364
|
-
)}
|
|
2365
|
-
{'category' === legend.type && (
|
|
2366
|
-
<React.Fragment>
|
|
1990
|
+
Remove
|
|
1991
|
+
</button>
|
|
1992
|
+
<p>Special Class {i + 1}</p>
|
|
2367
1993
|
<label>
|
|
2368
|
-
<span className='edit-label'>
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
</Tooltip>
|
|
2378
|
-
</span>
|
|
2379
|
-
</label>
|
|
2380
|
-
{/* 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. */}
|
|
2381
|
-
<DragDropContext onDragEnd={({ source, destination }) => categoryMove(source.index, destination.index)}>
|
|
2382
|
-
<Droppable droppableId='category_order'>
|
|
2383
|
-
{provided => (
|
|
2384
|
-
<ul {...provided.droppableProps} className='sort-list' ref={provided.innerRef}>
|
|
2385
|
-
<CategoryList />
|
|
2386
|
-
{provided.placeholder}
|
|
2387
|
-
</ul>
|
|
2388
|
-
)}
|
|
2389
|
-
</Droppable>
|
|
2390
|
-
</DragDropContext>
|
|
2391
|
-
{state.legend.categoryValuesOrder && state.legend.categoryValuesOrder.length >= 10 && (
|
|
2392
|
-
<section className='error-box my-2'>
|
|
2393
|
-
<div>
|
|
2394
|
-
<strong className='pt-1'>Warning</strong>
|
|
2395
|
-
<p>The maximum number of categorical legend items is 10. If your data has more than 10 categories your map will not display properly.</p>
|
|
2396
|
-
</div>
|
|
2397
|
-
</section>
|
|
2398
|
-
)}
|
|
2399
|
-
</React.Fragment>
|
|
2400
|
-
)}
|
|
2401
|
-
<TextField value={legend.title} updateField={updateField} section='legend' fieldName='title' label='Legend Title' placeholder='Legend Title' />
|
|
2402
|
-
{false === legend.dynamicDescription && <TextField type='textarea' value={legend.description} updateField={updateField} section='legend' fieldName='description' label='Legend Description' />}
|
|
2403
|
-
{true === legend.dynamicDescription && (
|
|
2404
|
-
<React.Fragment>
|
|
2405
|
-
<label>
|
|
2406
|
-
<span>Legend Description</span>
|
|
2407
|
-
<span className='subtext'>For {displayFilterLegendValue(activeFilterValueForDescription)}</span>
|
|
2408
|
-
<DynamicDesc value={legend.descriptions[String(activeFilterValueForDescription)]} />
|
|
1994
|
+
<span className='edit-label column-heading'>Data Key</span>
|
|
1995
|
+
<select
|
|
1996
|
+
value={specialClass.key}
|
|
1997
|
+
onChange={e => {
|
|
1998
|
+
editColumn('primary', 'specialClassEdit', { prop: 'key', index: i, value: e.target.value })
|
|
1999
|
+
}}
|
|
2000
|
+
>
|
|
2001
|
+
{columnsOptions}
|
|
2002
|
+
</select>
|
|
2409
2003
|
</label>
|
|
2410
2004
|
<label>
|
|
2005
|
+
<span className='edit-label column-heading'>Value</span>
|
|
2411
2006
|
<select
|
|
2412
|
-
value={
|
|
2413
|
-
onChange={
|
|
2414
|
-
|
|
2007
|
+
value={specialClass.value}
|
|
2008
|
+
onChange={e => {
|
|
2009
|
+
editColumn('primary', 'specialClassEdit', { prop: 'value', index: i, value: e.target.value })
|
|
2415
2010
|
}}
|
|
2416
2011
|
>
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
<option value={arr} key={i}>
|
|
2420
|
-
{displayFilterLegendValue(arr)}
|
|
2421
|
-
</option>
|
|
2422
|
-
)
|
|
2423
|
-
})}
|
|
2012
|
+
<option value=''>- Select Value -</option>
|
|
2013
|
+
{columnsByKey[specialClass.key] && columnsByKey[specialClass.key].sort().map(option => <option key={`special-class-value-option-${i}-${option}`}>{option}</option>)}
|
|
2424
2014
|
</select>
|
|
2425
2015
|
</label>
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2016
|
+
<label>
|
|
2017
|
+
<span className='edit-label column-heading'>Label</span>
|
|
2018
|
+
<input
|
|
2019
|
+
type='text'
|
|
2020
|
+
value={specialClass.label}
|
|
2021
|
+
onChange={e => {
|
|
2022
|
+
editColumn('primary', 'specialClassEdit', { prop: 'label', index: i, value: e.target.value })
|
|
2023
|
+
}}
|
|
2024
|
+
/>
|
|
2025
|
+
</label>
|
|
2026
|
+
</div>
|
|
2027
|
+
))}
|
|
2028
|
+
<button
|
|
2029
|
+
className='btn full-width'
|
|
2030
|
+
onClick={e => {
|
|
2031
|
+
e.preventDefault()
|
|
2032
|
+
editColumn('primary', 'specialClassAdd', {})
|
|
2033
|
+
}}
|
|
2034
|
+
>
|
|
2035
|
+
Add Special Class
|
|
2036
|
+
</button>
|
|
2037
|
+
</fieldset>
|
|
2038
|
+
)}
|
|
2039
|
+
|
|
2040
|
+
<label className='edit-block navigate column-heading'>
|
|
2041
|
+
<span className='edit-label column-heading'>
|
|
2042
|
+
Navigation
|
|
2043
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2044
|
+
<Tooltip.Target>
|
|
2045
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2046
|
+
</Tooltip.Target>
|
|
2047
|
+
<Tooltip.Content>
|
|
2048
|
+
<p>To provide end users with navigation functionality, select the source column containing the navigation URLs.</p>
|
|
2049
|
+
</Tooltip.Content>
|
|
2050
|
+
</Tooltip>
|
|
2051
|
+
</span>
|
|
2052
|
+
<select
|
|
2053
|
+
value={state.columns.navigate ? state.columns.navigate.name : columnsOptions[0]}
|
|
2054
|
+
onChange={event => {
|
|
2055
|
+
editColumn('navigate', 'name', event.target.value)
|
|
2056
|
+
}}
|
|
2057
|
+
>
|
|
2058
|
+
{columnsOptions}
|
|
2059
|
+
</select>
|
|
2060
|
+
</label>
|
|
2061
|
+
{'navigation' !== state.general.type && (
|
|
2062
|
+
<fieldset className='primary-fieldset edit-block'>
|
|
2063
|
+
<label>
|
|
2064
|
+
<span className='edit-label'>
|
|
2065
|
+
Additional Columns
|
|
2066
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2067
|
+
<Tooltip.Target>
|
|
2068
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2069
|
+
</Tooltip.Target>
|
|
2070
|
+
<Tooltip.Content>
|
|
2071
|
+
<p>You can specify additional columns to display in tooltips and / or the supporting data table.</p>
|
|
2072
|
+
</Tooltip.Content>
|
|
2073
|
+
</Tooltip>
|
|
2074
|
+
</span>
|
|
2075
|
+
</label>
|
|
2076
|
+
{additionalColumns.map(val => (
|
|
2077
|
+
<fieldset className='edit-block' key={val}>
|
|
2078
|
+
<button
|
|
2079
|
+
className='remove-column'
|
|
2080
|
+
onClick={event => {
|
|
2081
|
+
event.preventDefault()
|
|
2082
|
+
removeAdditionalColumn(val)
|
|
2435
2083
|
}}
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2084
|
+
>
|
|
2085
|
+
Remove
|
|
2086
|
+
</button>
|
|
2087
|
+
<label>
|
|
2088
|
+
<span className='edit-label column-heading'>Column</span>
|
|
2089
|
+
<select
|
|
2090
|
+
value={state.columns[val] ? state.columns[val].name : columnsOptions[0]}
|
|
2091
|
+
onChange={event => {
|
|
2092
|
+
editColumn(val, 'name', event.target.value)
|
|
2093
|
+
}}
|
|
2094
|
+
>
|
|
2095
|
+
{columnsOptions}
|
|
2096
|
+
</select>
|
|
2097
|
+
</label>
|
|
2098
|
+
<TextField value={columns[val].label} section='columns' subsection={val} fieldName='label' label='Label' updateField={updateField} />
|
|
2099
|
+
<ul className='column-edit'>
|
|
2100
|
+
<li className='three-col'>
|
|
2101
|
+
<TextField value={columns[val].prefix} section='columns' subsection={val} fieldName='prefix' label='Prefix' updateField={updateField} />
|
|
2102
|
+
<TextField value={columns[val].suffix} section='columns' subsection={val} fieldName='suffix' label='Suffix' updateField={updateField} />
|
|
2103
|
+
<TextField type='number' value={columns[val].roundToPlace} section='columns' subsection={val} fieldName='roundToPlace' label='Round' updateField={updateField} />
|
|
2104
|
+
</li>
|
|
2105
|
+
<li>
|
|
2106
|
+
<label className='checkbox'>
|
|
2107
|
+
<input
|
|
2108
|
+
type='checkbox'
|
|
2109
|
+
checked={state.columns[val].useCommas}
|
|
2110
|
+
onChange={event => {
|
|
2111
|
+
editColumn(val, 'useCommas', event.target.checked)
|
|
2112
|
+
}}
|
|
2113
|
+
/>
|
|
2114
|
+
<span className='edit-label'>Add Commas to Numbers</span>
|
|
2115
|
+
</label>
|
|
2116
|
+
</li>
|
|
2117
|
+
<li>
|
|
2118
|
+
<label className='checkbox'>
|
|
2119
|
+
<input
|
|
2120
|
+
type='checkbox'
|
|
2121
|
+
checked={state.columns[val].dataTable}
|
|
2122
|
+
onChange={event => {
|
|
2123
|
+
editColumn(val, 'dataTable', event.target.checked)
|
|
2124
|
+
}}
|
|
2125
|
+
/>
|
|
2126
|
+
<span className='edit-label'>Show in Data Table</span>
|
|
2127
|
+
</label>
|
|
2128
|
+
</li>
|
|
2129
|
+
<li>
|
|
2130
|
+
<label className='checkbox'>
|
|
2131
|
+
<input
|
|
2132
|
+
type='checkbox'
|
|
2133
|
+
checked={state.columns[val].tooltip}
|
|
2134
|
+
onChange={event => {
|
|
2135
|
+
editColumn(val, 'tooltip', event.target.checked)
|
|
2136
|
+
}}
|
|
2137
|
+
/>
|
|
2138
|
+
<span className='edit-label'>Show in Tooltips</span>
|
|
2139
|
+
</label>
|
|
2140
|
+
</li>
|
|
2141
|
+
</ul>
|
|
2142
|
+
</fieldset>
|
|
2143
|
+
))}
|
|
2480
2144
|
<button
|
|
2481
2145
|
className={'btn full-width'}
|
|
2482
2146
|
onClick={event => {
|
|
2483
2147
|
event.preventDefault()
|
|
2484
|
-
|
|
2148
|
+
addAdditionalColumn(additionalColumns.length + 1)
|
|
2485
2149
|
}}
|
|
2486
2150
|
>
|
|
2487
|
-
Add
|
|
2151
|
+
Add Column
|
|
2488
2152
|
</button>
|
|
2489
|
-
</
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
<AccordionItemHeading>
|
|
2497
|
-
<AccordionItemButton>Data Table</AccordionItemButton>
|
|
2498
|
-
</AccordionItemHeading>
|
|
2499
|
-
<AccordionItemPanel>
|
|
2500
|
-
<TextField
|
|
2501
|
-
value={table.label}
|
|
2502
|
-
updateField={updateField}
|
|
2503
|
-
section='table'
|
|
2504
|
-
fieldName='label'
|
|
2505
|
-
id='dataTableTitle'
|
|
2506
|
-
label='Data Table Title'
|
|
2507
|
-
placeholder='Data Table'
|
|
2508
|
-
tooltip={
|
|
2153
|
+
</fieldset>
|
|
2154
|
+
)}
|
|
2155
|
+
{'category' === state.legend.type && (
|
|
2156
|
+
<fieldset className='primary-fieldset edit-block'>
|
|
2157
|
+
<label>
|
|
2158
|
+
<span className='edit-label'>
|
|
2159
|
+
Additional Category
|
|
2509
2160
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
2510
2161
|
<Tooltip.Target>
|
|
2511
2162
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2512
2163
|
</Tooltip.Target>
|
|
2513
2164
|
<Tooltip.Content>
|
|
2514
|
-
<p>
|
|
2165
|
+
<p>You can provide additional categories to ensure they appear in the legend</p>
|
|
2515
2166
|
</Tooltip.Content>
|
|
2516
2167
|
</Tooltip>
|
|
2517
|
-
|
|
2518
|
-
|
|
2168
|
+
</span>
|
|
2169
|
+
</label>
|
|
2170
|
+
{state.legend.additionalCategories &&
|
|
2171
|
+
state.legend.additionalCategories.map((val, i) => (
|
|
2172
|
+
<fieldset className='edit-block' key={val}>
|
|
2173
|
+
<button
|
|
2174
|
+
className='remove-column'
|
|
2175
|
+
onClick={event => {
|
|
2176
|
+
event.preventDefault()
|
|
2177
|
+
const updatedAdditionaCategories = [...state.legend.additionalCategories]
|
|
2178
|
+
updatedAdditionaCategories.splice(i, 1)
|
|
2179
|
+
updateField('legend', null, 'additionalCategories', updatedAdditionaCategories)
|
|
2180
|
+
}}
|
|
2181
|
+
>
|
|
2182
|
+
Remove
|
|
2183
|
+
</button>
|
|
2184
|
+
<label>
|
|
2185
|
+
<span className='edit-label column-heading'>Category</span>
|
|
2186
|
+
<TextField
|
|
2187
|
+
value={val}
|
|
2188
|
+
section='legend'
|
|
2189
|
+
subsection={null}
|
|
2190
|
+
fieldName='additionalCategories'
|
|
2191
|
+
updateField={(section, subsection, fieldName, value) => {
|
|
2192
|
+
const updatedAdditionaCategories = [...state.legend.additionalCategories]
|
|
2193
|
+
updatedAdditionaCategories[i] = value
|
|
2194
|
+
updateField(section, subsection, fieldName, updatedAdditionaCategories)
|
|
2195
|
+
}}
|
|
2196
|
+
/>
|
|
2197
|
+
</label>
|
|
2198
|
+
</fieldset>
|
|
2199
|
+
))}
|
|
2200
|
+
<button
|
|
2201
|
+
className={'btn full-width'}
|
|
2202
|
+
onClick={event => {
|
|
2203
|
+
event.preventDefault()
|
|
2204
|
+
const updatedAdditionaCategories = [...(state.legend.additionalCategories || [])]
|
|
2205
|
+
updatedAdditionaCategories.push('')
|
|
2206
|
+
updateField('legend', null, 'additionalCategories', updatedAdditionaCategories)
|
|
2207
|
+
}}
|
|
2208
|
+
>
|
|
2209
|
+
Add Category
|
|
2210
|
+
</button>
|
|
2211
|
+
</fieldset>
|
|
2212
|
+
)}
|
|
2213
|
+
</AccordionItemPanel>
|
|
2214
|
+
</AccordionItem>{' '}
|
|
2215
|
+
{/* Columns */}
|
|
2216
|
+
{'navigation' !== state.general.type && (
|
|
2217
|
+
<AccordionItem>
|
|
2218
|
+
{' '}
|
|
2219
|
+
{/* Legend */}
|
|
2220
|
+
<AccordionItemHeading>
|
|
2221
|
+
<AccordionItemButton>Legend</AccordionItemButton>
|
|
2222
|
+
</AccordionItemHeading>
|
|
2223
|
+
<AccordionItemPanel>
|
|
2224
|
+
{(state.legend.type === 'equalnumber' || state.legend.type === 'equalinterval') && (
|
|
2225
|
+
<label>
|
|
2226
|
+
<span className='edit-label'>Legend Type</span>
|
|
2227
|
+
<select
|
|
2228
|
+
value={legend.type}
|
|
2229
|
+
onChange={event => {
|
|
2230
|
+
handleEditorChanges('legendType', event.target.value)
|
|
2231
|
+
}}
|
|
2232
|
+
>
|
|
2233
|
+
<option value='equalnumber'>Equal Number (Quantiles)</option>
|
|
2234
|
+
<option value='equalinterval'>Equal Interval</option>
|
|
2235
|
+
</select>
|
|
2236
|
+
</label>
|
|
2237
|
+
)}
|
|
2238
|
+
{'navigation' !== state.general.type && (
|
|
2519
2239
|
<label className='checkbox'>
|
|
2520
2240
|
<input
|
|
2521
2241
|
type='checkbox'
|
|
2522
|
-
checked={state.
|
|
2242
|
+
checked={state.general.showSidebar || false}
|
|
2523
2243
|
onChange={event => {
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2244
|
+
handleEditorChanges('showSidebar', event.target.checked)
|
|
2245
|
+
}}
|
|
2246
|
+
/>
|
|
2247
|
+
<span className='edit-label'>Show Legend</span>
|
|
2248
|
+
</label>
|
|
2249
|
+
)}
|
|
2250
|
+
{'navigation' !== state.general.type && (
|
|
2251
|
+
<label>
|
|
2252
|
+
<span className='edit-label'>Legend Position</span>
|
|
2253
|
+
<select
|
|
2254
|
+
value={legend.position || false}
|
|
2255
|
+
onChange={event => {
|
|
2256
|
+
handleEditorChanges('sidebarPosition', event.target.value)
|
|
2257
|
+
}}
|
|
2258
|
+
>
|
|
2259
|
+
<option value='side'>Side</option>
|
|
2260
|
+
<option value='bottom'>Bottom</option>
|
|
2261
|
+
</select>
|
|
2262
|
+
</label>
|
|
2263
|
+
)}
|
|
2264
|
+
{'side' === legend.position && (
|
|
2265
|
+
<label className='checkbox'>
|
|
2266
|
+
<input
|
|
2267
|
+
type='checkbox'
|
|
2268
|
+
checked={legend.singleColumn}
|
|
2269
|
+
onChange={event => {
|
|
2270
|
+
handleEditorChanges('singleColumnLegend', event.target.checked)
|
|
2271
|
+
}}
|
|
2272
|
+
/>
|
|
2273
|
+
<span className='edit-label'>Single Column Legend</span>
|
|
2274
|
+
</label>
|
|
2275
|
+
)}
|
|
2276
|
+
{'bottom' === legend.position && (
|
|
2277
|
+
<label className='checkbox'>
|
|
2278
|
+
<input
|
|
2279
|
+
type='checkbox'
|
|
2280
|
+
checked={legend.singleRow}
|
|
2281
|
+
onChange={event => {
|
|
2282
|
+
handleEditorChanges('singleRowLegend', event.target.checked)
|
|
2531
2283
|
}}
|
|
2532
2284
|
/>
|
|
2533
|
-
<span className='edit-label
|
|
2285
|
+
<span className='edit-label'>Single Row Legend</span>
|
|
2534
2286
|
</label>
|
|
2287
|
+
)}
|
|
2288
|
+
<label className='checkbox'>
|
|
2289
|
+
<input
|
|
2290
|
+
type='checkbox'
|
|
2291
|
+
checked={legend.verticalSorted}
|
|
2292
|
+
onChange={event => {
|
|
2293
|
+
handleEditorChanges('verticalSortedLegend', event.target.checked)
|
|
2294
|
+
}}
|
|
2295
|
+
/>
|
|
2296
|
+
<span className='edit-label'>Vertical sorted legend</span>
|
|
2297
|
+
</label>
|
|
2298
|
+
{/* always show */}
|
|
2299
|
+
{
|
|
2535
2300
|
<label className='checkbox'>
|
|
2536
2301
|
<input
|
|
2537
2302
|
type='checkbox'
|
|
2538
|
-
checked={
|
|
2303
|
+
checked={legend.showSpecialClassesLast}
|
|
2539
2304
|
onChange={event => {
|
|
2540
|
-
handleEditorChanges('
|
|
2305
|
+
handleEditorChanges('legendShowSpecialClassesLast', event.target.checked)
|
|
2541
2306
|
}}
|
|
2542
2307
|
/>
|
|
2308
|
+
<span className='edit-label'>Show Special Classes Last</span>
|
|
2309
|
+
</label>
|
|
2310
|
+
}
|
|
2311
|
+
{'category' !== legend.type && (
|
|
2312
|
+
<label className='checkbox'>
|
|
2313
|
+
<input type='checkbox' checked={legend.separateZero || false} onChange={event => handleEditorChanges('separateZero', event.target.checked)} />
|
|
2543
2314
|
<span className='edit-label column-heading'>
|
|
2544
|
-
|
|
2315
|
+
Separate Zero
|
|
2545
2316
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
2546
2317
|
<Tooltip.Target>
|
|
2547
2318
|
<Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
|
|
2548
2319
|
</Tooltip.Target>
|
|
2549
2320
|
<Tooltip.Content>
|
|
2550
|
-
<p>
|
|
2321
|
+
<p>For numeric data, you can separate the zero value as its own data class.</p>
|
|
2551
2322
|
</Tooltip.Content>
|
|
2552
2323
|
</Tooltip>
|
|
2553
2324
|
</span>
|
|
2554
2325
|
</label>
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
section='table'
|
|
2559
|
-
fieldName='indexLabel'
|
|
2560
|
-
label='Index Column Header'
|
|
2561
|
-
placeholder='Location'
|
|
2562
|
-
tooltip={
|
|
2563
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2564
|
-
<Tooltip.Target>
|
|
2565
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2566
|
-
</Tooltip.Target>
|
|
2567
|
-
<Tooltip.Content>
|
|
2568
|
-
<p>To comply with 508 standards, if the first column in the data table has no header, enter a brief one here.</p>
|
|
2569
|
-
</Tooltip.Content>
|
|
2570
|
-
</Tooltip>
|
|
2571
|
-
}
|
|
2572
|
-
/>
|
|
2573
|
-
<TextField
|
|
2574
|
-
value={state.table.caption}
|
|
2575
|
-
updateField={updateField}
|
|
2576
|
-
section='table'
|
|
2577
|
-
fieldName='caption'
|
|
2578
|
-
label='Screen Reader Description'
|
|
2579
|
-
placeholder='Data Table'
|
|
2580
|
-
tooltip={
|
|
2581
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2582
|
-
<Tooltip.Target>
|
|
2583
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2584
|
-
</Tooltip.Target>
|
|
2585
|
-
<Tooltip.Content>
|
|
2586
|
-
<p>Enter a description of the data table to be read by screen readers.</p>
|
|
2587
|
-
</Tooltip.Content>
|
|
2588
|
-
</Tooltip>
|
|
2589
|
-
}
|
|
2590
|
-
type='textarea'
|
|
2591
|
-
/>
|
|
2326
|
+
)}
|
|
2327
|
+
{/* Temp Checkbox */}
|
|
2328
|
+
{state.legend.type === 'equalnumber' && (
|
|
2592
2329
|
<label className='checkbox'>
|
|
2593
2330
|
<input
|
|
2594
2331
|
type='checkbox'
|
|
2595
|
-
checked={state.
|
|
2332
|
+
checked={state.general.equalNumberOptIn}
|
|
2596
2333
|
onChange={event => {
|
|
2597
|
-
handleEditorChanges('
|
|
2334
|
+
handleEditorChanges('showEqualNumber', event.target.checked)
|
|
2598
2335
|
}}
|
|
2599
2336
|
/>
|
|
2600
|
-
<span className='edit-label'>
|
|
2337
|
+
<span className='edit-label column-heading'>Use new quantile legend</span>
|
|
2338
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2339
|
+
<Tooltip.Target>
|
|
2340
|
+
<Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
|
|
2341
|
+
</Tooltip.Target>
|
|
2342
|
+
<Tooltip.Content>
|
|
2343
|
+
<p>This prevents numbers from being used in more than one category (ie. 0-1, 1-2, 2-3) </p>
|
|
2344
|
+
</Tooltip.Content>
|
|
2345
|
+
</Tooltip>
|
|
2601
2346
|
</label>
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2347
|
+
)}
|
|
2348
|
+
{'category' !== legend.type && (
|
|
2349
|
+
<label>
|
|
2350
|
+
<span className='edit-label'>
|
|
2351
|
+
Number of Items
|
|
2352
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2353
|
+
<Tooltip.Target>
|
|
2354
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2355
|
+
</Tooltip.Target>
|
|
2356
|
+
<Tooltip.Content>
|
|
2357
|
+
<p>For numeric maps, select the number of data classes. Do not include designated special classes.</p>
|
|
2358
|
+
</Tooltip.Content>
|
|
2359
|
+
</Tooltip>
|
|
2360
|
+
</span>
|
|
2361
|
+
<select
|
|
2362
|
+
value={legend.numberOfItems}
|
|
2607
2363
|
onChange={event => {
|
|
2608
|
-
handleEditorChanges('
|
|
2364
|
+
handleEditorChanges('legendNumber', event.target.value)
|
|
2609
2365
|
}}
|
|
2610
|
-
|
|
2611
|
-
|
|
2366
|
+
>
|
|
2367
|
+
{[...Array(numberOfItemsLimit).keys()].map(num => {
|
|
2368
|
+
return (
|
|
2369
|
+
<option value={num + 1} key={num + 1}>
|
|
2370
|
+
{num + 1}
|
|
2371
|
+
</option>
|
|
2372
|
+
)
|
|
2373
|
+
})}
|
|
2374
|
+
</select>
|
|
2612
2375
|
</label>
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2376
|
+
)}
|
|
2377
|
+
{'category' === legend.type && (
|
|
2378
|
+
<React.Fragment>
|
|
2379
|
+
<label>
|
|
2380
|
+
<span className='edit-label'>
|
|
2381
|
+
Category Order
|
|
2382
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2383
|
+
<Tooltip.Target>
|
|
2384
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2385
|
+
</Tooltip.Target>
|
|
2386
|
+
<Tooltip.Content>
|
|
2387
|
+
<p>Drag map categories into preferred legend order. </p>
|
|
2388
|
+
</Tooltip.Content>
|
|
2389
|
+
</Tooltip>
|
|
2390
|
+
</span>
|
|
2623
2391
|
</label>
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2392
|
+
{/* 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 onDragEnd={({ source, destination }) => categoryMove(source.index, destination.index)}>
|
|
2394
|
+
<Droppable droppableId='category_order'>
|
|
2395
|
+
{provided => (
|
|
2396
|
+
<ul {...provided.droppableProps} className='sort-list' ref={provided.innerRef}>
|
|
2397
|
+
<CategoryList />
|
|
2398
|
+
{provided.placeholder}
|
|
2399
|
+
</ul>
|
|
2400
|
+
)}
|
|
2401
|
+
</Droppable>
|
|
2402
|
+
</DragDropContext>
|
|
2403
|
+
{state.legend.categoryValuesOrder && state.legend.categoryValuesOrder.length >= 10 && (
|
|
2404
|
+
<section className='error-box my-2'>
|
|
2405
|
+
<div>
|
|
2406
|
+
<strong className='pt-1'>Warning</strong>
|
|
2407
|
+
<p>The maximum number of categorical legend items is 10. If your data has more than 10 categories your map will not display properly.</p>
|
|
2408
|
+
</div>
|
|
2409
|
+
</section>
|
|
2410
|
+
)}
|
|
2411
|
+
</React.Fragment>
|
|
2412
|
+
)}
|
|
2413
|
+
<TextField value={legend.title} updateField={updateField} section='legend' fieldName='title' label='Legend Title' placeholder='Legend Title' />
|
|
2414
|
+
{false === legend.dynamicDescription && <TextField type='textarea' value={legend.description} updateField={updateField} section='legend' fieldName='description' label='Legend Description' />}
|
|
2415
|
+
{true === legend.dynamicDescription && (
|
|
2416
|
+
<React.Fragment>
|
|
2417
|
+
<label>
|
|
2418
|
+
<span>Legend Description</span>
|
|
2419
|
+
<span className='subtext'>For {displayFilterLegendValue(activeFilterValueForDescription)}</span>
|
|
2420
|
+
<DynamicDesc value={legend.descriptions[String(activeFilterValueForDescription)]} />
|
|
2421
|
+
</label>
|
|
2422
|
+
<label>
|
|
2423
|
+
<select
|
|
2424
|
+
value={String(activeFilterValueForDescription)}
|
|
2630
2425
|
onChange={event => {
|
|
2631
|
-
handleEditorChanges('
|
|
2426
|
+
handleEditorChanges('changeActiveFilterValue', event.target.value)
|
|
2632
2427
|
}}
|
|
2633
|
-
|
|
2634
|
-
|
|
2428
|
+
>
|
|
2429
|
+
{filterValueOptionList.map((arr, i) => {
|
|
2430
|
+
return (
|
|
2431
|
+
<option value={arr} key={i}>
|
|
2432
|
+
{displayFilterLegendValue(arr)}
|
|
2433
|
+
</option>
|
|
2434
|
+
)
|
|
2435
|
+
})}
|
|
2436
|
+
</select>
|
|
2635
2437
|
</label>
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
type='checkbox'
|
|
2640
|
-
checked={state.general.showDownloadButton}
|
|
2641
|
-
onChange={event => {
|
|
2642
|
-
handleEditorChanges('toggleDownloadButton', event.target.checked)
|
|
2643
|
-
}}
|
|
2644
|
-
/>
|
|
2645
|
-
<span className='edit-label'>Show Download CSV Link</span>
|
|
2646
|
-
</label>
|
|
2438
|
+
</React.Fragment>
|
|
2439
|
+
)}
|
|
2440
|
+
{filtersJSX.length > 0 && (
|
|
2647
2441
|
<label className='checkbox'>
|
|
2648
2442
|
<input
|
|
2649
2443
|
type='checkbox'
|
|
2650
|
-
checked={
|
|
2651
|
-
onChange={
|
|
2652
|
-
handleEditorChanges('
|
|
2444
|
+
checked={legend.dynamicDescription}
|
|
2445
|
+
onChange={() => {
|
|
2446
|
+
handleEditorChanges('dynamicDescription', filterValueOptionList[0])
|
|
2653
2447
|
}}
|
|
2654
2448
|
/>
|
|
2655
|
-
<span className='edit-label'>
|
|
2449
|
+
<span className='edit-label column-heading'>
|
|
2450
|
+
Dynamic Legend Description
|
|
2451
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2452
|
+
<Tooltip.Target>
|
|
2453
|
+
<Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
|
|
2454
|
+
</Tooltip.Target>
|
|
2455
|
+
<Tooltip.Content>
|
|
2456
|
+
<p>Check this option if the map has multiple filter controls and you want to specify a description for each filter selection.</p>
|
|
2457
|
+
</Tooltip.Content>
|
|
2458
|
+
</Tooltip>
|
|
2459
|
+
</span>
|
|
2656
2460
|
</label>
|
|
2461
|
+
)}
|
|
2462
|
+
{(filtersJSX.length > 0 || state.general.type === 'bubble' || state.general.geoType === 'us') && (
|
|
2657
2463
|
<label className='checkbox'>
|
|
2658
|
-
<input
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2464
|
+
<input type='checkbox' checked={legend.unified} onChange={event => handleEditorChanges('unifiedLegend', event.target.checked)} />
|
|
2465
|
+
<span className='edit-label column-heading'>
|
|
2466
|
+
Unified Legend
|
|
2467
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2468
|
+
<Tooltip.Target>
|
|
2469
|
+
<Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
|
|
2470
|
+
</Tooltip.Target>
|
|
2471
|
+
<Tooltip.Content>
|
|
2472
|
+
<p>
|
|
2473
|
+
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.
|
|
2474
|
+
</p>
|
|
2475
|
+
</Tooltip.Content>
|
|
2476
|
+
</Tooltip>
|
|
2477
|
+
</span>
|
|
2666
2478
|
</label>
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
handleEditorChanges('toggleDownloadPdfButton', event.target.checked)
|
|
2673
|
-
}}
|
|
2674
|
-
/>
|
|
2675
|
-
<span className='edit-label'>Enable Pdf Download</span>
|
|
2676
|
-
</label> */}
|
|
2677
|
-
</AccordionItemPanel>
|
|
2678
|
-
</AccordionItem>
|
|
2679
|
-
)}
|
|
2479
|
+
)}
|
|
2480
|
+
</AccordionItemPanel>
|
|
2481
|
+
</AccordionItem>
|
|
2482
|
+
)}
|
|
2483
|
+
{'navigation' !== state.general.type && (
|
|
2680
2484
|
<AccordionItem>
|
|
2681
2485
|
{' '}
|
|
2682
|
-
{/*
|
|
2486
|
+
{/* Filters */}
|
|
2683
2487
|
<AccordionItemHeading>
|
|
2684
|
-
<AccordionItemButton>
|
|
2488
|
+
<AccordionItemButton>Filters</AccordionItemButton>
|
|
2685
2489
|
</AccordionItemHeading>
|
|
2686
2490
|
<AccordionItemPanel>
|
|
2687
|
-
<
|
|
2688
|
-
|
|
2689
|
-
|
|
2491
|
+
{filtersJSX.length > 0 ? <MapFilters /> : <p style={{ textAlign: 'center' }}>There are currently no filters.</p>}
|
|
2492
|
+
<button
|
|
2493
|
+
className={'btn full-width'}
|
|
2494
|
+
onClick={event => {
|
|
2495
|
+
event.preventDefault()
|
|
2496
|
+
changeFilter(null, 'addNew')
|
|
2497
|
+
}}
|
|
2498
|
+
>
|
|
2499
|
+
Add Filter
|
|
2500
|
+
</button>
|
|
2501
|
+
</AccordionItemPanel>
|
|
2502
|
+
</AccordionItem>
|
|
2503
|
+
)}
|
|
2504
|
+
{'navigation' !== state.general.type && (
|
|
2505
|
+
<AccordionItem>
|
|
2506
|
+
{' '}
|
|
2507
|
+
{/* Data Table */}
|
|
2508
|
+
<AccordionItemHeading>
|
|
2509
|
+
<AccordionItemButton>Data Table</AccordionItemButton>
|
|
2510
|
+
</AccordionItemHeading>
|
|
2511
|
+
<AccordionItemPanel>
|
|
2512
|
+
<TextField
|
|
2513
|
+
value={table.label}
|
|
2514
|
+
updateField={updateField}
|
|
2515
|
+
section='table'
|
|
2516
|
+
fieldName='label'
|
|
2517
|
+
id='dataTableTitle'
|
|
2518
|
+
label='Data Table Title'
|
|
2519
|
+
placeholder='Data Table'
|
|
2520
|
+
tooltip={
|
|
2521
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2522
|
+
<Tooltip.Target>
|
|
2523
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2524
|
+
</Tooltip.Target>
|
|
2525
|
+
<Tooltip.Content>
|
|
2526
|
+
<p>Label is required for Data Table for 508 Compliance</p>
|
|
2527
|
+
</Tooltip.Content>
|
|
2528
|
+
</Tooltip>
|
|
2529
|
+
}
|
|
2530
|
+
/>
|
|
2531
|
+
<label className='checkbox'>
|
|
2532
|
+
<input
|
|
2533
|
+
type='checkbox'
|
|
2534
|
+
checked={state.table.wrapColumns}
|
|
2535
|
+
onChange={event => {
|
|
2536
|
+
setState({
|
|
2537
|
+
...state,
|
|
2538
|
+
table: {
|
|
2539
|
+
...state.table,
|
|
2540
|
+
wrapColumns: event.target.checked
|
|
2541
|
+
}
|
|
2542
|
+
})
|
|
2543
|
+
}}
|
|
2544
|
+
/>
|
|
2545
|
+
<span className='edit-label column-heading'>WRAP DATA TABLE COLUMNS</span>
|
|
2546
|
+
</label>
|
|
2547
|
+
<label className='checkbox'>
|
|
2548
|
+
<input
|
|
2549
|
+
type='checkbox'
|
|
2550
|
+
checked={state.table.forceDisplay !== undefined ? state.table.forceDisplay : !isDashboard}
|
|
2551
|
+
onChange={event => {
|
|
2552
|
+
handleEditorChanges('showDataTable', event.target.checked)
|
|
2553
|
+
}}
|
|
2554
|
+
/>
|
|
2555
|
+
<span className='edit-label column-heading'>
|
|
2556
|
+
Show Data Table
|
|
2690
2557
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
2691
2558
|
<Tooltip.Target>
|
|
2692
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2559
|
+
<Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
|
|
2693
2560
|
</Tooltip.Target>
|
|
2694
2561
|
<Tooltip.Content>
|
|
2695
|
-
<p>
|
|
2562
|
+
<p>Data tables are required for 508 compliance. When choosing to hide this data table, replace with your own version.</p>
|
|
2696
2563
|
</Tooltip.Content>
|
|
2697
2564
|
</Tooltip>
|
|
2698
2565
|
</span>
|
|
2699
|
-
<select
|
|
2700
|
-
value={state.tooltips.appearanceType}
|
|
2701
|
-
onChange={event => {
|
|
2702
|
-
handleEditorChanges('appearanceType', event.target.value)
|
|
2703
|
-
}}
|
|
2704
|
-
>
|
|
2705
|
-
<option value='hover'>Hover - Tooltip</option>
|
|
2706
|
-
<option value='click'>Click - Popover Modal</option>
|
|
2707
|
-
</select>
|
|
2708
2566
|
</label>
|
|
2709
|
-
|
|
2567
|
+
<TextField
|
|
2568
|
+
value={table.indexLabel || ''}
|
|
2569
|
+
updateField={updateField}
|
|
2570
|
+
section='table'
|
|
2571
|
+
fieldName='indexLabel'
|
|
2572
|
+
label='Index Column Header'
|
|
2573
|
+
placeholder='Location'
|
|
2574
|
+
tooltip={
|
|
2575
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2576
|
+
<Tooltip.Target>
|
|
2577
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2578
|
+
</Tooltip.Target>
|
|
2579
|
+
<Tooltip.Content>
|
|
2580
|
+
<p>To comply with 508 standards, if the first column in the data table has no header, enter a brief one here.</p>
|
|
2581
|
+
</Tooltip.Content>
|
|
2582
|
+
</Tooltip>
|
|
2583
|
+
}
|
|
2584
|
+
/>
|
|
2585
|
+
<TextField
|
|
2586
|
+
value={state.table.caption}
|
|
2587
|
+
updateField={updateField}
|
|
2588
|
+
section='table'
|
|
2589
|
+
fieldName='caption'
|
|
2590
|
+
label='Screen Reader Description'
|
|
2591
|
+
placeholder='Data Table'
|
|
2592
|
+
tooltip={
|
|
2593
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2594
|
+
<Tooltip.Target>
|
|
2595
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2596
|
+
</Tooltip.Target>
|
|
2597
|
+
<Tooltip.Content>
|
|
2598
|
+
<p>Enter a description of the data table to be read by screen readers.</p>
|
|
2599
|
+
</Tooltip.Content>
|
|
2600
|
+
</Tooltip>
|
|
2601
|
+
}
|
|
2602
|
+
type='textarea'
|
|
2603
|
+
/>
|
|
2710
2604
|
<label className='checkbox'>
|
|
2711
2605
|
<input
|
|
2712
2606
|
type='checkbox'
|
|
2713
|
-
checked={state.
|
|
2607
|
+
checked={state.table.limitHeight}
|
|
2714
2608
|
onChange={event => {
|
|
2715
|
-
handleEditorChanges('
|
|
2609
|
+
handleEditorChanges('limitDataTableHeight', event.target.checked)
|
|
2716
2610
|
}}
|
|
2717
2611
|
/>
|
|
2718
|
-
<span className='edit-label'>
|
|
2719
|
-
</label>
|
|
2720
|
-
</AccordionItemPanel>
|
|
2721
|
-
</AccordionItem>
|
|
2722
|
-
<AccordionItem>
|
|
2723
|
-
{' '}
|
|
2724
|
-
{/* Visual */}
|
|
2725
|
-
<AccordionItemHeading>
|
|
2726
|
-
<AccordionItemButton>Visual</AccordionItemButton>
|
|
2727
|
-
</AccordionItemHeading>
|
|
2728
|
-
<AccordionItemPanel>
|
|
2729
|
-
<label>
|
|
2730
|
-
<span className='edit-label'>Header Theme</span>
|
|
2731
|
-
<ul className='color-palette'>
|
|
2732
|
-
{headerColors.map(palette => {
|
|
2733
|
-
return (
|
|
2734
|
-
<li
|
|
2735
|
-
title={palette}
|
|
2736
|
-
key={palette}
|
|
2737
|
-
onClick={() => {
|
|
2738
|
-
handleEditorChanges('headerColor', palette)
|
|
2739
|
-
}}
|
|
2740
|
-
className={state.general.headerColor === palette ? 'selected ' + palette : palette}
|
|
2741
|
-
></li>
|
|
2742
|
-
)
|
|
2743
|
-
})}
|
|
2744
|
-
</ul>
|
|
2612
|
+
<span className='edit-label'>Limit Table Height</span>
|
|
2745
2613
|
</label>
|
|
2614
|
+
{state.table.limitHeight && <TextField value={table.height} updateField={updateField} section='table' fieldName='height' label='Data Table Height' placeholder='Height(px)' type='number' min='0' max='500' />}
|
|
2746
2615
|
<label className='checkbox'>
|
|
2747
2616
|
<input
|
|
2748
2617
|
type='checkbox'
|
|
2749
|
-
checked={state.
|
|
2618
|
+
checked={state.table.expanded || false}
|
|
2750
2619
|
onChange={event => {
|
|
2751
|
-
handleEditorChanges('
|
|
2620
|
+
handleEditorChanges('expandDataTable', event.target.checked)
|
|
2752
2621
|
}}
|
|
2753
2622
|
/>
|
|
2754
|
-
<span className='edit-label'>
|
|
2623
|
+
<span className='edit-label'>Map loads with data table expanded</span>
|
|
2755
2624
|
</label>
|
|
2756
|
-
|
|
2757
|
-
{'navigation' === state.general.type && (
|
|
2625
|
+
{isDashboard && (
|
|
2758
2626
|
<label className='checkbox'>
|
|
2759
2627
|
<input
|
|
2760
2628
|
type='checkbox'
|
|
2761
|
-
checked={state.
|
|
2629
|
+
checked={state.table.showDataTableLink}
|
|
2762
2630
|
onChange={event => {
|
|
2763
|
-
handleEditorChanges('
|
|
2631
|
+
handleEditorChanges('toggleDataTableLink', event.target.checked)
|
|
2764
2632
|
}}
|
|
2765
2633
|
/>
|
|
2766
|
-
<span className='edit-label'>
|
|
2634
|
+
<span className='edit-label'>Show Data Table Name & Link</span>
|
|
2767
2635
|
</label>
|
|
2768
2636
|
)}
|
|
2769
|
-
|
|
2770
|
-
<
|
|
2771
|
-
|
|
2772
|
-
|
|
2637
|
+
{isLoadedFromUrl && (
|
|
2638
|
+
<label className='checkbox'>
|
|
2639
|
+
<input
|
|
2640
|
+
type='checkbox'
|
|
2641
|
+
checked={state.table.showDownloadUrl}
|
|
2642
|
+
onChange={event => {
|
|
2643
|
+
handleEditorChanges('toggleDataUrl', event.target.checked)
|
|
2644
|
+
}}
|
|
2645
|
+
/>
|
|
2646
|
+
<span className='edit-label'>Show URL to Automatically Updated Data</span>
|
|
2647
|
+
</label>
|
|
2648
|
+
)}
|
|
2649
|
+
<label className='checkbox'>
|
|
2650
|
+
<input
|
|
2651
|
+
type='checkbox'
|
|
2652
|
+
checked={state.general.showFullGeoNameInCSV}
|
|
2773
2653
|
onChange={event => {
|
|
2774
|
-
handleEditorChanges('
|
|
2654
|
+
handleEditorChanges('toggleShowFullGeoNameInCSV', event.target.checked)
|
|
2775
2655
|
}}
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
<option value='sameAsBackground'>White</option>
|
|
2779
|
-
</select>
|
|
2656
|
+
/>
|
|
2657
|
+
<span className='edit-label'>Include Full Geo Name in CSV Download</span>
|
|
2780
2658
|
</label>
|
|
2781
|
-
<label>
|
|
2782
|
-
<
|
|
2659
|
+
<label className='checkbox'>
|
|
2660
|
+
<input
|
|
2661
|
+
type='checkbox'
|
|
2662
|
+
checked={state.general.showDownloadImgButton}
|
|
2663
|
+
onChange={event => {
|
|
2664
|
+
handleEditorChanges('toggleDownloadImgButton', event.target.checked)
|
|
2665
|
+
}}
|
|
2666
|
+
/>
|
|
2667
|
+
<span className='edit-label'>Enable Image Download</span>
|
|
2783
2668
|
</label>
|
|
2784
|
-
{/* <
|
|
2785
|
-
|
|
2786
|
-
|
|
2669
|
+
{/* <label className='checkbox'>
|
|
2670
|
+
<input
|
|
2671
|
+
type='checkbox'
|
|
2672
|
+
checked={state.general.showDownloadPdfButton}
|
|
2673
|
+
onChange={event => {
|
|
2674
|
+
handleEditorChanges('toggleDownloadPdfButton', event.target.checked)
|
|
2675
|
+
}}
|
|
2676
|
+
/>
|
|
2677
|
+
<span className='edit-label'>Enable Pdf Download</span>
|
|
2678
|
+
</label> */}
|
|
2679
|
+
</AccordionItemPanel>
|
|
2680
|
+
</AccordionItem>
|
|
2681
|
+
)}
|
|
2682
|
+
<AccordionItem>
|
|
2683
|
+
{' '}
|
|
2684
|
+
{/* Tooltips */}
|
|
2685
|
+
<AccordionItemHeading>
|
|
2686
|
+
<AccordionItemButton>Interactivity</AccordionItemButton>
|
|
2687
|
+
</AccordionItemHeading>
|
|
2688
|
+
<AccordionItemPanel>
|
|
2689
|
+
<label>
|
|
2690
|
+
<span className='edit-label'>
|
|
2691
|
+
Detail displays on{' '}
|
|
2692
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2693
|
+
<Tooltip.Target>
|
|
2694
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2695
|
+
</Tooltip.Target>
|
|
2696
|
+
<Tooltip.Content>
|
|
2697
|
+
<p>At mobile sizes, information always appears in a popover modal when a user taps on an item.</p>
|
|
2698
|
+
</Tooltip.Content>
|
|
2699
|
+
</Tooltip>
|
|
2700
|
+
</span>
|
|
2701
|
+
<select
|
|
2702
|
+
value={state.tooltips.appearanceType}
|
|
2703
|
+
onChange={event => {
|
|
2704
|
+
handleEditorChanges('appearanceType', event.target.value)
|
|
2705
|
+
}}
|
|
2706
|
+
>
|
|
2707
|
+
<option value='hover'>Hover - Tooltip</option>
|
|
2708
|
+
<option value='click'>Click - Popover Modal</option>
|
|
2709
|
+
</select>
|
|
2710
|
+
</label>
|
|
2711
|
+
{'click' === state.tooltips.appearanceType && <TextField value={tooltips.linkLabel} section='tooltips' fieldName='linkLabel' label='Tooltips Link Label' updateField={updateField} />}
|
|
2712
|
+
<label className='checkbox'>
|
|
2713
|
+
<input
|
|
2714
|
+
type='checkbox'
|
|
2715
|
+
checked={state.tooltips.capitalizeLabels}
|
|
2716
|
+
onChange={event => {
|
|
2717
|
+
handleEditorChanges('capitalizeLabels', event.target.checked)
|
|
2718
|
+
}}
|
|
2719
|
+
/>
|
|
2720
|
+
<span className='edit-label'>Capitalize text inside tooltip</span>
|
|
2721
|
+
</label>
|
|
2722
|
+
</AccordionItemPanel>
|
|
2723
|
+
</AccordionItem>
|
|
2724
|
+
<AccordionItem>
|
|
2725
|
+
{' '}
|
|
2726
|
+
{/* Visual */}
|
|
2727
|
+
<AccordionItemHeading>
|
|
2728
|
+
<AccordionItemButton>Visual</AccordionItemButton>
|
|
2729
|
+
</AccordionItemHeading>
|
|
2730
|
+
<AccordionItemPanel>
|
|
2731
|
+
<label>
|
|
2732
|
+
<span className='edit-label'>Header Theme</span>
|
|
2787
2733
|
<ul className='color-palette'>
|
|
2788
|
-
{
|
|
2789
|
-
const colorOne = {
|
|
2790
|
-
backgroundColor: colorPalettes[palette][2]
|
|
2791
|
-
}
|
|
2792
|
-
|
|
2793
|
-
const colorTwo = {
|
|
2794
|
-
backgroundColor: colorPalettes[palette][4]
|
|
2795
|
-
}
|
|
2796
|
-
|
|
2797
|
-
const colorThree = {
|
|
2798
|
-
backgroundColor: colorPalettes[palette][6]
|
|
2799
|
-
}
|
|
2800
|
-
|
|
2734
|
+
{headerColors.map(palette => {
|
|
2801
2735
|
return (
|
|
2802
2736
|
<li
|
|
2803
2737
|
title={palette}
|
|
2804
2738
|
key={palette}
|
|
2805
2739
|
onClick={() => {
|
|
2806
|
-
handleEditorChanges('
|
|
2740
|
+
handleEditorChanges('headerColor', palette)
|
|
2807
2741
|
}}
|
|
2808
|
-
className={state.
|
|
2809
|
-
>
|
|
2810
|
-
<span style={colorOne}></span>
|
|
2811
|
-
<span style={colorTwo}></span>
|
|
2812
|
-
<span style={colorThree}></span>
|
|
2813
|
-
</li>
|
|
2742
|
+
className={state.general.headerColor === palette ? 'selected ' + palette : palette}
|
|
2743
|
+
></li>
|
|
2814
2744
|
)
|
|
2815
2745
|
})}
|
|
2816
2746
|
</ul>
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2747
|
+
</label>
|
|
2748
|
+
<label className='checkbox'>
|
|
2749
|
+
<input
|
|
2750
|
+
type='checkbox'
|
|
2751
|
+
checked={state.general.showTitle || false}
|
|
2752
|
+
onChange={event => {
|
|
2753
|
+
handleEditorChanges('showTitle', event.target.checked)
|
|
2754
|
+
}}
|
|
2755
|
+
/>
|
|
2756
|
+
<span className='edit-label'>Show Title</span>
|
|
2757
|
+
</label>
|
|
2823
2758
|
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2759
|
+
{'navigation' === state.general.type && (
|
|
2760
|
+
<label className='checkbox'>
|
|
2761
|
+
<input
|
|
2762
|
+
type='checkbox'
|
|
2763
|
+
checked={state.general.fullBorder || false}
|
|
2764
|
+
onChange={event => {
|
|
2765
|
+
handleEditorChanges('fullBorder', event.target.checked)
|
|
2766
|
+
}}
|
|
2767
|
+
/>
|
|
2768
|
+
<span className='edit-label'>Add border around map</span>
|
|
2769
|
+
</label>
|
|
2770
|
+
)}
|
|
2771
|
+
<label>
|
|
2772
|
+
<span className='edit-label'>Geo Border Color</span>
|
|
2773
|
+
<select
|
|
2774
|
+
value={state.general.geoBorderColor || false}
|
|
2775
|
+
onChange={event => {
|
|
2776
|
+
handleEditorChanges('geoBorderColor', event.target.value)
|
|
2777
|
+
}}
|
|
2778
|
+
>
|
|
2779
|
+
<option value='darkGray'>Dark Gray (Default)</option>
|
|
2780
|
+
<option value='sameAsBackground'>White</option>
|
|
2781
|
+
</select>
|
|
2782
|
+
</label>
|
|
2783
|
+
<label>
|
|
2784
|
+
<span className='edit-label'>Map Color Palette</span>
|
|
2785
|
+
</label>
|
|
2786
|
+
{/* <InputCheckbox section="general" subsection="palette" fieldName='isReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} /> */}
|
|
2787
|
+
<InputToggle type='3d' section='general' subsection='palette' fieldName='isReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={state.general.palette.isReversed} />
|
|
2788
|
+
<span>Sequential</span>
|
|
2789
|
+
<ul className='color-palette'>
|
|
2790
|
+
{sequential.map(palette => {
|
|
2791
|
+
const colorOne = {
|
|
2792
|
+
backgroundColor: colorPalettes[palette][2]
|
|
2793
|
+
}
|
|
2827
2794
|
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2795
|
+
const colorTwo = {
|
|
2796
|
+
backgroundColor: colorPalettes[palette][4]
|
|
2797
|
+
}
|
|
2831
2798
|
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
}
|
|
2836
|
-
return (
|
|
2837
|
-
<li
|
|
2838
|
-
title={palette}
|
|
2839
|
-
key={palette}
|
|
2840
|
-
onClick={() => {
|
|
2841
|
-
handleEditorChanges('color', palette)
|
|
2842
|
-
}}
|
|
2843
|
-
className={state.color === palette ? 'selected' : ''}
|
|
2844
|
-
>
|
|
2845
|
-
<span style={colorOne}></span>
|
|
2846
|
-
<span style={colorTwo}></span>
|
|
2847
|
-
<span style={colorThree}></span>
|
|
2848
|
-
</li>
|
|
2849
|
-
)
|
|
2850
|
-
})}
|
|
2851
|
-
</ul>
|
|
2852
|
-
{state.visual.cityStyle === 'circle' && (
|
|
2853
|
-
<label>
|
|
2854
|
-
Geocode Settings
|
|
2855
|
-
<TextField type='number' value={state.visual.geoCodeCircleSize} section='visual' max='10' fieldName='geoCodeCircleSize' label='Geocode Circle Size' updateField={updateField} />
|
|
2856
|
-
</label>
|
|
2857
|
-
)}
|
|
2799
|
+
const colorThree = {
|
|
2800
|
+
backgroundColor: colorPalettes[palette][6]
|
|
2801
|
+
}
|
|
2858
2802
|
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
{(state.general.geoType === 'world' || (state.general.geoType === 'us' && state.general.type === 'bubble')) && (
|
|
2866
|
-
<label className='checkbox'>
|
|
2867
|
-
<input
|
|
2868
|
-
type='checkbox'
|
|
2869
|
-
checked={state.visual.showBubbleZeros}
|
|
2870
|
-
onChange={event => {
|
|
2871
|
-
handleEditorChanges('showBubbleZeros', event.target.checked)
|
|
2872
|
-
}}
|
|
2873
|
-
/>
|
|
2874
|
-
<span className='edit-label'>Show Data with Zero's on Bubble Map</span>
|
|
2875
|
-
</label>
|
|
2876
|
-
)}
|
|
2877
|
-
{state.general.geoType === 'world' && (
|
|
2878
|
-
<label className='checkbox'>
|
|
2879
|
-
<input
|
|
2880
|
-
type='checkbox'
|
|
2881
|
-
checked={state.general.allowMapZoom}
|
|
2882
|
-
onChange={event => {
|
|
2883
|
-
handleEditorChanges('allowMapZoom', event.target.checked)
|
|
2803
|
+
return (
|
|
2804
|
+
<li
|
|
2805
|
+
title={palette}
|
|
2806
|
+
key={palette}
|
|
2807
|
+
onClick={() => {
|
|
2808
|
+
handleEditorChanges('color', palette)
|
|
2884
2809
|
}}
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2810
|
+
className={state.color === palette ? 'selected' : ''}
|
|
2811
|
+
>
|
|
2812
|
+
<span style={colorOne}></span>
|
|
2813
|
+
<span style={colorTwo}></span>
|
|
2814
|
+
<span style={colorThree}></span>
|
|
2815
|
+
</li>
|
|
2816
|
+
)
|
|
2817
|
+
})}
|
|
2818
|
+
</ul>
|
|
2819
|
+
<span>Non-Sequential</span>
|
|
2820
|
+
<ul className='color-palette'>
|
|
2821
|
+
{nonSequential.map(palette => {
|
|
2822
|
+
const colorOne = {
|
|
2823
|
+
backgroundColor: colorPalettes[palette][2]
|
|
2824
|
+
}
|
|
2825
|
+
|
|
2826
|
+
const colorTwo = {
|
|
2827
|
+
backgroundColor: colorPalettes[palette][4]
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
const colorThree = {
|
|
2831
|
+
backgroundColor: colorPalettes[palette][6]
|
|
2832
|
+
}
|
|
2833
|
+
|
|
2834
|
+
// hide palettes with too few colors for region maps
|
|
2835
|
+
if (colorPalettes[palette].length <= 8 && state.general.geoType === 'us-region') {
|
|
2836
|
+
return ''
|
|
2837
|
+
}
|
|
2838
|
+
return (
|
|
2839
|
+
<li
|
|
2840
|
+
title={palette}
|
|
2841
|
+
key={palette}
|
|
2842
|
+
onClick={() => {
|
|
2843
|
+
handleEditorChanges('color', palette)
|
|
2896
2844
|
}}
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2845
|
+
className={state.color === palette ? 'selected' : ''}
|
|
2846
|
+
>
|
|
2847
|
+
<span style={colorOne}></span>
|
|
2848
|
+
<span style={colorTwo}></span>
|
|
2849
|
+
<span style={colorThree}></span>
|
|
2850
|
+
</li>
|
|
2851
|
+
)
|
|
2852
|
+
})}
|
|
2853
|
+
</ul>
|
|
2854
|
+
<label>
|
|
2855
|
+
Geocode Settings
|
|
2856
|
+
<TextField type='number' value={state.visual.geoCodeCircleSize} section='visual' max='10' fieldName='geoCodeCircleSize' label='Geocode Circle Size' updateField={updateField} />
|
|
2857
|
+
</label>
|
|
2858
|
+
|
|
2859
|
+
{state.general.type === 'bubble' && (
|
|
2860
|
+
<>
|
|
2861
|
+
<TextField type='number' value={state.visual.minBubbleSize} section='visual' fieldName='minBubbleSize' label='Minimum Bubble Size' updateField={updateField} />
|
|
2862
|
+
<TextField type='number' value={state.visual.maxBubbleSize} section='visual' fieldName='maxBubbleSize' label='Maximum Bubble Size' updateField={updateField} />
|
|
2863
|
+
</>
|
|
2864
|
+
)}
|
|
2865
|
+
{(state.general.geoType === 'world' || (state.general.geoType === 'us' && state.general.type === 'bubble')) && (
|
|
2866
|
+
<label className='checkbox'>
|
|
2867
|
+
<input
|
|
2868
|
+
type='checkbox'
|
|
2869
|
+
checked={state.visual.showBubbleZeros}
|
|
2870
|
+
onChange={event => {
|
|
2871
|
+
handleEditorChanges('showBubbleZeros', event.target.checked)
|
|
2872
|
+
}}
|
|
2873
|
+
/>
|
|
2874
|
+
<span className='edit-label'>Show Data with Zero's on Bubble Map</span>
|
|
2875
|
+
</label>
|
|
2876
|
+
)}
|
|
2877
|
+
{state.general.geoType === 'world' && (
|
|
2878
|
+
<label className='checkbox'>
|
|
2879
|
+
<input
|
|
2880
|
+
type='checkbox'
|
|
2881
|
+
checked={state.general.allowMapZoom}
|
|
2882
|
+
onChange={event => {
|
|
2883
|
+
handleEditorChanges('allowMapZoom', event.target.checked)
|
|
2884
|
+
}}
|
|
2885
|
+
/>
|
|
2886
|
+
<span className='edit-label'>Allow Map Zooming</span>
|
|
2887
|
+
</label>
|
|
2888
|
+
)}
|
|
2889
|
+
{state.general.type === 'bubble' && (
|
|
2890
|
+
<label className='checkbox'>
|
|
2891
|
+
<input
|
|
2892
|
+
type='checkbox'
|
|
2893
|
+
checked={state.visual.extraBubbleBorder}
|
|
2894
|
+
onChange={event => {
|
|
2895
|
+
handleEditorChanges('toggleExtraBubbleBorder', event.target.checked)
|
|
2896
|
+
}}
|
|
2897
|
+
/>
|
|
2898
|
+
<span className='edit-label'>Bubble Map has extra border</span>
|
|
2899
|
+
</label>
|
|
2900
|
+
)}
|
|
2901
|
+
{(state.general.geoType === 'us' || state.general.geoType === 'us-county' || state.general.geoType === 'world') && (
|
|
2902
|
+
<>
|
|
2902
2903
|
<label>
|
|
2903
|
-
<span className='edit-label'>City Style</span>
|
|
2904
|
+
<span className='edit-label'>Default City Style</span>
|
|
2904
2905
|
<select
|
|
2905
2906
|
value={state.visual.cityStyle || false}
|
|
2906
2907
|
onChange={event => {
|
|
@@ -2909,65 +2910,154 @@ const EditorPanel = props => {
|
|
|
2909
2910
|
>
|
|
2910
2911
|
<option value='circle'>Circle</option>
|
|
2911
2912
|
<option value='pin'>Pin</option>
|
|
2913
|
+
<option value='square'>Square</option>
|
|
2914
|
+
<option value='triangle'>Triangle</option>
|
|
2915
|
+
<option value='diamond'>Diamond</option>
|
|
2916
|
+
<option value='star'>Star</option>
|
|
2912
2917
|
</select>
|
|
2913
2918
|
</label>
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2919
|
+
<TextField
|
|
2920
|
+
value={state.visual.cityStyleLabel}
|
|
2921
|
+
section='visual'
|
|
2922
|
+
fieldName='cityStyleLabel'
|
|
2923
|
+
label='Label (Optional) '
|
|
2924
|
+
updateField={updateField}
|
|
2925
|
+
tooltip={
|
|
2926
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2927
|
+
<Tooltip.Target>
|
|
2928
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2929
|
+
</Tooltip.Target>
|
|
2930
|
+
<Tooltip.Content>
|
|
2931
|
+
<p>When a label is provided, the default city style will appear in the legend.</p>
|
|
2932
|
+
</Tooltip.Content>
|
|
2933
|
+
</Tooltip>
|
|
2934
|
+
}
|
|
2935
|
+
/>
|
|
2936
|
+
</>
|
|
2937
|
+
)}
|
|
2938
|
+
{/* <AdditionalCityStyles /> */}
|
|
2939
|
+
<>
|
|
2940
|
+
{state.visual.additionalCityStyles.length > 0 &&
|
|
2941
|
+
state.visual.additionalCityStyles.map(({ label, column, value, shape }, i) => {
|
|
2942
|
+
return (
|
|
2943
|
+
<div className='edit-block' key={`additional-city-style-${i}`}>
|
|
2944
|
+
<button
|
|
2945
|
+
className='remove-column'
|
|
2946
|
+
onClick={e => {
|
|
2947
|
+
e.preventDefault()
|
|
2948
|
+
editCityStyles('remove', i, '', '')
|
|
2949
|
+
}}
|
|
2950
|
+
>
|
|
2951
|
+
Remove
|
|
2952
|
+
</button>
|
|
2953
|
+
<p>City Style {i + 1}</p>
|
|
2954
|
+
<label>
|
|
2955
|
+
<span className='edit-label column-heading'>Column with configuration value</span>
|
|
2956
|
+
<select
|
|
2957
|
+
value={column}
|
|
2958
|
+
onChange={e => {
|
|
2959
|
+
editCityStyles('update', i, 'column', e.target.value)
|
|
2960
|
+
}}
|
|
2961
|
+
>
|
|
2962
|
+
{columnsOptions}
|
|
2963
|
+
</select>
|
|
2964
|
+
</label>
|
|
2965
|
+
<label>
|
|
2966
|
+
<span className='edit-label column-heading'>Value to Trigger</span>
|
|
2967
|
+
<input
|
|
2968
|
+
type='text'
|
|
2969
|
+
value={value}
|
|
2970
|
+
onChange={e => {
|
|
2971
|
+
editCityStyles('update', i, 'value', e.target.value)
|
|
2972
|
+
}}
|
|
2973
|
+
></input>
|
|
2974
|
+
</label>
|
|
2975
|
+
<label>
|
|
2976
|
+
<span className='edit-label column-heading'>Shape</span>
|
|
2977
|
+
<select
|
|
2978
|
+
value={shape}
|
|
2979
|
+
onChange={e => {
|
|
2980
|
+
editCityStyles('update', i, 'shape', e.target.value)
|
|
2981
|
+
}}
|
|
2982
|
+
>
|
|
2983
|
+
{getCityStyleOptions('value')}
|
|
2984
|
+
</select>
|
|
2985
|
+
</label>
|
|
2986
|
+
<label>
|
|
2987
|
+
<span className='edit-label column-heading'>Label</span>
|
|
2988
|
+
<input
|
|
2989
|
+
key={i}
|
|
2990
|
+
type='text'
|
|
2991
|
+
value={label}
|
|
2992
|
+
onChange={e => {
|
|
2993
|
+
editCityStyles('update', i, 'label', e.target.value)
|
|
2994
|
+
}}
|
|
2995
|
+
/>
|
|
2996
|
+
</label>
|
|
2997
|
+
</div>
|
|
2998
|
+
)
|
|
2999
|
+
})}
|
|
2926
3000
|
|
|
2927
|
-
{
|
|
2928
|
-
|
|
2929
|
-
<>
|
|
2930
|
-
<Accordion allowZeroExpanded>
|
|
2931
|
-
<AccordionItem className='series-item map-layers-list'>
|
|
2932
|
-
<AccordionItemHeading className='series-item__title map-layers-list--title'>
|
|
2933
|
-
<AccordionItemButton>{`Layer ${index + 1}: ${layer.name}`}</AccordionItemButton>
|
|
2934
|
-
</AccordionItemHeading>
|
|
2935
|
-
<AccordionItemPanel>
|
|
2936
|
-
<div className='map-layers-panel'>
|
|
2937
|
-
<label htmlFor='layerName'>Layer Name:</label>
|
|
2938
|
-
<input type='text' name='layerName' value={layer.name} onChange={e => handleMapLayer(e, index, 'name')} />
|
|
2939
|
-
<label htmlFor='layerFilename'>File:</label>
|
|
2940
|
-
<input type='text' name='layerFilename' value={layer.url} onChange={e => handleMapLayer(e, index, 'url')} />
|
|
2941
|
-
<label htmlFor='layerNamespace'>TOPOJSON Namespace:</label>
|
|
2942
|
-
<input type='text' name='layerNamespace' value={layer.namespace} onChange={e => handleMapLayer(e, index, 'namespace')} />
|
|
2943
|
-
<label htmlFor='layerFill'>Fill Color:</label>
|
|
2944
|
-
<input type='text' name='layerFill' value={layer.fill} onChange={e => handleMapLayer(e, index, 'fill')} />
|
|
2945
|
-
<label htmlFor='layerFill'>Fill Opacity (%):</label>
|
|
2946
|
-
<input type='number' min={0} max={100} name='layerFill' value={layer.fillOpacity ? layer.fillOpacity * 100 : ''} onChange={e => handleMapLayer(e, index, 'fillOpacity')} />
|
|
2947
|
-
<label htmlFor='layerStroke'>Stroke Color:</label>
|
|
2948
|
-
<input type='text' name='layerStroke' value={layer.stroke} onChange={e => handleMapLayer(e, index, 'stroke')} />
|
|
2949
|
-
<label htmlFor='layerStroke'>Stroke Width:</label>
|
|
2950
|
-
<input type='number' min={0} max={5} name='layerStrokeWidth' value={layer.strokeWidth} onChange={e => handleMapLayer(e, index, 'strokeWidth')} />
|
|
2951
|
-
<label htmlFor='layerTooltip'>Tooltip:</label>
|
|
2952
|
-
<textarea name='layerTooltip' value={layer.tooltip} onChange={e => handleMapLayer(e, index, 'tooltip')}></textarea>
|
|
2953
|
-
<button onClick={e => handleRemoveLayer(e, index)}>Remove Layer</button>
|
|
2954
|
-
</div>
|
|
2955
|
-
</AccordionItemPanel>
|
|
2956
|
-
</AccordionItem>
|
|
2957
|
-
</Accordion>
|
|
2958
|
-
</>
|
|
2959
|
-
)
|
|
2960
|
-
})}
|
|
2961
|
-
<button className={'btn full-width'} onClick={handleAddLayer}>
|
|
2962
|
-
Add Map Layer
|
|
3001
|
+
<button type='button' onClick={() => editCityStyles('add', 0, '', '')} className='btn full-width'>
|
|
3002
|
+
Add city style
|
|
2963
3003
|
</button>
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
3004
|
+
</>
|
|
3005
|
+
<label htmlFor='opacity'>
|
|
3006
|
+
<TextField type='number' min={0} max={100} value={state.tooltips.opacity ? state.tooltips.opacity : 100} section='tooltips' fieldName='opacity' label='Tooltip Opacity (%)' updateField={updateField} />
|
|
3007
|
+
</label>
|
|
3008
|
+
</AccordionItemPanel>
|
|
3009
|
+
</AccordionItem>
|
|
3010
|
+
<AccordionItem>
|
|
3011
|
+
<AccordionItemHeading>
|
|
3012
|
+
<AccordionItemButton>Custom Map Layers</AccordionItemButton>
|
|
3013
|
+
</AccordionItemHeading>
|
|
3014
|
+
<AccordionItemPanel>
|
|
3015
|
+
{state.map.layers.length === 0 && <p>There are currently no layers.</p>}
|
|
3016
|
+
|
|
3017
|
+
{state.map.layers.map((layer, index) => {
|
|
3018
|
+
return (
|
|
3019
|
+
<>
|
|
3020
|
+
<Accordion allowZeroExpanded>
|
|
3021
|
+
<AccordionItem className='series-item map-layers-list'>
|
|
3022
|
+
<AccordionItemHeading className='series-item__title map-layers-list--title'>
|
|
3023
|
+
<AccordionItemButton>{`Layer ${index + 1}: ${layer.name}`}</AccordionItemButton>
|
|
3024
|
+
</AccordionItemHeading>
|
|
3025
|
+
<AccordionItemPanel>
|
|
3026
|
+
<div className='map-layers-panel'>
|
|
3027
|
+
<label htmlFor='layerName'>Layer Name:</label>
|
|
3028
|
+
<input type='text' name='layerName' value={layer.name} onChange={e => handleMapLayer(e, index, 'name')} />
|
|
3029
|
+
<label htmlFor='layerFilename'>File:</label>
|
|
3030
|
+
<input type='text' name='layerFilename' value={layer.url} onChange={e => handleMapLayer(e, index, 'url')} />
|
|
3031
|
+
<label htmlFor='layerNamespace'>TOPOJSON Namespace:</label>
|
|
3032
|
+
<input type='text' name='layerNamespace' value={layer.namespace} onChange={e => handleMapLayer(e, index, 'namespace')} />
|
|
3033
|
+
<label htmlFor='layerFill'>Fill Color:</label>
|
|
3034
|
+
<input type='text' name='layerFill' value={layer.fill} onChange={e => handleMapLayer(e, index, 'fill')} />
|
|
3035
|
+
<label htmlFor='layerFill'>Fill Opacity (%):</label>
|
|
3036
|
+
<input type='number' min={0} max={100} name='layerFill' value={layer.fillOpacity ? layer.fillOpacity * 100 : ''} onChange={e => handleMapLayer(e, index, 'fillOpacity')} />
|
|
3037
|
+
<label htmlFor='layerStroke'>Stroke Color:</label>
|
|
3038
|
+
<input type='text' name='layerStroke' value={layer.stroke} onChange={e => handleMapLayer(e, index, 'stroke')} />
|
|
3039
|
+
<label htmlFor='layerStroke'>Stroke Width:</label>
|
|
3040
|
+
<input type='number' min={0} max={5} name='layerStrokeWidth' value={layer.strokeWidth} onChange={e => handleMapLayer(e, index, 'strokeWidth')} />
|
|
3041
|
+
<label htmlFor='layerTooltip'>Tooltip:</label>
|
|
3042
|
+
<textarea name='layerTooltip' value={layer.tooltip} onChange={e => handleMapLayer(e, index, 'tooltip')}></textarea>
|
|
3043
|
+
<button onClick={e => handleRemoveLayer(e, index)}>Remove Layer</button>
|
|
3044
|
+
</div>
|
|
3045
|
+
</AccordionItemPanel>
|
|
3046
|
+
</AccordionItem>
|
|
3047
|
+
</Accordion>
|
|
3048
|
+
</>
|
|
3049
|
+
)
|
|
3050
|
+
})}
|
|
3051
|
+
<button className={'btn full-width'} onClick={handleAddLayer}>
|
|
3052
|
+
Add Map Layer
|
|
3053
|
+
</button>
|
|
3054
|
+
<p className='layer-purpose-details'>Context should be added to your visualization or associated page to describe the significance of layers that are added to maps.</p>
|
|
3055
|
+
</AccordionItemPanel>
|
|
3056
|
+
</AccordionItem>
|
|
3057
|
+
{state.general.geoType === 'us' && <Panels.PatternSettings name='Pattern Settings' />}
|
|
3058
|
+
</Accordion>
|
|
3059
|
+
<AdvancedEditor loadConfig={loadConfig} state={state} convertStateToConfig={convertStateToConfig} />
|
|
3060
|
+
</Layout.Sidebar>
|
|
2971
3061
|
</ErrorBoundary>
|
|
2972
3062
|
)
|
|
2973
3063
|
}
|