@cdc/map 4.23.5 → 4.23.7
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 +23051 -22172
- package/examples/custom-map-layers.json +10 -2
- package/examples/example-city-state.json +36 -0
- package/examples/new-cities.json +656 -0
- package/examples/testing-layer-2.json +61 -1
- package/examples/testing-layer.json +1 -5
- package/index.html +8 -7
- package/package.json +3 -3
- package/src/CdcMap.jsx +61 -87
- package/src/components/CountyMap.jsx +25 -14
- package/src/components/DataTable.jsx +6 -6
- package/src/components/EditorPanel.jsx +1272 -1232
- package/src/components/UsaMap.jsx +7 -1
- package/src/data/initial-state.js +3 -1
- package/src/data/supported-cities.csv +165 -0
- package/src/data/supported-geos.js +14 -0
- package/src/hooks/useMapLayers.jsx +11 -75
- package/src/hooks/useTooltip.js +135 -0
- package/src/scss/editor-panel.scss +1 -7
- package/src/scss/main.scss +1 -1
- package/src/scss/map.scss +202 -203
- package/LICENSE +0 -201
- package/src/scss/tooltips.scss +0 -36
|
@@ -89,12 +89,9 @@ const EditorPanel = props => {
|
|
|
89
89
|
const {
|
|
90
90
|
// prettier-ignore
|
|
91
91
|
MapLayerHandlers: {
|
|
92
|
+
handleMapLayer,
|
|
92
93
|
handleAddLayer,
|
|
93
|
-
|
|
94
|
-
handleMapLayerUrl,
|
|
95
|
-
handleRemoveLayer,
|
|
96
|
-
handleMapLayerNamespace,
|
|
97
|
-
handleMapLayerTooltip
|
|
94
|
+
handleRemoveLayer
|
|
98
95
|
}
|
|
99
96
|
} = useMapLayers(state, setState, false, true)
|
|
100
97
|
|
|
@@ -428,6 +425,16 @@ const EditorPanel = props => {
|
|
|
428
425
|
}
|
|
429
426
|
})
|
|
430
427
|
break
|
|
428
|
+
case 'toggleShowFullGeoNameInCSV':
|
|
429
|
+
setState({
|
|
430
|
+
...state,
|
|
431
|
+
table: {
|
|
432
|
+
// setting both bc DataTable new core needs it here
|
|
433
|
+
...state.table,
|
|
434
|
+
showFullGeoNameInCSV: !state.table.showFullGeoNameInCSV
|
|
435
|
+
}
|
|
436
|
+
})
|
|
437
|
+
break
|
|
431
438
|
case 'toggleDownloadImgButton':
|
|
432
439
|
setState({
|
|
433
440
|
...state,
|
|
@@ -883,6 +890,10 @@ const EditorPanel = props => {
|
|
|
883
890
|
newFilters[idx] = { ...newFilters[idx] }
|
|
884
891
|
newFilters[idx].filterStyle = value
|
|
885
892
|
break
|
|
893
|
+
case 'showDropdown':
|
|
894
|
+
newFilters[idx] = { ...newFilters[idx] }
|
|
895
|
+
newFilters[idx].showDropdown = value
|
|
896
|
+
break
|
|
886
897
|
case 'columnName':
|
|
887
898
|
newFilters[idx] = { ...newFilters[idx] }
|
|
888
899
|
newFilters[idx].columnName = value
|
|
@@ -1231,6 +1242,17 @@ const EditorPanel = props => {
|
|
|
1231
1242
|
</select>
|
|
1232
1243
|
</label>
|
|
1233
1244
|
|
|
1245
|
+
<label>
|
|
1246
|
+
<span className='edit-showDropdown column-heading'>Show Filter Input</span>
|
|
1247
|
+
<input
|
|
1248
|
+
type='checkbox'
|
|
1249
|
+
checked={filter.showDropdown === undefined ? true : filter.showDropdown}
|
|
1250
|
+
onChange={e => {
|
|
1251
|
+
changeFilter(index, 'showDropdown', e.target.checked)
|
|
1252
|
+
}}
|
|
1253
|
+
/>
|
|
1254
|
+
</label>
|
|
1255
|
+
|
|
1234
1256
|
<label>
|
|
1235
1257
|
<span className='edit-filterOrder column-heading'>Filter Style</span>
|
|
1236
1258
|
<select
|
|
@@ -1404,310 +1426,361 @@ const EditorPanel = props => {
|
|
|
1404
1426
|
<ReactTooltip multiline={true} />
|
|
1405
1427
|
<span className='base-label'>Configure Map</span>
|
|
1406
1428
|
<section className='form-container'>
|
|
1407
|
-
<
|
|
1408
|
-
<
|
|
1409
|
-
|
|
1410
|
-
|
|
1429
|
+
<Accordion allowZeroExpanded={true}>
|
|
1430
|
+
<AccordionItem>
|
|
1431
|
+
{' '}
|
|
1432
|
+
{/* Type */}
|
|
1433
|
+
<AccordionItemHeading>
|
|
1434
|
+
<AccordionItemButton>Type</AccordionItemButton>
|
|
1435
|
+
</AccordionItemHeading>
|
|
1436
|
+
<AccordionItemPanel>
|
|
1437
|
+
{/* Geography */}
|
|
1438
|
+
<label>
|
|
1439
|
+
<span className='edit-label column-heading'>
|
|
1440
|
+
<span>Geography</span>
|
|
1441
|
+
</span>
|
|
1442
|
+
<ul className='geo-buttons'>
|
|
1443
|
+
<button
|
|
1444
|
+
className={state.general.geoType === 'us' || state.general.geoType === 'us-county' ? 'active' : ''}
|
|
1445
|
+
onClick={e => {
|
|
1446
|
+
e.preventDefault()
|
|
1447
|
+
handleEditorChanges('geoType', 'us')
|
|
1448
|
+
}}
|
|
1449
|
+
>
|
|
1450
|
+
<UsaGraphic />
|
|
1451
|
+
<span>United States</span>
|
|
1452
|
+
</button>
|
|
1453
|
+
<button
|
|
1454
|
+
className={state.general.geoType === 'us-region' ? 'active' : ''}
|
|
1455
|
+
onClick={e => {
|
|
1456
|
+
e.preventDefault()
|
|
1457
|
+
handleEditorChanges('geoType', 'us-region')
|
|
1458
|
+
}}
|
|
1459
|
+
>
|
|
1460
|
+
<UsaRegionGraphic />
|
|
1461
|
+
<span>U.S. Region</span>
|
|
1462
|
+
</button>
|
|
1463
|
+
<button
|
|
1464
|
+
className={state.general.geoType === 'world' ? 'active' : ''}
|
|
1465
|
+
onClick={e => {
|
|
1466
|
+
e.preventDefault()
|
|
1467
|
+
handleEditorChanges('geoType', 'world')
|
|
1468
|
+
}}
|
|
1469
|
+
>
|
|
1470
|
+
<WorldGraphic />
|
|
1471
|
+
<span>World</span>
|
|
1472
|
+
</button>
|
|
1473
|
+
<button
|
|
1474
|
+
className={state.general.geoType === 'single-state' ? 'active' : ''}
|
|
1475
|
+
onClick={e => {
|
|
1476
|
+
e.preventDefault()
|
|
1477
|
+
handleEditorChanges('geoType', 'single-state')
|
|
1478
|
+
}}
|
|
1479
|
+
>
|
|
1480
|
+
<AlabamaGraphic />
|
|
1481
|
+
<span>U.S. State</span>
|
|
1482
|
+
</button>
|
|
1483
|
+
</ul>
|
|
1484
|
+
</label>
|
|
1485
|
+
{/* Select > State or County Map */}
|
|
1486
|
+
{(state.general.geoType === 'us' || state.general.geoType === 'us-county') && (
|
|
1487
|
+
<label>
|
|
1488
|
+
<span className='edit-label column-heading'>Geography Subtype</span>
|
|
1489
|
+
<select
|
|
1490
|
+
value={state.general.geoType}
|
|
1491
|
+
onChange={event => {
|
|
1492
|
+
handleEditorChanges('geoType', event.target.value)
|
|
1493
|
+
}}
|
|
1494
|
+
>
|
|
1495
|
+
<option value='us'>US State-Level</option>
|
|
1496
|
+
<option value='us-county'>US County-Level</option>
|
|
1497
|
+
</select>
|
|
1498
|
+
</label>
|
|
1499
|
+
)}
|
|
1411
1500
|
{/* Type */}
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
</AccordionItemHeading>
|
|
1415
|
-
<AccordionItemPanel>
|
|
1416
|
-
{/* Geography */}
|
|
1501
|
+
{/* Select > Filter a state */}
|
|
1502
|
+
{state.general.geoType === 'single-state' && (
|
|
1417
1503
|
<label>
|
|
1418
|
-
<span className='edit-label column-heading'>
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
}}
|
|
1428
|
-
>
|
|
1429
|
-
<UsaGraphic />
|
|
1430
|
-
<span>United States</span>
|
|
1431
|
-
</button>
|
|
1432
|
-
<button
|
|
1433
|
-
className={state.general.geoType === 'us-region' ? 'active' : ''}
|
|
1434
|
-
onClick={e => {
|
|
1435
|
-
e.preventDefault()
|
|
1436
|
-
handleEditorChanges('geoType', 'us-region')
|
|
1437
|
-
}}
|
|
1438
|
-
>
|
|
1439
|
-
<UsaRegionGraphic />
|
|
1440
|
-
<span>U.S. Region</span>
|
|
1441
|
-
</button>
|
|
1442
|
-
<button
|
|
1443
|
-
className={state.general.geoType === 'world' ? 'active' : ''}
|
|
1444
|
-
onClick={e => {
|
|
1445
|
-
e.preventDefault()
|
|
1446
|
-
handleEditorChanges('geoType', 'world')
|
|
1447
|
-
}}
|
|
1448
|
-
>
|
|
1449
|
-
<WorldGraphic />
|
|
1450
|
-
<span>World</span>
|
|
1451
|
-
</button>
|
|
1452
|
-
<button
|
|
1453
|
-
className={state.general.geoType === 'single-state' ? 'active' : ''}
|
|
1454
|
-
onClick={e => {
|
|
1455
|
-
e.preventDefault()
|
|
1456
|
-
handleEditorChanges('geoType', 'single-state')
|
|
1457
|
-
}}
|
|
1458
|
-
>
|
|
1459
|
-
<AlabamaGraphic />
|
|
1460
|
-
<span>U.S. State</span>
|
|
1461
|
-
</button>
|
|
1462
|
-
</ul>
|
|
1504
|
+
<span className='edit-label column-heading'>State Selector</span>
|
|
1505
|
+
<select
|
|
1506
|
+
value={state.general.hasOwnProperty('statePicked') ? state.general.statePicked.stateName : { fipsCode: '04', stateName: 'Alabama' }}
|
|
1507
|
+
onChange={event => {
|
|
1508
|
+
handleEditorChanges('chooseState', event.target.value)
|
|
1509
|
+
}}
|
|
1510
|
+
>
|
|
1511
|
+
<StateOptionList />
|
|
1512
|
+
</select>
|
|
1463
1513
|
</label>
|
|
1464
|
-
|
|
1465
|
-
|
|
1514
|
+
)}
|
|
1515
|
+
{/* Type */}
|
|
1516
|
+
<label>
|
|
1517
|
+
<span className='edit-label column-heading'>
|
|
1518
|
+
Map Type
|
|
1519
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1520
|
+
<Tooltip.Target>
|
|
1521
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1522
|
+
</Tooltip.Target>
|
|
1523
|
+
<Tooltip.Content>
|
|
1524
|
+
<p>Select "Data" to create a color-coded data map. To create a navigation-only map, select "Navigation."</p>
|
|
1525
|
+
</Tooltip.Content>
|
|
1526
|
+
</Tooltip>
|
|
1527
|
+
</span>
|
|
1528
|
+
<select
|
|
1529
|
+
value={state.general.type}
|
|
1530
|
+
onChange={event => {
|
|
1531
|
+
handleEditorChanges('editorMapType', event.target.value)
|
|
1532
|
+
}}
|
|
1533
|
+
>
|
|
1534
|
+
<option value='data'>Data</option>
|
|
1535
|
+
{state.general.geoType === 'us-county' && <option value='us-geocode'>Geocode</option>}
|
|
1536
|
+
{state.general.geoType === 'world' && <option value='world-geocode'>Geocode</option>}
|
|
1537
|
+
<option value='navigation'>Navigation</option>
|
|
1538
|
+
{(state.general.geoType === 'world' || state.general.geoType === 'us') && <option value='bubble'>Bubble</option>}
|
|
1539
|
+
</select>
|
|
1540
|
+
</label>
|
|
1541
|
+
<label>
|
|
1542
|
+
<span className='edit-label'>Data Classification Type</span>
|
|
1543
|
+
<div>
|
|
1466
1544
|
<label>
|
|
1467
|
-
<
|
|
1468
|
-
|
|
1469
|
-
value={state.general.geoType}
|
|
1470
|
-
onChange={event => {
|
|
1471
|
-
handleEditorChanges('geoType', event.target.value)
|
|
1472
|
-
}}
|
|
1473
|
-
>
|
|
1474
|
-
<option value='us'>US State-Level</option>
|
|
1475
|
-
<option value='us-county'>US County-Level</option>
|
|
1476
|
-
</select>
|
|
1545
|
+
<input type='radio' name='equalnumber' value='equalnumber' checked={state.legend.type === 'equalnumber'} onChange={e => handleEditorChanges('classificationType', e.target.value)} />
|
|
1546
|
+
Numeric/Quantitative
|
|
1477
1547
|
</label>
|
|
1478
|
-
)}
|
|
1479
|
-
{/* Type */}
|
|
1480
|
-
{/* Select > Filter a state */}
|
|
1481
|
-
{state.general.geoType === 'single-state' && (
|
|
1482
1548
|
<label>
|
|
1483
|
-
<
|
|
1484
|
-
|
|
1485
|
-
value={state.general.hasOwnProperty('statePicked') ? state.general.statePicked.stateName : { fipsCode: '04', stateName: 'Alabama' }}
|
|
1486
|
-
onChange={event => {
|
|
1487
|
-
handleEditorChanges('chooseState', event.target.value)
|
|
1488
|
-
}}
|
|
1489
|
-
>
|
|
1490
|
-
<StateOptionList />
|
|
1491
|
-
</select>
|
|
1549
|
+
<input type='radio' name='category' value='category' checked={state.legend.type === 'category'} onChange={e => handleEditorChanges('classificationType', e.target.value)} />
|
|
1550
|
+
Categorical
|
|
1492
1551
|
</label>
|
|
1493
|
-
|
|
1494
|
-
|
|
1552
|
+
</div>
|
|
1553
|
+
</label>
|
|
1554
|
+
{/* SubType */}
|
|
1555
|
+
{'us' === state.general.geoType && 'data' === state.general.type && (
|
|
1556
|
+
<label className='checkbox mt-4'>
|
|
1557
|
+
<input
|
|
1558
|
+
type='checkbox'
|
|
1559
|
+
checked={state.general.displayAsHex}
|
|
1560
|
+
onChange={event => {
|
|
1561
|
+
handleEditorChanges('displayAsHex', event.target.checked)
|
|
1562
|
+
}}
|
|
1563
|
+
/>
|
|
1564
|
+
<span className='edit-label'>Display As Hex Map</span>
|
|
1565
|
+
</label>
|
|
1566
|
+
)}
|
|
1567
|
+
{'us' === state.general.geoType && 'bubble' !== state.general.type && false === state.general.displayAsHex && (
|
|
1568
|
+
<label className='checkbox'>
|
|
1569
|
+
<input
|
|
1570
|
+
type='checkbox'
|
|
1571
|
+
checked={state.general.displayStateLabels}
|
|
1572
|
+
onChange={event => {
|
|
1573
|
+
handleEditorChanges('displayStateLabels', event.target.checked)
|
|
1574
|
+
}}
|
|
1575
|
+
/>
|
|
1576
|
+
<span className='edit-label'>Show state labels</span>
|
|
1577
|
+
</label>
|
|
1578
|
+
)}
|
|
1579
|
+
</AccordionItemPanel>
|
|
1580
|
+
</AccordionItem>
|
|
1581
|
+
<AccordionItem>
|
|
1582
|
+
{' '}
|
|
1583
|
+
{/* General */}
|
|
1584
|
+
<AccordionItemHeading>
|
|
1585
|
+
<AccordionItemButton>General</AccordionItemButton>
|
|
1586
|
+
</AccordionItemHeading>
|
|
1587
|
+
<AccordionItemPanel>
|
|
1588
|
+
<TextField
|
|
1589
|
+
value={general.title}
|
|
1590
|
+
data-testid='title-input'
|
|
1591
|
+
updateField={updateField}
|
|
1592
|
+
section='general'
|
|
1593
|
+
fieldName='title'
|
|
1594
|
+
id='title'
|
|
1595
|
+
label='Title'
|
|
1596
|
+
placeholder='Map Title'
|
|
1597
|
+
tooltip={
|
|
1598
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1599
|
+
<Tooltip.Target>
|
|
1600
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1601
|
+
</Tooltip.Target>
|
|
1602
|
+
<Tooltip.Content>
|
|
1603
|
+
<p>Title is required to set the name of the download file but can be hidden using the option below.</p>
|
|
1604
|
+
</Tooltip.Content>
|
|
1605
|
+
</Tooltip>
|
|
1606
|
+
}
|
|
1607
|
+
/>
|
|
1608
|
+
<label className='checkbox'>
|
|
1609
|
+
<input
|
|
1610
|
+
type='checkbox'
|
|
1611
|
+
checked={state.general.showTitle || false}
|
|
1612
|
+
onChange={event => {
|
|
1613
|
+
handleEditorChanges('showTitle', event.target.checked)
|
|
1614
|
+
}}
|
|
1615
|
+
/>
|
|
1616
|
+
<span className='edit-label'>Show Title</span>
|
|
1617
|
+
</label>
|
|
1618
|
+
<TextField
|
|
1619
|
+
value={general.superTitle || ''}
|
|
1620
|
+
updateField={updateField}
|
|
1621
|
+
section='general'
|
|
1622
|
+
fieldName='superTitle'
|
|
1623
|
+
label='Super Title'
|
|
1624
|
+
tooltip={
|
|
1625
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1626
|
+
<Tooltip.Target>
|
|
1627
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1628
|
+
</Tooltip.Target>
|
|
1629
|
+
<Tooltip.Content>
|
|
1630
|
+
<p>Super Title</p>
|
|
1631
|
+
</Tooltip.Content>
|
|
1632
|
+
</Tooltip>
|
|
1633
|
+
}
|
|
1634
|
+
/>
|
|
1635
|
+
<TextField
|
|
1636
|
+
type='textarea'
|
|
1637
|
+
value={general.introText}
|
|
1638
|
+
updateField={updateField}
|
|
1639
|
+
section='general'
|
|
1640
|
+
fieldName='introText'
|
|
1641
|
+
label='Intro Text'
|
|
1642
|
+
tooltip={
|
|
1643
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1644
|
+
<Tooltip.Target>
|
|
1645
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1646
|
+
</Tooltip.Target>
|
|
1647
|
+
<Tooltip.Content>
|
|
1648
|
+
<p>Intro Text</p>
|
|
1649
|
+
</Tooltip.Content>
|
|
1650
|
+
</Tooltip>
|
|
1651
|
+
}
|
|
1652
|
+
/>
|
|
1653
|
+
<TextField
|
|
1654
|
+
type='textarea'
|
|
1655
|
+
value={general.subtext}
|
|
1656
|
+
updateField={updateField}
|
|
1657
|
+
section='general'
|
|
1658
|
+
fieldName='subtext'
|
|
1659
|
+
label='Subtext'
|
|
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>Enter supporting text to display below the data visualization, if applicable. The following HTML tags are supported: strong, em, sup, and sub.</p>
|
|
1667
|
+
</Tooltip.Content>
|
|
1668
|
+
</Tooltip>
|
|
1669
|
+
}
|
|
1670
|
+
/>
|
|
1671
|
+
<TextField
|
|
1672
|
+
type='textarea'
|
|
1673
|
+
value={general.footnotes}
|
|
1674
|
+
updateField={updateField}
|
|
1675
|
+
section='general'
|
|
1676
|
+
fieldName='footnotes'
|
|
1677
|
+
label='Footnotes'
|
|
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>Footnotes</p>
|
|
1685
|
+
</Tooltip.Content>
|
|
1686
|
+
</Tooltip>
|
|
1687
|
+
}
|
|
1688
|
+
/>
|
|
1689
|
+
{'us' === state.general.geoType && <TextField value={general.territoriesLabel} updateField={updateField} section='general' fieldName='territoriesLabel' label='Territories Label' placeholder='Territories' />}
|
|
1690
|
+
{'us' === state.general.geoType && (
|
|
1691
|
+
<label className='checkbox'>
|
|
1692
|
+
<input
|
|
1693
|
+
type='checkbox'
|
|
1694
|
+
checked={general.territoriesAlwaysShow || false}
|
|
1695
|
+
onChange={event => {
|
|
1696
|
+
handleEditorChanges('territoriesAlwaysShow', event.target.checked)
|
|
1697
|
+
}}
|
|
1698
|
+
/>
|
|
1699
|
+
<span className='edit-label'>Show All Territories</span>
|
|
1700
|
+
</label>
|
|
1701
|
+
)}
|
|
1702
|
+
{/* <label className="checkbox mt-4">
|
|
1703
|
+
<input type="checkbox" checked={ state.general.showDownloadMediaButton } onChange={(event) => { handleEditorChanges("toggleDownloadMediaButton", event.target.checked) }} />
|
|
1704
|
+
<span className="edit-label">Enable Media Download</span>
|
|
1705
|
+
</label> */}
|
|
1706
|
+
</AccordionItemPanel>
|
|
1707
|
+
</AccordionItem>
|
|
1708
|
+
<AccordionItem>
|
|
1709
|
+
{' '}
|
|
1710
|
+
{/* Columns */}
|
|
1711
|
+
<AccordionItemHeading>
|
|
1712
|
+
<AccordionItemButton>Columns</AccordionItemButton>
|
|
1713
|
+
</AccordionItemHeading>
|
|
1714
|
+
<AccordionItemPanel>
|
|
1715
|
+
<fieldset className='primary-fieldset edit-block'>
|
|
1495
1716
|
<label>
|
|
1496
1717
|
<span className='edit-label column-heading'>
|
|
1497
|
-
|
|
1718
|
+
Geography
|
|
1498
1719
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
1499
1720
|
<Tooltip.Target>
|
|
1500
1721
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1501
1722
|
</Tooltip.Target>
|
|
1502
1723
|
<Tooltip.Content>
|
|
1503
|
-
<p>Select
|
|
1724
|
+
<p>Select the source column containing the map location names or, for county-level maps, the FIPS codes.</p>
|
|
1504
1725
|
</Tooltip.Content>
|
|
1505
1726
|
</Tooltip>
|
|
1506
1727
|
</span>
|
|
1507
1728
|
<select
|
|
1508
|
-
value={state.
|
|
1729
|
+
value={state.columns.geo ? state.columns.geo.name : columnsOptions[0]}
|
|
1509
1730
|
onChange={event => {
|
|
1510
|
-
|
|
1731
|
+
editColumn('geo', 'name', event.target.value)
|
|
1511
1732
|
}}
|
|
1512
1733
|
>
|
|
1513
|
-
|
|
1514
|
-
{state.general.geoType === 'us-county' && <option value='us-geocode'>Geocode</option>}
|
|
1515
|
-
{state.general.geoType === 'world' && <option value='world-geocode'>Geocode</option>}
|
|
1516
|
-
<option value='navigation'>Navigation</option>
|
|
1517
|
-
{(state.general.geoType === 'world' || state.general.geoType === 'us') && <option value='bubble'>Bubble</option>}
|
|
1734
|
+
{columnsOptions}
|
|
1518
1735
|
</select>
|
|
1519
1736
|
</label>
|
|
1520
|
-
<label>
|
|
1521
|
-
<span className='edit-label'>Data Classification Type</span>
|
|
1522
|
-
<div>
|
|
1523
|
-
<label>
|
|
1524
|
-
<input type='radio' name='equalnumber' value='equalnumber' checked={state.legend.type === 'equalnumber'} onChange={e => handleEditorChanges('classificationType', e.target.value)} />
|
|
1525
|
-
Numeric/Quantitative
|
|
1526
|
-
</label>
|
|
1527
|
-
<label>
|
|
1528
|
-
<input type='radio' name='category' value='category' checked={state.legend.type === 'category'} onChange={e => handleEditorChanges('classificationType', e.target.value)} />
|
|
1529
|
-
Categorical
|
|
1530
|
-
</label>
|
|
1531
|
-
</div>
|
|
1532
|
-
</label>
|
|
1533
|
-
{/* SubType */}
|
|
1534
|
-
{'us' === state.general.geoType && 'data' === state.general.type && (
|
|
1535
|
-
<label className='checkbox mt-4'>
|
|
1536
|
-
<input
|
|
1537
|
-
type='checkbox'
|
|
1538
|
-
checked={state.general.displayAsHex}
|
|
1539
|
-
onChange={event => {
|
|
1540
|
-
handleEditorChanges('displayAsHex', event.target.checked)
|
|
1541
|
-
}}
|
|
1542
|
-
/>
|
|
1543
|
-
<span className='edit-label'>Display As Hex Map</span>
|
|
1544
|
-
</label>
|
|
1545
|
-
)}
|
|
1546
|
-
{'us' === state.general.geoType && 'bubble' !== state.general.type && false === state.general.displayAsHex && (
|
|
1547
|
-
<label className='checkbox'>
|
|
1548
|
-
<input
|
|
1549
|
-
type='checkbox'
|
|
1550
|
-
checked={state.general.displayStateLabels}
|
|
1551
|
-
onChange={event => {
|
|
1552
|
-
handleEditorChanges('displayStateLabels', event.target.checked)
|
|
1553
|
-
}}
|
|
1554
|
-
/>
|
|
1555
|
-
<span className='edit-label'>Display state labels</span>
|
|
1556
|
-
</label>
|
|
1557
|
-
)}
|
|
1558
|
-
</AccordionItemPanel>
|
|
1559
|
-
</AccordionItem>
|
|
1560
|
-
<AccordionItem>
|
|
1561
|
-
{' '}
|
|
1562
|
-
{/* General */}
|
|
1563
|
-
<AccordionItemHeading>
|
|
1564
|
-
<AccordionItemButton>General</AccordionItemButton>
|
|
1565
|
-
</AccordionItemHeading>
|
|
1566
|
-
<AccordionItemPanel>
|
|
1567
|
-
<TextField
|
|
1568
|
-
value={general.title}
|
|
1569
|
-
data-testid='title-input'
|
|
1570
|
-
updateField={updateField}
|
|
1571
|
-
section='general'
|
|
1572
|
-
fieldName='title'
|
|
1573
|
-
id='title'
|
|
1574
|
-
label='Title'
|
|
1575
|
-
placeholder='Map Title'
|
|
1576
|
-
tooltip={
|
|
1577
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
1578
|
-
<Tooltip.Target>
|
|
1579
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1580
|
-
</Tooltip.Target>
|
|
1581
|
-
<Tooltip.Content>
|
|
1582
|
-
<p>Title is required to set the name of the download file but can be hidden using the option below.</p>
|
|
1583
|
-
</Tooltip.Content>
|
|
1584
|
-
</Tooltip>
|
|
1585
|
-
}
|
|
1586
|
-
/>
|
|
1587
1737
|
<label className='checkbox'>
|
|
1588
1738
|
<input
|
|
1589
1739
|
type='checkbox'
|
|
1590
|
-
checked={state.general.
|
|
1740
|
+
checked={state.general.hideGeoColumnInTooltip || false}
|
|
1591
1741
|
onChange={event => {
|
|
1592
|
-
handleEditorChanges('
|
|
1742
|
+
handleEditorChanges('hideGeoColumnInTooltip', event.target.checked)
|
|
1593
1743
|
}}
|
|
1594
1744
|
/>
|
|
1595
|
-
<span className='edit-label'>
|
|
1745
|
+
<span className='edit-label'>Hide Geography Column Name in Tooltip</span>
|
|
1596
1746
|
</label>
|
|
1597
1747
|
<TextField
|
|
1598
|
-
value={general.
|
|
1599
|
-
updateField={updateField}
|
|
1600
|
-
section='general'
|
|
1601
|
-
fieldName='superTitle'
|
|
1602
|
-
label='Super Title'
|
|
1603
|
-
tooltip={
|
|
1604
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
1605
|
-
<Tooltip.Target>
|
|
1606
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1607
|
-
</Tooltip.Target>
|
|
1608
|
-
<Tooltip.Content>
|
|
1609
|
-
<p>Super Title</p>
|
|
1610
|
-
</Tooltip.Content>
|
|
1611
|
-
</Tooltip>
|
|
1612
|
-
}
|
|
1613
|
-
/>
|
|
1614
|
-
<TextField
|
|
1615
|
-
type='textarea'
|
|
1616
|
-
value={general.introText}
|
|
1617
|
-
updateField={updateField}
|
|
1618
|
-
section='general'
|
|
1619
|
-
fieldName='introText'
|
|
1620
|
-
label='Intro Text'
|
|
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>Intro Text</p>
|
|
1628
|
-
</Tooltip.Content>
|
|
1629
|
-
</Tooltip>
|
|
1630
|
-
}
|
|
1631
|
-
/>
|
|
1632
|
-
<TextField
|
|
1633
|
-
type='textarea'
|
|
1634
|
-
value={general.subtext}
|
|
1635
|
-
updateField={updateField}
|
|
1748
|
+
value={state.general.geoLabelOverride}
|
|
1636
1749
|
section='general'
|
|
1637
|
-
fieldName='
|
|
1638
|
-
label='
|
|
1639
|
-
|
|
1640
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
1641
|
-
<Tooltip.Target>
|
|
1642
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1643
|
-
</Tooltip.Target>
|
|
1644
|
-
<Tooltip.Content>
|
|
1645
|
-
<p>Enter supporting text to display below the data visualization, if applicable. The following HTML tags are supported: strong, em, sup, and sub.</p>
|
|
1646
|
-
</Tooltip.Content>
|
|
1647
|
-
</Tooltip>
|
|
1648
|
-
}
|
|
1649
|
-
/>
|
|
1650
|
-
<TextField
|
|
1651
|
-
type='textarea'
|
|
1652
|
-
value={general.footnotes}
|
|
1750
|
+
fieldName='geoLabelOverride'
|
|
1751
|
+
label='Geography Label'
|
|
1752
|
+
className='edit-label'
|
|
1653
1753
|
updateField={updateField}
|
|
1654
|
-
section='general'
|
|
1655
|
-
fieldName='footnotes'
|
|
1656
|
-
label='Footnotes'
|
|
1657
1754
|
tooltip={
|
|
1658
1755
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
1659
1756
|
<Tooltip.Target>
|
|
1660
1757
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1661
1758
|
</Tooltip.Target>
|
|
1662
1759
|
<Tooltip.Content>
|
|
1663
|
-
<p>
|
|
1760
|
+
<p>Enter a geography label for use in tooltips.</p>
|
|
1664
1761
|
</Tooltip.Content>
|
|
1665
1762
|
</Tooltip>
|
|
1666
1763
|
}
|
|
1667
1764
|
/>
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
<label className='checkbox'>
|
|
1671
|
-
<input
|
|
1672
|
-
type='checkbox'
|
|
1673
|
-
checked={general.territoriesAlwaysShow || false}
|
|
1674
|
-
onChange={event => {
|
|
1675
|
-
handleEditorChanges('territoriesAlwaysShow', event.target.checked)
|
|
1676
|
-
}}
|
|
1677
|
-
/>
|
|
1678
|
-
<span className='edit-label'>Show All Territories</span>
|
|
1679
|
-
</label>
|
|
1680
|
-
)}
|
|
1681
|
-
{/* <label className="checkbox mt-4">
|
|
1682
|
-
<input type="checkbox" checked={ state.general.showDownloadMediaButton } onChange={(event) => { handleEditorChanges("toggleDownloadMediaButton", event.target.checked) }} />
|
|
1683
|
-
<span className="edit-label">Enable Media Download</span>
|
|
1684
|
-
</label> */}
|
|
1685
|
-
</AccordionItemPanel>
|
|
1686
|
-
</AccordionItem>
|
|
1687
|
-
<AccordionItem>
|
|
1688
|
-
{' '}
|
|
1689
|
-
{/* Columns */}
|
|
1690
|
-
<AccordionItemHeading>
|
|
1691
|
-
<AccordionItemButton>Columns</AccordionItemButton>
|
|
1692
|
-
</AccordionItemHeading>
|
|
1693
|
-
<AccordionItemPanel>
|
|
1765
|
+
</fieldset>
|
|
1766
|
+
{'navigation' !== state.general.type && (
|
|
1694
1767
|
<fieldset className='primary-fieldset edit-block'>
|
|
1695
1768
|
<label>
|
|
1696
1769
|
<span className='edit-label column-heading'>
|
|
1697
|
-
|
|
1770
|
+
Data Column
|
|
1698
1771
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
1699
1772
|
<Tooltip.Target>
|
|
1700
1773
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1701
1774
|
</Tooltip.Target>
|
|
1702
1775
|
<Tooltip.Content>
|
|
1703
|
-
<p>Select the source column containing the
|
|
1776
|
+
<p>Select the source column containing the categorical or numeric values to be mapped.</p>
|
|
1704
1777
|
</Tooltip.Content>
|
|
1705
1778
|
</Tooltip>
|
|
1706
1779
|
</span>
|
|
1707
1780
|
<select
|
|
1708
|
-
value={state.columns.
|
|
1781
|
+
value={state.columns.primary ? state.columns.primary.name : columnsOptions[0]}
|
|
1709
1782
|
onChange={event => {
|
|
1710
|
-
editColumn('
|
|
1783
|
+
editColumn('primary', 'name', event.target.value)
|
|
1711
1784
|
}}
|
|
1712
1785
|
>
|
|
1713
1786
|
{columnsOptions}
|
|
@@ -1716,19 +1789,19 @@ const EditorPanel = props => {
|
|
|
1716
1789
|
<label className='checkbox'>
|
|
1717
1790
|
<input
|
|
1718
1791
|
type='checkbox'
|
|
1719
|
-
checked={state.general.
|
|
1792
|
+
checked={state.general.hidePrimaryColumnInTooltip || false}
|
|
1720
1793
|
onChange={event => {
|
|
1721
|
-
handleEditorChanges('
|
|
1794
|
+
handleEditorChanges('hidePrimaryColumnInTooltip', event.target.checked)
|
|
1722
1795
|
}}
|
|
1723
1796
|
/>
|
|
1724
|
-
<span className='edit-label'>Hide
|
|
1797
|
+
<span className='edit-label'>Hide Data Column Name in Tooltip</span>
|
|
1725
1798
|
</label>
|
|
1726
1799
|
<TextField
|
|
1727
|
-
value={
|
|
1728
|
-
section='
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1800
|
+
value={columns.primary.label}
|
|
1801
|
+
section='columns'
|
|
1802
|
+
subsection='primary'
|
|
1803
|
+
fieldName='label'
|
|
1804
|
+
label='Data Label'
|
|
1732
1805
|
updateField={updateField}
|
|
1733
1806
|
tooltip={
|
|
1734
1807
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
@@ -1736,1125 +1809,1092 @@ const EditorPanel = props => {
|
|
|
1736
1809
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1737
1810
|
</Tooltip.Target>
|
|
1738
1811
|
<Tooltip.Content>
|
|
1739
|
-
<p>Enter a
|
|
1812
|
+
<p>Enter a data label for use in tooltips and the data table.</p>
|
|
1740
1813
|
</Tooltip.Content>
|
|
1741
1814
|
</Tooltip>
|
|
1742
1815
|
}
|
|
1743
1816
|
/>
|
|
1817
|
+
<ul className='column-edit'>
|
|
1818
|
+
<li className='three-col'>
|
|
1819
|
+
<TextField value={columns.primary.prefix} section='columns' subsection='primary' fieldName='prefix' label='Prefix' updateField={updateField} />
|
|
1820
|
+
<TextField value={columns.primary.suffix} section='columns' subsection='primary' fieldName='suffix' label='Suffix' updateField={updateField} />
|
|
1821
|
+
<TextField type='number' value={columns.primary.roundToPlace} section='columns' subsection='primary' fieldName='roundToPlace' label='Round' updateField={updateField} min={0} />
|
|
1822
|
+
</li>
|
|
1823
|
+
<li>
|
|
1824
|
+
<label className='checkbox'>
|
|
1825
|
+
<input
|
|
1826
|
+
type='checkbox'
|
|
1827
|
+
checked={state.columns.primary.useCommas}
|
|
1828
|
+
onChange={event => {
|
|
1829
|
+
editColumn('primary', 'useCommas', event.target.checked)
|
|
1830
|
+
}}
|
|
1831
|
+
/>
|
|
1832
|
+
<span className='edit-label'>Add Commas to Numbers</span>
|
|
1833
|
+
</label>
|
|
1834
|
+
</li>
|
|
1835
|
+
<li>
|
|
1836
|
+
<label className='checkbox'>
|
|
1837
|
+
<input
|
|
1838
|
+
type='checkbox'
|
|
1839
|
+
checked={state.columns.primary.dataTable || false}
|
|
1840
|
+
onChange={event => {
|
|
1841
|
+
editColumn('primary', 'dataTable', event.target.checked)
|
|
1842
|
+
}}
|
|
1843
|
+
/>
|
|
1844
|
+
<span className='edit-label'>Show in Data Table</span>
|
|
1845
|
+
</label>
|
|
1846
|
+
</li>
|
|
1847
|
+
<li>
|
|
1848
|
+
<label className='checkbox'>
|
|
1849
|
+
<input
|
|
1850
|
+
type='checkbox'
|
|
1851
|
+
checked={state.columns.primary.tooltip || false}
|
|
1852
|
+
onChange={event => {
|
|
1853
|
+
editColumn('primary', 'tooltip', event.target.checked)
|
|
1854
|
+
}}
|
|
1855
|
+
/>
|
|
1856
|
+
<span className='edit-label'>Show in Tooltips</span>
|
|
1857
|
+
</label>
|
|
1858
|
+
</li>
|
|
1859
|
+
</ul>
|
|
1744
1860
|
</fieldset>
|
|
1745
|
-
|
|
1746
|
-
<fieldset className='primary-fieldset edit-block'>
|
|
1747
|
-
<label>
|
|
1748
|
-
<span className='edit-label column-heading'>
|
|
1749
|
-
Data Column
|
|
1750
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
1751
|
-
<Tooltip.Target>
|
|
1752
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1753
|
-
</Tooltip.Target>
|
|
1754
|
-
<Tooltip.Content>
|
|
1755
|
-
<p>Select the source column containing the categorical or numeric values to be mapped.</p>
|
|
1756
|
-
</Tooltip.Content>
|
|
1757
|
-
</Tooltip>
|
|
1758
|
-
</span>
|
|
1759
|
-
<select
|
|
1760
|
-
value={state.columns.primary ? state.columns.primary.name : columnsOptions[0]}
|
|
1761
|
-
onChange={event => {
|
|
1762
|
-
editColumn('primary', 'name', event.target.value)
|
|
1763
|
-
}}
|
|
1764
|
-
>
|
|
1765
|
-
{columnsOptions}
|
|
1766
|
-
</select>
|
|
1767
|
-
</label>
|
|
1768
|
-
<label className='checkbox'>
|
|
1769
|
-
<input
|
|
1770
|
-
type='checkbox'
|
|
1771
|
-
checked={state.general.hidePrimaryColumnInTooltip || false}
|
|
1772
|
-
onChange={event => {
|
|
1773
|
-
handleEditorChanges('hidePrimaryColumnInTooltip', event.target.checked)
|
|
1774
|
-
}}
|
|
1775
|
-
/>
|
|
1776
|
-
<span className='edit-label'>Hide Data Column Name in Tooltip</span>
|
|
1777
|
-
</label>
|
|
1778
|
-
<TextField
|
|
1779
|
-
value={columns.primary.label}
|
|
1780
|
-
section='columns'
|
|
1781
|
-
subsection='primary'
|
|
1782
|
-
fieldName='label'
|
|
1783
|
-
label='Data Label'
|
|
1784
|
-
updateField={updateField}
|
|
1785
|
-
tooltip={
|
|
1786
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
1787
|
-
<Tooltip.Target>
|
|
1788
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1789
|
-
</Tooltip.Target>
|
|
1790
|
-
<Tooltip.Content>
|
|
1791
|
-
<p>Enter a data label for use in tooltips and the data table.</p>
|
|
1792
|
-
</Tooltip.Content>
|
|
1793
|
-
</Tooltip>
|
|
1794
|
-
}
|
|
1795
|
-
/>
|
|
1796
|
-
<ul className='column-edit'>
|
|
1797
|
-
<li className='three-col'>
|
|
1798
|
-
<TextField value={columns.primary.prefix} section='columns' subsection='primary' fieldName='prefix' label='Prefix' updateField={updateField} />
|
|
1799
|
-
<TextField value={columns.primary.suffix} section='columns' subsection='primary' fieldName='suffix' label='Suffix' updateField={updateField} />
|
|
1800
|
-
<TextField type='number' value={columns.primary.roundToPlace} section='columns' subsection='primary' fieldName='roundToPlace' label='Round' updateField={updateField} min={0} />
|
|
1801
|
-
</li>
|
|
1802
|
-
<li>
|
|
1803
|
-
<label className='checkbox'>
|
|
1804
|
-
<input
|
|
1805
|
-
type='checkbox'
|
|
1806
|
-
checked={state.columns.primary.useCommas}
|
|
1807
|
-
onChange={event => {
|
|
1808
|
-
editColumn('primary', 'useCommas', event.target.checked)
|
|
1809
|
-
}}
|
|
1810
|
-
/>
|
|
1811
|
-
<span className='edit-label'>Add Commas to Numbers</span>
|
|
1812
|
-
</label>
|
|
1813
|
-
</li>
|
|
1814
|
-
<li>
|
|
1815
|
-
<label className='checkbox'>
|
|
1816
|
-
<input
|
|
1817
|
-
type='checkbox'
|
|
1818
|
-
checked={state.columns.primary.dataTable || false}
|
|
1819
|
-
onChange={event => {
|
|
1820
|
-
editColumn('primary', 'dataTable', event.target.checked)
|
|
1821
|
-
}}
|
|
1822
|
-
/>
|
|
1823
|
-
<span className='edit-label'>Display in Data Table</span>
|
|
1824
|
-
</label>
|
|
1825
|
-
</li>
|
|
1826
|
-
<li>
|
|
1827
|
-
<label className='checkbox'>
|
|
1828
|
-
<input
|
|
1829
|
-
type='checkbox'
|
|
1830
|
-
checked={state.columns.primary.tooltip || false}
|
|
1831
|
-
onChange={event => {
|
|
1832
|
-
editColumn('primary', 'tooltip', event.target.checked)
|
|
1833
|
-
}}
|
|
1834
|
-
/>
|
|
1835
|
-
<span className='edit-label'>Display in Tooltips</span>
|
|
1836
|
-
</label>
|
|
1837
|
-
</li>
|
|
1838
|
-
</ul>
|
|
1839
|
-
</fieldset>
|
|
1840
|
-
)}
|
|
1861
|
+
)}
|
|
1841
1862
|
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
<select
|
|
1857
|
-
value={state.columns.categorical ? state.columns.categorical.name : columnsOptions[0]}
|
|
1858
|
-
onChange={event => {
|
|
1859
|
-
editColumn('categorical', 'name', event.target.value)
|
|
1860
|
-
}}
|
|
1861
|
-
>
|
|
1862
|
-
{columnsOptions}
|
|
1863
|
-
</select>
|
|
1864
|
-
</label>
|
|
1865
|
-
</fieldset>
|
|
1866
|
-
)}
|
|
1867
|
-
{('us-geocode' === state.general.type || 'world-geocode' === state.general.type) && (
|
|
1868
|
-
<>
|
|
1869
|
-
<label>Latitude Column</label>
|
|
1870
|
-
<select
|
|
1871
|
-
value={state.columns.latitude.name ? state.columns.latitude.name : ''}
|
|
1872
|
-
onChange={e => {
|
|
1873
|
-
editColumn('latitude', 'name', e.target.value)
|
|
1874
|
-
}}
|
|
1875
|
-
>
|
|
1876
|
-
{columnsOptions}
|
|
1877
|
-
</select>
|
|
1878
|
-
<label>Longitude Column</label>
|
|
1863
|
+
{state.general.type === 'bubble' && state.legend.type === 'category' && (
|
|
1864
|
+
<fieldset className='primary-fieldset edit-block'>
|
|
1865
|
+
<label>
|
|
1866
|
+
<span className='edit-label column-heading'>
|
|
1867
|
+
Category Column
|
|
1868
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1869
|
+
<Tooltip.Target>
|
|
1870
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1871
|
+
</Tooltip.Target>
|
|
1872
|
+
<Tooltip.Content>
|
|
1873
|
+
<p>Select the source column containing the categorical bubble values to be mapped.</p>
|
|
1874
|
+
</Tooltip.Content>
|
|
1875
|
+
</Tooltip>
|
|
1876
|
+
</span>
|
|
1879
1877
|
<select
|
|
1880
|
-
value={state.columns.
|
|
1881
|
-
onChange={
|
|
1882
|
-
editColumn('
|
|
1878
|
+
value={state.columns.categorical ? state.columns.categorical.name : columnsOptions[0]}
|
|
1879
|
+
onChange={event => {
|
|
1880
|
+
editColumn('categorical', 'name', event.target.value)
|
|
1883
1881
|
}}
|
|
1884
1882
|
>
|
|
1885
1883
|
{columnsOptions}
|
|
1886
1884
|
</select>
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
<span className='edit-label'>
|
|
1894
|
-
Special Classes
|
|
1895
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
1896
|
-
<Tooltip.Target>
|
|
1897
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1898
|
-
</Tooltip.Target>
|
|
1899
|
-
<Tooltip.Content>
|
|
1900
|
-
<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>
|
|
1901
|
-
</Tooltip.Content>
|
|
1902
|
-
</Tooltip>
|
|
1903
|
-
</span>
|
|
1904
|
-
</label>
|
|
1905
|
-
{specialClasses.map((specialClass, i) => (
|
|
1906
|
-
<div className='edit-block' key={`special-class-${i}`}>
|
|
1907
|
-
<button
|
|
1908
|
-
className='remove-column'
|
|
1909
|
-
onClick={e => {
|
|
1910
|
-
e.preventDefault()
|
|
1911
|
-
editColumn('primary', 'specialClassDelete', i)
|
|
1912
|
-
}}
|
|
1913
|
-
>
|
|
1914
|
-
Remove
|
|
1915
|
-
</button>
|
|
1916
|
-
<p>Special Class {i + 1}</p>
|
|
1917
|
-
<label>
|
|
1918
|
-
<span className='edit-label column-heading'>Data Key</span>
|
|
1919
|
-
<select
|
|
1920
|
-
value={specialClass.key}
|
|
1921
|
-
onChange={e => {
|
|
1922
|
-
editColumn('primary', 'specialClassEdit', { prop: 'key', index: i, value: e.target.value })
|
|
1923
|
-
}}
|
|
1924
|
-
>
|
|
1925
|
-
{columnsOptions}
|
|
1926
|
-
</select>
|
|
1927
|
-
</label>
|
|
1928
|
-
<label>
|
|
1929
|
-
<span className='edit-label column-heading'>Value</span>
|
|
1930
|
-
<select
|
|
1931
|
-
value={specialClass.value}
|
|
1932
|
-
onChange={e => {
|
|
1933
|
-
editColumn('primary', 'specialClassEdit', { prop: 'value', index: i, value: e.target.value })
|
|
1934
|
-
}}
|
|
1935
|
-
>
|
|
1936
|
-
<option value=''>- Select Value -</option>
|
|
1937
|
-
{columnsByKey[specialClass.key] && columnsByKey[specialClass.key].sort().map(option => <option key={`special-class-value-option-${i}-${option}`}>{option}</option>)}
|
|
1938
|
-
</select>
|
|
1939
|
-
</label>
|
|
1940
|
-
<label>
|
|
1941
|
-
<span className='edit-label column-heading'>Label</span>
|
|
1942
|
-
<input
|
|
1943
|
-
type='text'
|
|
1944
|
-
value={specialClass.label}
|
|
1945
|
-
onChange={e => {
|
|
1946
|
-
editColumn('primary', 'specialClassEdit', { prop: 'label', index: i, value: e.target.value })
|
|
1947
|
-
}}
|
|
1948
|
-
/>
|
|
1949
|
-
</label>
|
|
1950
|
-
</div>
|
|
1951
|
-
))}
|
|
1952
|
-
<button
|
|
1953
|
-
className='btn full-width'
|
|
1954
|
-
onClick={e => {
|
|
1955
|
-
e.preventDefault()
|
|
1956
|
-
editColumn('primary', 'specialClassAdd', {})
|
|
1957
|
-
}}
|
|
1958
|
-
>
|
|
1959
|
-
Add Special Class
|
|
1960
|
-
</button>
|
|
1961
|
-
</fieldset>
|
|
1962
|
-
)}
|
|
1963
|
-
|
|
1964
|
-
<label className='edit-block navigate column-heading'>
|
|
1965
|
-
<span className='edit-label column-heading'>
|
|
1966
|
-
Navigation
|
|
1967
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
1968
|
-
<Tooltip.Target>
|
|
1969
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1970
|
-
</Tooltip.Target>
|
|
1971
|
-
<Tooltip.Content>
|
|
1972
|
-
<p>To provide end users with navigation functionality, select the source column containing the navigation URLs.</p>
|
|
1973
|
-
</Tooltip.Content>
|
|
1974
|
-
</Tooltip>
|
|
1975
|
-
</span>
|
|
1885
|
+
</label>
|
|
1886
|
+
</fieldset>
|
|
1887
|
+
)}
|
|
1888
|
+
{('us-geocode' === state.general.type || 'world-geocode' === state.general.type) && (
|
|
1889
|
+
<>
|
|
1890
|
+
<label>Latitude Column</label>
|
|
1976
1891
|
<select
|
|
1977
|
-
value={state.columns.
|
|
1978
|
-
onChange={
|
|
1979
|
-
editColumn('
|
|
1892
|
+
value={state.columns.latitude.name ? state.columns.latitude.name : ''}
|
|
1893
|
+
onChange={e => {
|
|
1894
|
+
editColumn('latitude', 'name', e.target.value)
|
|
1980
1895
|
}}
|
|
1981
1896
|
>
|
|
1982
1897
|
{columnsOptions}
|
|
1983
1898
|
</select>
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
<fieldset className='edit-block' key={val}>
|
|
2002
|
-
<button
|
|
2003
|
-
className='remove-column'
|
|
2004
|
-
onClick={event => {
|
|
2005
|
-
event.preventDefault()
|
|
2006
|
-
removeAdditionalColumn(val)
|
|
2007
|
-
}}
|
|
2008
|
-
>
|
|
2009
|
-
Remove
|
|
2010
|
-
</button>
|
|
2011
|
-
<label>
|
|
2012
|
-
<span className='edit-label column-heading'>Column</span>
|
|
2013
|
-
<select
|
|
2014
|
-
value={state.columns[val] ? state.columns[val].name : columnsOptions[0]}
|
|
2015
|
-
onChange={event => {
|
|
2016
|
-
editColumn(val, 'name', event.target.value)
|
|
2017
|
-
}}
|
|
2018
|
-
>
|
|
2019
|
-
{columnsOptions}
|
|
2020
|
-
</select>
|
|
2021
|
-
</label>
|
|
2022
|
-
<TextField value={columns[val].label} section='columns' subsection={val} fieldName='label' label='Label' updateField={updateField} />
|
|
2023
|
-
<ul className='column-edit'>
|
|
2024
|
-
<li className='three-col'>
|
|
2025
|
-
<TextField value={columns[val].prefix} section='columns' subsection={val} fieldName='prefix' label='Prefix' updateField={updateField} />
|
|
2026
|
-
<TextField value={columns[val].suffix} section='columns' subsection={val} fieldName='suffix' label='Suffix' updateField={updateField} />
|
|
2027
|
-
<TextField type='number' value={columns[val].roundToPlace} section='columns' subsection={val} fieldName='roundToPlace' label='Round' updateField={updateField} />
|
|
2028
|
-
</li>
|
|
2029
|
-
<li>
|
|
2030
|
-
<label className='checkbox'>
|
|
2031
|
-
<input
|
|
2032
|
-
type='checkbox'
|
|
2033
|
-
checked={state.columns[val].useCommas}
|
|
2034
|
-
onChange={event => {
|
|
2035
|
-
editColumn(val, 'useCommas', event.target.checked)
|
|
2036
|
-
}}
|
|
2037
|
-
/>
|
|
2038
|
-
<span className='edit-label'>Add Commas to Numbers</span>
|
|
2039
|
-
</label>
|
|
2040
|
-
</li>
|
|
2041
|
-
<li>
|
|
2042
|
-
<label className='checkbox'>
|
|
2043
|
-
<input
|
|
2044
|
-
type='checkbox'
|
|
2045
|
-
checked={state.columns[val].dataTable}
|
|
2046
|
-
onChange={event => {
|
|
2047
|
-
editColumn(val, 'dataTable', event.target.checked)
|
|
2048
|
-
}}
|
|
2049
|
-
/>
|
|
2050
|
-
<span className='edit-label'>Display in Data Table</span>
|
|
2051
|
-
</label>
|
|
2052
|
-
</li>
|
|
2053
|
-
<li>
|
|
2054
|
-
<label className='checkbox'>
|
|
2055
|
-
<input
|
|
2056
|
-
type='checkbox'
|
|
2057
|
-
checked={state.columns[val].tooltip}
|
|
2058
|
-
onChange={event => {
|
|
2059
|
-
editColumn(val, 'tooltip', event.target.checked)
|
|
2060
|
-
}}
|
|
2061
|
-
/>
|
|
2062
|
-
<span className='edit-label'>Display in Tooltips</span>
|
|
2063
|
-
</label>
|
|
2064
|
-
</li>
|
|
2065
|
-
</ul>
|
|
2066
|
-
</fieldset>
|
|
2067
|
-
))}
|
|
2068
|
-
<button
|
|
2069
|
-
className={'btn full-width'}
|
|
2070
|
-
onClick={event => {
|
|
2071
|
-
event.preventDefault()
|
|
2072
|
-
addAdditionalColumn(additionalColumns.length + 1)
|
|
2073
|
-
}}
|
|
2074
|
-
>
|
|
2075
|
-
Add Column
|
|
2076
|
-
</button>
|
|
2077
|
-
</fieldset>
|
|
2078
|
-
)}
|
|
2079
|
-
{'category' === state.legend.type && (
|
|
2080
|
-
<fieldset className='primary-fieldset edit-block'>
|
|
2081
|
-
<label>
|
|
2082
|
-
<span className='edit-label'>
|
|
2083
|
-
Additional Category
|
|
2084
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2085
|
-
<Tooltip.Target>
|
|
2086
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2087
|
-
</Tooltip.Target>
|
|
2088
|
-
<Tooltip.Content>
|
|
2089
|
-
<p>You can provide additional categories to ensure they appear in the legend</p>
|
|
2090
|
-
</Tooltip.Content>
|
|
2091
|
-
</Tooltip>
|
|
2092
|
-
</span>
|
|
2093
|
-
</label>
|
|
2094
|
-
{state.legend.additionalCategories &&
|
|
2095
|
-
state.legend.additionalCategories.map((val, i) => (
|
|
2096
|
-
<fieldset className='edit-block' key={val}>
|
|
2097
|
-
<button
|
|
2098
|
-
className='remove-column'
|
|
2099
|
-
onClick={event => {
|
|
2100
|
-
event.preventDefault()
|
|
2101
|
-
const updatedAdditionaCategories = [...state.legend.additionalCategories]
|
|
2102
|
-
updatedAdditionaCategories.splice(i, 1)
|
|
2103
|
-
updateField('legend', null, 'additionalCategories', updatedAdditionaCategories)
|
|
2104
|
-
}}
|
|
2105
|
-
>
|
|
2106
|
-
Remove
|
|
2107
|
-
</button>
|
|
2108
|
-
<label>
|
|
2109
|
-
<span className='edit-label column-heading'>Category</span>
|
|
2110
|
-
<TextField
|
|
2111
|
-
value={val}
|
|
2112
|
-
section='legend'
|
|
2113
|
-
subsection={null}
|
|
2114
|
-
fieldName='additionalCategories'
|
|
2115
|
-
updateField={(section, subsection, fieldName, value) => {
|
|
2116
|
-
const updatedAdditionaCategories = [...state.legend.additionalCategories]
|
|
2117
|
-
updatedAdditionaCategories[i] = value
|
|
2118
|
-
updateField(section, subsection, fieldName, updatedAdditionaCategories)
|
|
2119
|
-
}}
|
|
2120
|
-
/>
|
|
2121
|
-
</label>
|
|
2122
|
-
</fieldset>
|
|
2123
|
-
))}
|
|
2124
|
-
<button
|
|
2125
|
-
className={'btn full-width'}
|
|
2126
|
-
onClick={event => {
|
|
2127
|
-
event.preventDefault()
|
|
2128
|
-
const updatedAdditionaCategories = [...(state.legend.additionalCategories || [])]
|
|
2129
|
-
updatedAdditionaCategories.push('')
|
|
2130
|
-
updateField('legend', null, 'additionalCategories', updatedAdditionaCategories)
|
|
2131
|
-
}}
|
|
2132
|
-
>
|
|
2133
|
-
Add Category
|
|
2134
|
-
</button>
|
|
2135
|
-
</fieldset>
|
|
2136
|
-
)}
|
|
2137
|
-
</AccordionItemPanel>
|
|
2138
|
-
</AccordionItem>{' '}
|
|
2139
|
-
{/* Columns */}
|
|
2140
|
-
{'navigation' !== state.general.type && (
|
|
2141
|
-
<AccordionItem>
|
|
2142
|
-
{' '}
|
|
2143
|
-
{/* Legend */}
|
|
2144
|
-
<AccordionItemHeading>
|
|
2145
|
-
<AccordionItemButton>Legend</AccordionItemButton>
|
|
2146
|
-
</AccordionItemHeading>
|
|
2147
|
-
<AccordionItemPanel>
|
|
2148
|
-
{(state.legend.type === 'equalnumber' || state.legend.type === 'equalinterval') && (
|
|
2149
|
-
<label>
|
|
2150
|
-
<span className='edit-label'>Legend Type</span>
|
|
2151
|
-
<select
|
|
2152
|
-
value={legend.type}
|
|
2153
|
-
onChange={event => {
|
|
2154
|
-
handleEditorChanges('legendType', event.target.value)
|
|
2155
|
-
}}
|
|
2156
|
-
>
|
|
2157
|
-
<option value='equalnumber'>Equal Number (Quantiles)</option>
|
|
2158
|
-
<option value='equalinterval'>Equal Interval</option>
|
|
2159
|
-
</select>
|
|
2160
|
-
</label>
|
|
2161
|
-
)}
|
|
2162
|
-
{'navigation' !== state.general.type && (
|
|
2163
|
-
<label className='checkbox'>
|
|
2164
|
-
<input
|
|
2165
|
-
type='checkbox'
|
|
2166
|
-
checked={state.general.showSidebar || false}
|
|
2167
|
-
onChange={event => {
|
|
2168
|
-
handleEditorChanges('showSidebar', event.target.checked)
|
|
2169
|
-
}}
|
|
2170
|
-
/>
|
|
2171
|
-
<span className='edit-label'>Show Legend</span>
|
|
2172
|
-
</label>
|
|
2173
|
-
)}
|
|
2174
|
-
{'navigation' !== state.general.type && (
|
|
2175
|
-
<label>
|
|
2176
|
-
<span className='edit-label'>Legend Position</span>
|
|
2177
|
-
<select
|
|
2178
|
-
value={legend.position || false}
|
|
2179
|
-
onChange={event => {
|
|
2180
|
-
handleEditorChanges('sidebarPosition', event.target.value)
|
|
2181
|
-
}}
|
|
2182
|
-
>
|
|
2183
|
-
<option value='side'>Side</option>
|
|
2184
|
-
<option value='bottom'>Bottom</option>
|
|
2185
|
-
</select>
|
|
2186
|
-
</label>
|
|
2187
|
-
)}
|
|
2188
|
-
{'side' === legend.position && (
|
|
2189
|
-
<label className='checkbox'>
|
|
2190
|
-
<input
|
|
2191
|
-
type='checkbox'
|
|
2192
|
-
checked={legend.singleColumn}
|
|
2193
|
-
onChange={event => {
|
|
2194
|
-
handleEditorChanges('singleColumnLegend', event.target.checked)
|
|
2195
|
-
}}
|
|
2196
|
-
/>
|
|
2197
|
-
<span className='edit-label'>Single Column Legend</span>
|
|
2198
|
-
</label>
|
|
2199
|
-
)}
|
|
2200
|
-
{'bottom' === legend.position && (
|
|
2201
|
-
<label className='checkbox'>
|
|
2202
|
-
<input
|
|
2203
|
-
type='checkbox'
|
|
2204
|
-
checked={legend.singleRow}
|
|
2205
|
-
onChange={event => {
|
|
2206
|
-
handleEditorChanges('singleRowLegend', event.target.checked)
|
|
2207
|
-
}}
|
|
2208
|
-
/>
|
|
2209
|
-
<span className='edit-label'>Single Row Legend</span>
|
|
2210
|
-
</label>
|
|
2211
|
-
)}
|
|
2212
|
-
{/* always show */}
|
|
2213
|
-
{/*
|
|
2214
|
-
<label className='checkbox'>
|
|
2215
|
-
<input
|
|
2216
|
-
type='checkbox'
|
|
2217
|
-
checked={legend.showSpecialClassesLast}
|
|
2218
|
-
onChange={event => {
|
|
2219
|
-
handleEditorChanges('legendShowSpecialClassesLast', event.target.checked)
|
|
2220
|
-
}}
|
|
2221
|
-
/>
|
|
2222
|
-
<span className='edit-label'>Show Special Classes Last</span>
|
|
2223
|
-
</label> */}
|
|
2224
|
-
{'category' !== legend.type && (
|
|
2225
|
-
<label className='checkbox'>
|
|
2226
|
-
<input type='checkbox' checked={legend.separateZero || false} onChange={event => handleEditorChanges('separateZero', event.target.checked)} />
|
|
2227
|
-
<span className='edit-label'>
|
|
2228
|
-
Separate Zero
|
|
2229
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2230
|
-
<Tooltip.Target>
|
|
2231
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2232
|
-
</Tooltip.Target>
|
|
2233
|
-
<Tooltip.Content>
|
|
2234
|
-
<p>For numeric data, you can separate the zero value as its own data class.</p>
|
|
2235
|
-
</Tooltip.Content>
|
|
2236
|
-
</Tooltip>
|
|
2237
|
-
</span>
|
|
2238
|
-
</label>
|
|
2239
|
-
)}
|
|
2240
|
-
{/* Temp Checkbox */}
|
|
2241
|
-
{state.legend.type === 'equalnumber' && (
|
|
2242
|
-
<label className='checkbox mt-4'>
|
|
2243
|
-
<input
|
|
2244
|
-
type='checkbox'
|
|
2245
|
-
checked={state.general.equalNumberOptIn}
|
|
2246
|
-
onChange={event => {
|
|
2247
|
-
handleEditorChanges('showEqualNumber', event.target.checked)
|
|
2248
|
-
}}
|
|
2249
|
-
/>
|
|
2250
|
-
<span className='edit-label'>Use new quantile legend</span>
|
|
1899
|
+
<label>Longitude Column</label>
|
|
1900
|
+
<select
|
|
1901
|
+
value={state.columns.longitude.name ? state.columns.longitude.name : ''}
|
|
1902
|
+
onChange={e => {
|
|
1903
|
+
editColumn('longitude', 'name', e.target.value)
|
|
1904
|
+
}}
|
|
1905
|
+
>
|
|
1906
|
+
{columnsOptions}
|
|
1907
|
+
</select>
|
|
1908
|
+
</>
|
|
1909
|
+
)}
|
|
1910
|
+
|
|
1911
|
+
{'navigation' !== state.general.type && (
|
|
1912
|
+
<fieldset className='primary-fieldset edit-block'>
|
|
1913
|
+
<label>
|
|
1914
|
+
<span className='edit-label'>
|
|
1915
|
+
Special Classes
|
|
2251
1916
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
2252
1917
|
<Tooltip.Target>
|
|
2253
1918
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2254
1919
|
</Tooltip.Target>
|
|
2255
1920
|
<Tooltip.Content>
|
|
2256
|
-
<p>
|
|
1921
|
+
<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>
|
|
2257
1922
|
</Tooltip.Content>
|
|
2258
1923
|
</Tooltip>
|
|
2259
|
-
</
|
|
2260
|
-
|
|
2261
|
-
{
|
|
2262
|
-
<
|
|
2263
|
-
<
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
</Tooltip.Target>
|
|
2269
|
-
<Tooltip.Content>
|
|
2270
|
-
<p>For numeric maps, select the number of data classes. Do not include designated special classes.</p>
|
|
2271
|
-
</Tooltip.Content>
|
|
2272
|
-
</Tooltip>
|
|
2273
|
-
</span>
|
|
2274
|
-
<select
|
|
2275
|
-
value={legend.numberOfItems}
|
|
2276
|
-
onChange={event => {
|
|
2277
|
-
handleEditorChanges('legendNumber', event.target.value)
|
|
1924
|
+
</span>
|
|
1925
|
+
</label>
|
|
1926
|
+
{specialClasses.map((specialClass, i) => (
|
|
1927
|
+
<div className='edit-block' key={`special-class-${i}`}>
|
|
1928
|
+
<button
|
|
1929
|
+
className='remove-column'
|
|
1930
|
+
onClick={e => {
|
|
1931
|
+
e.preventDefault()
|
|
1932
|
+
editColumn('primary', 'specialClassDelete', i)
|
|
2278
1933
|
}}
|
|
2279
1934
|
>
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
{num + 1}
|
|
2284
|
-
</option>
|
|
2285
|
-
)
|
|
2286
|
-
})}
|
|
2287
|
-
</select>
|
|
2288
|
-
</label>
|
|
2289
|
-
)}
|
|
2290
|
-
{'category' === legend.type && (
|
|
2291
|
-
<React.Fragment>
|
|
1935
|
+
Remove
|
|
1936
|
+
</button>
|
|
1937
|
+
<p>Special Class {i + 1}</p>
|
|
2292
1938
|
<label>
|
|
2293
|
-
<span className='edit-label'>
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
</Tooltip>
|
|
2303
|
-
</span>
|
|
1939
|
+
<span className='edit-label column-heading'>Data Key</span>
|
|
1940
|
+
<select
|
|
1941
|
+
value={specialClass.key}
|
|
1942
|
+
onChange={e => {
|
|
1943
|
+
editColumn('primary', 'specialClassEdit', { prop: 'key', index: i, value: e.target.value })
|
|
1944
|
+
}}
|
|
1945
|
+
>
|
|
1946
|
+
{columnsOptions}
|
|
1947
|
+
</select>
|
|
2304
1948
|
</label>
|
|
2305
|
-
{/* 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. */}
|
|
2306
|
-
<DragDropContext onDragEnd={({ source, destination }) => categoryMove(source.index, destination.index)}>
|
|
2307
|
-
<Droppable droppableId='category_order'>
|
|
2308
|
-
{provided => (
|
|
2309
|
-
<ul {...provided.droppableProps} className='sort-list' ref={provided.innerRef}>
|
|
2310
|
-
<CategoryList />
|
|
2311
|
-
{provided.placeholder}
|
|
2312
|
-
</ul>
|
|
2313
|
-
)}
|
|
2314
|
-
</Droppable>
|
|
2315
|
-
</DragDropContext>
|
|
2316
|
-
{state.legend.categoryValuesOrder && state.legend.categoryValuesOrder.length >= 10 && (
|
|
2317
|
-
<section className='error-box my-2'>
|
|
2318
|
-
<div>
|
|
2319
|
-
<strong className='pt-1'>Warning</strong>
|
|
2320
|
-
<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>
|
|
2321
|
-
</div>
|
|
2322
|
-
</section>
|
|
2323
|
-
)}
|
|
2324
|
-
</React.Fragment>
|
|
2325
|
-
)}
|
|
2326
|
-
<TextField value={legend.title} updateField={updateField} section='legend' fieldName='title' label='Legend Title' placeholder='Legend Title' />
|
|
2327
|
-
{false === legend.dynamicDescription && <TextField type='textarea' value={legend.description} updateField={updateField} section='legend' fieldName='description' label='Legend Description' />}
|
|
2328
|
-
{true === legend.dynamicDescription && (
|
|
2329
|
-
<React.Fragment>
|
|
2330
1949
|
<label>
|
|
2331
|
-
<span>
|
|
2332
|
-
<
|
|
2333
|
-
|
|
1950
|
+
<span className='edit-label column-heading'>Value</span>
|
|
1951
|
+
<select
|
|
1952
|
+
value={specialClass.value}
|
|
1953
|
+
onChange={e => {
|
|
1954
|
+
editColumn('primary', 'specialClassEdit', { prop: 'value', index: i, value: e.target.value })
|
|
1955
|
+
}}
|
|
1956
|
+
>
|
|
1957
|
+
<option value=''>- Select Value -</option>
|
|
1958
|
+
{columnsByKey[specialClass.key] && columnsByKey[specialClass.key].sort().map(option => <option key={`special-class-value-option-${i}-${option}`}>{option}</option>)}
|
|
1959
|
+
</select>
|
|
1960
|
+
</label>
|
|
1961
|
+
<label>
|
|
1962
|
+
<span className='edit-label column-heading'>Label</span>
|
|
1963
|
+
<input
|
|
1964
|
+
type='text'
|
|
1965
|
+
value={specialClass.label}
|
|
1966
|
+
onChange={e => {
|
|
1967
|
+
editColumn('primary', 'specialClassEdit', { prop: 'label', index: i, value: e.target.value })
|
|
1968
|
+
}}
|
|
1969
|
+
/>
|
|
2334
1970
|
</label>
|
|
1971
|
+
</div>
|
|
1972
|
+
))}
|
|
1973
|
+
<button
|
|
1974
|
+
className='btn full-width'
|
|
1975
|
+
onClick={e => {
|
|
1976
|
+
e.preventDefault()
|
|
1977
|
+
editColumn('primary', 'specialClassAdd', {})
|
|
1978
|
+
}}
|
|
1979
|
+
>
|
|
1980
|
+
Add Special Class
|
|
1981
|
+
</button>
|
|
1982
|
+
</fieldset>
|
|
1983
|
+
)}
|
|
1984
|
+
|
|
1985
|
+
<label className='edit-block navigate column-heading'>
|
|
1986
|
+
<span className='edit-label column-heading'>
|
|
1987
|
+
Navigation
|
|
1988
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1989
|
+
<Tooltip.Target>
|
|
1990
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1991
|
+
</Tooltip.Target>
|
|
1992
|
+
<Tooltip.Content>
|
|
1993
|
+
<p>To provide end users with navigation functionality, select the source column containing the navigation URLs.</p>
|
|
1994
|
+
</Tooltip.Content>
|
|
1995
|
+
</Tooltip>
|
|
1996
|
+
</span>
|
|
1997
|
+
<select
|
|
1998
|
+
value={state.columns.navigate ? state.columns.navigate.name : columnsOptions[0]}
|
|
1999
|
+
onChange={event => {
|
|
2000
|
+
editColumn('navigate', 'name', event.target.value)
|
|
2001
|
+
}}
|
|
2002
|
+
>
|
|
2003
|
+
{columnsOptions}
|
|
2004
|
+
</select>
|
|
2005
|
+
</label>
|
|
2006
|
+
{'navigation' !== state.general.type && (
|
|
2007
|
+
<fieldset className='primary-fieldset edit-block'>
|
|
2008
|
+
<label>
|
|
2009
|
+
<span className='edit-label'>
|
|
2010
|
+
Additional Columns
|
|
2011
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2012
|
+
<Tooltip.Target>
|
|
2013
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2014
|
+
</Tooltip.Target>
|
|
2015
|
+
<Tooltip.Content>
|
|
2016
|
+
<p>You can specify additional columns to display in tooltips and / or the supporting data table.</p>
|
|
2017
|
+
</Tooltip.Content>
|
|
2018
|
+
</Tooltip>
|
|
2019
|
+
</span>
|
|
2020
|
+
</label>
|
|
2021
|
+
{additionalColumns.map(val => (
|
|
2022
|
+
<fieldset className='edit-block' key={val}>
|
|
2023
|
+
<button
|
|
2024
|
+
className='remove-column'
|
|
2025
|
+
onClick={event => {
|
|
2026
|
+
event.preventDefault()
|
|
2027
|
+
removeAdditionalColumn(val)
|
|
2028
|
+
}}
|
|
2029
|
+
>
|
|
2030
|
+
Remove
|
|
2031
|
+
</button>
|
|
2335
2032
|
<label>
|
|
2033
|
+
<span className='edit-label column-heading'>Column</span>
|
|
2336
2034
|
<select
|
|
2337
|
-
value={
|
|
2035
|
+
value={state.columns[val] ? state.columns[val].name : columnsOptions[0]}
|
|
2338
2036
|
onChange={event => {
|
|
2339
|
-
|
|
2037
|
+
editColumn(val, 'name', event.target.value)
|
|
2340
2038
|
}}
|
|
2341
2039
|
>
|
|
2342
|
-
{
|
|
2343
|
-
return (
|
|
2344
|
-
<option value={arr} key={i}>
|
|
2345
|
-
{displayFilterLegendValue(arr)}
|
|
2346
|
-
</option>
|
|
2347
|
-
)
|
|
2348
|
-
})}
|
|
2040
|
+
{columnsOptions}
|
|
2349
2041
|
</select>
|
|
2350
2042
|
</label>
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
<AccordionItem>
|
|
2398
|
-
{' '}
|
|
2399
|
-
{/* Filters */}
|
|
2400
|
-
<AccordionItemHeading>
|
|
2401
|
-
<AccordionItemButton>Filters</AccordionItemButton>
|
|
2402
|
-
</AccordionItemHeading>
|
|
2403
|
-
<AccordionItemPanel>
|
|
2404
|
-
{filtersJSX.length > 0 ? <MapFilters /> : <p style={{ textAlign: 'center' }}>There are currently no filters.</p>}
|
|
2043
|
+
<TextField value={columns[val].label} section='columns' subsection={val} fieldName='label' label='Label' updateField={updateField} />
|
|
2044
|
+
<ul className='column-edit'>
|
|
2045
|
+
<li className='three-col'>
|
|
2046
|
+
<TextField value={columns[val].prefix} section='columns' subsection={val} fieldName='prefix' label='Prefix' updateField={updateField} />
|
|
2047
|
+
<TextField value={columns[val].suffix} section='columns' subsection={val} fieldName='suffix' label='Suffix' updateField={updateField} />
|
|
2048
|
+
<TextField type='number' value={columns[val].roundToPlace} section='columns' subsection={val} fieldName='roundToPlace' label='Round' updateField={updateField} />
|
|
2049
|
+
</li>
|
|
2050
|
+
<li>
|
|
2051
|
+
<label className='checkbox'>
|
|
2052
|
+
<input
|
|
2053
|
+
type='checkbox'
|
|
2054
|
+
checked={state.columns[val].useCommas}
|
|
2055
|
+
onChange={event => {
|
|
2056
|
+
editColumn(val, 'useCommas', event.target.checked)
|
|
2057
|
+
}}
|
|
2058
|
+
/>
|
|
2059
|
+
<span className='edit-label'>Add Commas to Numbers</span>
|
|
2060
|
+
</label>
|
|
2061
|
+
</li>
|
|
2062
|
+
<li>
|
|
2063
|
+
<label className='checkbox'>
|
|
2064
|
+
<input
|
|
2065
|
+
type='checkbox'
|
|
2066
|
+
checked={state.columns[val].dataTable}
|
|
2067
|
+
onChange={event => {
|
|
2068
|
+
editColumn(val, 'dataTable', event.target.checked)
|
|
2069
|
+
}}
|
|
2070
|
+
/>
|
|
2071
|
+
<span className='edit-label'>Show in Data Table</span>
|
|
2072
|
+
</label>
|
|
2073
|
+
</li>
|
|
2074
|
+
<li>
|
|
2075
|
+
<label className='checkbox'>
|
|
2076
|
+
<input
|
|
2077
|
+
type='checkbox'
|
|
2078
|
+
checked={state.columns[val].tooltip}
|
|
2079
|
+
onChange={event => {
|
|
2080
|
+
editColumn(val, 'tooltip', event.target.checked)
|
|
2081
|
+
}}
|
|
2082
|
+
/>
|
|
2083
|
+
<span className='edit-label'>Show in Tooltips</span>
|
|
2084
|
+
</label>
|
|
2085
|
+
</li>
|
|
2086
|
+
</ul>
|
|
2087
|
+
</fieldset>
|
|
2088
|
+
))}
|
|
2405
2089
|
<button
|
|
2406
2090
|
className={'btn full-width'}
|
|
2407
2091
|
onClick={event => {
|
|
2408
2092
|
event.preventDefault()
|
|
2409
|
-
|
|
2093
|
+
addAdditionalColumn(additionalColumns.length + 1)
|
|
2410
2094
|
}}
|
|
2411
2095
|
>
|
|
2412
|
-
Add
|
|
2096
|
+
Add Column
|
|
2413
2097
|
</button>
|
|
2414
|
-
</
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
<AccordionItemHeading>
|
|
2422
|
-
<AccordionItemButton>Data Table</AccordionItemButton>
|
|
2423
|
-
</AccordionItemHeading>
|
|
2424
|
-
<AccordionItemPanel>
|
|
2425
|
-
<TextField
|
|
2426
|
-
value={table.label}
|
|
2427
|
-
updateField={updateField}
|
|
2428
|
-
section='table'
|
|
2429
|
-
fieldName='label'
|
|
2430
|
-
id='dataTableTitle'
|
|
2431
|
-
label='Data Table Title'
|
|
2432
|
-
placeholder='Data Table'
|
|
2433
|
-
tooltip={
|
|
2098
|
+
</fieldset>
|
|
2099
|
+
)}
|
|
2100
|
+
{'category' === state.legend.type && (
|
|
2101
|
+
<fieldset className='primary-fieldset edit-block'>
|
|
2102
|
+
<label>
|
|
2103
|
+
<span className='edit-label'>
|
|
2104
|
+
Additional Category
|
|
2434
2105
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
2435
2106
|
<Tooltip.Target>
|
|
2436
2107
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2437
2108
|
</Tooltip.Target>
|
|
2438
2109
|
<Tooltip.Content>
|
|
2439
|
-
<p>
|
|
2110
|
+
<p>You can provide additional categories to ensure they appear in the legend</p>
|
|
2440
2111
|
</Tooltip.Content>
|
|
2441
2112
|
</Tooltip>
|
|
2442
|
-
|
|
2443
|
-
|
|
2113
|
+
</span>
|
|
2114
|
+
</label>
|
|
2115
|
+
{state.legend.additionalCategories &&
|
|
2116
|
+
state.legend.additionalCategories.map((val, i) => (
|
|
2117
|
+
<fieldset className='edit-block' key={val}>
|
|
2118
|
+
<button
|
|
2119
|
+
className='remove-column'
|
|
2120
|
+
onClick={event => {
|
|
2121
|
+
event.preventDefault()
|
|
2122
|
+
const updatedAdditionaCategories = [...state.legend.additionalCategories]
|
|
2123
|
+
updatedAdditionaCategories.splice(i, 1)
|
|
2124
|
+
updateField('legend', null, 'additionalCategories', updatedAdditionaCategories)
|
|
2125
|
+
}}
|
|
2126
|
+
>
|
|
2127
|
+
Remove
|
|
2128
|
+
</button>
|
|
2129
|
+
<label>
|
|
2130
|
+
<span className='edit-label column-heading'>Category</span>
|
|
2131
|
+
<TextField
|
|
2132
|
+
value={val}
|
|
2133
|
+
section='legend'
|
|
2134
|
+
subsection={null}
|
|
2135
|
+
fieldName='additionalCategories'
|
|
2136
|
+
updateField={(section, subsection, fieldName, value) => {
|
|
2137
|
+
const updatedAdditionaCategories = [...state.legend.additionalCategories]
|
|
2138
|
+
updatedAdditionaCategories[i] = value
|
|
2139
|
+
updateField(section, subsection, fieldName, updatedAdditionaCategories)
|
|
2140
|
+
}}
|
|
2141
|
+
/>
|
|
2142
|
+
</label>
|
|
2143
|
+
</fieldset>
|
|
2144
|
+
))}
|
|
2145
|
+
<button
|
|
2146
|
+
className={'btn full-width'}
|
|
2147
|
+
onClick={event => {
|
|
2148
|
+
event.preventDefault()
|
|
2149
|
+
const updatedAdditionaCategories = [...(state.legend.additionalCategories || [])]
|
|
2150
|
+
updatedAdditionaCategories.push('')
|
|
2151
|
+
updateField('legend', null, 'additionalCategories', updatedAdditionaCategories)
|
|
2152
|
+
}}
|
|
2153
|
+
>
|
|
2154
|
+
Add Category
|
|
2155
|
+
</button>
|
|
2156
|
+
</fieldset>
|
|
2157
|
+
)}
|
|
2158
|
+
</AccordionItemPanel>
|
|
2159
|
+
</AccordionItem>{' '}
|
|
2160
|
+
{/* Columns */}
|
|
2161
|
+
{'navigation' !== state.general.type && (
|
|
2162
|
+
<AccordionItem>
|
|
2163
|
+
{' '}
|
|
2164
|
+
{/* Legend */}
|
|
2165
|
+
<AccordionItemHeading>
|
|
2166
|
+
<AccordionItemButton>Legend</AccordionItemButton>
|
|
2167
|
+
</AccordionItemHeading>
|
|
2168
|
+
<AccordionItemPanel>
|
|
2169
|
+
{(state.legend.type === 'equalnumber' || state.legend.type === 'equalinterval') && (
|
|
2170
|
+
<label>
|
|
2171
|
+
<span className='edit-label'>Legend Type</span>
|
|
2172
|
+
<select
|
|
2173
|
+
value={legend.type}
|
|
2174
|
+
onChange={event => {
|
|
2175
|
+
handleEditorChanges('legendType', event.target.value)
|
|
2176
|
+
}}
|
|
2177
|
+
>
|
|
2178
|
+
<option value='equalnumber'>Equal Number (Quantiles)</option>
|
|
2179
|
+
<option value='equalinterval'>Equal Interval</option>
|
|
2180
|
+
</select>
|
|
2181
|
+
</label>
|
|
2182
|
+
)}
|
|
2183
|
+
{'navigation' !== state.general.type && (
|
|
2444
2184
|
<label className='checkbox'>
|
|
2445
2185
|
<input
|
|
2446
2186
|
type='checkbox'
|
|
2447
|
-
checked={state.
|
|
2187
|
+
checked={state.general.showSidebar || false}
|
|
2448
2188
|
onChange={event => {
|
|
2449
|
-
handleEditorChanges('
|
|
2189
|
+
handleEditorChanges('showSidebar', event.target.checked)
|
|
2450
2190
|
}}
|
|
2451
2191
|
/>
|
|
2452
|
-
<span className='edit-label
|
|
2453
|
-
Show Data Table
|
|
2454
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2455
|
-
<Tooltip.Target>
|
|
2456
|
-
<Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
|
|
2457
|
-
</Tooltip.Target>
|
|
2458
|
-
<Tooltip.Content>
|
|
2459
|
-
<p>Data tables are required for 508 compliance. When choosing to hide this data table, replace with your own version.</p>
|
|
2460
|
-
</Tooltip.Content>
|
|
2461
|
-
</Tooltip>
|
|
2462
|
-
</span>
|
|
2192
|
+
<span className='edit-label'>Show Legend</span>
|
|
2463
2193
|
</label>
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
}
|
|
2481
|
-
/>
|
|
2482
|
-
<TextField
|
|
2483
|
-
value={state.table.caption}
|
|
2484
|
-
updateField={updateField}
|
|
2485
|
-
section='table'
|
|
2486
|
-
fieldName='caption'
|
|
2487
|
-
label='Data Table Caption'
|
|
2488
|
-
placeholder='Data Table'
|
|
2489
|
-
tooltip={
|
|
2490
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2491
|
-
<Tooltip.Target>
|
|
2492
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2493
|
-
</Tooltip.Target>
|
|
2494
|
-
<Tooltip.Content>
|
|
2495
|
-
<p>Enter a description of the data table to be read by screen readers.</p>
|
|
2496
|
-
</Tooltip.Content>
|
|
2497
|
-
</Tooltip>
|
|
2498
|
-
}
|
|
2499
|
-
type='textarea'
|
|
2500
|
-
/>
|
|
2194
|
+
)}
|
|
2195
|
+
{'navigation' !== state.general.type && (
|
|
2196
|
+
<label>
|
|
2197
|
+
<span className='edit-label'>Legend Position</span>
|
|
2198
|
+
<select
|
|
2199
|
+
value={legend.position || false}
|
|
2200
|
+
onChange={event => {
|
|
2201
|
+
handleEditorChanges('sidebarPosition', event.target.value)
|
|
2202
|
+
}}
|
|
2203
|
+
>
|
|
2204
|
+
<option value='side'>Side</option>
|
|
2205
|
+
<option value='bottom'>Bottom</option>
|
|
2206
|
+
</select>
|
|
2207
|
+
</label>
|
|
2208
|
+
)}
|
|
2209
|
+
{'side' === legend.position && (
|
|
2501
2210
|
<label className='checkbox'>
|
|
2502
2211
|
<input
|
|
2503
2212
|
type='checkbox'
|
|
2504
|
-
checked={
|
|
2213
|
+
checked={legend.singleColumn}
|
|
2505
2214
|
onChange={event => {
|
|
2506
|
-
handleEditorChanges('
|
|
2215
|
+
handleEditorChanges('singleColumnLegend', event.target.checked)
|
|
2507
2216
|
}}
|
|
2508
2217
|
/>
|
|
2509
|
-
<span className='edit-label'>
|
|
2218
|
+
<span className='edit-label'>Single Column Legend</span>
|
|
2510
2219
|
</label>
|
|
2511
|
-
|
|
2220
|
+
)}
|
|
2221
|
+
{'bottom' === legend.position && (
|
|
2512
2222
|
<label className='checkbox'>
|
|
2513
2223
|
<input
|
|
2514
2224
|
type='checkbox'
|
|
2515
|
-
checked={
|
|
2225
|
+
checked={legend.singleRow}
|
|
2516
2226
|
onChange={event => {
|
|
2517
|
-
handleEditorChanges('
|
|
2227
|
+
handleEditorChanges('singleRowLegend', event.target.checked)
|
|
2518
2228
|
}}
|
|
2519
2229
|
/>
|
|
2520
|
-
<span className='edit-label'>
|
|
2230
|
+
<span className='edit-label'>Single Row Legend</span>
|
|
2521
2231
|
</label>
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
type='checkbox'
|
|
2526
|
-
checked={state.table.showDataTableLink}
|
|
2527
|
-
onChange={event => {
|
|
2528
|
-
handleEditorChanges('toggleDataTableLink', event.target.checked)
|
|
2529
|
-
}}
|
|
2530
|
-
/>
|
|
2531
|
-
<span className='edit-label'>Show Data Table Name & Link</span>
|
|
2532
|
-
</label>
|
|
2533
|
-
)}
|
|
2534
|
-
{isLoadedFromUrl && (
|
|
2535
|
-
<label className='checkbox'>
|
|
2536
|
-
<input
|
|
2537
|
-
type='checkbox'
|
|
2538
|
-
checked={state.table.showDownloadUrl}
|
|
2539
|
-
onChange={event => {
|
|
2540
|
-
handleEditorChanges('toggleDataUrl', event.target.checked)
|
|
2541
|
-
}}
|
|
2542
|
-
/>
|
|
2543
|
-
<span className='edit-label'>Show URL to Automatically Updated Data</span>
|
|
2544
|
-
</label>
|
|
2545
|
-
)}
|
|
2232
|
+
)}
|
|
2233
|
+
{/* always show */}
|
|
2234
|
+
{
|
|
2546
2235
|
<label className='checkbox'>
|
|
2547
2236
|
<input
|
|
2548
2237
|
type='checkbox'
|
|
2549
|
-
checked={
|
|
2238
|
+
checked={legend.showSpecialClassesLast}
|
|
2550
2239
|
onChange={event => {
|
|
2551
|
-
handleEditorChanges('
|
|
2240
|
+
handleEditorChanges('legendShowSpecialClassesLast', event.target.checked)
|
|
2552
2241
|
}}
|
|
2553
2242
|
/>
|
|
2554
|
-
<span className='edit-label'>Show
|
|
2243
|
+
<span className='edit-label'>Show Special Classes Last</span>
|
|
2244
|
+
</label>
|
|
2245
|
+
}
|
|
2246
|
+
{'category' !== legend.type && (
|
|
2247
|
+
<label className='checkbox'>
|
|
2248
|
+
<input type='checkbox' checked={legend.separateZero || false} onChange={event => handleEditorChanges('separateZero', event.target.checked)} />
|
|
2249
|
+
<span className='edit-label column-heading'>
|
|
2250
|
+
Separate Zero
|
|
2251
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2252
|
+
<Tooltip.Target>
|
|
2253
|
+
<Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
|
|
2254
|
+
</Tooltip.Target>
|
|
2255
|
+
<Tooltip.Content>
|
|
2256
|
+
<p>For numeric data, you can separate the zero value as its own data class.</p>
|
|
2257
|
+
</Tooltip.Content>
|
|
2258
|
+
</Tooltip>
|
|
2259
|
+
</span>
|
|
2555
2260
|
</label>
|
|
2556
|
-
|
|
2261
|
+
)}
|
|
2262
|
+
{/* Temp Checkbox */}
|
|
2263
|
+
{state.legend.type === 'equalnumber' && (
|
|
2264
|
+
<label className='checkbox'>
|
|
2557
2265
|
<input
|
|
2558
2266
|
type='checkbox'
|
|
2559
|
-
checked={state.general.
|
|
2267
|
+
checked={state.general.equalNumberOptIn}
|
|
2560
2268
|
onChange={event => {
|
|
2561
|
-
handleEditorChanges('
|
|
2269
|
+
handleEditorChanges('showEqualNumber', event.target.checked)
|
|
2562
2270
|
}}
|
|
2563
2271
|
/>
|
|
2564
|
-
<span className='edit-label'>
|
|
2565
|
-
|
|
2566
|
-
|
|
2272
|
+
<span className='edit-label column-heading'>Use new quantile legend</span>
|
|
2273
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2274
|
+
<Tooltip.Target>
|
|
2275
|
+
<Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
|
|
2276
|
+
</Tooltip.Target>
|
|
2277
|
+
<Tooltip.Content>
|
|
2278
|
+
<p>This prevents numbers from being used in more than one category (ie. 0-1, 1-2, 2-3) </p>
|
|
2279
|
+
</Tooltip.Content>
|
|
2280
|
+
</Tooltip>
|
|
2281
|
+
</label>
|
|
2282
|
+
)}
|
|
2283
|
+
{'category' !== legend.type && (
|
|
2284
|
+
<label>
|
|
2285
|
+
<span className='edit-label'>
|
|
2286
|
+
Number of Items
|
|
2287
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2288
|
+
<Tooltip.Target>
|
|
2289
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2290
|
+
</Tooltip.Target>
|
|
2291
|
+
<Tooltip.Content>
|
|
2292
|
+
<p>For numeric maps, select the number of data classes. Do not include designated special classes.</p>
|
|
2293
|
+
</Tooltip.Content>
|
|
2294
|
+
</Tooltip>
|
|
2295
|
+
</span>
|
|
2296
|
+
<select
|
|
2297
|
+
value={legend.numberOfItems}
|
|
2298
|
+
onChange={event => {
|
|
2299
|
+
handleEditorChanges('legendNumber', event.target.value)
|
|
2300
|
+
}}
|
|
2301
|
+
>
|
|
2302
|
+
{[...Array(numberOfItemsLimit).keys()].map(num => {
|
|
2303
|
+
return (
|
|
2304
|
+
<option value={num + 1} key={num + 1}>
|
|
2305
|
+
{num + 1}
|
|
2306
|
+
</option>
|
|
2307
|
+
)
|
|
2308
|
+
})}
|
|
2309
|
+
</select>
|
|
2310
|
+
</label>
|
|
2311
|
+
)}
|
|
2312
|
+
{'category' === legend.type && (
|
|
2313
|
+
<React.Fragment>
|
|
2314
|
+
<label>
|
|
2315
|
+
<span className='edit-label'>
|
|
2316
|
+
Category Order
|
|
2317
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2318
|
+
<Tooltip.Target>
|
|
2319
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2320
|
+
</Tooltip.Target>
|
|
2321
|
+
<Tooltip.Content>
|
|
2322
|
+
<p>Drag map categories into preferred legend order. </p>
|
|
2323
|
+
</Tooltip.Content>
|
|
2324
|
+
</Tooltip>
|
|
2325
|
+
</span>
|
|
2326
|
+
</label>
|
|
2327
|
+
{/* 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. */}
|
|
2328
|
+
<DragDropContext onDragEnd={({ source, destination }) => categoryMove(source.index, destination.index)}>
|
|
2329
|
+
<Droppable droppableId='category_order'>
|
|
2330
|
+
{provided => (
|
|
2331
|
+
<ul {...provided.droppableProps} className='sort-list' ref={provided.innerRef}>
|
|
2332
|
+
<CategoryList />
|
|
2333
|
+
{provided.placeholder}
|
|
2334
|
+
</ul>
|
|
2335
|
+
)}
|
|
2336
|
+
</Droppable>
|
|
2337
|
+
</DragDropContext>
|
|
2338
|
+
{state.legend.categoryValuesOrder && state.legend.categoryValuesOrder.length >= 10 && (
|
|
2339
|
+
<section className='error-box my-2'>
|
|
2340
|
+
<div>
|
|
2341
|
+
<strong className='pt-1'>Warning</strong>
|
|
2342
|
+
<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>
|
|
2343
|
+
</div>
|
|
2344
|
+
</section>
|
|
2345
|
+
)}
|
|
2346
|
+
</React.Fragment>
|
|
2347
|
+
)}
|
|
2348
|
+
<TextField value={legend.title} updateField={updateField} section='legend' fieldName='title' label='Legend Title' placeholder='Legend Title' />
|
|
2349
|
+
{false === legend.dynamicDescription && <TextField type='textarea' value={legend.description} updateField={updateField} section='legend' fieldName='description' label='Legend Description' />}
|
|
2350
|
+
{true === legend.dynamicDescription && (
|
|
2351
|
+
<React.Fragment>
|
|
2352
|
+
<label>
|
|
2353
|
+
<span>Legend Description</span>
|
|
2354
|
+
<span className='subtext'>For {displayFilterLegendValue(activeFilterValueForDescription)}</span>
|
|
2355
|
+
<DynamicDesc value={legend.descriptions[String(activeFilterValueForDescription)]} />
|
|
2356
|
+
</label>
|
|
2357
|
+
<label>
|
|
2358
|
+
<select
|
|
2359
|
+
value={String(activeFilterValueForDescription)}
|
|
2360
|
+
onChange={event => {
|
|
2361
|
+
handleEditorChanges('changeActiveFilterValue', event.target.value)
|
|
2362
|
+
}}
|
|
2363
|
+
>
|
|
2364
|
+
{filterValueOptionList.map((arr, i) => {
|
|
2365
|
+
return (
|
|
2366
|
+
<option value={arr} key={i}>
|
|
2367
|
+
{displayFilterLegendValue(arr)}
|
|
2368
|
+
</option>
|
|
2369
|
+
)
|
|
2370
|
+
})}
|
|
2371
|
+
</select>
|
|
2372
|
+
</label>
|
|
2373
|
+
</React.Fragment>
|
|
2374
|
+
)}
|
|
2375
|
+
{filtersJSX.length > 0 && (
|
|
2376
|
+
<label className='checkbox'>
|
|
2567
2377
|
<input
|
|
2568
2378
|
type='checkbox'
|
|
2569
|
-
checked={
|
|
2570
|
-
onChange={
|
|
2571
|
-
handleEditorChanges('
|
|
2379
|
+
checked={legend.dynamicDescription}
|
|
2380
|
+
onChange={() => {
|
|
2381
|
+
handleEditorChanges('dynamicDescription', filterValueOptionList[0])
|
|
2572
2382
|
}}
|
|
2573
2383
|
/>
|
|
2574
|
-
<span className='edit-label'>
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2384
|
+
<span className='edit-label column-heading'>
|
|
2385
|
+
Dynamic Legend Description
|
|
2386
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2387
|
+
<Tooltip.Target>
|
|
2388
|
+
<Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
|
|
2389
|
+
</Tooltip.Target>
|
|
2390
|
+
<Tooltip.Content>
|
|
2391
|
+
<p>Check this option if the map has multiple filter controls and you want to specify a description for each filter selection.</p>
|
|
2392
|
+
</Tooltip.Content>
|
|
2393
|
+
</Tooltip>
|
|
2394
|
+
</span>
|
|
2395
|
+
</label>
|
|
2396
|
+
)}
|
|
2397
|
+
{(filtersJSX.length > 0 || state.general.type === 'bubble' || state.general.geoType === 'us') && (
|
|
2398
|
+
<label className='checkbox'>
|
|
2399
|
+
<input type='checkbox' checked={legend.unified} onChange={event => handleEditorChanges('unifiedLegend', event.target.checked)} />
|
|
2400
|
+
<span className='edit-label column-heading'>
|
|
2401
|
+
Unified Legend
|
|
2402
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2403
|
+
<Tooltip.Target>
|
|
2404
|
+
<Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
|
|
2405
|
+
</Tooltip.Target>
|
|
2406
|
+
<Tooltip.Content>
|
|
2407
|
+
<p>
|
|
2408
|
+
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.
|
|
2409
|
+
</p>
|
|
2410
|
+
</Tooltip.Content>
|
|
2411
|
+
</Tooltip>
|
|
2412
|
+
</span>
|
|
2413
|
+
</label>
|
|
2414
|
+
)}
|
|
2415
|
+
</AccordionItemPanel>
|
|
2416
|
+
</AccordionItem>
|
|
2417
|
+
)}
|
|
2418
|
+
{'navigation' !== state.general.type && (
|
|
2579
2419
|
<AccordionItem>
|
|
2580
2420
|
{' '}
|
|
2581
|
-
{/*
|
|
2421
|
+
{/* Filters */}
|
|
2582
2422
|
<AccordionItemHeading>
|
|
2583
|
-
<AccordionItemButton>
|
|
2423
|
+
<AccordionItemButton>Filters</AccordionItemButton>
|
|
2584
2424
|
</AccordionItemHeading>
|
|
2585
2425
|
<AccordionItemPanel>
|
|
2586
|
-
<
|
|
2587
|
-
|
|
2588
|
-
|
|
2426
|
+
{filtersJSX.length > 0 ? <MapFilters /> : <p style={{ textAlign: 'center' }}>There are currently no filters.</p>}
|
|
2427
|
+
<button
|
|
2428
|
+
className={'btn full-width'}
|
|
2429
|
+
onClick={event => {
|
|
2430
|
+
event.preventDefault()
|
|
2431
|
+
changeFilter(null, 'addNew')
|
|
2432
|
+
}}
|
|
2433
|
+
>
|
|
2434
|
+
Add Filter
|
|
2435
|
+
</button>
|
|
2436
|
+
</AccordionItemPanel>
|
|
2437
|
+
</AccordionItem>
|
|
2438
|
+
)}
|
|
2439
|
+
{'navigation' !== state.general.type && (
|
|
2440
|
+
<AccordionItem>
|
|
2441
|
+
{' '}
|
|
2442
|
+
{/* Data Table */}
|
|
2443
|
+
<AccordionItemHeading>
|
|
2444
|
+
<AccordionItemButton>Data Table</AccordionItemButton>
|
|
2445
|
+
</AccordionItemHeading>
|
|
2446
|
+
<AccordionItemPanel>
|
|
2447
|
+
<TextField
|
|
2448
|
+
value={table.label}
|
|
2449
|
+
updateField={updateField}
|
|
2450
|
+
section='table'
|
|
2451
|
+
fieldName='label'
|
|
2452
|
+
id='dataTableTitle'
|
|
2453
|
+
label='Data Table Title'
|
|
2454
|
+
placeholder='Data Table'
|
|
2455
|
+
tooltip={
|
|
2589
2456
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
2590
2457
|
<Tooltip.Target>
|
|
2591
2458
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2592
2459
|
</Tooltip.Target>
|
|
2593
2460
|
<Tooltip.Content>
|
|
2594
|
-
<p>
|
|
2461
|
+
<p>Label is required for Data Table for 508 Compliance</p>
|
|
2595
2462
|
</Tooltip.Content>
|
|
2596
2463
|
</Tooltip>
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2464
|
+
}
|
|
2465
|
+
/>
|
|
2466
|
+
<label className='checkbox'>
|
|
2467
|
+
<input
|
|
2468
|
+
type='checkbox'
|
|
2469
|
+
checked={state.table.forceDisplay !== undefined ? state.table.forceDisplay : !isDashboard}
|
|
2600
2470
|
onChange={event => {
|
|
2601
|
-
handleEditorChanges('
|
|
2471
|
+
handleEditorChanges('showDataTable', event.target.checked)
|
|
2602
2472
|
}}
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2473
|
+
/>
|
|
2474
|
+
<span className='edit-label column-heading'>
|
|
2475
|
+
Show Data Table
|
|
2476
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2477
|
+
<Tooltip.Target>
|
|
2478
|
+
<Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
|
|
2479
|
+
</Tooltip.Target>
|
|
2480
|
+
<Tooltip.Content>
|
|
2481
|
+
<p>Data tables are required for 508 compliance. When choosing to hide this data table, replace with your own version.</p>
|
|
2482
|
+
</Tooltip.Content>
|
|
2483
|
+
</Tooltip>
|
|
2484
|
+
</span>
|
|
2607
2485
|
</label>
|
|
2608
|
-
|
|
2486
|
+
<TextField
|
|
2487
|
+
value={table.indexLabel || ''}
|
|
2488
|
+
updateField={updateField}
|
|
2489
|
+
section='table'
|
|
2490
|
+
fieldName='indexLabel'
|
|
2491
|
+
label='Index Column Header'
|
|
2492
|
+
placeholder='Location'
|
|
2493
|
+
tooltip={
|
|
2494
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2495
|
+
<Tooltip.Target>
|
|
2496
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2497
|
+
</Tooltip.Target>
|
|
2498
|
+
<Tooltip.Content>
|
|
2499
|
+
<p>To comply with 508 standards, if the first column in the data table has no header, enter a brief one here.</p>
|
|
2500
|
+
</Tooltip.Content>
|
|
2501
|
+
</Tooltip>
|
|
2502
|
+
}
|
|
2503
|
+
/>
|
|
2504
|
+
<TextField
|
|
2505
|
+
value={state.table.caption}
|
|
2506
|
+
updateField={updateField}
|
|
2507
|
+
section='table'
|
|
2508
|
+
fieldName='caption'
|
|
2509
|
+
label='Data Table Caption'
|
|
2510
|
+
placeholder='Data Table'
|
|
2511
|
+
tooltip={
|
|
2512
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2513
|
+
<Tooltip.Target>
|
|
2514
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2515
|
+
</Tooltip.Target>
|
|
2516
|
+
<Tooltip.Content>
|
|
2517
|
+
<p>Enter a description of the data table to be read by screen readers.</p>
|
|
2518
|
+
</Tooltip.Content>
|
|
2519
|
+
</Tooltip>
|
|
2520
|
+
}
|
|
2521
|
+
type='textarea'
|
|
2522
|
+
/>
|
|
2609
2523
|
<label className='checkbox'>
|
|
2610
2524
|
<input
|
|
2611
2525
|
type='checkbox'
|
|
2612
|
-
checked={state.
|
|
2526
|
+
checked={state.table.limitHeight}
|
|
2613
2527
|
onChange={event => {
|
|
2614
|
-
handleEditorChanges('
|
|
2528
|
+
handleEditorChanges('limitDataTableHeight', event.target.checked)
|
|
2615
2529
|
}}
|
|
2616
2530
|
/>
|
|
2617
|
-
<span className='edit-label'>
|
|
2618
|
-
</label>
|
|
2619
|
-
</AccordionItemPanel>
|
|
2620
|
-
</AccordionItem>
|
|
2621
|
-
<AccordionItem>
|
|
2622
|
-
{' '}
|
|
2623
|
-
{/* Visual */}
|
|
2624
|
-
<AccordionItemHeading>
|
|
2625
|
-
<AccordionItemButton>Visual</AccordionItemButton>
|
|
2626
|
-
</AccordionItemHeading>
|
|
2627
|
-
<AccordionItemPanel>
|
|
2628
|
-
<label>
|
|
2629
|
-
<span className='edit-label'>Header Theme</span>
|
|
2630
|
-
<ul className='color-palette'>
|
|
2631
|
-
{headerColors.map(palette => {
|
|
2632
|
-
return (
|
|
2633
|
-
<li
|
|
2634
|
-
title={palette}
|
|
2635
|
-
key={palette}
|
|
2636
|
-
onClick={() => {
|
|
2637
|
-
handleEditorChanges('headerColor', palette)
|
|
2638
|
-
}}
|
|
2639
|
-
className={state.general.headerColor === palette ? 'selected ' + palette : palette}
|
|
2640
|
-
></li>
|
|
2641
|
-
)
|
|
2642
|
-
})}
|
|
2643
|
-
</ul>
|
|
2531
|
+
<span className='edit-label'>Limit Table Height</span>
|
|
2644
2532
|
</label>
|
|
2533
|
+
{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' />}
|
|
2645
2534
|
<label className='checkbox'>
|
|
2646
2535
|
<input
|
|
2647
2536
|
type='checkbox'
|
|
2648
|
-
checked={state.
|
|
2537
|
+
checked={state.table.expanded || false}
|
|
2649
2538
|
onChange={event => {
|
|
2650
|
-
handleEditorChanges('
|
|
2539
|
+
handleEditorChanges('expandDataTable', event.target.checked)
|
|
2651
2540
|
}}
|
|
2652
2541
|
/>
|
|
2653
|
-
<span className='edit-label'>
|
|
2542
|
+
<span className='edit-label'>Map loads with data table expanded</span>
|
|
2654
2543
|
</label>
|
|
2655
|
-
|
|
2656
|
-
{'navigation' === state.general.type && (
|
|
2544
|
+
{isDashboard && (
|
|
2657
2545
|
<label className='checkbox'>
|
|
2658
2546
|
<input
|
|
2659
2547
|
type='checkbox'
|
|
2660
|
-
checked={state.
|
|
2548
|
+
checked={state.table.showDataTableLink}
|
|
2661
2549
|
onChange={event => {
|
|
2662
|
-
handleEditorChanges('
|
|
2550
|
+
handleEditorChanges('toggleDataTableLink', event.target.checked)
|
|
2663
2551
|
}}
|
|
2664
2552
|
/>
|
|
2665
|
-
<span className='edit-label'>
|
|
2666
|
-
</label>
|
|
2667
|
-
)}
|
|
2668
|
-
<label>
|
|
2669
|
-
<span className='edit-label'>Geo Border Color</span>
|
|
2670
|
-
<select
|
|
2671
|
-
value={state.general.geoBorderColor || false}
|
|
2672
|
-
onChange={event => {
|
|
2673
|
-
handleEditorChanges('geoBorderColor', event.target.value)
|
|
2674
|
-
}}
|
|
2675
|
-
>
|
|
2676
|
-
<option value='darkGray'>Dark Gray (Default)</option>
|
|
2677
|
-
<option value='sameAsBackground'>White</option>
|
|
2678
|
-
</select>
|
|
2679
|
-
</label>
|
|
2680
|
-
<label>
|
|
2681
|
-
<span className='edit-label'>Map Color Palette</span>
|
|
2682
|
-
</label>
|
|
2683
|
-
{/* <InputCheckbox section="general" subsection="palette" fieldName='isReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} /> */}
|
|
2684
|
-
<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} />
|
|
2685
|
-
<span>Sequential</span>
|
|
2686
|
-
<ul className='color-palette'>
|
|
2687
|
-
{sequential.map(palette => {
|
|
2688
|
-
const colorOne = {
|
|
2689
|
-
backgroundColor: colorPalettes[palette][2]
|
|
2690
|
-
}
|
|
2691
|
-
|
|
2692
|
-
const colorTwo = {
|
|
2693
|
-
backgroundColor: colorPalettes[palette][4]
|
|
2694
|
-
}
|
|
2695
|
-
|
|
2696
|
-
const colorThree = {
|
|
2697
|
-
backgroundColor: colorPalettes[palette][6]
|
|
2698
|
-
}
|
|
2699
|
-
|
|
2700
|
-
return (
|
|
2701
|
-
<li
|
|
2702
|
-
title={palette}
|
|
2703
|
-
key={palette}
|
|
2704
|
-
onClick={() => {
|
|
2705
|
-
handleEditorChanges('color', palette)
|
|
2706
|
-
}}
|
|
2707
|
-
className={state.color === palette ? 'selected' : ''}
|
|
2708
|
-
>
|
|
2709
|
-
<span style={colorOne}></span>
|
|
2710
|
-
<span style={colorTwo}></span>
|
|
2711
|
-
<span style={colorThree}></span>
|
|
2712
|
-
</li>
|
|
2713
|
-
)
|
|
2714
|
-
})}
|
|
2715
|
-
</ul>
|
|
2716
|
-
<span>Non-Sequential</span>
|
|
2717
|
-
<ul className='color-palette'>
|
|
2718
|
-
{nonSequential.map(palette => {
|
|
2719
|
-
const colorOne = {
|
|
2720
|
-
backgroundColor: colorPalettes[palette][2]
|
|
2721
|
-
}
|
|
2722
|
-
|
|
2723
|
-
const colorTwo = {
|
|
2724
|
-
backgroundColor: colorPalettes[palette][4]
|
|
2725
|
-
}
|
|
2726
|
-
|
|
2727
|
-
const colorThree = {
|
|
2728
|
-
backgroundColor: colorPalettes[palette][6]
|
|
2729
|
-
}
|
|
2730
|
-
|
|
2731
|
-
// hide palettes with too few colors for region maps
|
|
2732
|
-
if (colorPalettes[palette].length <= 8 && state.general.geoType === 'us-region') {
|
|
2733
|
-
return ''
|
|
2734
|
-
}
|
|
2735
|
-
return (
|
|
2736
|
-
<li
|
|
2737
|
-
title={palette}
|
|
2738
|
-
key={palette}
|
|
2739
|
-
onClick={() => {
|
|
2740
|
-
handleEditorChanges('color', palette)
|
|
2741
|
-
}}
|
|
2742
|
-
className={state.color === palette ? 'selected' : ''}
|
|
2743
|
-
>
|
|
2744
|
-
<span style={colorOne}></span>
|
|
2745
|
-
<span style={colorTwo}></span>
|
|
2746
|
-
<span style={colorThree}></span>
|
|
2747
|
-
</li>
|
|
2748
|
-
)
|
|
2749
|
-
})}
|
|
2750
|
-
</ul>
|
|
2751
|
-
{('us-geocode' === state.general.type || 'world-geocode' === state.general.type) && (
|
|
2752
|
-
<label>
|
|
2753
|
-
Geocode Settings
|
|
2754
|
-
<TextField type='number' value={state.visual.geoCodeCircleSize} section='visual' max='10' fieldName='geoCodeCircleSize' label='Geocode Circle Size' updateField={updateField} />
|
|
2553
|
+
<span className='edit-label'>Show Data Table Name & Link</span>
|
|
2755
2554
|
</label>
|
|
2756
2555
|
)}
|
|
2757
|
-
|
|
2758
|
-
{state.general.type === 'bubble' && (
|
|
2759
|
-
<>
|
|
2760
|
-
<TextField type='number' value={state.visual.minBubbleSize} section='visual' fieldName='minBubbleSize' label='Minimum Bubble Size' updateField={updateField} />
|
|
2761
|
-
<TextField type='number' value={state.visual.maxBubbleSize} section='visual' fieldName='maxBubbleSize' label='Maximum Bubble Size' updateField={updateField} />
|
|
2762
|
-
</>
|
|
2763
|
-
)}
|
|
2764
|
-
{(state.general.geoType === 'world' || (state.general.geoType === 'us' && state.general.type === 'bubble')) && (
|
|
2556
|
+
{isLoadedFromUrl && (
|
|
2765
2557
|
<label className='checkbox'>
|
|
2766
2558
|
<input
|
|
2767
2559
|
type='checkbox'
|
|
2768
|
-
checked={state.
|
|
2560
|
+
checked={state.table.showDownloadUrl}
|
|
2769
2561
|
onChange={event => {
|
|
2770
|
-
handleEditorChanges('
|
|
2562
|
+
handleEditorChanges('toggleDataUrl', event.target.checked)
|
|
2771
2563
|
}}
|
|
2772
2564
|
/>
|
|
2773
|
-
<span className='edit-label'>Show
|
|
2565
|
+
<span className='edit-label'>Show URL to Automatically Updated Data</span>
|
|
2774
2566
|
</label>
|
|
2775
2567
|
)}
|
|
2776
|
-
|
|
2777
|
-
<
|
|
2568
|
+
<label className='checkbox'>
|
|
2569
|
+
<input
|
|
2570
|
+
type='checkbox'
|
|
2571
|
+
checked={state.general.showDownloadButton}
|
|
2572
|
+
onChange={event => {
|
|
2573
|
+
handleEditorChanges('toggleDownloadButton', event.target.checked)
|
|
2574
|
+
}}
|
|
2575
|
+
/>
|
|
2576
|
+
<span className='edit-label'>Show Download CSV Link</span>
|
|
2577
|
+
</label>
|
|
2578
|
+
<label className='checkbox'>
|
|
2579
|
+
<input
|
|
2580
|
+
type='checkbox'
|
|
2581
|
+
checked={state.general.showFullGeoNameInCSV}
|
|
2582
|
+
onChange={event => {
|
|
2583
|
+
handleEditorChanges('toggleShowFullGeoNameInCSV', event.target.checked)
|
|
2584
|
+
}}
|
|
2585
|
+
/>
|
|
2586
|
+
<span className='edit-label'>Include Full Geo Name in CSV Download</span>
|
|
2587
|
+
</label>
|
|
2588
|
+
{/* <label className='checkbox'>
|
|
2778
2589
|
<input
|
|
2779
2590
|
type='checkbox'
|
|
2780
|
-
checked={state.general.
|
|
2591
|
+
checked={state.general.showDownloadImgButton}
|
|
2781
2592
|
onChange={event => {
|
|
2782
|
-
handleEditorChanges('
|
|
2593
|
+
handleEditorChanges('toggleDownloadImgButton', event.target.checked)
|
|
2783
2594
|
}}
|
|
2784
2595
|
/>
|
|
2785
|
-
<span className='edit-label'>
|
|
2786
|
-
</label>
|
|
2787
|
-
|
|
2788
|
-
{state.general.type === 'bubble' && (
|
|
2789
|
-
<label className='checkbox'>
|
|
2596
|
+
<span className='edit-label'>Enable Image Download</span>
|
|
2597
|
+
</label> */}
|
|
2598
|
+
{/* <label className='checkbox'>
|
|
2790
2599
|
<input
|
|
2791
2600
|
type='checkbox'
|
|
2792
|
-
checked={state.
|
|
2601
|
+
checked={state.general.showDownloadPdfButton}
|
|
2793
2602
|
onChange={event => {
|
|
2794
|
-
handleEditorChanges('
|
|
2603
|
+
handleEditorChanges('toggleDownloadPdfButton', event.target.checked)
|
|
2795
2604
|
}}
|
|
2796
2605
|
/>
|
|
2797
|
-
<span className='edit-label'>
|
|
2798
|
-
</label>
|
|
2799
|
-
)}
|
|
2800
|
-
{state.general.geoType === 'us' ||
|
|
2801
|
-
state.general.geoType === 'us-county' ||
|
|
2802
|
-
(state.general.geoType === 'world' && (
|
|
2803
|
-
<label>
|
|
2804
|
-
<span className='edit-label'>City Style</span>
|
|
2805
|
-
<select
|
|
2806
|
-
value={state.visual.cityStyle || false}
|
|
2807
|
-
onChange={event => {
|
|
2808
|
-
handleEditorChanges('handleCityStyle', event.target.value)
|
|
2809
|
-
}}
|
|
2810
|
-
>
|
|
2811
|
-
<option value='circle'>Circle</option>
|
|
2812
|
-
<option value='pin'>Pin</option>
|
|
2813
|
-
</select>
|
|
2814
|
-
</label>
|
|
2815
|
-
))}
|
|
2606
|
+
<span className='edit-label'>Enable Pdf Download</span>
|
|
2607
|
+
</label> */}
|
|
2816
2608
|
</AccordionItemPanel>
|
|
2817
2609
|
</AccordionItem>
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2610
|
+
)}
|
|
2611
|
+
<AccordionItem>
|
|
2612
|
+
{' '}
|
|
2613
|
+
{/* Tooltips */}
|
|
2614
|
+
<AccordionItemHeading>
|
|
2615
|
+
<AccordionItemButton>Interactivity</AccordionItemButton>
|
|
2616
|
+
</AccordionItemHeading>
|
|
2617
|
+
<AccordionItemPanel>
|
|
2618
|
+
<label>
|
|
2619
|
+
<span className='edit-label'>
|
|
2620
|
+
Detail displays on{' '}
|
|
2621
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2622
|
+
<Tooltip.Target>
|
|
2623
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2624
|
+
</Tooltip.Target>
|
|
2625
|
+
<Tooltip.Content>
|
|
2626
|
+
<p>At mobile sizes, information always appears in a popover modal when a user taps on an item.</p>
|
|
2627
|
+
</Tooltip.Content>
|
|
2628
|
+
</Tooltip>
|
|
2629
|
+
</span>
|
|
2630
|
+
<select
|
|
2631
|
+
value={state.tooltips.appearanceType}
|
|
2632
|
+
onChange={event => {
|
|
2633
|
+
handleEditorChanges('appearanceType', event.target.value)
|
|
2634
|
+
}}
|
|
2635
|
+
>
|
|
2636
|
+
<option value='hover'>Hover - Tooltip</option>
|
|
2637
|
+
<option value='click'>Click - Popover Modal</option>
|
|
2638
|
+
</select>
|
|
2639
|
+
</label>
|
|
2640
|
+
{'click' === state.tooltips.appearanceType && <TextField value={tooltips.linkLabel} section='tooltips' fieldName='linkLabel' label='Tooltips Link Label' updateField={updateField} />}
|
|
2641
|
+
<label className='checkbox'>
|
|
2642
|
+
<input
|
|
2643
|
+
type='checkbox'
|
|
2644
|
+
checked={state.tooltips.capitalizeLabels}
|
|
2645
|
+
onChange={event => {
|
|
2646
|
+
handleEditorChanges('capitalizeLabels', event.target.checked)
|
|
2647
|
+
}}
|
|
2648
|
+
/>
|
|
2649
|
+
<span className='edit-label'>Capitalize text inside tooltip</span>
|
|
2650
|
+
</label>
|
|
2651
|
+
</AccordionItemPanel>
|
|
2652
|
+
</AccordionItem>
|
|
2653
|
+
<AccordionItem>
|
|
2654
|
+
{' '}
|
|
2655
|
+
{/* Visual */}
|
|
2656
|
+
<AccordionItemHeading>
|
|
2657
|
+
<AccordionItemButton>Visual</AccordionItemButton>
|
|
2658
|
+
</AccordionItemHeading>
|
|
2659
|
+
<AccordionItemPanel>
|
|
2660
|
+
<label>
|
|
2661
|
+
<span className='edit-label'>Header Theme</span>
|
|
2662
|
+
<ul className='color-palette'>
|
|
2663
|
+
{headerColors.map(palette => {
|
|
2664
|
+
return (
|
|
2665
|
+
<li
|
|
2666
|
+
title={palette}
|
|
2667
|
+
key={palette}
|
|
2668
|
+
onClick={() => {
|
|
2669
|
+
handleEditorChanges('headerColor', palette)
|
|
2670
|
+
}}
|
|
2671
|
+
className={state.general.headerColor === palette ? 'selected ' + palette : palette}
|
|
2672
|
+
></li>
|
|
2673
|
+
)
|
|
2674
|
+
})}
|
|
2675
|
+
</ul>
|
|
2676
|
+
</label>
|
|
2677
|
+
<label className='checkbox'>
|
|
2678
|
+
<input
|
|
2679
|
+
type='checkbox'
|
|
2680
|
+
checked={state.general.showTitle || false}
|
|
2681
|
+
onChange={event => {
|
|
2682
|
+
handleEditorChanges('showTitle', event.target.checked)
|
|
2683
|
+
}}
|
|
2684
|
+
/>
|
|
2685
|
+
<span className='edit-label'>Show Title</span>
|
|
2686
|
+
</label>
|
|
2687
|
+
|
|
2688
|
+
{'navigation' === state.general.type && (
|
|
2689
|
+
<label className='checkbox'>
|
|
2690
|
+
<input
|
|
2691
|
+
type='checkbox'
|
|
2692
|
+
checked={state.general.fullBorder || false}
|
|
2693
|
+
onChange={event => {
|
|
2694
|
+
handleEditorChanges('fullBorder', event.target.checked)
|
|
2695
|
+
}}
|
|
2696
|
+
/>
|
|
2697
|
+
<span className='edit-label'>Add border around map</span>
|
|
2698
|
+
</label>
|
|
2699
|
+
)}
|
|
2700
|
+
<label>
|
|
2701
|
+
<span className='edit-label'>Geo Border Color</span>
|
|
2702
|
+
<select
|
|
2703
|
+
value={state.general.geoBorderColor || false}
|
|
2704
|
+
onChange={event => {
|
|
2705
|
+
handleEditorChanges('geoBorderColor', event.target.value)
|
|
2706
|
+
}}
|
|
2707
|
+
>
|
|
2708
|
+
<option value='darkGray'>Dark Gray (Default)</option>
|
|
2709
|
+
<option value='sameAsBackground'>White</option>
|
|
2710
|
+
</select>
|
|
2711
|
+
</label>
|
|
2712
|
+
<label>
|
|
2713
|
+
<span className='edit-label'>Map Color Palette</span>
|
|
2714
|
+
</label>
|
|
2715
|
+
{/* <InputCheckbox section="general" subsection="palette" fieldName='isReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} /> */}
|
|
2716
|
+
<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} />
|
|
2717
|
+
<span>Sequential</span>
|
|
2718
|
+
<ul className='color-palette'>
|
|
2719
|
+
{sequential.map(palette => {
|
|
2720
|
+
const colorOne = {
|
|
2721
|
+
backgroundColor: colorPalettes[palette][2]
|
|
2722
|
+
}
|
|
2723
|
+
|
|
2724
|
+
const colorTwo = {
|
|
2725
|
+
backgroundColor: colorPalettes[palette][4]
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2728
|
+
const colorThree = {
|
|
2729
|
+
backgroundColor: colorPalettes[palette][6]
|
|
2730
|
+
}
|
|
2824
2731
|
|
|
2825
|
-
{state.map.layers.map((layer, index) => {
|
|
2826
2732
|
return (
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
<label htmlFor='layerNamespace'>TOPOJSON Namespace:</label>
|
|
2840
|
-
<input type='text' name='layerNamespace' value={layer.namespace} onChange={e => handleMapLayerNamespace(e, index)} />
|
|
2841
|
-
<label htmlFor='layerTooltip'>Tooltip:</label>
|
|
2842
|
-
<textarea name='layerTooltip' value={layer.tooltip} onChange={e => handleMapLayerTooltip(e, index)}></textarea>
|
|
2843
|
-
<button onClick={e => handleRemoveLayer(e, index)}>Remove Layer</button>
|
|
2844
|
-
</div>
|
|
2845
|
-
</AccordionItemPanel>
|
|
2846
|
-
</AccordionItem>
|
|
2847
|
-
</Accordion>
|
|
2848
|
-
</>
|
|
2733
|
+
<li
|
|
2734
|
+
title={palette}
|
|
2735
|
+
key={palette}
|
|
2736
|
+
onClick={() => {
|
|
2737
|
+
handleEditorChanges('color', palette)
|
|
2738
|
+
}}
|
|
2739
|
+
className={state.color === palette ? 'selected' : ''}
|
|
2740
|
+
>
|
|
2741
|
+
<span style={colorOne}></span>
|
|
2742
|
+
<span style={colorTwo}></span>
|
|
2743
|
+
<span style={colorThree}></span>
|
|
2744
|
+
</li>
|
|
2849
2745
|
)
|
|
2850
2746
|
})}
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2747
|
+
</ul>
|
|
2748
|
+
<span>Non-Sequential</span>
|
|
2749
|
+
<ul className='color-palette'>
|
|
2750
|
+
{nonSequential.map(palette => {
|
|
2751
|
+
const colorOne = {
|
|
2752
|
+
backgroundColor: colorPalettes[palette][2]
|
|
2753
|
+
}
|
|
2754
|
+
|
|
2755
|
+
const colorTwo = {
|
|
2756
|
+
backgroundColor: colorPalettes[palette][4]
|
|
2757
|
+
}
|
|
2758
|
+
|
|
2759
|
+
const colorThree = {
|
|
2760
|
+
backgroundColor: colorPalettes[palette][6]
|
|
2761
|
+
}
|
|
2762
|
+
|
|
2763
|
+
// hide palettes with too few colors for region maps
|
|
2764
|
+
if (colorPalettes[palette].length <= 8 && state.general.geoType === 'us-region') {
|
|
2765
|
+
return ''
|
|
2766
|
+
}
|
|
2767
|
+
return (
|
|
2768
|
+
<li
|
|
2769
|
+
title={palette}
|
|
2770
|
+
key={palette}
|
|
2771
|
+
onClick={() => {
|
|
2772
|
+
handleEditorChanges('color', palette)
|
|
2773
|
+
}}
|
|
2774
|
+
className={state.color === palette ? 'selected' : ''}
|
|
2775
|
+
>
|
|
2776
|
+
<span style={colorOne}></span>
|
|
2777
|
+
<span style={colorTwo}></span>
|
|
2778
|
+
<span style={colorThree}></span>
|
|
2779
|
+
</li>
|
|
2780
|
+
)
|
|
2781
|
+
})}
|
|
2782
|
+
</ul>
|
|
2783
|
+
{('us-geocode' === state.general.type || 'world-geocode' === state.general.type) && (
|
|
2784
|
+
<label>
|
|
2785
|
+
Geocode Settings
|
|
2786
|
+
<TextField type='number' value={state.visual.geoCodeCircleSize} section='visual' max='10' fieldName='geoCodeCircleSize' label='Geocode Circle Size' updateField={updateField} />
|
|
2787
|
+
</label>
|
|
2788
|
+
)}
|
|
2789
|
+
|
|
2790
|
+
{state.general.type === 'bubble' && (
|
|
2791
|
+
<>
|
|
2792
|
+
<TextField type='number' value={state.visual.minBubbleSize} section='visual' fieldName='minBubbleSize' label='Minimum Bubble Size' updateField={updateField} />
|
|
2793
|
+
<TextField type='number' value={state.visual.maxBubbleSize} section='visual' fieldName='maxBubbleSize' label='Maximum Bubble Size' updateField={updateField} />
|
|
2794
|
+
</>
|
|
2795
|
+
)}
|
|
2796
|
+
{(state.general.geoType === 'world' || (state.general.geoType === 'us' && state.general.type === 'bubble')) && (
|
|
2797
|
+
<label className='checkbox'>
|
|
2798
|
+
<input
|
|
2799
|
+
type='checkbox'
|
|
2800
|
+
checked={state.visual.showBubbleZeros}
|
|
2801
|
+
onChange={event => {
|
|
2802
|
+
handleEditorChanges('showBubbleZeros', event.target.checked)
|
|
2803
|
+
}}
|
|
2804
|
+
/>
|
|
2805
|
+
<span className='edit-label'>Show Data with Zero's on Bubble Map</span>
|
|
2806
|
+
</label>
|
|
2807
|
+
)}
|
|
2808
|
+
{state.general.geoType === 'world' && (
|
|
2809
|
+
<label className='checkbox'>
|
|
2810
|
+
<input
|
|
2811
|
+
type='checkbox'
|
|
2812
|
+
checked={state.general.allowMapZoom}
|
|
2813
|
+
onChange={event => {
|
|
2814
|
+
handleEditorChanges('allowMapZoom', event.target.checked)
|
|
2815
|
+
}}
|
|
2816
|
+
/>
|
|
2817
|
+
<span className='edit-label'>Allow Map Zooming</span>
|
|
2818
|
+
</label>
|
|
2819
|
+
)}
|
|
2820
|
+
{state.general.type === 'bubble' && (
|
|
2821
|
+
<label className='checkbox'>
|
|
2822
|
+
<input
|
|
2823
|
+
type='checkbox'
|
|
2824
|
+
checked={state.visual.extraBubbleBorder}
|
|
2825
|
+
onChange={event => {
|
|
2826
|
+
handleEditorChanges('toggleExtraBubbleBorder', event.target.checked)
|
|
2827
|
+
}}
|
|
2828
|
+
/>
|
|
2829
|
+
<span className='edit-label'>Bubble Map has extra border</span>
|
|
2830
|
+
</label>
|
|
2831
|
+
)}
|
|
2832
|
+
{(state.general.geoType === 'us' || state.general.geoType === 'us-county' || state.general.geoType === 'world') && (
|
|
2833
|
+
<label>
|
|
2834
|
+
<span className='edit-label'>City Style</span>
|
|
2835
|
+
<select
|
|
2836
|
+
value={state.visual.cityStyle || false}
|
|
2837
|
+
onChange={event => {
|
|
2838
|
+
handleEditorChanges('handleCityStyle', event.target.value)
|
|
2839
|
+
}}
|
|
2840
|
+
>
|
|
2841
|
+
<option value='circle'>Circle</option>
|
|
2842
|
+
<option value='pin'>Pin</option>
|
|
2843
|
+
</select>
|
|
2844
|
+
</label>
|
|
2845
|
+
)}
|
|
2846
|
+
<label htmlFor='opacity'>
|
|
2847
|
+
<TextField type='number' min={0} max={100} value={state.tooltips.opacity ? state.tooltips.opacity : 100} section='tooltips' fieldName='opacity' label='Tooltip Opacity (%)' updateField={updateField} />
|
|
2848
|
+
</label>
|
|
2849
|
+
</AccordionItemPanel>
|
|
2850
|
+
</AccordionItem>
|
|
2851
|
+
<AccordionItem>
|
|
2852
|
+
<AccordionItemHeading>
|
|
2853
|
+
<AccordionItemButton>Custom Map Layers</AccordionItemButton>
|
|
2854
|
+
</AccordionItemHeading>
|
|
2855
|
+
<AccordionItemPanel>
|
|
2856
|
+
{state.map.layers.length === 0 && <p>There are currently no layers.</p>}
|
|
2857
|
+
|
|
2858
|
+
{state.map.layers.map((layer, index) => {
|
|
2859
|
+
return (
|
|
2860
|
+
<>
|
|
2861
|
+
<Accordion allowZeroExpanded>
|
|
2862
|
+
<AccordionItem className='series-item map-layers-list'>
|
|
2863
|
+
<AccordionItemHeading className='series-item__title map-layers-list--title'>
|
|
2864
|
+
<AccordionItemButton>{`Layer ${index + 1}: ${layer.name}`}</AccordionItemButton>
|
|
2865
|
+
</AccordionItemHeading>
|
|
2866
|
+
<AccordionItemPanel>
|
|
2867
|
+
<div className='map-layers-panel'>
|
|
2868
|
+
<label htmlFor='layerName'>Layer Name:</label>
|
|
2869
|
+
<input type='text' name='layerName' value={layer.name} onChange={e => handleMapLayer(e, index, 'name')} />
|
|
2870
|
+
<label htmlFor='layerFilename'>File:</label>
|
|
2871
|
+
<input type='text' name='layerFilename' value={layer.url} onChange={e => handleMapLayer(e, index, 'url')} />
|
|
2872
|
+
<label htmlFor='layerNamespace'>TOPOJSON Namespace:</label>
|
|
2873
|
+
<input type='text' name='layerNamespace' value={layer.namespace} onChange={e => handleMapLayer(e, index, 'namespace')} />
|
|
2874
|
+
<label htmlFor='layerFill'>Fill Color:</label>
|
|
2875
|
+
<input type='text' name='layerFill' value={layer.fill} onChange={e => handleMapLayer(e, index, 'fill')} />
|
|
2876
|
+
<label htmlFor='layerFill'>Fill Opacity (%):</label>
|
|
2877
|
+
<input type='number' min={0} max={100} name='layerFill' value={layer.fillOpacity ? layer.fillOpacity * 100 : ''} onChange={e => handleMapLayer(e, index, 'fillOpacity')} />
|
|
2878
|
+
<label htmlFor='layerStroke'>Stroke Color:</label>
|
|
2879
|
+
<input type='text' name='layerStroke' value={layer.stroke} onChange={e => handleMapLayer(e, index, 'stroke')} />
|
|
2880
|
+
<label htmlFor='layerStroke'>Stroke Width:</label>
|
|
2881
|
+
<input type='number' min={0} max={5} name='layerStrokeWidth' value={layer.strokeWidth} onChange={e => handleMapLayer(e, index, 'strokeWidth')} />
|
|
2882
|
+
<label htmlFor='layerTooltip'>Tooltip:</label>
|
|
2883
|
+
<textarea name='layerTooltip' value={layer.tooltip} onChange={e => handleMapLayer(e, index, 'tooltip')}></textarea>
|
|
2884
|
+
<button onClick={e => handleRemoveLayer(e, index)}>Remove Layer</button>
|
|
2885
|
+
</div>
|
|
2886
|
+
</AccordionItemPanel>
|
|
2887
|
+
</AccordionItem>
|
|
2888
|
+
</Accordion>
|
|
2889
|
+
</>
|
|
2890
|
+
)
|
|
2891
|
+
})}
|
|
2892
|
+
<button className={'btn full-width'} onClick={handleAddLayer}>
|
|
2893
|
+
Add Map Layer
|
|
2894
|
+
</button>
|
|
2895
|
+
</AccordionItemPanel>
|
|
2896
|
+
</AccordionItem>
|
|
2897
|
+
</Accordion>
|
|
2858
2898
|
<AdvancedEditor loadConfig={loadConfig} state={state} convertStateToConfig={convertStateToConfig} />
|
|
2859
2899
|
</section>
|
|
2860
2900
|
</section>
|