@cdc/map 2.6.3 → 2.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdcmap.js +26 -18
- package/examples/bubble-us.json +363 -0
- package/examples/bubble-world.json +427 -0
- package/examples/default-hex.json +475 -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 +36 -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/default-world-data.json +1444 -0
- package/examples/private/default.json +968 -0
- package/examples/private/map.csv +60 -0
- package/examples/private/mdx.json +210 -0
- package/examples/private/regions.json +52 -0
- package/examples/private/wcmsrd-13881-data.json +2858 -0
- package/examples/private/wcmsrd-13881.json +5823 -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 +340 -79
- package/src/components/BubbleList.js +240 -0
- package/src/components/CityList.js +19 -1
- package/src/components/CountyMap.js +3 -2
- package/src/components/DataTable.js +17 -10
- package/src/components/EditorPanel.js +741 -348
- package/src/components/Geo.js +1 -1
- package/src/components/SingleStateMap.js +1 -1
- package/src/components/UsaMap.js +22 -7
- package/src/components/UsaRegionMap.js +319 -0
- package/src/components/WorldMap.js +112 -35
- package/src/data/country-coordinates.js +250 -0
- package/src/data/initial-state.js +19 -2
- package/src/data/state-coordinates.js +55 -0
- package/src/data/supported-geos.js +91 -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 +10 -2
- package/src/scss/editor-panel.scss +76 -55
- package/src/scss/map.scss +108 -2
- package/src/data/color-palettes.js +0 -200
- package/src/images/map-folded.svg +0 -1
|
@@ -13,27 +13,25 @@ import { useDebounce } from 'use-debounce';
|
|
|
13
13
|
import ErrorBoundary from '@cdc/core/components/ErrorBoundary';
|
|
14
14
|
import Waiting from '@cdc/core/components/Waiting';
|
|
15
15
|
|
|
16
|
-
import MapIcon from '../images/map-folded.svg';
|
|
17
16
|
import UsaGraphic from '@cdc/core/assets/usa-graphic.svg';
|
|
18
17
|
import WorldGraphic from '@cdc/core/assets/world-graphic.svg';
|
|
19
18
|
import AlabamaGraphic from '@cdc/core/assets/alabama-graphic.svg';
|
|
20
|
-
import colorPalettes from '
|
|
19
|
+
import colorPalettes from '../../../core/data/colorPalettes';
|
|
21
20
|
import worldDefaultConfig from '../../examples/default-world.json';
|
|
22
21
|
import usaDefaultConfig from '../../examples/default-usa.json';
|
|
23
22
|
import countyDefaultConfig from '../../examples/default-county.json';
|
|
24
23
|
import QuestionIcon from '@cdc/core/assets/question-circle.svg';
|
|
25
24
|
|
|
26
25
|
import { supportedStatesFipsCodes } from '../data/supported-geos';
|
|
26
|
+
import { GET_PALETTE,useColorPalette } from '../hooks/useColorPalette';
|
|
27
|
+
import InputCheckbox from '@cdc/core/components/inputs/InputCheckbox';
|
|
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,6 +105,9 @@ const EditorPanel = (props) => {
|
|
|
107
105
|
|
|
108
106
|
const [activeFilterValueForDescription, setActiveFilterValueForDescription] = useState([0, 0]);
|
|
109
107
|
|
|
108
|
+
const {filteredPallets,filteredQualitative,isPaletteReversed,paletteName} = useColorPalette(colorPalettes,state);
|
|
109
|
+
|
|
110
|
+
|
|
110
111
|
const [editorCatOrder, setEditorCatOrder] = useState(state.legend.categoryValuesOrder || []);
|
|
111
112
|
|
|
112
113
|
const headerColors = [
|
|
@@ -162,7 +163,7 @@ const EditorPanel = (props) => {
|
|
|
162
163
|
};
|
|
163
164
|
|
|
164
165
|
|
|
165
|
-
const DynamicDesc = ({ label, fieldName, value: stateValue, type = 'input',
|
|
166
|
+
const DynamicDesc = ({ label, fieldName, value: stateValue, type = 'input', ...attributes }) => {
|
|
166
167
|
const [value, setValue] = useState(stateValue);
|
|
167
168
|
|
|
168
169
|
const [debouncedValue] = useDebounce(value, 500);
|
|
@@ -183,6 +184,67 @@ const EditorPanel = (props) => {
|
|
|
183
184
|
|
|
184
185
|
const handleEditorChanges = async (property, value) => {
|
|
185
186
|
switch (property) {
|
|
187
|
+
|
|
188
|
+
// change these to be more generic.
|
|
189
|
+
// updateVisualPropertyValue
|
|
190
|
+
// updateGeneralPropertyValue, etc.
|
|
191
|
+
case 'showBubbleZeros':
|
|
192
|
+
setState({
|
|
193
|
+
...state,
|
|
194
|
+
visual: {
|
|
195
|
+
...state.visual,
|
|
196
|
+
showBubbleZeros: value
|
|
197
|
+
}
|
|
198
|
+
})
|
|
199
|
+
break;
|
|
200
|
+
|
|
201
|
+
case 'showEqualNumber':
|
|
202
|
+
setState({
|
|
203
|
+
...state,
|
|
204
|
+
general: {
|
|
205
|
+
...state.general,
|
|
206
|
+
equalNumberOptIn: value
|
|
207
|
+
}
|
|
208
|
+
})
|
|
209
|
+
break;
|
|
210
|
+
|
|
211
|
+
case 'hideGeoColumnInTooltip':
|
|
212
|
+
setState({
|
|
213
|
+
...state,
|
|
214
|
+
general: {
|
|
215
|
+
...state.general,
|
|
216
|
+
[property]: value
|
|
217
|
+
}
|
|
218
|
+
})
|
|
219
|
+
break;
|
|
220
|
+
|
|
221
|
+
case 'toggleExtraBubbleBorder':
|
|
222
|
+
setState({
|
|
223
|
+
...state,
|
|
224
|
+
visual: {
|
|
225
|
+
...state.visual,
|
|
226
|
+
extraBubbleBorder: value
|
|
227
|
+
}
|
|
228
|
+
})
|
|
229
|
+
break;
|
|
230
|
+
case 'allowMapZoom':
|
|
231
|
+
setState({
|
|
232
|
+
...state,
|
|
233
|
+
general: {
|
|
234
|
+
...state.general,
|
|
235
|
+
[property]: value
|
|
236
|
+
}
|
|
237
|
+
})
|
|
238
|
+
break;
|
|
239
|
+
case 'hidePrimaryColumnInTooltip':
|
|
240
|
+
setState({
|
|
241
|
+
...state,
|
|
242
|
+
general: {
|
|
243
|
+
...state.general,
|
|
244
|
+
[property]: value
|
|
245
|
+
}
|
|
246
|
+
})
|
|
247
|
+
break;
|
|
186
248
|
case 'showTitle':
|
|
187
249
|
setState({
|
|
188
250
|
...state,
|
|
@@ -274,12 +336,31 @@ const EditorPanel = (props) => {
|
|
|
274
336
|
});
|
|
275
337
|
break;
|
|
276
338
|
case 'legendType':
|
|
339
|
+
|
|
340
|
+
let testForType = typeof state.data[0][state.columns.primary.name];
|
|
341
|
+
let hasValue = state.data[0][state.columns.primary.name];
|
|
342
|
+
let messages = [];
|
|
343
|
+
|
|
344
|
+
if(!hasValue) {
|
|
345
|
+
messages.push(`There appears to be values missing for data in the primary column ${state.columns.primary.name}`);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if (testForType === 'string' && value !== 'category') {
|
|
349
|
+
messages.push( 'Error with legend. Primary columns that are text must use a categorical legend type. Try changing the legend type to categorical.' );
|
|
350
|
+
} else {
|
|
351
|
+
messages = []
|
|
352
|
+
}
|
|
353
|
+
|
|
277
354
|
setState({
|
|
278
355
|
...state,
|
|
279
356
|
legend: {
|
|
280
357
|
...state.legend,
|
|
281
358
|
type: value,
|
|
282
359
|
},
|
|
360
|
+
runtime: {
|
|
361
|
+
...state.runtime,
|
|
362
|
+
editorErrorMessage: messages
|
|
363
|
+
}
|
|
283
364
|
});
|
|
284
365
|
break;
|
|
285
366
|
case 'legendNumber':
|
|
@@ -367,6 +448,20 @@ const EditorPanel = (props) => {
|
|
|
367
448
|
},
|
|
368
449
|
});
|
|
369
450
|
break;
|
|
451
|
+
case 'bubble':
|
|
452
|
+
setState({
|
|
453
|
+
...state,
|
|
454
|
+
general: {
|
|
455
|
+
...state.general,
|
|
456
|
+
showSidebar: false,
|
|
457
|
+
type: 'bubble',
|
|
458
|
+
},
|
|
459
|
+
tooltips: {
|
|
460
|
+
...state.tooltips,
|
|
461
|
+
appearanceType: 'hover',
|
|
462
|
+
},
|
|
463
|
+
});
|
|
464
|
+
break;
|
|
370
465
|
default:
|
|
371
466
|
console.warn('Map type not set');
|
|
372
467
|
break;
|
|
@@ -558,6 +653,15 @@ const EditorPanel = (props) => {
|
|
|
558
653
|
},
|
|
559
654
|
});
|
|
560
655
|
break;
|
|
656
|
+
case "classificationType":
|
|
657
|
+
setState({
|
|
658
|
+
...state,
|
|
659
|
+
legend: {
|
|
660
|
+
...state.legend,
|
|
661
|
+
type: value,
|
|
662
|
+
},
|
|
663
|
+
});
|
|
664
|
+
break;
|
|
561
665
|
default:
|
|
562
666
|
console.warn(`Did not recognize editor property.`);
|
|
563
667
|
break;
|
|
@@ -804,7 +908,7 @@ const EditorPanel = (props) => {
|
|
|
804
908
|
}, [state]);
|
|
805
909
|
|
|
806
910
|
useEffect(() => {
|
|
807
|
-
if ('category' === state.legend.type
|
|
911
|
+
if ('category' === state.legend.type) {
|
|
808
912
|
let arr = runtimeLegend.filter((item) => !item.special).map(({ value }) => value);
|
|
809
913
|
|
|
810
914
|
setEditorCatOrder(arr);
|
|
@@ -948,7 +1052,12 @@ const EditorPanel = (props) => {
|
|
|
948
1052
|
<label>
|
|
949
1053
|
<span className='edit-label column-heading'>
|
|
950
1054
|
Filter Column{' '}
|
|
951
|
-
|
|
1055
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1056
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1057
|
+
<Tooltip.Content>
|
|
1058
|
+
<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>
|
|
1059
|
+
</Tooltip.Content>
|
|
1060
|
+
</Tooltip>
|
|
952
1061
|
</span>
|
|
953
1062
|
<select
|
|
954
1063
|
value={filter.columnName}
|
|
@@ -961,7 +1070,7 @@ const EditorPanel = (props) => {
|
|
|
961
1070
|
)}
|
|
962
1071
|
</select>
|
|
963
1072
|
</label>
|
|
964
|
-
|
|
1073
|
+
|
|
965
1074
|
<label>
|
|
966
1075
|
<span className="edit-filterOrder column-heading">Filter Order</span>
|
|
967
1076
|
<select value={filter.order} onChange={ (e) => {
|
|
@@ -1009,7 +1118,7 @@ const EditorPanel = (props) => {
|
|
|
1009
1118
|
</Droppable>
|
|
1010
1119
|
</DragDropContext>
|
|
1011
1120
|
}
|
|
1012
|
-
|
|
1121
|
+
|
|
1013
1122
|
</fieldset>
|
|
1014
1123
|
);
|
|
1015
1124
|
});
|
|
@@ -1043,21 +1152,28 @@ const EditorPanel = (props) => {
|
|
|
1043
1152
|
});
|
|
1044
1153
|
}
|
|
1045
1154
|
|
|
1155
|
+
|
|
1156
|
+
useEffect(()=>{
|
|
1157
|
+
if(paletteName) handleEditorChanges('color',paletteName)
|
|
1158
|
+
},[paletteName]) // dont add handleEditorChanges as a dependency even if it requires
|
|
1159
|
+
|
|
1046
1160
|
useEffect(() => {
|
|
1047
1161
|
const parsedData = convertStateToConfig();
|
|
1048
1162
|
const formattedData = JSON.stringify(parsedData, undefined, 2);
|
|
1049
1163
|
|
|
1050
1164
|
setConfigTextbox(formattedData);
|
|
1165
|
+
}, [state]);
|
|
1051
1166
|
|
|
1167
|
+
useEffect(() => {
|
|
1052
1168
|
// Pass up to Editor if needed
|
|
1053
1169
|
if (setParentConfig) {
|
|
1054
1170
|
const newConfig = convertStateToConfig();
|
|
1055
1171
|
setParentConfig(newConfig);
|
|
1056
1172
|
}
|
|
1057
1173
|
|
|
1058
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1059
1174
|
}, [state]);
|
|
1060
1175
|
|
|
1176
|
+
|
|
1061
1177
|
let numberOfItemsLimit = 8;
|
|
1062
1178
|
|
|
1063
1179
|
const getItemStyle = (isDragging, draggableStyle) => ({
|
|
@@ -1084,8 +1200,20 @@ const EditorPanel = (props) => {
|
|
|
1084
1200
|
));
|
|
1085
1201
|
};
|
|
1086
1202
|
|
|
1203
|
+
const Error = () => {
|
|
1204
|
+
return (
|
|
1205
|
+
<section className="waiting">
|
|
1206
|
+
<section className="waiting-container">
|
|
1207
|
+
<h3>Error With Configuration</h3>
|
|
1208
|
+
<p>{state.runtime.editorErrorMessage}</p>
|
|
1209
|
+
</section>
|
|
1210
|
+
</section>
|
|
1211
|
+
);
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1087
1214
|
return (
|
|
1088
1215
|
<ErrorBoundary component='EditorPanel'>
|
|
1216
|
+
{state?.runtime?.editorErrorMessage.length > 0 && <Error />}
|
|
1089
1217
|
{requiredColumns && (
|
|
1090
1218
|
<Waiting requiredColumns={requiredColumns} className={displayPanel ? `waiting` : `waiting collapsed`} />
|
|
1091
1219
|
)}
|
|
@@ -1095,7 +1223,8 @@ const EditorPanel = (props) => {
|
|
|
1095
1223
|
onClick={onBackClick}
|
|
1096
1224
|
data-html2canvas-ignore
|
|
1097
1225
|
></button>
|
|
1098
|
-
|
|
1226
|
+
|
|
1227
|
+
<section className={displayPanel ? 'editor-panel cove' : 'hidden editor-panel cove'} data-html2canvas-ignore>
|
|
1099
1228
|
<ReactTooltip html={true} multiline={true} />
|
|
1100
1229
|
<span className='base-label'>Configure Map</span>
|
|
1101
1230
|
<section className='form-container'>
|
|
@@ -1145,7 +1274,15 @@ const EditorPanel = (props) => {
|
|
|
1145
1274
|
{/* Select > State or County Map */}
|
|
1146
1275
|
{(state.general.geoType === 'us' || state.general.geoType === 'us-county') && (
|
|
1147
1276
|
<label>
|
|
1148
|
-
<span className='edit-label column-heading'>
|
|
1277
|
+
<span className='edit-label column-heading'>
|
|
1278
|
+
Map Type
|
|
1279
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1280
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1281
|
+
<Tooltip.Content>
|
|
1282
|
+
<p>Select "Data" to create a color-coded data map. To create a navigation-only map, select "Navigation."</p>
|
|
1283
|
+
</Tooltip.Content>
|
|
1284
|
+
</Tooltip>
|
|
1285
|
+
</span>
|
|
1149
1286
|
<select
|
|
1150
1287
|
value={state.general.geoType}
|
|
1151
1288
|
onChange={(event) => {
|
|
@@ -1187,6 +1324,7 @@ const EditorPanel = (props) => {
|
|
|
1187
1324
|
>
|
|
1188
1325
|
<option value='data'>Data</option>
|
|
1189
1326
|
<option value='navigation'>Navigation</option>
|
|
1327
|
+
{ (state.general.geoType === 'world' || state.general.geoType === 'us') && <option value="bubble">Bubble</option>}
|
|
1190
1328
|
</select>
|
|
1191
1329
|
</label>
|
|
1192
1330
|
{/* SubType */}
|
|
@@ -1232,7 +1370,14 @@ const EditorPanel = (props) => {
|
|
|
1232
1370
|
fieldName='title'
|
|
1233
1371
|
label='Title'
|
|
1234
1372
|
placeholder='Map Title'
|
|
1235
|
-
|
|
1373
|
+
tooltip={
|
|
1374
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1375
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1376
|
+
<Tooltip.Content>
|
|
1377
|
+
<p>For accessibility reasons, you should enter a title even if you are not planning on displaying it.</p>
|
|
1378
|
+
</Tooltip.Content>
|
|
1379
|
+
</Tooltip>
|
|
1380
|
+
}
|
|
1236
1381
|
/>
|
|
1237
1382
|
<TextField
|
|
1238
1383
|
type='textarea'
|
|
@@ -1241,6 +1386,14 @@ const EditorPanel = (props) => {
|
|
|
1241
1386
|
section='general'
|
|
1242
1387
|
fieldName='subtext'
|
|
1243
1388
|
label='Subtext'
|
|
1389
|
+
tooltip={
|
|
1390
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1391
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1392
|
+
<Tooltip.Content>
|
|
1393
|
+
<p>Enter supporting text to display below the data visualization, if applicable. The following HTML tags are supported: strong, em, sup, and sub.</p>
|
|
1394
|
+
</Tooltip.Content>
|
|
1395
|
+
</Tooltip>
|
|
1396
|
+
}
|
|
1244
1397
|
/>
|
|
1245
1398
|
{'us' === state.general.geoType && (
|
|
1246
1399
|
<TextField
|
|
@@ -1252,6 +1405,41 @@ const EditorPanel = (props) => {
|
|
|
1252
1405
|
placeholder='Territories'
|
|
1253
1406
|
/>
|
|
1254
1407
|
)}
|
|
1408
|
+
<label>
|
|
1409
|
+
<span className="edit-label">Data Classification Type</span>
|
|
1410
|
+
<div>
|
|
1411
|
+
<label>
|
|
1412
|
+
<input
|
|
1413
|
+
type="radio"
|
|
1414
|
+
name="equalnumber"
|
|
1415
|
+
value="equalnumber"
|
|
1416
|
+
checked={state.legend.type === "equalnumber"}
|
|
1417
|
+
onChange={(e) =>
|
|
1418
|
+
handleEditorChanges(
|
|
1419
|
+
"classificationType",
|
|
1420
|
+
e.target.value
|
|
1421
|
+
)
|
|
1422
|
+
}
|
|
1423
|
+
/>
|
|
1424
|
+
Numeric/Quantitative
|
|
1425
|
+
</label>
|
|
1426
|
+
<label>
|
|
1427
|
+
<input
|
|
1428
|
+
type="radio"
|
|
1429
|
+
name="category"
|
|
1430
|
+
value="category"
|
|
1431
|
+
checked={state.legend.type === "category"}
|
|
1432
|
+
onChange={(e) =>
|
|
1433
|
+
handleEditorChanges(
|
|
1434
|
+
"classificationType",
|
|
1435
|
+
e.target.value
|
|
1436
|
+
)
|
|
1437
|
+
}
|
|
1438
|
+
/>
|
|
1439
|
+
Categorical
|
|
1440
|
+
</label>
|
|
1441
|
+
</div>
|
|
1442
|
+
</label>
|
|
1255
1443
|
{/* <label className="checkbox mt-4">
|
|
1256
1444
|
<input type="checkbox" checked={ state.general.showDownloadMediaButton } onChange={(event) => { handleEditorChanges("toggleDownloadMediaButton", event.target.checked) }} />
|
|
1257
1445
|
<span className="edit-label">Enable Media Download</span>
|
|
@@ -1266,7 +1454,15 @@ const EditorPanel = (props) => {
|
|
|
1266
1454
|
</AccordionItemHeading>
|
|
1267
1455
|
<AccordionItemPanel>
|
|
1268
1456
|
<label className='edit-block geo'>
|
|
1269
|
-
<span className='edit-label column-heading'>
|
|
1457
|
+
<span className='edit-label column-heading'>
|
|
1458
|
+
Geography
|
|
1459
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1460
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1461
|
+
<Tooltip.Content>
|
|
1462
|
+
<p>Select the source column containing the map location names or, for county-level maps, the FIPS codes.</p>
|
|
1463
|
+
</Tooltip.Content>
|
|
1464
|
+
</Tooltip>
|
|
1465
|
+
</span>
|
|
1270
1466
|
<select
|
|
1271
1467
|
value={state.columns.geo ? state.columns.geo.name : columnsOptions[0]}
|
|
1272
1468
|
onChange={(event) => {
|
|
@@ -1276,155 +1472,222 @@ const EditorPanel = (props) => {
|
|
|
1276
1472
|
{columnsOptions}
|
|
1277
1473
|
</select>
|
|
1278
1474
|
</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
|
-
|
|
1475
|
+
|
|
1476
|
+
{'navigation' !== state.general.type && (
|
|
1477
|
+
<fieldset className='primary-fieldset edit-block'>
|
|
1478
|
+
<label>
|
|
1479
|
+
<span className='edit-label column-heading'>
|
|
1480
|
+
Data Column
|
|
1481
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1482
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1483
|
+
<Tooltip.Content>
|
|
1484
|
+
<p>Select the source column containing the categorical or numeric values to be mapped.</p>
|
|
1485
|
+
</Tooltip.Content>
|
|
1486
|
+
</Tooltip>
|
|
1487
|
+
</span>
|
|
1488
|
+
<select
|
|
1489
|
+
value={
|
|
1490
|
+
state.columns.primary
|
|
1491
|
+
? state.columns.primary.name
|
|
1492
|
+
: columnsOptions[0]
|
|
1493
|
+
}
|
|
1494
|
+
onChange={(event) => {
|
|
1495
|
+
editColumn('primary', 'name', event.target.value);
|
|
1496
|
+
}}
|
|
1497
|
+
>
|
|
1498
|
+
{columnsOptions}
|
|
1499
|
+
</select>
|
|
1500
|
+
</label>
|
|
1501
|
+
<TextField
|
|
1502
|
+
value={columns.primary.label}
|
|
1503
|
+
section='columns'
|
|
1504
|
+
subsection='primary'
|
|
1505
|
+
fieldName='label'
|
|
1506
|
+
label='Label'
|
|
1507
|
+
updateField={updateField}
|
|
1508
|
+
tooltip={
|
|
1509
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1510
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1511
|
+
<Tooltip.Content>
|
|
1512
|
+
<p>Enter a data label for use in tooltips and the data table.</p>
|
|
1513
|
+
</Tooltip.Content>
|
|
1514
|
+
</Tooltip>
|
|
1515
|
+
}
|
|
1516
|
+
/>
|
|
1517
|
+
<ul className='column-edit'>
|
|
1518
|
+
<li className='three-col'>
|
|
1519
|
+
<TextField
|
|
1520
|
+
value={columns.primary.prefix}
|
|
1521
|
+
section='columns'
|
|
1522
|
+
subsection='primary'
|
|
1523
|
+
fieldName='prefix'
|
|
1524
|
+
label='Prefix'
|
|
1525
|
+
updateField={updateField}
|
|
1526
|
+
/>
|
|
1527
|
+
<TextField
|
|
1528
|
+
value={columns.primary.suffix}
|
|
1529
|
+
section='columns'
|
|
1530
|
+
subsection='primary'
|
|
1531
|
+
fieldName='suffix'
|
|
1532
|
+
label='Suffix'
|
|
1533
|
+
updateField={updateField}
|
|
1534
|
+
/>
|
|
1535
|
+
<TextField
|
|
1536
|
+
type='number'
|
|
1537
|
+
value={columns.primary.roundToPlace}
|
|
1538
|
+
section='columns'
|
|
1539
|
+
subsection='primary'
|
|
1540
|
+
fieldName='roundToPlace'
|
|
1541
|
+
label='Round'
|
|
1542
|
+
updateField={updateField}
|
|
1543
|
+
/>
|
|
1544
|
+
</li>
|
|
1545
|
+
<li>
|
|
1546
|
+
<label className='checkbox'>
|
|
1547
|
+
<input
|
|
1548
|
+
type='checkbox'
|
|
1549
|
+
checked={state.columns.primary.useCommas}
|
|
1550
|
+
onChange={(event) => {
|
|
1551
|
+
editColumn(
|
|
1552
|
+
'primary',
|
|
1553
|
+
'useCommas',
|
|
1554
|
+
event.target.checked
|
|
1555
|
+
);
|
|
1556
|
+
}}
|
|
1557
|
+
/>
|
|
1558
|
+
<span className='edit-label'>Add Commas to Numbers</span>
|
|
1559
|
+
</label>
|
|
1560
|
+
</li>
|
|
1561
|
+
<li>
|
|
1562
|
+
<label className='checkbox'>
|
|
1563
|
+
<input
|
|
1564
|
+
type='checkbox'
|
|
1565
|
+
checked={state.columns.primary.dataTable || false}
|
|
1566
|
+
onChange={(event) => {
|
|
1567
|
+
editColumn(
|
|
1568
|
+
'primary',
|
|
1569
|
+
'dataTable',
|
|
1570
|
+
event.target.checked
|
|
1571
|
+
);
|
|
1572
|
+
}}
|
|
1573
|
+
/>
|
|
1574
|
+
<span className='edit-label'>Display in Data Table</span>
|
|
1575
|
+
</label>
|
|
1576
|
+
</li>
|
|
1577
|
+
<li>
|
|
1578
|
+
<label className='checkbox'>
|
|
1579
|
+
<input
|
|
1580
|
+
type='checkbox'
|
|
1581
|
+
checked={state.columns.primary.tooltip || false}
|
|
1582
|
+
onChange={(event) => {
|
|
1583
|
+
editColumn('primary', 'tooltip', event.target.checked);
|
|
1584
|
+
}}
|
|
1585
|
+
/>
|
|
1586
|
+
<span className='edit-label'>Display in Tooltips</span>
|
|
1587
|
+
</label>
|
|
1588
|
+
</li>
|
|
1589
|
+
</ul>
|
|
1590
|
+
</fieldset>
|
|
1591
|
+
)}
|
|
1592
|
+
|
|
1593
|
+
|
|
1594
|
+
|
|
1595
|
+
{ (state.general.type === 'bubble') && state.legend.type === 'category' && (
|
|
1596
|
+
<fieldset className='primary-fieldset edit-block'>
|
|
1597
|
+
<label>
|
|
1598
|
+
<span className='edit-label column-heading'>
|
|
1599
|
+
Category Column
|
|
1600
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1601
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1602
|
+
<Tooltip.Content>
|
|
1603
|
+
<p>Select the source column containing the categorical bubble values to be mapped.</p>
|
|
1604
|
+
</Tooltip.Content>
|
|
1605
|
+
</Tooltip>
|
|
1606
|
+
</span>
|
|
1607
|
+
<select
|
|
1608
|
+
value={
|
|
1609
|
+
state.columns.categorical
|
|
1610
|
+
? state.columns.categorical.name
|
|
1611
|
+
: columnsOptions[0]
|
|
1612
|
+
}
|
|
1613
|
+
onChange={(event) => {
|
|
1614
|
+
editColumn('categorical', 'name', event.target.value);
|
|
1615
|
+
}}
|
|
1616
|
+
>
|
|
1617
|
+
{columnsOptions}
|
|
1618
|
+
</select>
|
|
1619
|
+
</label>
|
|
1620
|
+
</fieldset>
|
|
1621
|
+
)}
|
|
1622
|
+
|
|
1623
|
+
{'navigation' !== state.general.type && (
|
|
1624
|
+
<fieldset className="primary-fieldset edit-block">
|
|
1625
|
+
<label>
|
|
1626
|
+
<span className='edit-label'>
|
|
1627
|
+
Special Classes
|
|
1628
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1629
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1630
|
+
<Tooltip.Content>
|
|
1631
|
+
<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>
|
|
1632
|
+
</Tooltip.Content>
|
|
1633
|
+
</Tooltip>
|
|
1634
|
+
</span>
|
|
1635
|
+
</label>
|
|
1636
|
+
{specialClasses.map((specialClass, i) => (
|
|
1637
|
+
<div className="edit-block" key={`special-class-${i}`}>
|
|
1638
|
+
<button className="remove-column"
|
|
1639
|
+
onClick={(e) => {
|
|
1640
|
+
e.preventDefault();
|
|
1641
|
+
editColumn('primary', 'specialClassDelete', i);
|
|
1642
|
+
}}
|
|
1643
|
+
>Remove</button>
|
|
1644
|
+
<p>Special Class {i + 1}</p>
|
|
1645
|
+
<label>
|
|
1646
|
+
<span className="edit-label column-heading">Data Key</span>
|
|
1647
|
+
<select value={specialClass.key} onChange={(e) => {
|
|
1648
|
+
editColumn('primary', 'specialClassEdit', {prop: 'key', index: i, value: e.target.value});
|
|
1649
|
+
}}>
|
|
1650
|
+
{columnsOptions}
|
|
1651
|
+
</select>
|
|
1652
|
+
</label>
|
|
1653
|
+
<label>
|
|
1654
|
+
<span className="edit-label column-heading">Value</span>
|
|
1655
|
+
<select value={specialClass.value} onChange={(e) => {
|
|
1656
|
+
editColumn('primary', 'specialClassEdit', {prop: 'value', index: i, value: e.target.value});
|
|
1657
|
+
}}>
|
|
1658
|
+
<option value="">- Select Value -</option>
|
|
1659
|
+
{columnsByKey[specialClass.key] && columnsByKey[specialClass.key].sort().map(option => (
|
|
1660
|
+
<option key={`special-class-value-option-${i}-${option}`}>{option}</option>
|
|
1661
|
+
))}
|
|
1662
|
+
</select>
|
|
1663
|
+
</label>
|
|
1664
|
+
<label>
|
|
1665
|
+
<span className="edit-label column-heading">Label</span>
|
|
1666
|
+
<input type="text" value={specialClass.label} onChange={(e) => {
|
|
1667
|
+
editColumn('primary', 'specialClassEdit', {prop: 'label', index: i, value: e.target.value});
|
|
1668
|
+
}} />
|
|
1669
|
+
</label>
|
|
1670
|
+
</div>
|
|
1671
|
+
))}
|
|
1672
|
+
<button className="btn full-width" onClick={(e) => {
|
|
1673
|
+
e.preventDefault();
|
|
1674
|
+
editColumn('primary', 'specialClassAdd', {});
|
|
1675
|
+
}}>
|
|
1676
|
+
Add Special Class
|
|
1677
|
+
</button>
|
|
1678
|
+
</fieldset>
|
|
1679
|
+
)}
|
|
1680
|
+
|
|
1426
1681
|
<label className='edit-block navigate column-heading'>
|
|
1427
|
-
<span className='edit-label column-heading'>
|
|
1682
|
+
<span className='edit-label column-heading'>
|
|
1683
|
+
Navigation
|
|
1684
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1685
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1686
|
+
<Tooltip.Content>
|
|
1687
|
+
<p>To provide end users with navigation functionality, select the source column containing the navigation URLs.</p>
|
|
1688
|
+
</Tooltip.Content>
|
|
1689
|
+
</Tooltip>
|
|
1690
|
+
</span>
|
|
1428
1691
|
<select
|
|
1429
1692
|
value={
|
|
1430
1693
|
state.columns.navigate ? state.columns.navigate.name : columnsOptions[0]
|
|
@@ -1437,118 +1700,130 @@ const EditorPanel = (props) => {
|
|
|
1437
1700
|
</select>
|
|
1438
1701
|
</label>
|
|
1439
1702
|
{'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
|
-
|
|
1703
|
+
<fieldset className="primary-fieldset edit-block">
|
|
1704
|
+
<label>
|
|
1705
|
+
<span className="edit-label">
|
|
1706
|
+
Additional Columns
|
|
1707
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1708
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1709
|
+
<Tooltip.Content>
|
|
1710
|
+
<p>You can specify additional columns to display in tooltips and / or the supporting data table.</p>
|
|
1711
|
+
</Tooltip.Content>
|
|
1712
|
+
</Tooltip>
|
|
1713
|
+
</span>
|
|
1714
|
+
</label>
|
|
1715
|
+
{additionalColumns.map((val) => (
|
|
1716
|
+
<fieldset className="edit-block" key={val}>
|
|
1717
|
+
<button
|
|
1718
|
+
className="remove-column"
|
|
1719
|
+
onClick={(event) => {
|
|
1720
|
+
event.preventDefault()
|
|
1721
|
+
removeAdditionalColumn(val)
|
|
1722
|
+
}}
|
|
1723
|
+
>
|
|
1724
|
+
Remove
|
|
1725
|
+
</button>
|
|
1726
|
+
<label>
|
|
1727
|
+
<span className="edit-label column-heading">Column</span>
|
|
1728
|
+
<select
|
|
1729
|
+
value={
|
|
1730
|
+
state.columns[val]
|
|
1731
|
+
? state.columns[val].name
|
|
1732
|
+
: columnsOptions[0]
|
|
1733
|
+
}
|
|
1734
|
+
onChange={(event) => {
|
|
1735
|
+
editColumn(val, 'name', event.target.value)
|
|
1736
|
+
}}
|
|
1737
|
+
>
|
|
1738
|
+
{columnsOptions}
|
|
1739
|
+
</select>
|
|
1740
|
+
</label>
|
|
1741
|
+
<TextField
|
|
1742
|
+
value={columns[val].label}
|
|
1743
|
+
section="columns"
|
|
1744
|
+
subsection={val}
|
|
1745
|
+
fieldName="label"
|
|
1746
|
+
label="Label"
|
|
1747
|
+
updateField={updateField}
|
|
1748
|
+
/>
|
|
1749
|
+
<ul className="column-edit">
|
|
1750
|
+
<li className="three-col">
|
|
1751
|
+
<TextField
|
|
1752
|
+
value={columns[val].prefix}
|
|
1753
|
+
section="columns"
|
|
1754
|
+
subsection={val}
|
|
1755
|
+
fieldName="prefix"
|
|
1756
|
+
label="Prefix"
|
|
1757
|
+
updateField={updateField}
|
|
1758
|
+
/>
|
|
1759
|
+
<TextField
|
|
1760
|
+
value={columns[val].suffix}
|
|
1761
|
+
section="columns"
|
|
1762
|
+
subsection={val}
|
|
1763
|
+
fieldName="suffix"
|
|
1764
|
+
label="Suffix"
|
|
1765
|
+
updateField={updateField}
|
|
1766
|
+
/>
|
|
1767
|
+
<TextField
|
|
1768
|
+
type="number"
|
|
1769
|
+
value={columns[val].roundToPlace}
|
|
1770
|
+
section="columns"
|
|
1771
|
+
subsection={val}
|
|
1772
|
+
fieldName="roundToPlace"
|
|
1773
|
+
label="Round"
|
|
1774
|
+
updateField={updateField}
|
|
1775
|
+
/>
|
|
1776
|
+
</li>
|
|
1777
|
+
<li>
|
|
1778
|
+
<label className="checkbox">
|
|
1779
|
+
<input
|
|
1780
|
+
type="checkbox"
|
|
1781
|
+
checked={state.columns[val].useCommas}
|
|
1782
|
+
onChange={(event) => {
|
|
1783
|
+
editColumn(val, 'useCommas', event.target.checked)
|
|
1784
|
+
}}
|
|
1785
|
+
/>
|
|
1786
|
+
<span className="edit-label">Add Commas to Numbers</span>
|
|
1787
|
+
</label>
|
|
1788
|
+
</li>
|
|
1789
|
+
<li>
|
|
1790
|
+
<label className="checkbox">
|
|
1791
|
+
<input
|
|
1792
|
+
type="checkbox"
|
|
1793
|
+
checked={state.columns[val].dataTable}
|
|
1794
|
+
onChange={(event) => {
|
|
1795
|
+
editColumn(val, 'dataTable', event.target.checked)
|
|
1796
|
+
}}
|
|
1797
|
+
/>
|
|
1798
|
+
<span className="edit-label">Display in Data Table</span>
|
|
1799
|
+
</label>
|
|
1800
|
+
</li>
|
|
1801
|
+
<li>
|
|
1802
|
+
<label className="checkbox">
|
|
1803
|
+
<input
|
|
1804
|
+
type="checkbox"
|
|
1805
|
+
checked={state.columns[val].tooltip}
|
|
1806
|
+
onChange={(event) => {
|
|
1807
|
+
editColumn(val, 'tooltip', event.target.checked)
|
|
1808
|
+
}}
|
|
1809
|
+
/>
|
|
1810
|
+
<span className="edit-label">Display in Tooltips</span>
|
|
1811
|
+
</label>
|
|
1812
|
+
</li>
|
|
1813
|
+
</ul>
|
|
1814
|
+
</fieldset>
|
|
1815
|
+
))}
|
|
1816
|
+
<button
|
|
1817
|
+
className={'btn full-width'}
|
|
1818
|
+
onClick={(event) => {
|
|
1819
|
+
event.preventDefault();
|
|
1820
|
+
addAdditionalColumn(additionalColumns.length + 1);
|
|
1821
|
+
}}
|
|
1822
|
+
>
|
|
1823
|
+
Add Column
|
|
1824
|
+
</button>
|
|
1825
|
+
</fieldset>
|
|
1826
|
+
}
|
|
1552
1827
|
</AccordionItemPanel>
|
|
1553
1828
|
</AccordionItem>{' '}
|
|
1554
1829
|
{/* Columns */}
|
|
@@ -1560,6 +1835,7 @@ const EditorPanel = (props) => {
|
|
|
1560
1835
|
<AccordionItemButton>Legend</AccordionItemButton>
|
|
1561
1836
|
</AccordionItemHeading>
|
|
1562
1837
|
<AccordionItemPanel>
|
|
1838
|
+
{(state.legend.type === "equalnumber" || state.legend.type === 'equalinterval') && (
|
|
1563
1839
|
<label>
|
|
1564
1840
|
<span className='edit-label'>Legend Type</span>
|
|
1565
1841
|
<select
|
|
@@ -1572,7 +1848,8 @@ const EditorPanel = (props) => {
|
|
|
1572
1848
|
<option value='equalinterval'>Equal Interval</option>
|
|
1573
1849
|
<option value='category'>Categorical</option>
|
|
1574
1850
|
</select>
|
|
1575
|
-
|
|
1851
|
+
</label>
|
|
1852
|
+
)}
|
|
1576
1853
|
{'category' !== legend.type && (
|
|
1577
1854
|
<label className='checkbox'>
|
|
1578
1855
|
<input
|
|
@@ -1582,12 +1859,42 @@ const EditorPanel = (props) => {
|
|
|
1582
1859
|
handleEditorChanges('separateZero', event.target.checked)
|
|
1583
1860
|
}
|
|
1584
1861
|
/>
|
|
1585
|
-
<span className='edit-label'>
|
|
1862
|
+
<span className='edit-label'>
|
|
1863
|
+
Separate Zero
|
|
1864
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1865
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1866
|
+
<Tooltip.Content>
|
|
1867
|
+
<p>For numeric data, you can separate the zero value as its own data class.</p>
|
|
1868
|
+
</Tooltip.Content>
|
|
1869
|
+
</Tooltip>
|
|
1870
|
+
</span>
|
|
1871
|
+
|
|
1586
1872
|
</label>
|
|
1587
1873
|
)}
|
|
1874
|
+
{/* Temp Checkbox */}
|
|
1875
|
+
{state.legend.type === 'equalnumber' &&
|
|
1876
|
+
<label className="checkbox mt-4">
|
|
1877
|
+
<input type="checkbox" checked={ state.general.equalNumberOptIn } onChange={(event) => { handleEditorChanges("showEqualNumber", event.target.checked) }} />
|
|
1878
|
+
<span className="edit-label">Use new quantile legend</span>
|
|
1879
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1880
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1881
|
+
<Tooltip.Content>
|
|
1882
|
+
<p>This prevents numbers from being used in more than one category (ie. 0-1, 1-2, 2-3) </p>
|
|
1883
|
+
</Tooltip.Content>
|
|
1884
|
+
</Tooltip>
|
|
1885
|
+
</label>
|
|
1886
|
+
}
|
|
1588
1887
|
{'category' !== legend.type && (
|
|
1589
1888
|
<label>
|
|
1590
|
-
<span className='edit-label'>
|
|
1889
|
+
<span className='edit-label'>
|
|
1890
|
+
Number of Items
|
|
1891
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1892
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1893
|
+
<Tooltip.Content>
|
|
1894
|
+
<p>For numeric maps, select the number of data classes. Do not include designated special classes.</p>
|
|
1895
|
+
</Tooltip.Content>
|
|
1896
|
+
</Tooltip>
|
|
1897
|
+
</span>
|
|
1591
1898
|
<select
|
|
1592
1899
|
value={legend.numberOfItems}
|
|
1593
1900
|
onChange={(event) => {
|
|
@@ -1607,7 +1914,15 @@ const EditorPanel = (props) => {
|
|
|
1607
1914
|
{'category' === legend.type && (
|
|
1608
1915
|
<React.Fragment>
|
|
1609
1916
|
<label>
|
|
1610
|
-
<span className='edit-label'>
|
|
1917
|
+
<span className='edit-label'>
|
|
1918
|
+
Category Order
|
|
1919
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
1920
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
1921
|
+
<Tooltip.Content>
|
|
1922
|
+
<p>Drag map categories into preferred legend order. </p>
|
|
1923
|
+
</Tooltip.Content>
|
|
1924
|
+
</Tooltip>
|
|
1925
|
+
</span>
|
|
1611
1926
|
</label>
|
|
1612
1927
|
{/* 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
1928
|
<DragDropContext
|
|
@@ -1628,13 +1943,13 @@ const EditorPanel = (props) => {
|
|
|
1628
1943
|
)}
|
|
1629
1944
|
</Droppable>
|
|
1630
1945
|
</DragDropContext>
|
|
1631
|
-
{editorCatOrder.length >=
|
|
1946
|
+
{editorCatOrder.length >= 10 && (
|
|
1632
1947
|
<section className='error-box my-2'>
|
|
1633
1948
|
<div>
|
|
1634
1949
|
<strong className='pt-1'>Warning</strong>
|
|
1635
1950
|
<p>
|
|
1636
|
-
The maximum number of categorical legend items is
|
|
1637
|
-
your data has more than
|
|
1951
|
+
The maximum number of categorical legend items is 10. If
|
|
1952
|
+
your data has more than 10 categories your map will not
|
|
1638
1953
|
display properly.
|
|
1639
1954
|
</p>
|
|
1640
1955
|
</div>
|
|
@@ -1706,10 +2021,18 @@ const EditorPanel = (props) => {
|
|
|
1706
2021
|
);
|
|
1707
2022
|
}}
|
|
1708
2023
|
/>
|
|
1709
|
-
<span className='edit-label'>
|
|
2024
|
+
<span className='edit-label'>
|
|
2025
|
+
Dynamic Legend Description
|
|
2026
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
2027
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
2028
|
+
<Tooltip.Content>
|
|
2029
|
+
<p>Check this option if the map has multiple filter controls and you want to specify a description for each filter selection.</p>
|
|
2030
|
+
</Tooltip.Content>
|
|
2031
|
+
</Tooltip>
|
|
2032
|
+
</span>
|
|
1710
2033
|
</label>
|
|
1711
2034
|
)}
|
|
1712
|
-
{filtersJSX.length > 0 && (
|
|
2035
|
+
{filtersJSX.length > 0 || state.general.type === 'bubble' && (
|
|
1713
2036
|
<label className='checkbox'>
|
|
1714
2037
|
<input
|
|
1715
2038
|
type='checkbox'
|
|
@@ -1718,7 +2041,15 @@ const EditorPanel = (props) => {
|
|
|
1718
2041
|
handleEditorChanges('unifiedLegend', event.target.checked)
|
|
1719
2042
|
}
|
|
1720
2043
|
/>
|
|
1721
|
-
<span className='edit-label'>
|
|
2044
|
+
<span className='edit-label'>
|
|
2045
|
+
Unified Legend
|
|
2046
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
2047
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
2048
|
+
<Tooltip.Content>
|
|
2049
|
+
<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>
|
|
2050
|
+
</Tooltip.Content>
|
|
2051
|
+
</Tooltip>
|
|
2052
|
+
</span>
|
|
1722
2053
|
</label>
|
|
1723
2054
|
)}
|
|
1724
2055
|
</AccordionItemPanel>
|
|
@@ -1766,12 +2097,20 @@ const EditorPanel = (props) => {
|
|
|
1766
2097
|
placeholder='Data Table'
|
|
1767
2098
|
/>
|
|
1768
2099
|
<TextField
|
|
1769
|
-
value={dataTable.
|
|
2100
|
+
value={dataTable.indexLabel || ''}
|
|
1770
2101
|
updateField={updateField}
|
|
1771
2102
|
section='dataTable'
|
|
1772
|
-
fieldName='
|
|
1773
|
-
label='Index Column
|
|
2103
|
+
fieldName='indexLabel'
|
|
2104
|
+
label='Index Column Header'
|
|
1774
2105
|
placeholder='Location'
|
|
2106
|
+
tooltip={
|
|
2107
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
2108
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
2109
|
+
<Tooltip.Content>
|
|
2110
|
+
<p>To comply with 508 standards, if the first column in the data table has no header, enter a brief one here.</p>
|
|
2111
|
+
</Tooltip.Content>
|
|
2112
|
+
</Tooltip>
|
|
2113
|
+
}
|
|
1775
2114
|
/>
|
|
1776
2115
|
<TextField
|
|
1777
2116
|
value={dataTable.caption}
|
|
@@ -1780,7 +2119,14 @@ const EditorPanel = (props) => {
|
|
|
1780
2119
|
fieldName='caption'
|
|
1781
2120
|
label='Data Table Caption'
|
|
1782
2121
|
placeholder='Data Table'
|
|
1783
|
-
|
|
2122
|
+
tooltip={
|
|
2123
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
2124
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
2125
|
+
<Tooltip.Content>
|
|
2126
|
+
<p>Enter a description of the data table to be read by screen readers.</p>
|
|
2127
|
+
</Tooltip.Content>
|
|
2128
|
+
</Tooltip>
|
|
2129
|
+
}
|
|
1784
2130
|
type="textarea"
|
|
1785
2131
|
/>
|
|
1786
2132
|
<label className='checkbox'>
|
|
@@ -1795,8 +2141,15 @@ const EditorPanel = (props) => {
|
|
|
1795
2141
|
handleEditorChanges('showDataTable', event.target.checked);
|
|
1796
2142
|
}}
|
|
1797
2143
|
/>
|
|
1798
|
-
<span className='edit-label'>
|
|
1799
|
-
|
|
2144
|
+
<span className='edit-label'>
|
|
2145
|
+
Show Table
|
|
2146
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
2147
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
2148
|
+
<Tooltip.Content>
|
|
2149
|
+
<p>Data tables are required for 508 compliance. When choosing to hide this data table, replace with your own version.</p>
|
|
2150
|
+
</Tooltip.Content>
|
|
2151
|
+
</Tooltip>
|
|
2152
|
+
</span>
|
|
1800
2153
|
</label>
|
|
1801
2154
|
<label className='checkbox'>
|
|
1802
2155
|
<input
|
|
@@ -1854,7 +2207,12 @@ const EditorPanel = (props) => {
|
|
|
1854
2207
|
<label>
|
|
1855
2208
|
<span className='edit-label'>
|
|
1856
2209
|
Detail displays on{' '}
|
|
1857
|
-
|
|
2210
|
+
<Tooltip style={{textTransform: 'none'}}>
|
|
2211
|
+
<Tooltip.Target><Icon display="question" style={{marginLeft: '0.5rem'}}/></Tooltip.Target>
|
|
2212
|
+
<Tooltip.Content>
|
|
2213
|
+
<p>At mobile sizes, information always appears in a popover modal when a user taps on an item.</p>
|
|
2214
|
+
</Tooltip.Content>
|
|
2215
|
+
</Tooltip>
|
|
1858
2216
|
</span>
|
|
1859
2217
|
<select
|
|
1860
2218
|
value={state.tooltips.appearanceType}
|
|
@@ -1894,7 +2252,7 @@ const EditorPanel = (props) => {
|
|
|
1894
2252
|
<AccordionItemButton>Visual</AccordionItemButton>
|
|
1895
2253
|
</AccordionItemHeading>
|
|
1896
2254
|
<AccordionItemPanel>
|
|
1897
|
-
<label
|
|
2255
|
+
<label>
|
|
1898
2256
|
<span className='edit-label'>Header Theme</span>
|
|
1899
2257
|
<ul className='color-palette'>
|
|
1900
2258
|
{headerColors.map((palette) => {
|
|
@@ -1925,6 +2283,29 @@ const EditorPanel = (props) => {
|
|
|
1925
2283
|
/>
|
|
1926
2284
|
<span className='edit-label'>Show Title</span>
|
|
1927
2285
|
</label>
|
|
2286
|
+
|
|
2287
|
+
<label className='checkbox'>
|
|
2288
|
+
<input
|
|
2289
|
+
type='checkbox'
|
|
2290
|
+
checked={state.general.hideGeoColumnInTooltip || false}
|
|
2291
|
+
onChange={(event) => {
|
|
2292
|
+
handleEditorChanges('hideGeoColumnInTooltip', event.target.checked);
|
|
2293
|
+
}}
|
|
2294
|
+
/>
|
|
2295
|
+
<span className='edit-label'>Hide Geography Column Name in Tooltip</span>
|
|
2296
|
+
</label>
|
|
2297
|
+
|
|
2298
|
+
<label className='checkbox'>
|
|
2299
|
+
<input
|
|
2300
|
+
type='checkbox'
|
|
2301
|
+
checked={state.general.hidePrimaryColumnInTooltip || false}
|
|
2302
|
+
onChange={(event) => {
|
|
2303
|
+
handleEditorChanges('hidePrimaryColumnInTooltip', event.target.checked);
|
|
2304
|
+
}}
|
|
2305
|
+
/>
|
|
2306
|
+
<span className='edit-label'>Hide Primary Column Name in Tooltip</span>
|
|
2307
|
+
</label>
|
|
2308
|
+
|
|
1928
2309
|
{'navigation' !== state.general.type && (
|
|
1929
2310
|
<label className='checkbox'>
|
|
1930
2311
|
<input
|
|
@@ -1990,10 +2371,11 @@ const EditorPanel = (props) => {
|
|
|
1990
2371
|
<label>
|
|
1991
2372
|
<span className='edit-label'>Map Color Palette</span>
|
|
1992
2373
|
</label>
|
|
1993
|
-
<
|
|
2374
|
+
{/* <InputCheckbox section="general" subsection="palette" fieldName='isReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} /> */}
|
|
2375
|
+
<InputToggle type='3d' section="general" subsection="palette" fieldName='isReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} />
|
|
2376
|
+
<span>Sequential</span>
|
|
1994
2377
|
<ul className='color-palette'>
|
|
1995
|
-
{
|
|
1996
|
-
.filter((name) => !name.includes('qualitative'))
|
|
2378
|
+
{filteredPallets
|
|
1997
2379
|
.map((palette) => {
|
|
1998
2380
|
const colorOne = {
|
|
1999
2381
|
backgroundColor: colorPalettes[palette][2],
|
|
@@ -2023,10 +2405,9 @@ const EditorPanel = (props) => {
|
|
|
2023
2405
|
);
|
|
2024
2406
|
})}
|
|
2025
2407
|
</ul>
|
|
2026
|
-
<span
|
|
2408
|
+
<span>Non-Sequential</span>
|
|
2027
2409
|
<ul className='color-palette'>
|
|
2028
|
-
{
|
|
2029
|
-
.filter((name) => name.includes('qualitative'))
|
|
2410
|
+
{filteredQualitative
|
|
2030
2411
|
.map((palette) => {
|
|
2031
2412
|
const colorOne = {
|
|
2032
2413
|
backgroundColor: colorPalettes[palette][2],
|
|
@@ -2056,52 +2437,64 @@ const EditorPanel = (props) => {
|
|
|
2056
2437
|
);
|
|
2057
2438
|
})}
|
|
2058
2439
|
</ul>
|
|
2440
|
+
<TextField
|
|
2441
|
+
type='number'
|
|
2442
|
+
value={state.visual.minBubbleSize}
|
|
2443
|
+
section='visual'
|
|
2444
|
+
fieldName='minBubbleSize'
|
|
2445
|
+
label='Minimum Bubble Size'
|
|
2446
|
+
updateField={updateField}
|
|
2447
|
+
/>
|
|
2448
|
+
<TextField
|
|
2449
|
+
type='number'
|
|
2450
|
+
value={state.visual.maxBubbleSize}
|
|
2451
|
+
section='visual'
|
|
2452
|
+
fieldName='maxBubbleSize'
|
|
2453
|
+
label='Maximum Bubble Size'
|
|
2454
|
+
updateField={updateField}
|
|
2455
|
+
/>
|
|
2456
|
+
{ (state.general.geoType === 'world' || state.general.geoType === 'us') &&
|
|
2457
|
+
<label className='checkbox'>
|
|
2458
|
+
<input
|
|
2459
|
+
type='checkbox'
|
|
2460
|
+
checked={state.visual.showBubbleZeros}
|
|
2461
|
+
onChange={(event) => {
|
|
2462
|
+
handleEditorChanges('showBubbleZeros', event.target.checked);
|
|
2463
|
+
}}
|
|
2464
|
+
/>
|
|
2465
|
+
<span className='edit-label'>Show Data with Zero's on Bubble Map</span>
|
|
2466
|
+
</label>
|
|
2467
|
+
}
|
|
2468
|
+
{state.general.geoType === 'world' &&
|
|
2469
|
+
<label className='checkbox'>
|
|
2470
|
+
<input
|
|
2471
|
+
type='checkbox'
|
|
2472
|
+
checked={state.general.allowMapZoom}
|
|
2473
|
+
onChange={(event) => {
|
|
2474
|
+
handleEditorChanges('allowMapZoom', event.target.checked);
|
|
2475
|
+
}}
|
|
2476
|
+
/>
|
|
2477
|
+
<span className='edit-label'>Allow Map Zooming</span>
|
|
2478
|
+
</label>
|
|
2479
|
+
}
|
|
2480
|
+
{state.general.type === 'bubble' &&
|
|
2481
|
+
<label className='checkbox'>
|
|
2482
|
+
<input
|
|
2483
|
+
type='checkbox'
|
|
2484
|
+
checked={state.visual.extraBubbleBorder}
|
|
2485
|
+
onChange={(event) => {
|
|
2486
|
+
handleEditorChanges('toggleExtraBubbleBorder', event.target.checked);
|
|
2487
|
+
}}
|
|
2488
|
+
/>
|
|
2489
|
+
<span className='edit-label'>Bubble Map has extra border</span>
|
|
2490
|
+
</label>
|
|
2491
|
+
}
|
|
2059
2492
|
</AccordionItemPanel>
|
|
2060
2493
|
</AccordionItem>
|
|
2061
2494
|
</Accordion>
|
|
2062
2495
|
</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>
|
|
2496
|
+
<AdvancedEditor loadConfig={loadConfig} state={state} convertStateToConfig={convertStateToConfig} />
|
|
2497
|
+
|
|
2105
2498
|
</section>
|
|
2106
2499
|
</section>
|
|
2107
2500
|
</ErrorBoundary>
|