@cdc/map 2.6.3 → 4.22.10-alpha.1
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/LICENSE +201 -0
- package/dist/cdcmap.js +32 -18
- package/examples/bubble-us.json +363 -0
- package/examples/bubble-world.json +427 -0
- package/examples/default-county.json +64 -12
- package/examples/default-geocode.json +746 -0
- package/examples/default-hex.json +477 -0
- package/examples/default-usa-regions.json +118 -0
- package/examples/default-usa.json +1 -1
- package/examples/default-world-data.json +1450 -0
- package/examples/default-world.json +5 -3
- package/examples/example-city-state.json +46 -1
- package/examples/gallery/categorical-qualitative.json +797 -0
- package/examples/gallery/categorical-scale-based.json +739 -0
- package/examples/gallery/city-state.json +479 -0
- package/examples/gallery/county.json +22731 -0
- package/examples/gallery/equal-interval.json +1027 -0
- package/examples/gallery/equal-number.json +1027 -0
- package/examples/gallery/filterable.json +909 -0
- package/examples/gallery/hex-filtered.json +420 -0
- package/examples/gallery/hex.json +413 -0
- package/examples/gallery/single-state.json +21402 -0
- package/examples/gallery/world.json +1592 -0
- package/examples/private/atsdr.json +439 -0
- package/examples/private/atsdr_new.json +436 -0
- package/examples/private/bubble.json +285 -0
- package/examples/private/city-state.json +428 -0
- package/examples/private/city-state2.json +434 -0
- package/examples/private/cty-issue.json +42768 -0
- package/examples/private/default-usa.json +460 -0
- package/examples/private/default-world-data.json +1444 -0
- package/examples/private/default.json +968 -0
- package/examples/private/legend-issue.json +1 -0
- package/examples/private/map-rounding-error.json +42759 -0
- package/examples/private/map.csv +60 -0
- package/examples/private/mdx.json +210 -0
- package/examples/private/monkeypox.json +376 -0
- package/examples/private/regions.json +52 -0
- package/examples/private/valid-data-map.csv +59 -0
- package/examples/private/wcmsrd-13881-data.json +2858 -0
- package/examples/private/wcmsrd-13881.json +5823 -0
- package/examples/private/wcmsrd-14492-data.json +292 -0
- package/examples/private/wcmsrd-14492.json +114 -0
- package/examples/private/wcmsrd-test.json +268 -0
- package/examples/private/world.json +1580 -0
- package/examples/private/worldmap.json +1490 -0
- package/package.json +51 -50
- package/src/CdcMap.js +1384 -1075
- package/src/components/BubbleList.js +244 -0
- package/src/components/CityList.js +79 -17
- package/src/components/CountyMap.js +104 -44
- package/src/components/DataTable.js +32 -22
- package/src/components/EditorPanel.js +977 -414
- package/src/components/Geo.js +1 -1
- package/src/components/Modal.js +2 -1
- package/src/components/NavigationMenu.js +4 -3
- package/src/components/Sidebar.js +14 -19
- package/src/components/SingleStateMap.js +178 -249
- package/src/components/UsaMap.js +104 -36
- package/src/components/UsaRegionMap.js +320 -0
- package/src/components/WorldMap.js +117 -34
- package/src/data/country-coordinates.js +250 -0
- package/src/data/{dfc-map.json → county-map.json} +0 -0
- package/src/data/initial-state.js +23 -3
- package/src/data/state-coordinates.js +55 -0
- package/src/data/supported-geos.js +101 -15
- package/src/data/us-regions-topo-2.json +360525 -0
- package/src/data/us-regions-topo.json +37894 -0
- package/src/hooks/useColorPalette.ts +96 -0
- package/src/index.html +8 -4
- package/src/scss/editor-panel.scss +78 -57
- package/src/scss/main.scss +1 -6
- package/src/scss/map.scss +126 -2
- package/src/scss/sidebar.scss +2 -1
- package/src/data/color-palettes.js +0 -200
- package/src/images/map-folded.svg +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useEffect, useCallback } from 'react';
|
|
1
|
+
import React, { useState, useEffect, useCallback, memo } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Accordion,
|
|
4
4
|
AccordionItem,
|
|
@@ -10,30 +10,28 @@ import ReactTooltip from 'react-tooltip';
|
|
|
10
10
|
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
|
|
11
11
|
import { useDebounce } from 'use-debounce';
|
|
12
12
|
|
|
13
|
+
import colorPalettes from '@cdc/core/data/colorPalettes';
|
|
14
|
+
import { supportedStatesFipsCodes } from '../data/supported-geos';
|
|
15
|
+
import { useColorPalette } from '../hooks/useColorPalette';
|
|
16
|
+
|
|
13
17
|
import ErrorBoundary from '@cdc/core/components/ErrorBoundary';
|
|
14
18
|
import Waiting from '@cdc/core/components/Waiting';
|
|
15
19
|
|
|
16
|
-
import
|
|
17
|
-
import
|
|
18
|
-
import WorldGraphic from '@cdc/core/assets/world
|
|
19
|
-
import AlabamaGraphic from '@cdc/core/assets/alabama
|
|
20
|
-
import colorPalettes from '../data/color-palettes';
|
|
20
|
+
import UsaGraphic from '@cdc/core/assets/icon-map-usa.svg';
|
|
21
|
+
import UsaRegionGraphic from '@cdc/core/assets/usa-region-graphic.svg';
|
|
22
|
+
import WorldGraphic from '@cdc/core/assets/icon-map-world.svg';
|
|
23
|
+
import AlabamaGraphic from '@cdc/core/assets/icon-map-alabama.svg';
|
|
21
24
|
import worldDefaultConfig from '../../examples/default-world.json';
|
|
22
25
|
import usaDefaultConfig from '../../examples/default-usa.json';
|
|
23
26
|
import countyDefaultConfig from '../../examples/default-county.json';
|
|
24
|
-
import QuestionIcon from '@cdc/core/assets/question-circle.svg';
|
|
25
27
|
|
|
26
|
-
import
|
|
28
|
+
import InputToggle from '@cdc/core/components/inputs/InputToggle';
|
|
29
|
+
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
30
|
+
import Icon from '@cdc/core/components/ui/Icon'
|
|
27
31
|
|
|
28
|
-
|
|
32
|
+
import AdvancedEditor from '@cdc/core/components/AdvancedEditor';
|
|
29
33
|
|
|
30
|
-
const
|
|
31
|
-
return (
|
|
32
|
-
<span className='tooltip helper' data-tip={text}>
|
|
33
|
-
<QuestionIcon />
|
|
34
|
-
</span>
|
|
35
|
-
);
|
|
36
|
-
};
|
|
34
|
+
const ReactTags = require('react-tag-autocomplete'); // Future: Lazy
|
|
37
35
|
|
|
38
36
|
const TextField = ({
|
|
39
37
|
label,
|
|
@@ -43,7 +41,7 @@ const TextField = ({
|
|
|
43
41
|
updateField,
|
|
44
42
|
value: stateValue,
|
|
45
43
|
type = 'input',
|
|
46
|
-
|
|
44
|
+
tooltip,
|
|
47
45
|
...attributes
|
|
48
46
|
}) => {
|
|
49
47
|
const [value, setValue] = useState(stateValue);
|
|
@@ -73,7 +71,7 @@ const TextField = ({
|
|
|
73
71
|
return (
|
|
74
72
|
<label>
|
|
75
73
|
<span className='edit-label column-heading'>
|
|
76
|
-
{label}
|
|
74
|
+
{label}{tooltip}
|
|
77
75
|
</span>
|
|
78
76
|
{formElement}
|
|
79
77
|
</label>
|
|
@@ -107,7 +105,7 @@ const EditorPanel = (props) => {
|
|
|
107
105
|
|
|
108
106
|
const [activeFilterValueForDescription, setActiveFilterValueForDescription] = useState([0, 0]);
|
|
109
107
|
|
|
110
|
-
const
|
|
108
|
+
const {filteredPallets,filteredQualitative,isPaletteReversed,paletteName} = useColorPalette(colorPalettes,state);
|
|
111
109
|
|
|
112
110
|
const headerColors = [
|
|
113
111
|
'theme-blue',
|
|
@@ -124,14 +122,12 @@ const EditorPanel = (props) => {
|
|
|
124
122
|
];
|
|
125
123
|
|
|
126
124
|
const categoryMove = (idx1, idx2) => {
|
|
127
|
-
let categoryValuesOrder = [...
|
|
125
|
+
let categoryValuesOrder = [...state.legend.categoryValuesOrder];
|
|
128
126
|
|
|
129
127
|
let [movedItem] = categoryValuesOrder.splice(idx1, 1);
|
|
130
128
|
|
|
131
129
|
categoryValuesOrder.splice(idx2, 0, movedItem);
|
|
132
130
|
|
|
133
|
-
setEditorCatOrder(categoryValuesOrder);
|
|
134
|
-
|
|
135
131
|
setState({
|
|
136
132
|
...state,
|
|
137
133
|
legend: {
|
|
@@ -162,7 +158,7 @@ const EditorPanel = (props) => {
|
|
|
162
158
|
};
|
|
163
159
|
|
|
164
160
|
|
|
165
|
-
const DynamicDesc = ({ label, fieldName, value: stateValue, type = 'input',
|
|
161
|
+
const DynamicDesc = ({ label, fieldName, value: stateValue, type = 'input', ...attributes }) => {
|
|
166
162
|
const [value, setValue] = useState(stateValue);
|
|
167
163
|
|
|
168
164
|
const [debouncedValue] = useDebounce(value, 500);
|
|
@@ -182,7 +178,75 @@ const EditorPanel = (props) => {
|
|
|
182
178
|
};
|
|
183
179
|
|
|
184
180
|
const handleEditorChanges = async (property, value) => {
|
|
181
|
+
|
|
185
182
|
switch (property) {
|
|
183
|
+
|
|
184
|
+
// change these to be more generic.
|
|
185
|
+
// updateVisualPropertyValue
|
|
186
|
+
// updateGeneralPropertyValue, etc.
|
|
187
|
+
case 'showBubbleZeros':
|
|
188
|
+
setState({
|
|
189
|
+
...state,
|
|
190
|
+
visual: {
|
|
191
|
+
...state.visual,
|
|
192
|
+
showBubbleZeros: value
|
|
193
|
+
}
|
|
194
|
+
})
|
|
195
|
+
break;
|
|
196
|
+
|
|
197
|
+
case 'showEqualNumber':
|
|
198
|
+
setState({
|
|
199
|
+
...state,
|
|
200
|
+
general: {
|
|
201
|
+
...state.general,
|
|
202
|
+
equalNumberOptIn: value
|
|
203
|
+
}
|
|
204
|
+
})
|
|
205
|
+
break;
|
|
206
|
+
|
|
207
|
+
case 'hideGeoColumnInTooltip':
|
|
208
|
+
setState({
|
|
209
|
+
...state,
|
|
210
|
+
general: {
|
|
211
|
+
...state.general,
|
|
212
|
+
[property]: value
|
|
213
|
+
}
|
|
214
|
+
})
|
|
215
|
+
break;
|
|
216
|
+
|
|
217
|
+
case 'toggleExtraBubbleBorder':
|
|
218
|
+
setState({
|
|
219
|
+
...state,
|
|
220
|
+
visual: {
|
|
221
|
+
...state.visual,
|
|
222
|
+
extraBubbleBorder: value
|
|
223
|
+
}
|
|
224
|
+
})
|
|
225
|
+
break;
|
|
226
|
+
case 'allowMapZoom':
|
|
227
|
+
setState({
|
|
228
|
+
...state,
|
|
229
|
+
general: {
|
|
230
|
+
...state.general,
|
|
231
|
+
allowMapZoom: value
|
|
232
|
+
}
|
|
233
|
+
})
|
|
234
|
+
break;
|
|
235
|
+
case 'hideGeoColumnInTooltip':
|
|
236
|
+
setState({
|
|
237
|
+
...state,
|
|
238
|
+
[property]: value
|
|
239
|
+
})
|
|
240
|
+
break;
|
|
241
|
+
case 'hidePrimaryColumnInTooltip':
|
|
242
|
+
setState({
|
|
243
|
+
...state,
|
|
244
|
+
general: {
|
|
245
|
+
...state.general,
|
|
246
|
+
[property]: value
|
|
247
|
+
}
|
|
248
|
+
})
|
|
249
|
+
break;
|
|
186
250
|
case 'showTitle':
|
|
187
251
|
setState({
|
|
188
252
|
...state,
|
|
@@ -234,6 +298,14 @@ const EditorPanel = (props) => {
|
|
|
234
298
|
},
|
|
235
299
|
});
|
|
236
300
|
break;
|
|
301
|
+
case 'handleCityStyle':
|
|
302
|
+
setState({
|
|
303
|
+
...state,
|
|
304
|
+
visual: {
|
|
305
|
+
cityStyle: value,
|
|
306
|
+
},
|
|
307
|
+
});
|
|
308
|
+
break;
|
|
237
309
|
case 'geoBorderColor':
|
|
238
310
|
setState({
|
|
239
311
|
...state,
|
|
@@ -274,12 +346,33 @@ const EditorPanel = (props) => {
|
|
|
274
346
|
});
|
|
275
347
|
break;
|
|
276
348
|
case 'legendType':
|
|
349
|
+
|
|
350
|
+
let testForType = Number(typeof state.data[0][state.columns.primary.name]);
|
|
351
|
+
let hasValue = state.data[0][state.columns.primary.name];
|
|
352
|
+
let messages = [];
|
|
353
|
+
|
|
354
|
+
if(!hasValue) {
|
|
355
|
+
messages.push(`There appears to be values missing for data in the primary column ${state.columns.primary.name}`);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (testForType === 'string' && isNaN(testForType) && value !== 'category') {
|
|
359
|
+
messages.push(
|
|
360
|
+
"Error with legend. Primary columns that are text must use a categorical legend type. Try changing the legend type to DEV-12345categorical."
|
|
361
|
+
);
|
|
362
|
+
} else {
|
|
363
|
+
messages = []
|
|
364
|
+
}
|
|
365
|
+
|
|
277
366
|
setState({
|
|
278
367
|
...state,
|
|
279
368
|
legend: {
|
|
280
369
|
...state.legend,
|
|
281
370
|
type: value,
|
|
282
371
|
},
|
|
372
|
+
runtime: {
|
|
373
|
+
...state.runtime,
|
|
374
|
+
editorErrorMessage: messages
|
|
375
|
+
}
|
|
283
376
|
});
|
|
284
377
|
break;
|
|
285
378
|
case 'legendNumber':
|
|
@@ -343,6 +436,15 @@ const EditorPanel = (props) => {
|
|
|
343
436
|
break;
|
|
344
437
|
case 'editorMapType':
|
|
345
438
|
switch (value) {
|
|
439
|
+
case 'us-geocode':
|
|
440
|
+
setState({
|
|
441
|
+
...state,
|
|
442
|
+
general: {
|
|
443
|
+
...state.general,
|
|
444
|
+
type: value,
|
|
445
|
+
},
|
|
446
|
+
});
|
|
447
|
+
break;
|
|
346
448
|
case 'data':
|
|
347
449
|
setState({
|
|
348
450
|
...state,
|
|
@@ -367,6 +469,20 @@ const EditorPanel = (props) => {
|
|
|
367
469
|
},
|
|
368
470
|
});
|
|
369
471
|
break;
|
|
472
|
+
case 'bubble':
|
|
473
|
+
setState({
|
|
474
|
+
...state,
|
|
475
|
+
general: {
|
|
476
|
+
...state.general,
|
|
477
|
+
showSidebar: false,
|
|
478
|
+
type: 'bubble',
|
|
479
|
+
},
|
|
480
|
+
tooltips: {
|
|
481
|
+
...state.tooltips,
|
|
482
|
+
appearanceType: 'hover',
|
|
483
|
+
},
|
|
484
|
+
});
|
|
485
|
+
break;
|
|
370
486
|
default:
|
|
371
487
|
console.warn('Map type not set');
|
|
372
488
|
break;
|
|
@@ -407,6 +523,20 @@ const EditorPanel = (props) => {
|
|
|
407
523
|
});
|
|
408
524
|
ReactTooltip.rebuild();
|
|
409
525
|
break;
|
|
526
|
+
case 'us-region':
|
|
527
|
+
setState({
|
|
528
|
+
...state,
|
|
529
|
+
general: {
|
|
530
|
+
...state.general,
|
|
531
|
+
geoType: 'us-region',
|
|
532
|
+
},
|
|
533
|
+
dataTable: {
|
|
534
|
+
...state.dataTable,
|
|
535
|
+
forceDisplay: true,
|
|
536
|
+
},
|
|
537
|
+
});
|
|
538
|
+
ReactTooltip.rebuild();
|
|
539
|
+
break;
|
|
410
540
|
case 'world':
|
|
411
541
|
setState({
|
|
412
542
|
...state,
|
|
@@ -558,6 +688,15 @@ const EditorPanel = (props) => {
|
|
|
558
688
|
},
|
|
559
689
|
});
|
|
560
690
|
break;
|
|
691
|
+
case "classificationType":
|
|
692
|
+
setState({
|
|
693
|
+
...state,
|
|
694
|
+
legend: {
|
|
695
|
+
...state.legend,
|
|
696
|
+
type: value,
|
|
697
|
+
},
|
|
698
|
+
});
|
|
699
|
+
break;
|
|
561
700
|
default:
|
|
562
701
|
console.warn(`Did not recognize editor property.`);
|
|
563
702
|
break;
|
|
@@ -565,6 +704,7 @@ const EditorPanel = (props) => {
|
|
|
565
704
|
};
|
|
566
705
|
|
|
567
706
|
const columnsRequiredChecker = useCallback(() => {
|
|
707
|
+
console.info('Running columns required check.')
|
|
568
708
|
let columnList = [];
|
|
569
709
|
|
|
570
710
|
// Geo is always required
|
|
@@ -585,6 +725,14 @@ const EditorPanel = (props) => {
|
|
|
585
725
|
columnList.push('Navigation');
|
|
586
726
|
}
|
|
587
727
|
|
|
728
|
+
if ('us-geocode' === state.general.type && '' === state.columns.latitude.name) {
|
|
729
|
+
columnList.push('Latitude')
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
if ('us-geocode' === state.general.type && '' === state.columns.longitude.name) {
|
|
733
|
+
columnList.push('Longitude')
|
|
734
|
+
}
|
|
735
|
+
|
|
588
736
|
if (columnList.length === 0) columnList = null;
|
|
589
737
|
|
|
590
738
|
setRequiredColumns(columnList);
|
|
@@ -804,10 +952,30 @@ const EditorPanel = (props) => {
|
|
|
804
952
|
}, [state]);
|
|
805
953
|
|
|
806
954
|
useEffect(() => {
|
|
807
|
-
|
|
808
|
-
|
|
955
|
+
//If a categorical map is used and the order is either not defined or incorrect, fix it
|
|
956
|
+
if ('category' === state.legend.type) {
|
|
957
|
+
let valid = true;
|
|
958
|
+
if(state.legend.categoryValuesOrder){
|
|
959
|
+
runtimeLegend.forEach(item => {
|
|
960
|
+
if(!item.special && state.legend.categoryValuesOrder.indexOf(item.value) === -1) {
|
|
961
|
+
valid = false;
|
|
962
|
+
}
|
|
963
|
+
});
|
|
964
|
+
} else {
|
|
965
|
+
valid = false;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
if(!valid){
|
|
969
|
+
let arr = runtimeLegend.filter((item) => !item.special).map(({ value }) => value);
|
|
809
970
|
|
|
810
|
-
|
|
971
|
+
setState({
|
|
972
|
+
...state,
|
|
973
|
+
legend: {
|
|
974
|
+
...state.legend,
|
|
975
|
+
categoryValuesOrder: arr,
|
|
976
|
+
},
|
|
977
|
+
});
|
|
978
|
+
}
|
|
811
979
|
}
|
|
812
980
|
}, [runtimeLegend]);
|
|
813
981
|
|
|
@@ -868,7 +1036,7 @@ const EditorPanel = (props) => {
|
|
|
868
1036
|
}
|
|
869
1037
|
|
|
870
1038
|
const additionalColumns = Object.keys(state.columns).filter((value) => {
|
|
871
|
-
const defaultCols = ['geo', 'navigate', 'primary'];
|
|
1039
|
+
const defaultCols = ['geo', 'navigate', 'primary', 'latitude', 'longitude'];
|
|
872
1040
|
|
|
873
1041
|
if (true === defaultCols.includes(value)) {
|
|
874
1042
|
return false;
|
|
@@ -948,7 +1116,12 @@ const EditorPanel = (props) => {
|
|
|
948
1116
|
<label>
|
|
949
1117
|
<span className='edit-label column-heading'>
|
|
950
1118
|
Filter Column{' '}
|
|
951
|
-
|
|
1119
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1120
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1121
|
+
<Tooltip.Content>
|
|
1122
|
+
<p>Selecting a column will add a dropdown menu below the map legend and allow users to filter based on the values in this column.</p>
|
|
1123
|
+
</Tooltip.Content>
|
|
1124
|
+
</Tooltip>
|
|
952
1125
|
</span>
|
|
953
1126
|
<select
|
|
954
1127
|
value={filter.columnName}
|
|
@@ -961,7 +1134,7 @@ const EditorPanel = (props) => {
|
|
|
961
1134
|
)}
|
|
962
1135
|
</select>
|
|
963
1136
|
</label>
|
|
964
|
-
|
|
1137
|
+
|
|
965
1138
|
<label>
|
|
966
1139
|
<span className="edit-filterOrder column-heading">Filter Order</span>
|
|
967
1140
|
<select value={filter.order} onChange={ (e) => {
|
|
@@ -1009,7 +1182,7 @@ const EditorPanel = (props) => {
|
|
|
1009
1182
|
</Droppable>
|
|
1010
1183
|
</DragDropContext>
|
|
1011
1184
|
}
|
|
1012
|
-
|
|
1185
|
+
|
|
1013
1186
|
</fieldset>
|
|
1014
1187
|
);
|
|
1015
1188
|
});
|
|
@@ -1043,21 +1216,28 @@ const EditorPanel = (props) => {
|
|
|
1043
1216
|
});
|
|
1044
1217
|
}
|
|
1045
1218
|
|
|
1219
|
+
|
|
1220
|
+
useEffect(()=>{
|
|
1221
|
+
if(paletteName) handleEditorChanges('color',paletteName)
|
|
1222
|
+
},[paletteName]) // dont add handleEditorChanges as a dependency even if it requires
|
|
1223
|
+
|
|
1046
1224
|
useEffect(() => {
|
|
1047
1225
|
const parsedData = convertStateToConfig();
|
|
1048
1226
|
const formattedData = JSON.stringify(parsedData, undefined, 2);
|
|
1049
1227
|
|
|
1050
1228
|
setConfigTextbox(formattedData);
|
|
1229
|
+
}, [state]);
|
|
1051
1230
|
|
|
1231
|
+
useEffect(() => {
|
|
1052
1232
|
// Pass up to Editor if needed
|
|
1053
1233
|
if (setParentConfig) {
|
|
1054
1234
|
const newConfig = convertStateToConfig();
|
|
1055
1235
|
setParentConfig(newConfig);
|
|
1056
1236
|
}
|
|
1057
1237
|
|
|
1058
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1059
1238
|
}, [state]);
|
|
1060
1239
|
|
|
1240
|
+
|
|
1061
1241
|
let numberOfItemsLimit = 8;
|
|
1062
1242
|
|
|
1063
1243
|
const getItemStyle = (isDragging, draggableStyle) => ({
|
|
@@ -1065,7 +1245,7 @@ const EditorPanel = (props) => {
|
|
|
1065
1245
|
});
|
|
1066
1246
|
|
|
1067
1247
|
const CategoryList = () => {
|
|
1068
|
-
return
|
|
1248
|
+
return state.legend.categoryValuesOrder ? state.legend.categoryValuesOrder.map((value, index) => (
|
|
1069
1249
|
<Draggable key={value} draggableId={`item-${value}`} index={index}>
|
|
1070
1250
|
{(provided, snapshot) => (
|
|
1071
1251
|
<li style={{ position: 'relative' }}>
|
|
@@ -1081,11 +1261,23 @@ const EditorPanel = (props) => {
|
|
|
1081
1261
|
</li>
|
|
1082
1262
|
)}
|
|
1083
1263
|
</Draggable>
|
|
1084
|
-
))
|
|
1264
|
+
)) : <></>;
|
|
1085
1265
|
};
|
|
1086
1266
|
|
|
1267
|
+
const Error = () => {
|
|
1268
|
+
return (
|
|
1269
|
+
<section className="waiting">
|
|
1270
|
+
<section className="waiting-container">
|
|
1271
|
+
<h3>Error With Configuration</h3>
|
|
1272
|
+
<p>{state.runtime.editorErrorMessage}</p>
|
|
1273
|
+
</section>
|
|
1274
|
+
</section>
|
|
1275
|
+
);
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1087
1278
|
return (
|
|
1088
1279
|
<ErrorBoundary component='EditorPanel'>
|
|
1280
|
+
{state?.runtime?.editorErrorMessage.length > 0 && <Error />}
|
|
1089
1281
|
{requiredColumns && (
|
|
1090
1282
|
<Waiting requiredColumns={requiredColumns} className={displayPanel ? `waiting` : `waiting collapsed`} />
|
|
1091
1283
|
)}
|
|
@@ -1095,7 +1287,8 @@ const EditorPanel = (props) => {
|
|
|
1095
1287
|
onClick={onBackClick}
|
|
1096
1288
|
data-html2canvas-ignore
|
|
1097
1289
|
></button>
|
|
1098
|
-
|
|
1290
|
+
|
|
1291
|
+
<section className={displayPanel ? 'editor-panel cove' : 'hidden editor-panel cove'} data-html2canvas-ignore>
|
|
1099
1292
|
<ReactTooltip html={true} multiline={true} />
|
|
1100
1293
|
<span className='base-label'>Configure Map</span>
|
|
1101
1294
|
<section className='form-container'>
|
|
@@ -1114,38 +1307,61 @@ const EditorPanel = (props) => {
|
|
|
1114
1307
|
<span>Geography</span>
|
|
1115
1308
|
</span>
|
|
1116
1309
|
<ul className='geo-buttons'>
|
|
1117
|
-
<
|
|
1310
|
+
<button
|
|
1118
1311
|
className={
|
|
1119
1312
|
state.general.geoType === 'us' ||
|
|
1120
1313
|
state.general.geoType === 'us-county'
|
|
1121
1314
|
? 'active'
|
|
1122
1315
|
: ''
|
|
1123
1316
|
}
|
|
1124
|
-
onClick={() =>
|
|
1317
|
+
onClick={ (e) => {
|
|
1318
|
+
e.preventDefault();
|
|
1319
|
+
handleEditorChanges('geoType', 'us')
|
|
1320
|
+
}}
|
|
1125
1321
|
>
|
|
1126
1322
|
<UsaGraphic />
|
|
1127
1323
|
<span>United States</span>
|
|
1128
|
-
</
|
|
1129
|
-
|
|
1324
|
+
</button>
|
|
1325
|
+
<button
|
|
1326
|
+
className={state.general.geoType === 'us-region' ? 'active' : ''}
|
|
1327
|
+
onClick={ (e) => {
|
|
1328
|
+
e.preventDefault();
|
|
1329
|
+
handleEditorChanges('geoType', 'us-region')
|
|
1330
|
+
}}
|
|
1331
|
+
>
|
|
1332
|
+
<UsaRegionGraphic />
|
|
1333
|
+
<span>U.S. Region</span>
|
|
1334
|
+
</button>
|
|
1335
|
+
<button
|
|
1130
1336
|
className={state.general.geoType === 'world' ? 'active' : ''}
|
|
1131
|
-
onClick={() =>
|
|
1337
|
+
onClick={ (e) => {
|
|
1338
|
+
e.preventDefault();
|
|
1339
|
+
handleEditorChanges('geoType', 'world')
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1132
1342
|
>
|
|
1133
1343
|
<WorldGraphic />
|
|
1134
1344
|
<span>World</span>
|
|
1135
|
-
</
|
|
1136
|
-
<
|
|
1345
|
+
</button>
|
|
1346
|
+
<button
|
|
1137
1347
|
className={state.general.geoType === 'single-state' ? 'active' : ''}
|
|
1138
|
-
onClick={() =>
|
|
1348
|
+
onClick={(e) => {
|
|
1349
|
+
e.preventDefault();
|
|
1350
|
+
handleEditorChanges('geoType', 'single-state')
|
|
1351
|
+
}}
|
|
1139
1352
|
>
|
|
1140
1353
|
<AlabamaGraphic />
|
|
1141
1354
|
<span>U.S. State</span>
|
|
1142
|
-
</
|
|
1355
|
+
</button>
|
|
1143
1356
|
</ul>
|
|
1144
1357
|
</label>
|
|
1145
1358
|
{/* Select > State or County Map */}
|
|
1146
1359
|
{(state.general.geoType === 'us' || state.general.geoType === 'us-county') && (
|
|
1147
1360
|
<label>
|
|
1148
|
-
<span className='edit-label column-heading'>
|
|
1361
|
+
<span className='edit-label column-heading'>
|
|
1362
|
+
Geography Subtype
|
|
1363
|
+
|
|
1364
|
+
</span>
|
|
1149
1365
|
<select
|
|
1150
1366
|
value={state.general.geoType}
|
|
1151
1367
|
onChange={(event) => {
|
|
@@ -1178,7 +1394,15 @@ const EditorPanel = (props) => {
|
|
|
1178
1394
|
)}
|
|
1179
1395
|
{/* Type */}
|
|
1180
1396
|
<label>
|
|
1181
|
-
<span className='edit-label column-heading'>
|
|
1397
|
+
<span className='edit-label column-heading'>
|
|
1398
|
+
Map Type
|
|
1399
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1400
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1401
|
+
<Tooltip.Content>
|
|
1402
|
+
<p>Select "Data" to create a color-coded data map. To create a navigation-only map, select "Navigation."</p>
|
|
1403
|
+
</Tooltip.Content>
|
|
1404
|
+
</Tooltip>
|
|
1405
|
+
</span>
|
|
1182
1406
|
<select
|
|
1183
1407
|
value={state.general.type}
|
|
1184
1408
|
onChange={(event) => {
|
|
@@ -1186,9 +1410,46 @@ const EditorPanel = (props) => {
|
|
|
1186
1410
|
}}
|
|
1187
1411
|
>
|
|
1188
1412
|
<option value='data'>Data</option>
|
|
1413
|
+
<option value='us-geocode'>United States Geocode</option>
|
|
1189
1414
|
<option value='navigation'>Navigation</option>
|
|
1415
|
+
{ (state.general.geoType === 'world' || state.general.geoType === 'us') && <option value="bubble">Bubble</option>}
|
|
1190
1416
|
</select>
|
|
1191
1417
|
</label>
|
|
1418
|
+
<label>
|
|
1419
|
+
<span className="edit-label">Data Classification Type</span>
|
|
1420
|
+
<div>
|
|
1421
|
+
<label>
|
|
1422
|
+
<input
|
|
1423
|
+
type="radio"
|
|
1424
|
+
name="equalnumber"
|
|
1425
|
+
value="equalnumber"
|
|
1426
|
+
checked={state.legend.type === "equalnumber"}
|
|
1427
|
+
onChange={(e) =>
|
|
1428
|
+
handleEditorChanges(
|
|
1429
|
+
"classificationType",
|
|
1430
|
+
e.target.value
|
|
1431
|
+
)
|
|
1432
|
+
}
|
|
1433
|
+
/>
|
|
1434
|
+
Numeric/Quantitative
|
|
1435
|
+
</label>
|
|
1436
|
+
<label>
|
|
1437
|
+
<input
|
|
1438
|
+
type="radio"
|
|
1439
|
+
name="category"
|
|
1440
|
+
value="category"
|
|
1441
|
+
checked={state.legend.type === "category"}
|
|
1442
|
+
onChange={(e) =>
|
|
1443
|
+
handleEditorChanges(
|
|
1444
|
+
"classificationType",
|
|
1445
|
+
e.target.value
|
|
1446
|
+
)
|
|
1447
|
+
}
|
|
1448
|
+
/>
|
|
1449
|
+
Categorical
|
|
1450
|
+
</label>
|
|
1451
|
+
</div>
|
|
1452
|
+
</label>
|
|
1192
1453
|
{/* SubType */}
|
|
1193
1454
|
{'us' === state.general.geoType && 'data' === state.general.type && (
|
|
1194
1455
|
<label className='checkbox mt-4'>
|
|
@@ -1203,7 +1464,7 @@ const EditorPanel = (props) => {
|
|
|
1203
1464
|
</label>
|
|
1204
1465
|
)}
|
|
1205
1466
|
{'us' === state.general.geoType &&
|
|
1206
|
-
'
|
|
1467
|
+
'bubble' !== state.general.type &&
|
|
1207
1468
|
false === state.general.displayAsHex && (
|
|
1208
1469
|
<label className='checkbox'>
|
|
1209
1470
|
<input
|
|
@@ -1226,13 +1487,51 @@ const EditorPanel = (props) => {
|
|
|
1226
1487
|
</AccordionItemHeading>
|
|
1227
1488
|
<AccordionItemPanel>
|
|
1228
1489
|
<TextField
|
|
1229
|
-
value={
|
|
1490
|
+
value={general.title}
|
|
1230
1491
|
updateField={updateField}
|
|
1231
1492
|
section='general'
|
|
1232
1493
|
fieldName='title'
|
|
1233
1494
|
label='Title'
|
|
1234
1495
|
placeholder='Map Title'
|
|
1235
|
-
|
|
1496
|
+
tooltip={
|
|
1497
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1498
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1499
|
+
<Tooltip.Content>
|
|
1500
|
+
<p>For accessibility reasons, you should enter a title even if you are not planning on displaying it.</p>
|
|
1501
|
+
</Tooltip.Content>
|
|
1502
|
+
</Tooltip>
|
|
1503
|
+
}
|
|
1504
|
+
/>
|
|
1505
|
+
<TextField
|
|
1506
|
+
value={general.superTitle || ''}
|
|
1507
|
+
updateField={updateField}
|
|
1508
|
+
section='general'
|
|
1509
|
+
fieldName='superTitle'
|
|
1510
|
+
label='Super Title'
|
|
1511
|
+
tooltip={
|
|
1512
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1513
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1514
|
+
<Tooltip.Content>
|
|
1515
|
+
<p>Super Title</p>
|
|
1516
|
+
</Tooltip.Content>
|
|
1517
|
+
</Tooltip>
|
|
1518
|
+
}
|
|
1519
|
+
/>
|
|
1520
|
+
<TextField
|
|
1521
|
+
type='textarea'
|
|
1522
|
+
value={general.introText}
|
|
1523
|
+
updateField={updateField}
|
|
1524
|
+
section='general'
|
|
1525
|
+
fieldName='introText'
|
|
1526
|
+
label='Intro Text'
|
|
1527
|
+
tooltip={
|
|
1528
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1529
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1530
|
+
<Tooltip.Content>
|
|
1531
|
+
<p>Intro Text</p>
|
|
1532
|
+
</Tooltip.Content>
|
|
1533
|
+
</Tooltip>
|
|
1534
|
+
}
|
|
1236
1535
|
/>
|
|
1237
1536
|
<TextField
|
|
1238
1537
|
type='textarea'
|
|
@@ -1241,6 +1540,30 @@ const EditorPanel = (props) => {
|
|
|
1241
1540
|
section='general'
|
|
1242
1541
|
fieldName='subtext'
|
|
1243
1542
|
label='Subtext'
|
|
1543
|
+
tooltip={
|
|
1544
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1545
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1546
|
+
<Tooltip.Content>
|
|
1547
|
+
<p>Enter supporting text to display below the data visualization, if applicable. The following HTML tags are supported: strong, em, sup, and sub.</p>
|
|
1548
|
+
</Tooltip.Content>
|
|
1549
|
+
</Tooltip>
|
|
1550
|
+
}
|
|
1551
|
+
/>
|
|
1552
|
+
<TextField
|
|
1553
|
+
type='textarea'
|
|
1554
|
+
value={general.footnotes}
|
|
1555
|
+
updateField={updateField}
|
|
1556
|
+
section='general'
|
|
1557
|
+
fieldName='footnotes'
|
|
1558
|
+
label='Footnotes'
|
|
1559
|
+
tooltip={
|
|
1560
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1561
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1562
|
+
<Tooltip.Content>
|
|
1563
|
+
<p>Footnotes</p>
|
|
1564
|
+
</Tooltip.Content>
|
|
1565
|
+
</Tooltip>
|
|
1566
|
+
}
|
|
1244
1567
|
/>
|
|
1245
1568
|
{'us' === state.general.geoType && (
|
|
1246
1569
|
<TextField
|
|
@@ -1266,7 +1589,15 @@ const EditorPanel = (props) => {
|
|
|
1266
1589
|
</AccordionItemHeading>
|
|
1267
1590
|
<AccordionItemPanel>
|
|
1268
1591
|
<label className='edit-block geo'>
|
|
1269
|
-
<span className='edit-label column-heading'>
|
|
1592
|
+
<span className='edit-label column-heading'>
|
|
1593
|
+
Geography
|
|
1594
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1595
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1596
|
+
<Tooltip.Content>
|
|
1597
|
+
<p>Select the source column containing the map location names or, for county-level maps, the FIPS codes.</p>
|
|
1598
|
+
</Tooltip.Content>
|
|
1599
|
+
</Tooltip>
|
|
1600
|
+
</span>
|
|
1270
1601
|
<select
|
|
1271
1602
|
value={state.columns.geo ? state.columns.geo.name : columnsOptions[0]}
|
|
1272
1603
|
onChange={(event) => {
|
|
@@ -1276,155 +1607,240 @@ const EditorPanel = (props) => {
|
|
|
1276
1607
|
{columnsOptions}
|
|
1277
1608
|
</select>
|
|
1278
1609
|
</label>
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
<
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1610
|
+
|
|
1611
|
+
{'navigation' !== state.general.type && (
|
|
1612
|
+
<fieldset className='primary-fieldset edit-block'>
|
|
1613
|
+
<label>
|
|
1614
|
+
<span className='edit-label column-heading'>
|
|
1615
|
+
Data Column
|
|
1616
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1617
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1618
|
+
<Tooltip.Content>
|
|
1619
|
+
<p>Select the source column containing the categorical or numeric values to be mapped.</p>
|
|
1620
|
+
</Tooltip.Content>
|
|
1621
|
+
</Tooltip>
|
|
1622
|
+
</span>
|
|
1623
|
+
<select
|
|
1624
|
+
value={
|
|
1625
|
+
state.columns.primary
|
|
1626
|
+
? state.columns.primary.name
|
|
1627
|
+
: columnsOptions[0]
|
|
1628
|
+
}
|
|
1629
|
+
onChange={(event) => {
|
|
1630
|
+
editColumn('primary', 'name', event.target.value);
|
|
1631
|
+
}}
|
|
1632
|
+
>
|
|
1633
|
+
{columnsOptions}
|
|
1634
|
+
</select>
|
|
1635
|
+
</label>
|
|
1636
|
+
<TextField
|
|
1637
|
+
value={columns.primary.label}
|
|
1638
|
+
section='columns'
|
|
1639
|
+
subsection='primary'
|
|
1640
|
+
fieldName='label'
|
|
1641
|
+
label='Label'
|
|
1642
|
+
updateField={updateField}
|
|
1643
|
+
tooltip={
|
|
1644
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1645
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1646
|
+
<Tooltip.Content>
|
|
1647
|
+
<p>Enter a data label for use in tooltips and the data table.</p>
|
|
1648
|
+
</Tooltip.Content>
|
|
1649
|
+
</Tooltip>
|
|
1650
|
+
}
|
|
1651
|
+
/>
|
|
1652
|
+
<ul className='column-edit'>
|
|
1653
|
+
<li className='three-col'>
|
|
1654
|
+
<TextField
|
|
1655
|
+
value={columns.primary.prefix}
|
|
1656
|
+
section='columns'
|
|
1657
|
+
subsection='primary'
|
|
1658
|
+
fieldName='prefix'
|
|
1659
|
+
label='Prefix'
|
|
1660
|
+
updateField={updateField}
|
|
1661
|
+
/>
|
|
1662
|
+
<TextField
|
|
1663
|
+
value={columns.primary.suffix}
|
|
1664
|
+
section='columns'
|
|
1665
|
+
subsection='primary'
|
|
1666
|
+
fieldName='suffix'
|
|
1667
|
+
label='Suffix'
|
|
1668
|
+
updateField={updateField}
|
|
1669
|
+
/>
|
|
1670
|
+
<TextField
|
|
1671
|
+
type='number'
|
|
1672
|
+
value={columns.primary.roundToPlace}
|
|
1673
|
+
section='columns'
|
|
1674
|
+
subsection='primary'
|
|
1675
|
+
fieldName='roundToPlace'
|
|
1676
|
+
label='Round'
|
|
1677
|
+
updateField={updateField}
|
|
1678
|
+
min={0}
|
|
1679
|
+
/>
|
|
1680
|
+
</li>
|
|
1681
|
+
<li>
|
|
1682
|
+
<label className='checkbox'>
|
|
1683
|
+
<input
|
|
1684
|
+
type='checkbox'
|
|
1685
|
+
checked={state.columns.primary.useCommas}
|
|
1686
|
+
onChange={(event) => {
|
|
1687
|
+
editColumn(
|
|
1688
|
+
'primary',
|
|
1689
|
+
'useCommas',
|
|
1690
|
+
event.target.checked
|
|
1691
|
+
);
|
|
1692
|
+
}}
|
|
1693
|
+
/>
|
|
1694
|
+
<span className='edit-label'>Add Commas to Numbers</span>
|
|
1695
|
+
</label>
|
|
1696
|
+
</li>
|
|
1697
|
+
<li>
|
|
1698
|
+
<label className='checkbox'>
|
|
1699
|
+
<input
|
|
1700
|
+
type='checkbox'
|
|
1701
|
+
checked={state.columns.primary.dataTable || false}
|
|
1702
|
+
onChange={(event) => {
|
|
1703
|
+
editColumn(
|
|
1704
|
+
'primary',
|
|
1705
|
+
'dataTable',
|
|
1706
|
+
event.target.checked
|
|
1707
|
+
);
|
|
1708
|
+
}}
|
|
1709
|
+
/>
|
|
1710
|
+
<span className='edit-label'>Display in Data Table</span>
|
|
1711
|
+
</label>
|
|
1712
|
+
</li>
|
|
1713
|
+
<li>
|
|
1714
|
+
<label className='checkbox'>
|
|
1715
|
+
<input
|
|
1716
|
+
type='checkbox'
|
|
1717
|
+
checked={state.columns.primary.tooltip || false}
|
|
1718
|
+
onChange={(event) => {
|
|
1719
|
+
editColumn('primary', 'tooltip', event.target.checked);
|
|
1720
|
+
}}
|
|
1721
|
+
/>
|
|
1722
|
+
<span className='edit-label'>Display in Tooltips</span>
|
|
1723
|
+
</label>
|
|
1724
|
+
</li>
|
|
1725
|
+
</ul>
|
|
1726
|
+
</fieldset>
|
|
1727
|
+
)}
|
|
1728
|
+
|
|
1729
|
+
|
|
1730
|
+
|
|
1731
|
+
{ (state.general.type === 'bubble') && state.legend.type === 'category' && (
|
|
1732
|
+
<fieldset className='primary-fieldset edit-block'>
|
|
1733
|
+
<label>
|
|
1734
|
+
<span className='edit-label column-heading'>
|
|
1735
|
+
Category Column
|
|
1736
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1737
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1738
|
+
<Tooltip.Content>
|
|
1739
|
+
<p>Select the source column containing the categorical bubble values to be mapped.</p>
|
|
1740
|
+
</Tooltip.Content>
|
|
1741
|
+
</Tooltip>
|
|
1742
|
+
</span>
|
|
1743
|
+
<select
|
|
1744
|
+
value={
|
|
1745
|
+
state.columns.categorical
|
|
1746
|
+
? state.columns.categorical.name
|
|
1747
|
+
: columnsOptions[0]
|
|
1748
|
+
}
|
|
1749
|
+
onChange={(event) => {
|
|
1750
|
+
editColumn('categorical', 'name', event.target.value);
|
|
1751
|
+
}}
|
|
1752
|
+
>
|
|
1753
|
+
{columnsOptions}
|
|
1754
|
+
</select>
|
|
1755
|
+
</label>
|
|
1756
|
+
</fieldset>
|
|
1757
|
+
)}
|
|
1758
|
+
|
|
1759
|
+
{'us-geocode' === state.general.type &&
|
|
1760
|
+
<>
|
|
1761
|
+
<label>Latitude Column</label>
|
|
1762
|
+
<select value={state.columns.latitude.name ? state.columns.latitude.name : ''} onChange={(e) => {
|
|
1763
|
+
editColumn('latitude', 'name', e.target.value);
|
|
1764
|
+
}}>
|
|
1765
|
+
{columnsOptions}
|
|
1766
|
+
</select>
|
|
1767
|
+
<label>Longitude Column</label>
|
|
1768
|
+
<select value={state.columns.longitude.name ? state.columns.longitude.name : ''} onChange={(e) => {
|
|
1769
|
+
editColumn('longitude', 'name', e.target.value);
|
|
1770
|
+
}}>
|
|
1771
|
+
{columnsOptions}
|
|
1772
|
+
</select>
|
|
1773
|
+
</>
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
{'navigation' !== state.general.type && (
|
|
1777
|
+
<fieldset className="primary-fieldset edit-block">
|
|
1778
|
+
<label>
|
|
1779
|
+
<span className='edit-label'>
|
|
1780
|
+
Special Classes
|
|
1781
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1782
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1783
|
+
<Tooltip.Content>
|
|
1784
|
+
<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>
|
|
1785
|
+
</Tooltip.Content>
|
|
1786
|
+
</Tooltip>
|
|
1787
|
+
</span>
|
|
1788
|
+
</label>
|
|
1789
|
+
{specialClasses.map((specialClass, i) => (
|
|
1790
|
+
<div className="edit-block" key={`special-class-${i}`}>
|
|
1791
|
+
<button className="remove-column"
|
|
1792
|
+
onClick={(e) => {
|
|
1793
|
+
e.preventDefault();
|
|
1794
|
+
editColumn('primary', 'specialClassDelete', i);
|
|
1795
|
+
}}
|
|
1796
|
+
>Remove</button>
|
|
1797
|
+
<p>Special Class {i + 1}</p>
|
|
1798
|
+
<label>
|
|
1799
|
+
<span className="edit-label column-heading">Data Key</span>
|
|
1800
|
+
<select value={specialClass.key} onChange={(e) => {
|
|
1801
|
+
editColumn('primary', 'specialClassEdit', {prop: 'key', index: i, value: e.target.value});
|
|
1802
|
+
}}>
|
|
1803
|
+
{columnsOptions}
|
|
1804
|
+
</select>
|
|
1805
|
+
</label>
|
|
1806
|
+
<label>
|
|
1807
|
+
<span className="edit-label column-heading">Value</span>
|
|
1808
|
+
<select value={specialClass.value} onChange={(e) => {
|
|
1809
|
+
editColumn('primary', 'specialClassEdit', {prop: 'value', index: i, value: e.target.value});
|
|
1810
|
+
}}>
|
|
1811
|
+
<option value="">- Select Value -</option>
|
|
1812
|
+
{columnsByKey[specialClass.key] && columnsByKey[specialClass.key].sort().map(option => (
|
|
1813
|
+
<option key={`special-class-value-option-${i}-${option}`}>{option}</option>
|
|
1814
|
+
))}
|
|
1815
|
+
</select>
|
|
1816
|
+
</label>
|
|
1817
|
+
<label>
|
|
1818
|
+
<span className="edit-label column-heading">Label</span>
|
|
1819
|
+
<input type="text" value={specialClass.label} onChange={(e) => {
|
|
1820
|
+
editColumn('primary', 'specialClassEdit', {prop: 'label', index: i, value: e.target.value});
|
|
1821
|
+
}} />
|
|
1822
|
+
</label>
|
|
1823
|
+
</div>
|
|
1824
|
+
))}
|
|
1825
|
+
<button className="btn full-width" onClick={(e) => {
|
|
1826
|
+
e.preventDefault();
|
|
1827
|
+
editColumn('primary', 'specialClassAdd', {});
|
|
1828
|
+
}}>
|
|
1829
|
+
Add Special Class
|
|
1830
|
+
</button>
|
|
1831
|
+
</fieldset>
|
|
1832
|
+
)}
|
|
1833
|
+
|
|
1426
1834
|
<label className='edit-block navigate column-heading'>
|
|
1427
|
-
<span className='edit-label column-heading'>
|
|
1835
|
+
<span className='edit-label column-heading'>
|
|
1836
|
+
Navigation
|
|
1837
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1838
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1839
|
+
<Tooltip.Content>
|
|
1840
|
+
<p>To provide end users with navigation functionality, select the source column containing the navigation URLs.</p>
|
|
1841
|
+
</Tooltip.Content>
|
|
1842
|
+
</Tooltip>
|
|
1843
|
+
</span>
|
|
1428
1844
|
<select
|
|
1429
1845
|
value={
|
|
1430
1846
|
state.columns.navigate ? state.columns.navigate.name : columnsOptions[0]
|
|
@@ -1437,118 +1853,130 @@ const EditorPanel = (props) => {
|
|
|
1437
1853
|
</select>
|
|
1438
1854
|
</label>
|
|
1439
1855
|
{'navigation' !== state.general.type &&
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1856
|
+
<fieldset className="primary-fieldset edit-block">
|
|
1857
|
+
<label>
|
|
1858
|
+
<span className="edit-label">
|
|
1859
|
+
Additional Columns
|
|
1860
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1861
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1862
|
+
<Tooltip.Content>
|
|
1863
|
+
<p>You can specify additional columns to display in tooltips and / or the supporting data table.</p>
|
|
1864
|
+
</Tooltip.Content>
|
|
1865
|
+
</Tooltip>
|
|
1866
|
+
</span>
|
|
1867
|
+
</label>
|
|
1868
|
+
{additionalColumns.map((val) => (
|
|
1869
|
+
<fieldset className="edit-block" key={val}>
|
|
1870
|
+
<button
|
|
1871
|
+
className="remove-column"
|
|
1872
|
+
onClick={(event) => {
|
|
1873
|
+
event.preventDefault()
|
|
1874
|
+
removeAdditionalColumn(val)
|
|
1875
|
+
}}
|
|
1876
|
+
>
|
|
1877
|
+
Remove
|
|
1878
|
+
</button>
|
|
1879
|
+
<label>
|
|
1880
|
+
<span className="edit-label column-heading">Column</span>
|
|
1881
|
+
<select
|
|
1882
|
+
value={
|
|
1883
|
+
state.columns[val]
|
|
1884
|
+
? state.columns[val].name
|
|
1885
|
+
: columnsOptions[0]
|
|
1886
|
+
}
|
|
1887
|
+
onChange={(event) => {
|
|
1888
|
+
editColumn(val, 'name', event.target.value)
|
|
1889
|
+
}}
|
|
1890
|
+
>
|
|
1891
|
+
{columnsOptions}
|
|
1892
|
+
</select>
|
|
1893
|
+
</label>
|
|
1894
|
+
<TextField
|
|
1895
|
+
value={columns[val].label}
|
|
1896
|
+
section="columns"
|
|
1897
|
+
subsection={val}
|
|
1898
|
+
fieldName="label"
|
|
1899
|
+
label="Label"
|
|
1900
|
+
updateField={updateField}
|
|
1901
|
+
/>
|
|
1902
|
+
<ul className="column-edit">
|
|
1903
|
+
<li className="three-col">
|
|
1904
|
+
<TextField
|
|
1905
|
+
value={columns[val].prefix}
|
|
1906
|
+
section="columns"
|
|
1907
|
+
subsection={val}
|
|
1908
|
+
fieldName="prefix"
|
|
1909
|
+
label="Prefix"
|
|
1910
|
+
updateField={updateField}
|
|
1911
|
+
/>
|
|
1912
|
+
<TextField
|
|
1913
|
+
value={columns[val].suffix}
|
|
1914
|
+
section="columns"
|
|
1915
|
+
subsection={val}
|
|
1916
|
+
fieldName="suffix"
|
|
1917
|
+
label="Suffix"
|
|
1918
|
+
updateField={updateField}
|
|
1919
|
+
/>
|
|
1920
|
+
<TextField
|
|
1921
|
+
type="number"
|
|
1922
|
+
value={columns[val].roundToPlace}
|
|
1923
|
+
section="columns"
|
|
1924
|
+
subsection={val}
|
|
1925
|
+
fieldName="roundToPlace"
|
|
1926
|
+
label="Round"
|
|
1927
|
+
updateField={updateField}
|
|
1928
|
+
/>
|
|
1929
|
+
</li>
|
|
1930
|
+
<li>
|
|
1931
|
+
<label className="checkbox">
|
|
1932
|
+
<input
|
|
1933
|
+
type="checkbox"
|
|
1934
|
+
checked={state.columns[val].useCommas}
|
|
1935
|
+
onChange={(event) => {
|
|
1936
|
+
editColumn(val, 'useCommas', event.target.checked)
|
|
1937
|
+
}}
|
|
1938
|
+
/>
|
|
1939
|
+
<span className="edit-label">Add Commas to Numbers</span>
|
|
1940
|
+
</label>
|
|
1941
|
+
</li>
|
|
1942
|
+
<li>
|
|
1943
|
+
<label className="checkbox">
|
|
1944
|
+
<input
|
|
1945
|
+
type="checkbox"
|
|
1946
|
+
checked={state.columns[val].dataTable}
|
|
1947
|
+
onChange={(event) => {
|
|
1948
|
+
editColumn(val, 'dataTable', event.target.checked)
|
|
1949
|
+
}}
|
|
1950
|
+
/>
|
|
1951
|
+
<span className="edit-label">Display in Data Table</span>
|
|
1952
|
+
</label>
|
|
1953
|
+
</li>
|
|
1954
|
+
<li>
|
|
1955
|
+
<label className="checkbox">
|
|
1956
|
+
<input
|
|
1957
|
+
type="checkbox"
|
|
1958
|
+
checked={state.columns[val].tooltip}
|
|
1959
|
+
onChange={(event) => {
|
|
1960
|
+
editColumn(val, 'tooltip', event.target.checked)
|
|
1961
|
+
}}
|
|
1962
|
+
/>
|
|
1963
|
+
<span className="edit-label">Display in Tooltips</span>
|
|
1964
|
+
</label>
|
|
1965
|
+
</li>
|
|
1966
|
+
</ul>
|
|
1967
|
+
</fieldset>
|
|
1968
|
+
))}
|
|
1969
|
+
<button
|
|
1970
|
+
className={'btn full-width'}
|
|
1971
|
+
onClick={(event) => {
|
|
1972
|
+
event.preventDefault();
|
|
1973
|
+
addAdditionalColumn(additionalColumns.length + 1);
|
|
1974
|
+
}}
|
|
1975
|
+
>
|
|
1976
|
+
Add Column
|
|
1977
|
+
</button>
|
|
1978
|
+
</fieldset>
|
|
1979
|
+
}
|
|
1552
1980
|
</AccordionItemPanel>
|
|
1553
1981
|
</AccordionItem>{' '}
|
|
1554
1982
|
{/* Columns */}
|
|
@@ -1560,6 +1988,7 @@ const EditorPanel = (props) => {
|
|
|
1560
1988
|
<AccordionItemButton>Legend</AccordionItemButton>
|
|
1561
1989
|
</AccordionItemHeading>
|
|
1562
1990
|
<AccordionItemPanel>
|
|
1991
|
+
{(state.legend.type === "equalnumber" || state.legend.type === 'equalinterval') && (
|
|
1563
1992
|
<label>
|
|
1564
1993
|
<span className='edit-label'>Legend Type</span>
|
|
1565
1994
|
<select
|
|
@@ -1568,11 +1997,49 @@ const EditorPanel = (props) => {
|
|
|
1568
1997
|
handleEditorChanges('legendType', event.target.value);
|
|
1569
1998
|
}}
|
|
1570
1999
|
>
|
|
1571
|
-
<option value='equalnumber'>Equal Number</option>
|
|
2000
|
+
<option value='equalnumber'>Equal Number (Quantiles)</option>
|
|
1572
2001
|
<option value='equalinterval'>Equal Interval</option>
|
|
1573
|
-
|
|
2002
|
+
</select>
|
|
2003
|
+
</label>
|
|
2004
|
+
)}
|
|
2005
|
+
{'navigation' !== state.general.type && (
|
|
2006
|
+
<label className='checkbox'>
|
|
2007
|
+
<input
|
|
2008
|
+
type='checkbox'
|
|
2009
|
+
checked={state.general.showSidebar || false}
|
|
2010
|
+
onChange={(event) => {
|
|
2011
|
+
handleEditorChanges('showSidebar', event.target.checked);
|
|
2012
|
+
}}
|
|
2013
|
+
/>
|
|
2014
|
+
<span className='edit-label'>Show Legend</span>
|
|
2015
|
+
</label>
|
|
2016
|
+
)}
|
|
2017
|
+
{'navigation' !== state.general.type && (
|
|
2018
|
+
<label>
|
|
2019
|
+
<span className='edit-label'>Legend Position</span>
|
|
2020
|
+
<select
|
|
2021
|
+
value={legend.position || false}
|
|
2022
|
+
onChange={(event) => {
|
|
2023
|
+
handleEditorChanges('sidebarPosition', event.target.value);
|
|
2024
|
+
}}
|
|
2025
|
+
>
|
|
2026
|
+
<option value='side'>Side</option>
|
|
2027
|
+
<option value='bottom'>Bottom</option>
|
|
1574
2028
|
</select>
|
|
1575
2029
|
</label>
|
|
2030
|
+
)}
|
|
2031
|
+
{'side' === legend.position && (
|
|
2032
|
+
<label className='checkbox'>
|
|
2033
|
+
<input
|
|
2034
|
+
type='checkbox'
|
|
2035
|
+
checked={legend.singleColumn}
|
|
2036
|
+
onChange={(event) => {
|
|
2037
|
+
handleEditorChanges('singleColumnLegend', event.target.checked);
|
|
2038
|
+
}}
|
|
2039
|
+
/>
|
|
2040
|
+
<span className='edit-label'>Single Column Legend</span>
|
|
2041
|
+
</label>
|
|
2042
|
+
)}
|
|
1576
2043
|
{'category' !== legend.type && (
|
|
1577
2044
|
<label className='checkbox'>
|
|
1578
2045
|
<input
|
|
@@ -1582,12 +2049,43 @@ const EditorPanel = (props) => {
|
|
|
1582
2049
|
handleEditorChanges('separateZero', event.target.checked)
|
|
1583
2050
|
}
|
|
1584
2051
|
/>
|
|
1585
|
-
<span className='edit-label'>
|
|
2052
|
+
<span className='edit-label'>
|
|
2053
|
+
Separate Zero
|
|
2054
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
2055
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
2056
|
+
<Tooltip.Content>
|
|
2057
|
+
<p>For numeric data, you can separate the zero value as its own data class.</p>
|
|
2058
|
+
</Tooltip.Content>
|
|
2059
|
+
</Tooltip>
|
|
2060
|
+
</span>
|
|
2061
|
+
|
|
1586
2062
|
</label>
|
|
1587
2063
|
)}
|
|
2064
|
+
{/* Temp Checkbox */}
|
|
2065
|
+
|
|
2066
|
+
{state.legend.type === 'equalnumber' &&
|
|
2067
|
+
<label className="checkbox mt-4">
|
|
2068
|
+
<input type="checkbox" checked={ state.general.equalNumberOptIn } onChange={(event) => { handleEditorChanges("showEqualNumber", event.target.checked) }} />
|
|
2069
|
+
<span className="edit-label">Use new quantile legend</span>
|
|
2070
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
2071
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
2072
|
+
<Tooltip.Content>
|
|
2073
|
+
<p>This prevents numbers from being used in more than one category (ie. 0-1, 1-2, 2-3) </p>
|
|
2074
|
+
</Tooltip.Content>
|
|
2075
|
+
</Tooltip>
|
|
2076
|
+
</label>
|
|
2077
|
+
}
|
|
1588
2078
|
{'category' !== legend.type && (
|
|
1589
2079
|
<label>
|
|
1590
|
-
<span className='edit-label'>
|
|
2080
|
+
<span className='edit-label'>
|
|
2081
|
+
Number of Items
|
|
2082
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
2083
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
2084
|
+
<Tooltip.Content>
|
|
2085
|
+
<p>For numeric maps, select the number of data classes. Do not include designated special classes.</p>
|
|
2086
|
+
</Tooltip.Content>
|
|
2087
|
+
</Tooltip>
|
|
2088
|
+
</span>
|
|
1591
2089
|
<select
|
|
1592
2090
|
value={legend.numberOfItems}
|
|
1593
2091
|
onChange={(event) => {
|
|
@@ -1607,7 +2105,15 @@ const EditorPanel = (props) => {
|
|
|
1607
2105
|
{'category' === legend.type && (
|
|
1608
2106
|
<React.Fragment>
|
|
1609
2107
|
<label>
|
|
1610
|
-
<span className='edit-label'>
|
|
2108
|
+
<span className='edit-label'>
|
|
2109
|
+
Category Order
|
|
2110
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
2111
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
2112
|
+
<Tooltip.Content>
|
|
2113
|
+
<p>Drag map categories into preferred legend order. </p>
|
|
2114
|
+
</Tooltip.Content>
|
|
2115
|
+
</Tooltip>
|
|
2116
|
+
</span>
|
|
1611
2117
|
</label>
|
|
1612
2118
|
{/* TODO: Swap out this drag and drop library back to something simpler. I had to remove the old one because it hadn't been updated and wouldn't work with Webpack 5. This is overkill for our needs. */}
|
|
1613
2119
|
<DragDropContext
|
|
@@ -1628,13 +2134,13 @@ const EditorPanel = (props) => {
|
|
|
1628
2134
|
)}
|
|
1629
2135
|
</Droppable>
|
|
1630
2136
|
</DragDropContext>
|
|
1631
|
-
{
|
|
2137
|
+
{state.legend.categoryValuesOrder && state.legend.categoryValuesOrder.length >= 10 && (
|
|
1632
2138
|
<section className='error-box my-2'>
|
|
1633
2139
|
<div>
|
|
1634
2140
|
<strong className='pt-1'>Warning</strong>
|
|
1635
2141
|
<p>
|
|
1636
|
-
The maximum number of categorical legend items is
|
|
1637
|
-
your data has more than
|
|
2142
|
+
The maximum number of categorical legend items is 10. If
|
|
2143
|
+
your data has more than 10 categories your map will not
|
|
1638
2144
|
display properly.
|
|
1639
2145
|
</p>
|
|
1640
2146
|
</div>
|
|
@@ -1706,10 +2212,18 @@ const EditorPanel = (props) => {
|
|
|
1706
2212
|
);
|
|
1707
2213
|
}}
|
|
1708
2214
|
/>
|
|
1709
|
-
<span className='edit-label'>
|
|
2215
|
+
<span className='edit-label'>
|
|
2216
|
+
Dynamic Legend Description
|
|
2217
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
2218
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
2219
|
+
<Tooltip.Content>
|
|
2220
|
+
<p>Check this option if the map has multiple filter controls and you want to specify a description for each filter selection.</p>
|
|
2221
|
+
</Tooltip.Content>
|
|
2222
|
+
</Tooltip>
|
|
2223
|
+
</span>
|
|
1710
2224
|
</label>
|
|
1711
2225
|
)}
|
|
1712
|
-
{filtersJSX.length > 0 && (
|
|
2226
|
+
{(filtersJSX.length > 0 || state.general.type === 'bubble' || state.general.geoType === 'us') && (
|
|
1713
2227
|
<label className='checkbox'>
|
|
1714
2228
|
<input
|
|
1715
2229
|
type='checkbox'
|
|
@@ -1718,7 +2232,15 @@ const EditorPanel = (props) => {
|
|
|
1718
2232
|
handleEditorChanges('unifiedLegend', event.target.checked)
|
|
1719
2233
|
}
|
|
1720
2234
|
/>
|
|
1721
|
-
<span className='edit-label'>
|
|
2235
|
+
<span className='edit-label'>
|
|
2236
|
+
Unified Legend
|
|
2237
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
2238
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
2239
|
+
<Tooltip.Content>
|
|
2240
|
+
<p>For a map with filters, check this option if you want the high and low values in the legend to be based on <em>all</em> mapped values.</p>
|
|
2241
|
+
</Tooltip.Content>
|
|
2242
|
+
</Tooltip>
|
|
2243
|
+
</span>
|
|
1722
2244
|
</label>
|
|
1723
2245
|
)}
|
|
1724
2246
|
</AccordionItemPanel>
|
|
@@ -1766,12 +2288,20 @@ const EditorPanel = (props) => {
|
|
|
1766
2288
|
placeholder='Data Table'
|
|
1767
2289
|
/>
|
|
1768
2290
|
<TextField
|
|
1769
|
-
value={dataTable.
|
|
2291
|
+
value={dataTable.indexLabel || ''}
|
|
1770
2292
|
updateField={updateField}
|
|
1771
2293
|
section='dataTable'
|
|
1772
|
-
fieldName='
|
|
1773
|
-
label='Index Column
|
|
2294
|
+
fieldName='indexLabel'
|
|
2295
|
+
label='Index Column Header'
|
|
1774
2296
|
placeholder='Location'
|
|
2297
|
+
tooltip={
|
|
2298
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
2299
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
2300
|
+
<Tooltip.Content>
|
|
2301
|
+
<p>To comply with 508 standards, if the first column in the data table has no header, enter a brief one here.</p>
|
|
2302
|
+
</Tooltip.Content>
|
|
2303
|
+
</Tooltip>
|
|
2304
|
+
}
|
|
1775
2305
|
/>
|
|
1776
2306
|
<TextField
|
|
1777
2307
|
value={dataTable.caption}
|
|
@@ -1780,7 +2310,14 @@ const EditorPanel = (props) => {
|
|
|
1780
2310
|
fieldName='caption'
|
|
1781
2311
|
label='Data Table Caption'
|
|
1782
2312
|
placeholder='Data Table'
|
|
1783
|
-
|
|
2313
|
+
tooltip={
|
|
2314
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
2315
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
2316
|
+
<Tooltip.Content>
|
|
2317
|
+
<p>Enter a description of the data table to be read by screen readers.</p>
|
|
2318
|
+
</Tooltip.Content>
|
|
2319
|
+
</Tooltip>
|
|
2320
|
+
}
|
|
1784
2321
|
type="textarea"
|
|
1785
2322
|
/>
|
|
1786
2323
|
<label className='checkbox'>
|
|
@@ -1795,8 +2332,15 @@ const EditorPanel = (props) => {
|
|
|
1795
2332
|
handleEditorChanges('showDataTable', event.target.checked);
|
|
1796
2333
|
}}
|
|
1797
2334
|
/>
|
|
1798
|
-
<span className='edit-label'>
|
|
1799
|
-
|
|
2335
|
+
<span className='edit-label'>
|
|
2336
|
+
Show Table
|
|
2337
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
2338
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
2339
|
+
<Tooltip.Content>
|
|
2340
|
+
<p>Data tables are required for 508 compliance. When choosing to hide this data table, replace with your own version.</p>
|
|
2341
|
+
</Tooltip.Content>
|
|
2342
|
+
</Tooltip>
|
|
2343
|
+
</span>
|
|
1800
2344
|
</label>
|
|
1801
2345
|
<label className='checkbox'>
|
|
1802
2346
|
<input
|
|
@@ -1854,7 +2398,12 @@ const EditorPanel = (props) => {
|
|
|
1854
2398
|
<label>
|
|
1855
2399
|
<span className='edit-label'>
|
|
1856
2400
|
Detail displays on{' '}
|
|
1857
|
-
|
|
2401
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
2402
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
2403
|
+
<Tooltip.Content>
|
|
2404
|
+
<p>At mobile sizes, information always appears in a popover modal when a user taps on an item.</p>
|
|
2405
|
+
</Tooltip.Content>
|
|
2406
|
+
</Tooltip>
|
|
1858
2407
|
</span>
|
|
1859
2408
|
<select
|
|
1860
2409
|
value={state.tooltips.appearanceType}
|
|
@@ -1894,7 +2443,7 @@ const EditorPanel = (props) => {
|
|
|
1894
2443
|
<AccordionItemButton>Visual</AccordionItemButton>
|
|
1895
2444
|
</AccordionItemHeading>
|
|
1896
2445
|
<AccordionItemPanel>
|
|
1897
|
-
<label
|
|
2446
|
+
<label>
|
|
1898
2447
|
<span className='edit-label'>Header Theme</span>
|
|
1899
2448
|
<ul className='color-palette'>
|
|
1900
2449
|
{headerColors.map((palette) => {
|
|
@@ -1925,44 +2474,28 @@ const EditorPanel = (props) => {
|
|
|
1925
2474
|
/>
|
|
1926
2475
|
<span className='edit-label'>Show Title</span>
|
|
1927
2476
|
</label>
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
<
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
<option value='bottom'>Bottom</option>
|
|
1951
|
-
</select>
|
|
1952
|
-
</label>
|
|
1953
|
-
)}
|
|
1954
|
-
{'side' === legend.position && (
|
|
1955
|
-
<label className='checkbox'>
|
|
1956
|
-
<input
|
|
1957
|
-
type='checkbox'
|
|
1958
|
-
checked={legend.singleColumn}
|
|
1959
|
-
onChange={(event) => {
|
|
1960
|
-
handleEditorChanges('singleColumnLegend', event.target.checked);
|
|
1961
|
-
}}
|
|
1962
|
-
/>
|
|
1963
|
-
<span className='edit-label'>Single Column Legend</span>
|
|
1964
|
-
</label>
|
|
1965
|
-
)}
|
|
2477
|
+
|
|
2478
|
+
<label className='checkbox'>
|
|
2479
|
+
<input
|
|
2480
|
+
type='checkbox'
|
|
2481
|
+
checked={state.general.hideGeoColumnInTooltip || false}
|
|
2482
|
+
onChange={(event) => {
|
|
2483
|
+
handleEditorChanges('hideGeoColumnInTooltip', event.target.checked);
|
|
2484
|
+
}}
|
|
2485
|
+
/>
|
|
2486
|
+
<span className='edit-label'>Hide Geography Column Name in Tooltip</span>
|
|
2487
|
+
</label>
|
|
2488
|
+
|
|
2489
|
+
<label className='checkbox'>
|
|
2490
|
+
<input
|
|
2491
|
+
type='checkbox'
|
|
2492
|
+
checked={state.general.hidePrimaryColumnInTooltip || false}
|
|
2493
|
+
onChange={(event) => {
|
|
2494
|
+
handleEditorChanges('hidePrimaryColumnInTooltip', event.target.checked);
|
|
2495
|
+
}}
|
|
2496
|
+
/>
|
|
2497
|
+
<span className='edit-label'>Hide Primary Column Name in Tooltip</span>
|
|
2498
|
+
</label>
|
|
1966
2499
|
{'navigation' === state.general.type && (
|
|
1967
2500
|
<label className='checkbox'>
|
|
1968
2501
|
<input
|
|
@@ -1990,10 +2523,11 @@ const EditorPanel = (props) => {
|
|
|
1990
2523
|
<label>
|
|
1991
2524
|
<span className='edit-label'>Map Color Palette</span>
|
|
1992
2525
|
</label>
|
|
1993
|
-
<
|
|
2526
|
+
{/* <InputCheckbox section="general" subsection="palette" fieldName='isReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} /> */}
|
|
2527
|
+
<InputToggle type='3d' section="general" subsection="palette" fieldName='isReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} />
|
|
2528
|
+
<span>Sequential</span>
|
|
1994
2529
|
<ul className='color-palette'>
|
|
1995
|
-
{
|
|
1996
|
-
.filter((name) => !name.includes('qualitative'))
|
|
2530
|
+
{filteredPallets
|
|
1997
2531
|
.map((palette) => {
|
|
1998
2532
|
const colorOne = {
|
|
1999
2533
|
backgroundColor: colorPalettes[palette][2],
|
|
@@ -2023,10 +2557,9 @@ const EditorPanel = (props) => {
|
|
|
2023
2557
|
);
|
|
2024
2558
|
})}
|
|
2025
2559
|
</ul>
|
|
2026
|
-
<span
|
|
2560
|
+
<span>Non-Sequential</span>
|
|
2027
2561
|
<ul className='color-palette'>
|
|
2028
|
-
{
|
|
2029
|
-
.filter((name) => name.includes('qualitative'))
|
|
2562
|
+
{filteredQualitative
|
|
2030
2563
|
.map((palette) => {
|
|
2031
2564
|
const colorOne = {
|
|
2032
2565
|
backgroundColor: colorPalettes[palette][2],
|
|
@@ -2040,6 +2573,10 @@ const EditorPanel = (props) => {
|
|
|
2040
2573
|
backgroundColor: colorPalettes[palette][6],
|
|
2041
2574
|
};
|
|
2042
2575
|
|
|
2576
|
+
// hide palettes with too few colors for region maps
|
|
2577
|
+
if ( colorPalettes[palette].length <= 8 && state.general.geoType === 'us-region' ) {
|
|
2578
|
+
return('');
|
|
2579
|
+
}
|
|
2043
2580
|
return (
|
|
2044
2581
|
<li
|
|
2045
2582
|
title={palette}
|
|
@@ -2056,52 +2593,78 @@ const EditorPanel = (props) => {
|
|
|
2056
2593
|
);
|
|
2057
2594
|
})}
|
|
2058
2595
|
</ul>
|
|
2596
|
+
{(state.general.type === 'bubble') && <><TextField
|
|
2597
|
+
type='number'
|
|
2598
|
+
value={state.visual.minBubbleSize}
|
|
2599
|
+
section='visual'
|
|
2600
|
+
fieldName='minBubbleSize'
|
|
2601
|
+
label='Minimum Bubble Size'
|
|
2602
|
+
updateField={updateField}
|
|
2603
|
+
/>
|
|
2604
|
+
<TextField
|
|
2605
|
+
type='number'
|
|
2606
|
+
value={state.visual.maxBubbleSize}
|
|
2607
|
+
section='visual'
|
|
2608
|
+
fieldName='maxBubbleSize'
|
|
2609
|
+
label='Maximum Bubble Size'
|
|
2610
|
+
updateField={updateField}
|
|
2611
|
+
/></>}
|
|
2612
|
+
{ (state.general.geoType === 'world' || state.general.geoType === 'us' && state.general.type === 'bubble') &&
|
|
2613
|
+
<label className='checkbox'>
|
|
2614
|
+
<input
|
|
2615
|
+
type='checkbox'
|
|
2616
|
+
checked={state.visual.showBubbleZeros}
|
|
2617
|
+
onChange={(event) => {
|
|
2618
|
+
handleEditorChanges('showBubbleZeros', event.target.checked);
|
|
2619
|
+
}}
|
|
2620
|
+
/>
|
|
2621
|
+
<span className='edit-label'>Show Data with Zero's on Bubble Map</span>
|
|
2622
|
+
</label>
|
|
2623
|
+
}
|
|
2624
|
+
{state.general.geoType === 'world' &&
|
|
2625
|
+
<label className='checkbox'>
|
|
2626
|
+
<input
|
|
2627
|
+
type='checkbox'
|
|
2628
|
+
checked={state.general.allowMapZoom}
|
|
2629
|
+
onChange={(event) => {
|
|
2630
|
+
handleEditorChanges('allowMapZoom', event.target.checked);
|
|
2631
|
+
}}
|
|
2632
|
+
/>
|
|
2633
|
+
<span className='edit-label'>Allow Map Zooming</span>
|
|
2634
|
+
</label>
|
|
2635
|
+
}
|
|
2636
|
+
{state.general.type === 'bubble' &&
|
|
2637
|
+
<label className='checkbox'>
|
|
2638
|
+
<input
|
|
2639
|
+
type='checkbox'
|
|
2640
|
+
checked={state.visual.extraBubbleBorder}
|
|
2641
|
+
onChange={(event) => {
|
|
2642
|
+
handleEditorChanges('toggleExtraBubbleBorder', event.target.checked);
|
|
2643
|
+
}}
|
|
2644
|
+
/>
|
|
2645
|
+
<span className='edit-label'>Bubble Map has extra border</span>
|
|
2646
|
+
</label>
|
|
2647
|
+
}
|
|
2648
|
+
{state.general.geoType === 'us' &&
|
|
2649
|
+
<label>
|
|
2650
|
+
<span className='edit-label'>City Style</span>
|
|
2651
|
+
<select
|
|
2652
|
+
value={state.visual.cityStyle || false}
|
|
2653
|
+
onChange={(event) => {
|
|
2654
|
+
handleEditorChanges('handleCityStyle', event.target.value);
|
|
2655
|
+
}}
|
|
2656
|
+
>
|
|
2657
|
+
<option value='circle'>Circle</option>
|
|
2658
|
+
<option value='pin'>Pin</option>
|
|
2659
|
+
</select>
|
|
2660
|
+
</label>
|
|
2661
|
+
}
|
|
2059
2662
|
</AccordionItemPanel>
|
|
2060
2663
|
</AccordionItem>
|
|
2061
2664
|
</Accordion>
|
|
2062
2665
|
</form>
|
|
2063
|
-
<
|
|
2064
|
-
|
|
2065
|
-
target='_blank'
|
|
2066
|
-
rel='noopener noreferrer'
|
|
2067
|
-
className='guidance-link'
|
|
2068
|
-
>
|
|
2069
|
-
<MapIcon />
|
|
2070
|
-
<div>
|
|
2071
|
-
<span className='heading-3'>Get Maps Help</span>
|
|
2072
|
-
<p>Examples and documentation</p>
|
|
2073
|
-
</div>
|
|
2074
|
-
</a>
|
|
2075
|
-
<div className='advanced'>
|
|
2076
|
-
<span className='advanced-toggle-link' onClick={() => setAdvancedToggle(!advancedToggle)}>
|
|
2077
|
-
<span>{advancedToggle ? `— ` : `+ `}</span>Advanced Options
|
|
2078
|
-
</span>
|
|
2079
|
-
{advancedToggle && (
|
|
2080
|
-
<React.Fragment>
|
|
2081
|
-
<section className='error-box py-2 px-3 my-2'>
|
|
2082
|
-
<div>
|
|
2083
|
-
<strong className='pt-1'>Warning</strong>
|
|
2084
|
-
<p>This can cause serious errors in your map.</p>
|
|
2085
|
-
</div>
|
|
2086
|
-
</section>
|
|
2087
|
-
<p className='pb-2'>
|
|
2088
|
-
This tool displays the actual map configuration{' '}
|
|
2089
|
-
<acronym title='JavaScript Object Notation'>JSON</acronym> that is generated by this
|
|
2090
|
-
editor and allows you to edit properties directly and apply them.
|
|
2091
|
-
</p>
|
|
2092
|
-
<textarea
|
|
2093
|
-
value={configTextboxValue}
|
|
2094
|
-
onChange={(event) => setConfigTextbox(event.target.value)}
|
|
2095
|
-
/>
|
|
2096
|
-
<button
|
|
2097
|
-
className='btn full-width'
|
|
2098
|
-
onClick={() => loadConfig(JSON.parse(configTextboxValue))}
|
|
2099
|
-
>
|
|
2100
|
-
Apply
|
|
2101
|
-
</button>
|
|
2102
|
-
</React.Fragment>
|
|
2103
|
-
)}
|
|
2104
|
-
</div>
|
|
2666
|
+
<AdvancedEditor loadConfig={loadConfig} state={state} convertStateToConfig={convertStateToConfig} />
|
|
2667
|
+
|
|
2105
2668
|
</section>
|
|
2106
2669
|
</section>
|
|
2107
2670
|
</ErrorBoundary>
|