@cdc/map 4.25.8 → 4.25.11
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/.claude/agents/typescript-organizer.md +118 -0
- package/.claude/settings.local.json +30 -0
- package/dist/{cdcmap-fce76882.es.js → cdcmap-BnB1QM5d.es.js} +6 -13
- package/dist/{cdcmap-c55ac1ea.es.js → cdcmap-D6CG2-Hb.es.js} +5 -12
- package/dist/{cdcmap-31a33da1.es.js → cdcmap-MXgURbdZ.es.js} +6 -13
- package/dist/{cdcmap-1a1724a1.es.js → cdcmap-dgT_1dIT.es.js} +136 -151
- package/dist/cdcmap.js +56991 -53706
- package/examples/example-city-state.json +9 -1
- package/examples/multi-country-centering.json +45 -0
- package/examples/private/c.json +290 -0
- package/examples/private/canvas-city-hover.json +787 -0
- package/examples/private/colors-2.json +221 -0
- package/examples/private/colors.json +221 -0
- package/examples/private/d.json +345 -0
- package/examples/private/g.json +1 -0
- package/examples/private/h.json +105911 -0
- package/examples/private/measles-data.json +378 -0
- package/examples/private/measles.json +211 -0
- package/examples/private/north-dakota.json +1132 -0
- package/examples/private/state-with-pattern.json +883 -0
- package/index.html +36 -34
- package/package.json +26 -5
- package/src/CdcMap.tsx +23 -8
- package/src/CdcMapComponent.tsx +238 -308
- package/src/_stories/CdcMap.ColumnWrap.stories.tsx +31 -0
- package/src/_stories/CdcMap.DistrictOfColumbia.stories.tsx +320 -0
- package/src/_stories/CdcMap.Editor.stories.tsx +3371 -0
- package/src/_stories/CdcMap.Filters.stories.tsx +2 -2
- package/src/_stories/CdcMap.Legend.Gradient.stories.tsx +3 -3
- package/src/_stories/CdcMap.Legend.stories.tsx +7 -4
- package/src/_stories/CdcMap.Patterns.stories.tsx +2 -2
- package/src/_stories/CdcMap.SmallMultiples.stories.tsx +35 -0
- package/src/_stories/CdcMap.Table.stories.tsx +2 -2
- package/src/_stories/CdcMap.stories.tsx +37 -9
- package/src/_stories/GoogleMap.stories.tsx +2 -2
- package/src/_stories/UsaMap.NoData.stories.tsx +2 -2
- package/src/_stories/_mock/column-wrap-test.json +265 -0
- package/src/_stories/_mock/equal-number.json +1109 -0
- package/src/_stories/_mock/multi-country-hide.json +78 -0
- package/src/_stories/_mock/multi-country.json +95 -0
- package/src/_stories/_mock/multi-state.json +887 -20403
- package/src/_stories/_mock/small_multiples/multi-state-small-multiples.json +8399 -0
- package/src/_stories/_mock/small_multiples/region-small-multiples.json +657 -0
- package/src/_stories/_mock/small_multiples/wastewater-map-small-multiples.json +221 -0
- package/src/_stories/_mock/us-bubble-cities.json +306 -0
- package/src/_stories/_mock/usa-state-gradient.json +2 -4
- package/src/components/BubbleList.tsx +17 -13
- package/src/components/CityList.tsx +85 -107
- package/src/components/EditorPanel/components/EditorPanel.tsx +787 -709
- package/src/components/EditorPanel/components/HexShapeSettings.tsx +58 -95
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +34 -42
- package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.tsx +354 -0
- package/src/components/EditorPanel/components/Panels/index.tsx +3 -1
- package/src/components/Geo.tsx +22 -3
- package/src/components/Legend/components/Legend.tsx +76 -40
- package/src/components/Legend/components/LegendGroup/Legend.Group.tsx +10 -7
- package/src/components/Legend/components/index.scss +1 -1
- package/src/components/MapContainer.tsx +52 -0
- package/src/components/MapControls.tsx +44 -0
- package/src/components/NavigationMenu.tsx +27 -15
- package/src/components/SmallMultiples/SmallMultipleTile.tsx +163 -0
- package/src/components/SmallMultiples/SmallMultiples.css +32 -0
- package/src/components/SmallMultiples/SmallMultiples.tsx +150 -0
- package/src/components/SmallMultiples/SynchronizedTooltip.tsx +105 -0
- package/src/components/SmallMultiples/index.tsx +3 -0
- package/src/components/UsaMap/components/SingleState/SingleState.CountyOutput.tsx +36 -4
- package/src/components/UsaMap/components/TerritoriesSection.tsx +26 -12
- package/src/components/UsaMap/components/Territory/Territory.Hexagon.tsx +30 -4
- package/src/components/UsaMap/components/Territory/Territory.Rectangle.tsx +23 -4
- package/src/components/UsaMap/components/Territory/TerritoryShape.ts +6 -0
- package/src/components/UsaMap/components/UsaMap.County.tsx +123 -37
- package/src/components/UsaMap/components/UsaMap.Region.tsx +36 -5
- package/src/components/UsaMap/components/UsaMap.SingleState.tsx +30 -10
- package/src/components/UsaMap/components/UsaMap.State.tsx +53 -12
- package/src/components/UsaMap/helpers/map.ts +4 -4
- package/src/components/UsaMap/helpers/shapes.ts +9 -6
- package/src/components/WorldMap/WorldMap.tsx +193 -35
- package/src/components/ZoomControls.tsx +6 -9
- package/src/context/LegendMemoContext.tsx +30 -0
- package/src/context.ts +1 -40
- package/src/data/initial-state.js +153 -130
- package/src/data/supported-geos.js +25 -78
- package/src/helpers/addUIDs.ts +13 -2
- package/src/helpers/applyColorToLegend.ts +140 -20
- package/src/helpers/applyLegendToRow.ts +10 -6
- package/src/helpers/componentHelpers.ts +8 -0
- package/src/helpers/constants.ts +12 -14
- package/src/helpers/dataTableHelpers.ts +6 -0
- package/src/helpers/displayGeoName.ts +18 -3
- package/src/helpers/generateRuntimeLegend.ts +44 -10
- package/src/helpers/generateRuntimeLegendHash.ts +4 -2
- package/src/helpers/getColumnNames.ts +1 -1
- package/src/helpers/getCountriesPicked.ts +103 -0
- package/src/helpers/getMapContainerClasses.ts +7 -0
- package/src/helpers/getPatternForRow.ts +33 -0
- package/src/helpers/getStatesPicked.ts +8 -5
- package/src/helpers/index.ts +3 -3
- package/src/helpers/isLegendItemDisabled.ts +16 -0
- package/src/helpers/mapObserverHelpers.ts +40 -0
- package/src/helpers/resetLegendToggles.ts +3 -2
- package/src/helpers/smallMultiplesHelpers.ts +359 -0
- package/src/helpers/tests/titleCase.test.ts +76 -0
- package/src/helpers/titleCase.ts +13 -13
- package/src/helpers/toggleLegendActive.ts +6 -11
- package/src/helpers/urlDataHelpers.ts +70 -0
- package/src/hooks/useCountryZoom.tsx +241 -0
- package/src/hooks/useGeoClickHandler.ts +36 -2
- package/src/hooks/useLegendMemo.ts +17 -0
- package/src/hooks/useMapLayers.tsx +5 -4
- package/src/hooks/useProgrammaticMapTooltip.ts +110 -0
- package/src/hooks/useResizeObserver.ts +5 -2
- package/src/hooks/useStateZoom.tsx +30 -8
- package/src/hooks/useSynchronizedGeographies.ts +56 -0
- package/src/hooks/useTooltip.ts +1 -2
- package/src/index.jsx +1 -2
- package/src/scss/editor-panel.scss +4 -440
- package/src/scss/main.scss +1 -1
- package/src/scss/map.scss +12 -15
- package/src/store/map.actions.ts +7 -7
- package/src/store/map.reducer.ts +17 -6
- package/src/test/CdcMap.test.jsx +11 -0
- package/src/types/MapConfig.ts +46 -18
- package/src/types/MapContext.ts +6 -7
- package/src/types/runtimeLegend.ts +17 -1
- package/vite.config.js +2 -7
- package/vitest.config.ts +16 -0
- package/src/components/DataTable.tsx +0 -385
- package/src/components/EditorPanel/components/Inputs.tsx +0 -59
- package/src/coreStyles_map.scss +0 -3
- package/src/helpers/colorDistributions.ts +0 -12
- package/src/helpers/generateColorsArray.ts +0 -14
- package/src/helpers/tests/generateColorsArray.test.ts +0 -18
- package/src/helpers/tests/generateRuntimeLegendHash.test.ts +0 -11
- package/src/hooks/useActiveElement.ts +0 -19
- package/src/scss/mixins.scss +0 -47
- package/src/types/Annotations.ts +0 -24
- /package/dist/{cdcmap-548642e6.es.js → cdcmap-Ct2SB0vL.es.js} +0 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import React, { useContext, useEffect, useState } from 'react'
|
|
1
|
+
import React, { useContext, useEffect, useState, useMemo, useRef } from 'react'
|
|
2
|
+
import { filterColorPalettes } from '@cdc/core/helpers/filterColorPalettes'
|
|
3
|
+
import { cloneConfig } from '@cdc/core/helpers/cloneConfig'
|
|
2
4
|
|
|
3
5
|
// Third Party
|
|
4
6
|
import {
|
|
@@ -12,12 +14,14 @@ import { DragDropContext, Draggable, Droppable } from '@hello-pangea/dnd'
|
|
|
12
14
|
import { useDebounce } from 'use-debounce'
|
|
13
15
|
import _ from 'lodash'
|
|
14
16
|
import { Tooltip as ReactTooltip } from 'react-tooltip'
|
|
17
|
+
import 'react-tooltip/dist/react-tooltip.css'
|
|
15
18
|
import Panels from './Panels'
|
|
16
19
|
import Layout from '@cdc/core/components/Layout'
|
|
17
20
|
|
|
18
21
|
// Data
|
|
19
|
-
import colorPalettes from '@cdc/core/data/colorPalettes'
|
|
20
|
-
import { supportedStatesFipsCodes } from '../../../data/supported-geos.js'
|
|
22
|
+
import { mapColorPalettes as colorPalettes } from '@cdc/core/data/colorPalettes'
|
|
23
|
+
import { supportedStatesFipsCodes, supportedCountries } from '../../../data/supported-geos.js'
|
|
24
|
+
import { getSupportedCountryOptions } from '../../../helpers/getCountriesPicked'
|
|
21
25
|
|
|
22
26
|
// Components - Core
|
|
23
27
|
import AdvancedEditor from '@cdc/core/components/AdvancedEditor'
|
|
@@ -26,6 +30,7 @@ import Icon from '@cdc/core/components/ui/Icon'
|
|
|
26
30
|
import InputToggle from '@cdc/core/components/inputs/InputToggle'
|
|
27
31
|
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
28
32
|
import VizFilterEditor from '@cdc/core/components/EditorPanel/VizFilterEditor'
|
|
33
|
+
import PanelMarkup from '@cdc/core/components/EditorPanel/components/PanelMarkup'
|
|
29
34
|
|
|
30
35
|
// Assets
|
|
31
36
|
import UsaGraphic from '@cdc/core/assets/icon-map-usa.svg'
|
|
@@ -43,12 +48,23 @@ import { MapContext } from '../../../types/MapContext.js'
|
|
|
43
48
|
import Alert from '@cdc/core/components/Alert'
|
|
44
49
|
import { updateFieldFactory } from '@cdc/core/helpers/updateFieldFactory'
|
|
45
50
|
import { CheckBox, Select, TextField } from '@cdc/core/components/EditorPanel/Inputs'
|
|
51
|
+
import { HeaderThemeSelector } from '@cdc/core/components/HeaderThemeSelector'
|
|
46
52
|
import useColumnsRequiredChecker from '../../../hooks/useColumnsRequiredChecker'
|
|
47
|
-
import { addUIDs
|
|
53
|
+
import { addUIDs } from '../../../helpers'
|
|
54
|
+
import generateRuntimeData from '../../../helpers/generateRuntimeData'
|
|
55
|
+
|
|
56
|
+
import '@cdc/core/styles/v2/components/editor.scss'
|
|
48
57
|
import './editorPanel.styles.css'
|
|
49
58
|
import FootnotesEditor from '@cdc/core/components/EditorPanel/FootnotesEditor'
|
|
50
59
|
import { Datasets } from '@cdc/core/types/DataSet'
|
|
51
60
|
import MultiSelect from '@cdc/core/components/MultiSelect'
|
|
61
|
+
import { paletteMigrationMap } from '@cdc/core/helpers/palettes/migratePaletteName'
|
|
62
|
+
import { isV1Palette, getCurrentPaletteName, migratePaletteWithMap } from '@cdc/core/helpers/palettes/utils'
|
|
63
|
+
import { USE_V2_MIGRATION } from '@cdc/core/helpers/constants'
|
|
64
|
+
import { isCoveDeveloperMode } from '@cdc/core/helpers/queryStringUtils'
|
|
65
|
+
import { PaletteSelector, DeveloperPaletteRollback } from '@cdc/core/components/PaletteSelector'
|
|
66
|
+
import PaletteConversionModal from '@cdc/core/components/PaletteConversionModal'
|
|
67
|
+
import { CustomColorsEditor } from '@cdc/core/components/CustomColorsEditor'
|
|
52
68
|
|
|
53
69
|
type MapEditorPanelProps = {
|
|
54
70
|
datasets?: Datasets
|
|
@@ -65,30 +81,48 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
65
81
|
setConfig,
|
|
66
82
|
config,
|
|
67
83
|
tooltipId,
|
|
68
|
-
runtimeData
|
|
69
|
-
setRuntimeData
|
|
84
|
+
runtimeData
|
|
70
85
|
} = useContext<MapContext>(ConfigContext)
|
|
71
86
|
|
|
72
87
|
const { columnsRequiredChecker } = useColumnsRequiredChecker()
|
|
73
88
|
const dispatch = useContext(MapDispatchContext)
|
|
74
89
|
const { general, columns, legend, table, tooltips } = config
|
|
75
|
-
|
|
90
|
+
|
|
91
|
+
// Get columns from data with fallback to datasets (for dashboard context)
|
|
92
|
+
const columnsInData = useMemo(() => {
|
|
93
|
+
// First try config.data
|
|
94
|
+
if (config?.data?.[0]) {
|
|
95
|
+
return Object.keys(config.data[0])
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Fallback to datasets using config.dataKey (for dashboard visualizations)
|
|
99
|
+
if (datasets && config?.dataKey) {
|
|
100
|
+
const assignedDataset = datasets[config.dataKey]
|
|
101
|
+
if (assignedDataset?.data?.[0]) {
|
|
102
|
+
return Object.keys(assignedDataset.data[0])
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return []
|
|
107
|
+
}, [
|
|
108
|
+
config?.data?.length > 0 ? JSON.stringify(Object.keys(config.data[0])) : null,
|
|
109
|
+
datasets?.[config?.dataKey as string]?.data?.length,
|
|
110
|
+
config?.dataKey
|
|
111
|
+
])
|
|
76
112
|
|
|
77
113
|
const [loadedDefault, setLoadedDefault] = useState(false)
|
|
78
114
|
const [displayPanel, setDisplayPanel] = useState(true)
|
|
79
115
|
const [activeFilterValueForDescription, setActiveFilterValueForDescription] = useState([0, 0])
|
|
116
|
+
const [showConversionModal, setShowConversionModal] = useState(false)
|
|
117
|
+
const [pendingPaletteSelection, setPendingPaletteSelection] = useState<{
|
|
118
|
+
palette: string
|
|
119
|
+
action: () => void
|
|
120
|
+
} | null>(null)
|
|
80
121
|
|
|
81
122
|
const {
|
|
82
123
|
MapLayerHandlers: { handleMapLayer, handleAddLayer, handleRemoveLayer }
|
|
83
124
|
} = useMapLayers(config, setConfig, false, tooltipId)
|
|
84
125
|
|
|
85
|
-
useEffect(() => {
|
|
86
|
-
// Pass up to Editor if needed
|
|
87
|
-
if (setParentConfig) {
|
|
88
|
-
setParentConfig(convertStateToConfig())
|
|
89
|
-
}
|
|
90
|
-
}, [config])
|
|
91
|
-
|
|
92
126
|
const categoryMove = (idx1, idx2) => {
|
|
93
127
|
let categoryValuesOrder = getCategoryValuesOrder()
|
|
94
128
|
let [movedItem] = categoryValuesOrder.splice(idx1, 1)
|
|
@@ -690,8 +724,27 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
690
724
|
})
|
|
691
725
|
|
|
692
726
|
if (config) {
|
|
693
|
-
const newData = generateRuntimeData(config)
|
|
694
|
-
|
|
727
|
+
const newData = generateRuntimeData(config, [], 0, legend.type === 'category')
|
|
728
|
+
dispatch({ type: 'SET_RUNTIME_DATA', payload: newData })
|
|
729
|
+
}
|
|
730
|
+
break
|
|
731
|
+
case 'chooseCountry':
|
|
732
|
+
let countryData = value.map(countryName => ({
|
|
733
|
+
iso: Object.keys(supportedCountries).find(key => supportedCountries[key][0] === countryName),
|
|
734
|
+
name: countryName
|
|
735
|
+
}))
|
|
736
|
+
|
|
737
|
+
setConfig({
|
|
738
|
+
...config,
|
|
739
|
+
general: {
|
|
740
|
+
...config.general,
|
|
741
|
+
countriesPicked: countryData
|
|
742
|
+
}
|
|
743
|
+
})
|
|
744
|
+
|
|
745
|
+
if (config) {
|
|
746
|
+
const newData = generateRuntimeData(config, [], 0, legend.type === 'category')
|
|
747
|
+
dispatch({ type: 'SET_RUNTIME_DATA', payload: newData })
|
|
695
748
|
}
|
|
696
749
|
break
|
|
697
750
|
case 'classificationType':
|
|
@@ -868,7 +921,7 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
868
921
|
}
|
|
869
922
|
|
|
870
923
|
const convertStateToConfig = () => {
|
|
871
|
-
let strippedState =
|
|
924
|
+
let strippedState = cloneConfig(config) // Deep copy
|
|
872
925
|
|
|
873
926
|
// Strip ref
|
|
874
927
|
delete strippedState['']
|
|
@@ -900,58 +953,89 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
900
953
|
|
|
901
954
|
const isReversed = config.general.palette.isReversed
|
|
902
955
|
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
if (
|
|
925
|
-
|
|
926
|
-
}
|
|
927
|
-
if (paletteName.includes('colorblindsafe') && paletteName.endsWith('reverse')) {
|
|
928
|
-
accessibleColors.push(paletteName)
|
|
929
|
-
}
|
|
930
|
-
if (
|
|
931
|
-
!paletteName.includes('qualitative') &&
|
|
932
|
-
!paletteName.includes('colorblindsafe') &&
|
|
933
|
-
paletteName.endsWith('reverse')
|
|
934
|
-
) {
|
|
935
|
-
sequential.push(paletteName)
|
|
956
|
+
const { sequential, nonSequential, accessibleColors } = useMemo(
|
|
957
|
+
() => filterColorPalettes({ config, isReversed, colorPalettes }),
|
|
958
|
+
[isReversed, colorPalettes, config.general.palette.version]
|
|
959
|
+
)
|
|
960
|
+
|
|
961
|
+
// Helper function to handle palette selection with conversion prompt
|
|
962
|
+
const handlePaletteSelection = (palette: string) => {
|
|
963
|
+
const isV1PaletteConfig = isV1Palette(config)
|
|
964
|
+
|
|
965
|
+
const executeSelection = () => {
|
|
966
|
+
const _newConfig = _.cloneDeep(config)
|
|
967
|
+
|
|
968
|
+
// If v2 migration is disabled, use the original palette name and keep v1 version
|
|
969
|
+
if (!USE_V2_MIGRATION) {
|
|
970
|
+
_newConfig.general.palette.name = palette
|
|
971
|
+
_newConfig.general.palette.version = '1.0'
|
|
972
|
+
} else {
|
|
973
|
+
// V2 migration logic
|
|
974
|
+
_newConfig.general.palette.name = palette
|
|
975
|
+
? migratePaletteWithMap(palette, paletteMigrationMap, false)
|
|
976
|
+
: undefined
|
|
977
|
+
if (isV1PaletteConfig) {
|
|
978
|
+
_newConfig.general.palette.version = '2.0'
|
|
936
979
|
}
|
|
937
980
|
}
|
|
981
|
+
setConfig(_newConfig)
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
if (isV1PaletteConfig) {
|
|
985
|
+
setPendingPaletteSelection({ palette, action: executeSelection })
|
|
986
|
+
setShowConversionModal(true)
|
|
987
|
+
} else {
|
|
988
|
+
executeSelection()
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
// Modal handlers
|
|
993
|
+
const handleConversionConfirm = () => {
|
|
994
|
+
if (pendingPaletteSelection) {
|
|
995
|
+
pendingPaletteSelection.action()
|
|
996
|
+
}
|
|
997
|
+
setShowConversionModal(false)
|
|
998
|
+
setPendingPaletteSelection(null)
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
const handleConversionCancel = () => {
|
|
1002
|
+
setShowConversionModal(false)
|
|
1003
|
+
setPendingPaletteSelection(null)
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
const handleReturnToV1 = () => {
|
|
1007
|
+
if (pendingPaletteSelection) {
|
|
1008
|
+
const _newConfig = cloneConfig(config)
|
|
1009
|
+
_newConfig.general.palette.name = pendingPaletteSelection.palette
|
|
1010
|
+
_newConfig.general.palette.version = '1.0'
|
|
1011
|
+
setConfig(_newConfig)
|
|
938
1012
|
}
|
|
1013
|
+
setShowConversionModal(false)
|
|
1014
|
+
setPendingPaletteSelection(null)
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
// Helper function to determine if a palette should be marked as selected
|
|
1018
|
+
const getPaletteClassName = (palette: string) => {
|
|
1019
|
+
const currentPaletteName = config.general.palette.name || ''
|
|
939
1020
|
|
|
940
|
-
|
|
1021
|
+
// Direct comparison since the UI filters palettes by version
|
|
1022
|
+
// When v1 is selected, UI shows v1 palettes; when v2 is selected, UI shows v2 palettes
|
|
1023
|
+
return currentPaletteName === palette ? 'selected' : ''
|
|
941
1024
|
}
|
|
942
|
-
|
|
1025
|
+
|
|
1026
|
+
const configStringRef = useRef<string>()
|
|
943
1027
|
|
|
944
1028
|
useEffect(() => {
|
|
945
1029
|
setLoadedDefault(config.defaultData)
|
|
946
1030
|
columnsRequiredChecker()
|
|
947
1031
|
}, [config])
|
|
948
1032
|
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
}
|
|
1033
|
+
// Only update parent when config content actually changes (not just reference)
|
|
1034
|
+
const configString = JSON.stringify(convertStateToConfig())
|
|
1035
|
+
if (isEditor && setParentConfig && configStringRef.current !== configString) {
|
|
1036
|
+
configStringRef.current = configString
|
|
1037
|
+
setParentConfig(JSON.parse(configString))
|
|
1038
|
+
}
|
|
955
1039
|
|
|
956
1040
|
const columnsOptions = [
|
|
957
1041
|
<option value='' key={'Select Option'}>
|
|
@@ -1014,6 +1098,16 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
1014
1098
|
return options
|
|
1015
1099
|
}
|
|
1016
1100
|
|
|
1101
|
+
const CountryOptionList = () => {
|
|
1102
|
+
const countryOptions = getSupportedCountryOptions()
|
|
1103
|
+
|
|
1104
|
+
return countryOptions.map(({ value, label }) => (
|
|
1105
|
+
<option key={value} value={label}>
|
|
1106
|
+
{label}
|
|
1107
|
+
</option>
|
|
1108
|
+
))
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1017
1111
|
const filterValueOptionList = []
|
|
1018
1112
|
|
|
1019
1113
|
if (runtimeFilters.length > 0) {
|
|
@@ -1220,6 +1314,34 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
1220
1314
|
/>
|
|
1221
1315
|
</label>
|
|
1222
1316
|
)}
|
|
1317
|
+
{/* Country Selection for World Maps */}
|
|
1318
|
+
{config.general.geoType === 'world' && (
|
|
1319
|
+
<>
|
|
1320
|
+
<label>
|
|
1321
|
+
<span>Countries Selector</span>
|
|
1322
|
+
<MultiSelect
|
|
1323
|
+
selected={(config.general.countriesPicked || []).map(country => country.name)}
|
|
1324
|
+
options={CountryOptionList().map(option => ({
|
|
1325
|
+
value: option.props.value,
|
|
1326
|
+
label: option.props.children
|
|
1327
|
+
}))}
|
|
1328
|
+
fieldName={'countriesPicked'}
|
|
1329
|
+
updateField={(_, __, ___, selectedOptions) => {
|
|
1330
|
+
handleEditorChanges('chooseCountry', selectedOptions)
|
|
1331
|
+
}}
|
|
1332
|
+
/>
|
|
1333
|
+
</label>
|
|
1334
|
+
{config.general.countriesPicked && config.general.countriesPicked.length > 0 && (
|
|
1335
|
+
<CheckBox
|
|
1336
|
+
value={config.general.hideUnselectedCountries || false}
|
|
1337
|
+
fieldName='hideUnselectedCountries'
|
|
1338
|
+
label='Hide Unselected Countries'
|
|
1339
|
+
updateField={updateField}
|
|
1340
|
+
section='general'
|
|
1341
|
+
/>
|
|
1342
|
+
)}
|
|
1343
|
+
</>
|
|
1344
|
+
)}
|
|
1223
1345
|
{/* Type */}
|
|
1224
1346
|
<Select
|
|
1225
1347
|
label={
|
|
@@ -1263,7 +1385,7 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
1263
1385
|
{ value: '_blank', label: 'New Window' }
|
|
1264
1386
|
]}
|
|
1265
1387
|
onChange={event => {
|
|
1266
|
-
const _newConfig =
|
|
1388
|
+
const _newConfig = cloneConfig(config)
|
|
1267
1389
|
_newConfig.general.navigationTarget = event.target.value
|
|
1268
1390
|
setConfig(_newConfig)
|
|
1269
1391
|
}}
|
|
@@ -1297,37 +1419,35 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
1297
1419
|
|
|
1298
1420
|
{/* Display as Hex */}
|
|
1299
1421
|
{general.geoType === 'us' && general.type !== 'navigation' && general.type !== 'bubble' && (
|
|
1300
|
-
<
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
/>
|
|
1310
|
-
<span className='edit-label'>Display As Hex Map</span>
|
|
1311
|
-
</label>
|
|
1422
|
+
<CheckBox
|
|
1423
|
+
value={config.general.displayAsHex}
|
|
1424
|
+
section='general'
|
|
1425
|
+
subsection={null}
|
|
1426
|
+
fieldName='displayAsHex'
|
|
1427
|
+
label='Display As Hex Map'
|
|
1428
|
+
updateField={updateField}
|
|
1429
|
+
className=''
|
|
1430
|
+
/>
|
|
1312
1431
|
)}
|
|
1313
1432
|
|
|
1314
1433
|
{/* Shapes on Hex */}
|
|
1315
|
-
<
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1434
|
+
<CheckBox
|
|
1435
|
+
value={config.hexMap.type === 'shapes'}
|
|
1436
|
+
section='hexMap'
|
|
1437
|
+
subsection={null}
|
|
1438
|
+
fieldName='type'
|
|
1439
|
+
label='Display Shapes on Hex Map'
|
|
1440
|
+
updateField={updateField}
|
|
1441
|
+
onChange={event => {
|
|
1442
|
+
setConfig({
|
|
1443
|
+
...config,
|
|
1444
|
+
hexMap: {
|
|
1445
|
+
...config.hexMap,
|
|
1446
|
+
type: event.target.checked ? 'shapes' : 'standard'
|
|
1447
|
+
}
|
|
1448
|
+
})
|
|
1449
|
+
}}
|
|
1450
|
+
/>
|
|
1331
1451
|
<HexSetting.ShapeColumns columnsOptions={columnsOptions} />
|
|
1332
1452
|
|
|
1333
1453
|
{'us' === config.general.geoType &&
|
|
@@ -1353,18 +1473,14 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
1353
1473
|
)}
|
|
1354
1474
|
|
|
1355
1475
|
{'us' === config.general.geoType && (
|
|
1356
|
-
<
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
}}
|
|
1365
|
-
/>
|
|
1366
|
-
<span className='edit-label'>Show All Territories</span>
|
|
1367
|
-
</label>
|
|
1476
|
+
<CheckBox
|
|
1477
|
+
value={general.territoriesAlwaysShow || false}
|
|
1478
|
+
section='general'
|
|
1479
|
+
subsection={null}
|
|
1480
|
+
fieldName='territoriesAlwaysShow'
|
|
1481
|
+
label='Show All Territories'
|
|
1482
|
+
updateField={updateField}
|
|
1483
|
+
/>
|
|
1368
1484
|
)}
|
|
1369
1485
|
</AccordionItemPanel>
|
|
1370
1486
|
</AccordionItem>
|
|
@@ -1397,18 +1513,14 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
1397
1513
|
</Tooltip>
|
|
1398
1514
|
}
|
|
1399
1515
|
/>
|
|
1400
|
-
<
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
}}
|
|
1409
|
-
/>
|
|
1410
|
-
<span className='edit-label'>Show Title</span>
|
|
1411
|
-
</label>
|
|
1516
|
+
<CheckBox
|
|
1517
|
+
value={config.general.showTitle || false}
|
|
1518
|
+
section='general'
|
|
1519
|
+
subsection={null}
|
|
1520
|
+
fieldName='showTitle'
|
|
1521
|
+
label='Show Title'
|
|
1522
|
+
updateField={updateField}
|
|
1523
|
+
/>
|
|
1412
1524
|
<TextField
|
|
1413
1525
|
value={general.superTitle || ''}
|
|
1414
1526
|
updateField={updateField}
|
|
@@ -1518,41 +1630,28 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
1518
1630
|
options={columnsOptions.map(c => c.key)}
|
|
1519
1631
|
onChange={event => {
|
|
1520
1632
|
editColumn('geo', 'name', event.target.value)
|
|
1521
|
-
checkConfigurationNeeded(config)
|
|
1522
1633
|
}}
|
|
1523
1634
|
/>
|
|
1524
1635
|
</label>
|
|
1525
1636
|
{config.general.type === 'us-geocode' && (
|
|
1526
|
-
<
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
...config.general,
|
|
1535
|
-
convertFipsCodes: event.target.checked
|
|
1536
|
-
}
|
|
1537
|
-
})
|
|
1538
|
-
}}
|
|
1539
|
-
/>
|
|
1540
|
-
<span className='edit-label'>Convert FIPS Codes to Geography Name</span>
|
|
1541
|
-
</label>
|
|
1637
|
+
<CheckBox
|
|
1638
|
+
value={config.general.convertFipsCodes}
|
|
1639
|
+
section='general'
|
|
1640
|
+
subsection={null}
|
|
1641
|
+
fieldName='convertFipsCodes'
|
|
1642
|
+
label='Convert FIPS Codes to Geography Name'
|
|
1643
|
+
updateField={updateField}
|
|
1644
|
+
/>
|
|
1542
1645
|
)}
|
|
1543
1646
|
|
|
1544
|
-
<
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
}}
|
|
1553
|
-
/>
|
|
1554
|
-
<span className='edit-label'>Hide Geography Column Name in Tooltip</span>
|
|
1555
|
-
</label>
|
|
1647
|
+
<CheckBox
|
|
1648
|
+
value={config.general.hideGeoColumnInTooltip || false}
|
|
1649
|
+
section='general'
|
|
1650
|
+
subsection={null}
|
|
1651
|
+
fieldName='hideGeoColumnInTooltip'
|
|
1652
|
+
label='Hide Geography Column Name in Tooltip'
|
|
1653
|
+
updateField={updateField}
|
|
1654
|
+
/>
|
|
1556
1655
|
<TextField
|
|
1557
1656
|
value={config.general.geoLabelOverride}
|
|
1558
1657
|
section='general'
|
|
@@ -1579,11 +1678,10 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
1579
1678
|
value={columns.primary.name}
|
|
1580
1679
|
options={columnsOptions.map(c => c.key)}
|
|
1581
1680
|
onChange={event => {
|
|
1582
|
-
const _state =
|
|
1681
|
+
const _state = cloneConfig(config)
|
|
1583
1682
|
_state.columns.primary.name = event.target.value
|
|
1584
1683
|
_state.columns.primary.label = event.target.value
|
|
1585
1684
|
setConfig(_state)
|
|
1586
|
-
checkConfigurationNeeded(_state)
|
|
1587
1685
|
}}
|
|
1588
1686
|
tooltip={
|
|
1589
1687
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
@@ -1596,15 +1694,18 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
1596
1694
|
</Tooltip>
|
|
1597
1695
|
}
|
|
1598
1696
|
/>
|
|
1599
|
-
<label
|
|
1600
|
-
<
|
|
1601
|
-
|
|
1602
|
-
|
|
1697
|
+
<label>
|
|
1698
|
+
<CheckBox
|
|
1699
|
+
value={config.general.hidePrimaryColumnInTooltip || false}
|
|
1700
|
+
section='general'
|
|
1701
|
+
subsection={null}
|
|
1702
|
+
fieldName='hidePrimaryColumnInTooltip'
|
|
1703
|
+
label='Hide Data Column Name in Tooltip'
|
|
1704
|
+
updateField={updateField}
|
|
1603
1705
|
onChange={event => {
|
|
1604
1706
|
handleEditorChanges('hidePrimaryColumnInTooltip', event.target.checked)
|
|
1605
1707
|
}}
|
|
1606
1708
|
/>
|
|
1607
|
-
<span className='edit-label'>Hide Data Column Name in Tooltip</span>
|
|
1608
1709
|
</label>
|
|
1609
1710
|
<TextField
|
|
1610
1711
|
value={columns.primary.label}
|
|
@@ -1653,42 +1754,30 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
1653
1754
|
min={0}
|
|
1654
1755
|
/>
|
|
1655
1756
|
</li>
|
|
1656
|
-
<
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
<li>
|
|
1681
|
-
<label className='checkbox'>
|
|
1682
|
-
<input
|
|
1683
|
-
type='checkbox'
|
|
1684
|
-
checked={config.columns.primary.tooltip || false}
|
|
1685
|
-
onChange={event => {
|
|
1686
|
-
editColumn('primary', 'tooltip', event.target.checked)
|
|
1687
|
-
}}
|
|
1688
|
-
/>
|
|
1689
|
-
<span className='edit-label'>Show in Tooltips</span>
|
|
1690
|
-
</label>
|
|
1691
|
-
</li>
|
|
1757
|
+
<CheckBox
|
|
1758
|
+
value={config.columns.primary.useCommas}
|
|
1759
|
+
section='columns'
|
|
1760
|
+
subsection='primary'
|
|
1761
|
+
fieldName='useCommas'
|
|
1762
|
+
label='Add Commas to Numbers'
|
|
1763
|
+
updateField={updateField}
|
|
1764
|
+
/>
|
|
1765
|
+
<CheckBox
|
|
1766
|
+
value={config.columns.primary.dataTable || false}
|
|
1767
|
+
section='columns'
|
|
1768
|
+
subsection='primary'
|
|
1769
|
+
fieldName='dataTable'
|
|
1770
|
+
label='Show in Data Table'
|
|
1771
|
+
updateField={updateField}
|
|
1772
|
+
/>
|
|
1773
|
+
<CheckBox
|
|
1774
|
+
value={config.columns.primary.tooltip || false}
|
|
1775
|
+
section='columns'
|
|
1776
|
+
subsection='primary'
|
|
1777
|
+
fieldName='tooltip'
|
|
1778
|
+
label='Show in Tooltips'
|
|
1779
|
+
updateField={updateField}
|
|
1780
|
+
/>
|
|
1692
1781
|
</ul>
|
|
1693
1782
|
</fieldset>
|
|
1694
1783
|
)}
|
|
@@ -1707,14 +1796,14 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
1707
1796
|
</Tooltip.Content>
|
|
1708
1797
|
</Tooltip>
|
|
1709
1798
|
</span>
|
|
1710
|
-
<
|
|
1711
|
-
|
|
1799
|
+
<Select
|
|
1800
|
+
label=''
|
|
1801
|
+
value={config.columns.categorical ? config.columns.categorical.name : columnsOptions[0]?.key}
|
|
1802
|
+
options={columnsOptions.map(c => c.key)}
|
|
1712
1803
|
onChange={event => {
|
|
1713
1804
|
editColumn('categorical', 'name', event.target.value)
|
|
1714
1805
|
}}
|
|
1715
|
-
|
|
1716
|
-
{columnsOptions}
|
|
1717
|
-
</select>
|
|
1806
|
+
/>
|
|
1718
1807
|
</label>
|
|
1719
1808
|
</fieldset>
|
|
1720
1809
|
)}
|
|
@@ -1937,42 +2026,39 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
1937
2026
|
updateField={updateField}
|
|
1938
2027
|
/>
|
|
1939
2028
|
</li>
|
|
1940
|
-
<
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
<span className='edit-label'>Show in Tooltips</span>
|
|
1974
|
-
</label>
|
|
1975
|
-
</li>
|
|
2029
|
+
<CheckBox
|
|
2030
|
+
value={config.columns[val].useCommas}
|
|
2031
|
+
section='columns'
|
|
2032
|
+
subsection={val}
|
|
2033
|
+
fieldName='useCommas'
|
|
2034
|
+
label='Add Commas to Numbers'
|
|
2035
|
+
updateField={updateField}
|
|
2036
|
+
onChange={event => {
|
|
2037
|
+
editColumn(val, 'useCommas', event.target.checked)
|
|
2038
|
+
}}
|
|
2039
|
+
/>
|
|
2040
|
+
<CheckBox
|
|
2041
|
+
value={config.columns[val].dataTable}
|
|
2042
|
+
section='columns'
|
|
2043
|
+
subsection={val}
|
|
2044
|
+
fieldName='dataTable'
|
|
2045
|
+
label='Show in Data Table'
|
|
2046
|
+
updateField={updateField}
|
|
2047
|
+
onChange={event => {
|
|
2048
|
+
editColumn(val, 'dataTable', event.target.checked)
|
|
2049
|
+
}}
|
|
2050
|
+
/>
|
|
2051
|
+
<CheckBox
|
|
2052
|
+
value={config.columns[val].tooltip}
|
|
2053
|
+
section='columns'
|
|
2054
|
+
subsection={val}
|
|
2055
|
+
fieldName='tooltip'
|
|
2056
|
+
label='Show in Tooltips'
|
|
2057
|
+
updateField={updateField}
|
|
2058
|
+
onChange={event => {
|
|
2059
|
+
editColumn(val, 'tooltip', event.target.checked)
|
|
2060
|
+
}}
|
|
2061
|
+
/>
|
|
1976
2062
|
</ul>
|
|
1977
2063
|
</fieldset>
|
|
1978
2064
|
))}
|
|
@@ -2083,7 +2169,7 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2083
2169
|
messages = []
|
|
2084
2170
|
}
|
|
2085
2171
|
|
|
2086
|
-
const _newConfig =
|
|
2172
|
+
const _newConfig = cloneConfig(config)
|
|
2087
2173
|
_newConfig.legend.type = event.target.value
|
|
2088
2174
|
_newConfig.runtime.editorErrorMessage = messages
|
|
2089
2175
|
setConfig(_newConfig)
|
|
@@ -2091,18 +2177,14 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2091
2177
|
/>
|
|
2092
2178
|
)}
|
|
2093
2179
|
{'navigation' !== config.general.type && (
|
|
2094
|
-
<
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
}}
|
|
2103
|
-
/>
|
|
2104
|
-
<span className='edit-label'>Show Legend</span>
|
|
2105
|
-
</label>
|
|
2180
|
+
<CheckBox
|
|
2181
|
+
value={config.general.showSidebar || false}
|
|
2182
|
+
section='general'
|
|
2183
|
+
subsection={null}
|
|
2184
|
+
fieldName='showSidebar'
|
|
2185
|
+
label='Show Legend'
|
|
2186
|
+
updateField={updateField}
|
|
2187
|
+
/>
|
|
2106
2188
|
)}
|
|
2107
2189
|
{'navigation' !== config.general.type && (
|
|
2108
2190
|
<>
|
|
@@ -2159,18 +2241,14 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2159
2241
|
/>
|
|
2160
2242
|
)}
|
|
2161
2243
|
{'navigation' !== config.general.type && config.legend.style === 'gradient' && (
|
|
2162
|
-
<
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
<option value='linear blocks'>linear blocks</option>
|
|
2171
|
-
<option value='smooth'>smooth</option>
|
|
2172
|
-
</select>
|
|
2173
|
-
</label>
|
|
2244
|
+
<Select
|
|
2245
|
+
label='Gradient Style'
|
|
2246
|
+
value={legend.subStyle || ''}
|
|
2247
|
+
options={['linear blocks', 'smooth']}
|
|
2248
|
+
onChange={event => {
|
|
2249
|
+
handleEditorChanges('legendSubStyle', event.target.value)
|
|
2250
|
+
}}
|
|
2251
|
+
/>
|
|
2174
2252
|
)}
|
|
2175
2253
|
{allowLegendSeparators && (
|
|
2176
2254
|
<TextField
|
|
@@ -2208,61 +2286,66 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2208
2286
|
</label>
|
|
2209
2287
|
)}
|
|
2210
2288
|
{
|
|
2211
|
-
<
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2289
|
+
<CheckBox
|
|
2290
|
+
value={legend.hideBorder}
|
|
2291
|
+
section='legend'
|
|
2292
|
+
subsection={null}
|
|
2293
|
+
fieldName='hideBorder'
|
|
2294
|
+
label='Hide Legend Box'
|
|
2295
|
+
updateField={updateField}
|
|
2296
|
+
onChange={event => {
|
|
2297
|
+
handleEditorChanges('legendBorder', event.target.checked)
|
|
2298
|
+
}}
|
|
2299
|
+
tooltip={
|
|
2300
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2301
|
+
<Tooltip.Target>
|
|
2302
|
+
<Icon
|
|
2303
|
+
display='question'
|
|
2304
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
2305
|
+
/>
|
|
2306
|
+
</Tooltip.Target>
|
|
2307
|
+
<Tooltip.Content>
|
|
2308
|
+
<p> Default option for top and bottom legends is 'No Box.'</p>
|
|
2309
|
+
</Tooltip.Content>
|
|
2310
|
+
</Tooltip>
|
|
2311
|
+
}
|
|
2312
|
+
/>
|
|
2232
2313
|
}
|
|
2233
2314
|
{'side' === legend.position && (
|
|
2234
|
-
<
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2315
|
+
<CheckBox
|
|
2316
|
+
value={legend.singleColumn}
|
|
2317
|
+
section='legend'
|
|
2318
|
+
subsection={null}
|
|
2319
|
+
fieldName='singleColumn'
|
|
2320
|
+
label='Single Column Legend'
|
|
2321
|
+
updateField={updateField}
|
|
2322
|
+
onChange={event => {
|
|
2323
|
+
const _newConfig = cloneConfig(config)
|
|
2324
|
+
_newConfig.legend.singleColumn = event.target.checked
|
|
2325
|
+
_newConfig.legend.singleRow = false
|
|
2326
|
+
_newConfig.legend.verticalSorted = false
|
|
2243
2327
|
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
<span className='edit-label'>Single Column Legend</span>
|
|
2248
|
-
</label>
|
|
2328
|
+
setConfig(_newConfig)
|
|
2329
|
+
}}
|
|
2330
|
+
/>
|
|
2249
2331
|
)}
|
|
2250
2332
|
{'side' !== legend.position && legend.style !== 'gradient' && (
|
|
2251
|
-
<
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2333
|
+
<CheckBox
|
|
2334
|
+
value={legend.singleRow}
|
|
2335
|
+
section='legend'
|
|
2336
|
+
subsection={null}
|
|
2337
|
+
fieldName='singleRow'
|
|
2338
|
+
label='Single Row Legend'
|
|
2339
|
+
updateField={updateField}
|
|
2340
|
+
onChange={event => {
|
|
2341
|
+
const _newConfig = cloneConfig(config)
|
|
2342
|
+
_newConfig.legend.singleRow = event.target.checked
|
|
2343
|
+
_newConfig.legend.singleColumn = false
|
|
2344
|
+
_newConfig.legend.verticalSorted = false
|
|
2260
2345
|
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
<span className='edit-label'>Single Row Legend</span>
|
|
2265
|
-
</label>
|
|
2346
|
+
setConfig(_newConfig)
|
|
2347
|
+
}}
|
|
2348
|
+
/>
|
|
2266
2349
|
)}
|
|
2267
2350
|
|
|
2268
2351
|
{'navigation' !== config.general.type && config.legend.type === 'category' && (
|
|
@@ -2271,53 +2354,46 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2271
2354
|
value={legend.groupBy || ''}
|
|
2272
2355
|
options={columnsOptions.map(c => c.key)}
|
|
2273
2356
|
onChange={event => {
|
|
2274
|
-
const _newConfig =
|
|
2357
|
+
const _newConfig = cloneConfig(config)
|
|
2275
2358
|
_newConfig.legend.groupBy = event.target.value
|
|
2276
2359
|
setConfig(_newConfig)
|
|
2277
2360
|
}}
|
|
2278
2361
|
/>
|
|
2279
2362
|
)}
|
|
2280
2363
|
{config.legend.style !== 'gradient' && (
|
|
2281
|
-
<
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
}}
|
|
2290
|
-
/>
|
|
2291
|
-
<span className='edit-label'>Vertical sorted legend</span>
|
|
2292
|
-
</label>
|
|
2364
|
+
<CheckBox
|
|
2365
|
+
value={legend.verticalSorted}
|
|
2366
|
+
section='legend'
|
|
2367
|
+
subsection={null}
|
|
2368
|
+
fieldName='verticalSorted'
|
|
2369
|
+
label='Vertical sorted legend'
|
|
2370
|
+
updateField={updateField}
|
|
2371
|
+
/>
|
|
2293
2372
|
)}
|
|
2294
2373
|
|
|
2295
2374
|
{/* always show */}
|
|
2296
2375
|
{
|
|
2297
|
-
<
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2376
|
+
<CheckBox
|
|
2377
|
+
value={legend.showSpecialClassesLast}
|
|
2378
|
+
section='legend'
|
|
2379
|
+
subsection={null}
|
|
2380
|
+
fieldName='showSpecialClassesLast'
|
|
2381
|
+
label='Show Special Classes Last'
|
|
2382
|
+
updateField={updateField}
|
|
2383
|
+
onChange={event => {
|
|
2384
|
+
handleEditorChanges('legendShowSpecialClassesLast', event.target.checked)
|
|
2385
|
+
}}
|
|
2386
|
+
/>
|
|
2307
2387
|
}
|
|
2308
2388
|
{'category' !== legend.type && (
|
|
2309
|
-
<
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
}}
|
|
2318
|
-
/>
|
|
2319
|
-
<span className='edit-label column-heading'>
|
|
2320
|
-
Separate Zero
|
|
2389
|
+
<CheckBox
|
|
2390
|
+
value={legend.separateZero || false}
|
|
2391
|
+
section='legend'
|
|
2392
|
+
subsection={null}
|
|
2393
|
+
fieldName='separateZero'
|
|
2394
|
+
label='Separate Zero'
|
|
2395
|
+
updateField={updateField}
|
|
2396
|
+
tooltip={
|
|
2321
2397
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
2322
2398
|
<Tooltip.Target>
|
|
2323
2399
|
<Icon
|
|
@@ -2329,35 +2405,33 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2329
2405
|
<p>For numeric data, you can separate the zero value as its own data class.</p>
|
|
2330
2406
|
</Tooltip.Content>
|
|
2331
2407
|
</Tooltip>
|
|
2332
|
-
|
|
2333
|
-
|
|
2408
|
+
}
|
|
2409
|
+
/>
|
|
2334
2410
|
)}
|
|
2335
2411
|
|
|
2336
2412
|
{/* Temp Checkbox */}
|
|
2337
2413
|
{config.legend.type === 'equalnumber' && (
|
|
2338
|
-
<
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
}}
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
</Tooltip>
|
|
2360
|
-
</label>
|
|
2414
|
+
<CheckBox
|
|
2415
|
+
value={config.general.equalNumberOptIn}
|
|
2416
|
+
section='general'
|
|
2417
|
+
subsection={null}
|
|
2418
|
+
fieldName='equalNumberOptIn'
|
|
2419
|
+
label='Use new quantile legend'
|
|
2420
|
+
updateField={updateField}
|
|
2421
|
+
tooltip={
|
|
2422
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2423
|
+
<Tooltip.Target>
|
|
2424
|
+
<Icon
|
|
2425
|
+
display='question'
|
|
2426
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
2427
|
+
/>
|
|
2428
|
+
</Tooltip.Target>
|
|
2429
|
+
<Tooltip.Content>
|
|
2430
|
+
<p>This prevents numbers from being used in more than one category (ie. 0-1, 1-2, 2-3) </p>
|
|
2431
|
+
</Tooltip.Content>
|
|
2432
|
+
</Tooltip>
|
|
2433
|
+
}
|
|
2434
|
+
/>
|
|
2361
2435
|
)}
|
|
2362
2436
|
|
|
2363
2437
|
{'category' !== legend.type && (
|
|
@@ -2470,59 +2544,59 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2470
2544
|
</React.Fragment>
|
|
2471
2545
|
)}
|
|
2472
2546
|
{config.filters.length > 0 && (
|
|
2473
|
-
<label className='checkbox'>
|
|
2474
|
-
<
|
|
2475
|
-
|
|
2476
|
-
|
|
2547
|
+
<label className='checkbox column-heading'>
|
|
2548
|
+
<CheckBox
|
|
2549
|
+
value={legend.dynamicDescription}
|
|
2550
|
+
section='legend'
|
|
2551
|
+
subsection={null}
|
|
2552
|
+
fieldName='dynamicDescription'
|
|
2553
|
+
label='Dynamic Legend Description'
|
|
2554
|
+
updateField={updateField}
|
|
2477
2555
|
onChange={() => {
|
|
2478
2556
|
handleEditorChanges('dynamicDescription', filterValueOptionList[0])
|
|
2479
2557
|
}}
|
|
2480
2558
|
/>
|
|
2481
|
-
<
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
</Tooltip.Content>
|
|
2496
|
-
</Tooltip>
|
|
2497
|
-
</span>
|
|
2498
|
-
</label>
|
|
2499
|
-
)}
|
|
2500
|
-
{(config.filters.length > 0 || config.general.type === 'bubble' || config.general.geoType === 'us') && (
|
|
2501
|
-
<label className='checkbox'>
|
|
2502
|
-
<input
|
|
2503
|
-
type='checkbox'
|
|
2504
|
-
checked={legend.unified}
|
|
2505
|
-
onChange={event => handleEditorChanges('unifiedLegend', event.target.checked)}
|
|
2506
|
-
/>
|
|
2507
|
-
<span className='edit-label column-heading'>
|
|
2508
|
-
Unified Legend
|
|
2509
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2510
|
-
<Tooltip.Target>
|
|
2511
|
-
<Icon
|
|
2512
|
-
display='question'
|
|
2513
|
-
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
2514
|
-
/>
|
|
2515
|
-
</Tooltip.Target>
|
|
2516
|
-
<Tooltip.Content>
|
|
2517
|
-
<p>
|
|
2518
|
-
For a map with filters, check this option if you want the high and low values in the legend
|
|
2519
|
-
to be based on <em>all</em> mapped values.
|
|
2520
|
-
</p>
|
|
2521
|
-
</Tooltip.Content>
|
|
2522
|
-
</Tooltip>
|
|
2523
|
-
</span>
|
|
2559
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2560
|
+
<Tooltip.Target>
|
|
2561
|
+
<Icon
|
|
2562
|
+
display='question'
|
|
2563
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
2564
|
+
/>
|
|
2565
|
+
</Tooltip.Target>
|
|
2566
|
+
<Tooltip.Content>
|
|
2567
|
+
<p>
|
|
2568
|
+
Check this option if the map has multiple filter controls and you want to specify a
|
|
2569
|
+
description for each filter selection.
|
|
2570
|
+
</p>
|
|
2571
|
+
</Tooltip.Content>
|
|
2572
|
+
</Tooltip>
|
|
2524
2573
|
</label>
|
|
2525
2574
|
)}
|
|
2575
|
+
<span className='d-flex mt-2'>
|
|
2576
|
+
<CheckBox
|
|
2577
|
+
value={legend.unified}
|
|
2578
|
+
section='legend'
|
|
2579
|
+
subsection={null}
|
|
2580
|
+
fieldName='unified'
|
|
2581
|
+
label='Unified Legend'
|
|
2582
|
+
updateField={updateField}
|
|
2583
|
+
onChange={event => handleEditorChanges('unifiedLegend', event.target.checked)}
|
|
2584
|
+
/>
|
|
2585
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2586
|
+
<Tooltip.Target>
|
|
2587
|
+
<Icon
|
|
2588
|
+
display='question'
|
|
2589
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
2590
|
+
/>
|
|
2591
|
+
</Tooltip.Target>
|
|
2592
|
+
<Tooltip.Content>
|
|
2593
|
+
<p>
|
|
2594
|
+
Check this option if you want the high and low values in the legend to be based on <em>all</em>{' '}
|
|
2595
|
+
mapped values (useful for maps with filters or small multiples).
|
|
2596
|
+
</p>
|
|
2597
|
+
</Tooltip.Content>
|
|
2598
|
+
</Tooltip>
|
|
2599
|
+
</span>
|
|
2526
2600
|
</AccordionItemPanel>
|
|
2527
2601
|
</AccordionItem>
|
|
2528
2602
|
)}
|
|
@@ -2579,32 +2653,26 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2579
2653
|
</Tooltip>
|
|
2580
2654
|
}
|
|
2581
2655
|
/>
|
|
2582
|
-
<
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
onChange={event => {
|
|
2603
|
-
handleEditorChanges('showDataTable', event.target.checked)
|
|
2604
|
-
}}
|
|
2605
|
-
/>
|
|
2606
|
-
<span className='edit-label column-heading'>
|
|
2607
|
-
Show Data Table
|
|
2656
|
+
<CheckBox
|
|
2657
|
+
value={config.table.wrapColumns}
|
|
2658
|
+
section='table'
|
|
2659
|
+
subsection={null}
|
|
2660
|
+
fieldName='wrapColumns'
|
|
2661
|
+
label='WRAP DATA TABLE COLUMNS'
|
|
2662
|
+
updateField={updateField}
|
|
2663
|
+
className='column-heading'
|
|
2664
|
+
/>
|
|
2665
|
+
<CheckBox
|
|
2666
|
+
value={config.table.forceDisplay !== undefined ? config.table.forceDisplay : !isDashboard}
|
|
2667
|
+
section='table'
|
|
2668
|
+
subsection={null}
|
|
2669
|
+
fieldName='forceDisplay'
|
|
2670
|
+
label='Show Data Table'
|
|
2671
|
+
updateField={updateField}
|
|
2672
|
+
onChange={event => {
|
|
2673
|
+
handleEditorChanges('showDataTable', event.target.checked)
|
|
2674
|
+
}}
|
|
2675
|
+
tooltip={
|
|
2608
2676
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
2609
2677
|
<Tooltip.Target>
|
|
2610
2678
|
<Icon
|
|
@@ -2619,24 +2687,17 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2619
2687
|
</p>
|
|
2620
2688
|
</Tooltip.Content>
|
|
2621
2689
|
</Tooltip>
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
showNonGeoData: event.target.checked
|
|
2634
|
-
}
|
|
2635
|
-
})
|
|
2636
|
-
}}
|
|
2637
|
-
/>
|
|
2638
|
-
<span className='edit-label column-heading'>
|
|
2639
|
-
Show Non Geographic Data
|
|
2690
|
+
}
|
|
2691
|
+
/>
|
|
2692
|
+
|
|
2693
|
+
<CheckBox
|
|
2694
|
+
value={config.table.showNonGeoData}
|
|
2695
|
+
section='table'
|
|
2696
|
+
subsection={null}
|
|
2697
|
+
fieldName='showNonGeoData'
|
|
2698
|
+
label='Show Non Geographic Data'
|
|
2699
|
+
updateField={updateField}
|
|
2700
|
+
tooltip={
|
|
2640
2701
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
2641
2702
|
<Tooltip.Target>
|
|
2642
2703
|
<Icon
|
|
@@ -2648,8 +2709,9 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2648
2709
|
<p>Show any data not associated with a geographic location</p>
|
|
2649
2710
|
</Tooltip.Content>
|
|
2650
2711
|
</Tooltip>
|
|
2651
|
-
|
|
2652
|
-
|
|
2712
|
+
}
|
|
2713
|
+
/>
|
|
2714
|
+
|
|
2653
2715
|
<TextField
|
|
2654
2716
|
value={table.indexLabel || ''}
|
|
2655
2717
|
updateField={updateField}
|
|
@@ -2690,16 +2752,17 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2690
2752
|
}
|
|
2691
2753
|
type='textarea'
|
|
2692
2754
|
/>
|
|
2693
|
-
<
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2755
|
+
<CheckBox
|
|
2756
|
+
value={config.table.limitHeight}
|
|
2757
|
+
section='table'
|
|
2758
|
+
subsection={null}
|
|
2759
|
+
fieldName='limitHeight'
|
|
2760
|
+
label='Limit Table Height'
|
|
2761
|
+
updateField={updateField}
|
|
2762
|
+
onChange={event => {
|
|
2763
|
+
handleEditorChanges('limitDataTableHeight', event.target.checked)
|
|
2764
|
+
}}
|
|
2765
|
+
/>
|
|
2703
2766
|
{config.table.limitHeight && (
|
|
2704
2767
|
<TextField
|
|
2705
2768
|
value={table.height}
|
|
@@ -2725,16 +2788,17 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2725
2788
|
max='500'
|
|
2726
2789
|
/>
|
|
2727
2790
|
|
|
2728
|
-
<
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2791
|
+
<CheckBox
|
|
2792
|
+
value={config.table.expanded || false}
|
|
2793
|
+
section='table'
|
|
2794
|
+
subsection={null}
|
|
2795
|
+
fieldName='expanded'
|
|
2796
|
+
label='Map loads with data table expanded'
|
|
2797
|
+
updateField={updateField}
|
|
2798
|
+
onChange={event => {
|
|
2799
|
+
handleEditorChanges('expandDataTable', event.target.checked)
|
|
2800
|
+
}}
|
|
2801
|
+
/>
|
|
2738
2802
|
<CheckBox
|
|
2739
2803
|
value={config.table.download}
|
|
2740
2804
|
fieldName='download'
|
|
@@ -2744,17 +2808,18 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2744
2808
|
/>
|
|
2745
2809
|
{config.table.download && (
|
|
2746
2810
|
<>
|
|
2747
|
-
<
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2811
|
+
<CheckBox
|
|
2812
|
+
value={config.table.showDownloadLinkBelow}
|
|
2813
|
+
section='table'
|
|
2814
|
+
subsection={null}
|
|
2815
|
+
fieldName='showDownloadLinkBelow'
|
|
2816
|
+
label='Show Link Below Table'
|
|
2817
|
+
updateField={updateField}
|
|
2818
|
+
className='ms-4'
|
|
2819
|
+
onChange={event => {
|
|
2820
|
+
handleEditorChanges('toggleDownloadLinkBelow', event.target.checked)
|
|
2821
|
+
}}
|
|
2822
|
+
/>
|
|
2758
2823
|
<CheckBox
|
|
2759
2824
|
value={config.table.downloadVisibleDataOnly}
|
|
2760
2825
|
fieldName='downloadVisibleDataOnly'
|
|
@@ -2766,53 +2831,47 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2766
2831
|
</>
|
|
2767
2832
|
)}
|
|
2768
2833
|
{isDashboard && (
|
|
2769
|
-
<
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
}}
|
|
2778
|
-
/>
|
|
2779
|
-
<span className='edit-label'>Show Data Table Name & Link</span>
|
|
2780
|
-
</label>
|
|
2834
|
+
<CheckBox
|
|
2835
|
+
value={config.table.showDataTableLink}
|
|
2836
|
+
section='table'
|
|
2837
|
+
subsection={null}
|
|
2838
|
+
fieldName='showDataTableLink'
|
|
2839
|
+
label='Show Data Table Name & Link'
|
|
2840
|
+
updateField={updateField}
|
|
2841
|
+
/>
|
|
2781
2842
|
)}
|
|
2782
2843
|
{isLoadedFromUrl && (
|
|
2783
|
-
<
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
setConfig(_newConfig)
|
|
2791
|
-
}}
|
|
2792
|
-
/>
|
|
2793
|
-
<span className='edit-label'>Show URL to Automatically Updated Data</span>
|
|
2794
|
-
</label>
|
|
2795
|
-
)}
|
|
2796
|
-
<label className='checkbox'>
|
|
2797
|
-
<input
|
|
2798
|
-
type='checkbox'
|
|
2799
|
-
checked={config.table.showFullGeoNameInCSV}
|
|
2800
|
-
onChange={event => {
|
|
2801
|
-
handleEditorChanges('toggleShowFullGeoNameInCSV', event.target.checked)
|
|
2802
|
-
}}
|
|
2803
|
-
/>
|
|
2804
|
-
<span className='edit-label'>Include Full Geo Name in CSV Download</span>
|
|
2805
|
-
</label>
|
|
2806
|
-
<label className='checkbox'>
|
|
2807
|
-
<input
|
|
2808
|
-
type='checkbox'
|
|
2809
|
-
checked={config.general.showDownloadImgButton}
|
|
2810
|
-
onChange={event => {
|
|
2811
|
-
handleEditorChanges('toggleDownloadImgButton', event.target.checked)
|
|
2812
|
-
}}
|
|
2844
|
+
<CheckBox
|
|
2845
|
+
value={config.table.showDownloadUrl}
|
|
2846
|
+
section='table'
|
|
2847
|
+
subsection={null}
|
|
2848
|
+
fieldName='showDownloadUrl'
|
|
2849
|
+
label='Show URL to Automatically Updated Data'
|
|
2850
|
+
updateField={updateField}
|
|
2813
2851
|
/>
|
|
2814
|
-
|
|
2815
|
-
|
|
2852
|
+
)}
|
|
2853
|
+
<CheckBox
|
|
2854
|
+
value={config.table.showFullGeoNameInCSV}
|
|
2855
|
+
section='table'
|
|
2856
|
+
subsection={null}
|
|
2857
|
+
fieldName='showFullGeoNameInCSV'
|
|
2858
|
+
label='Include Full Geo Name in CSV Download'
|
|
2859
|
+
updateField={updateField}
|
|
2860
|
+
onChange={event => {
|
|
2861
|
+
handleEditorChanges('toggleShowFullGeoNameInCSV', event.target.checked)
|
|
2862
|
+
}}
|
|
2863
|
+
/>
|
|
2864
|
+
<CheckBox
|
|
2865
|
+
value={config.general.showDownloadImgButton}
|
|
2866
|
+
section='general'
|
|
2867
|
+
subsection={null}
|
|
2868
|
+
fieldName='showDownloadImgButton'
|
|
2869
|
+
label='Enable Image Download'
|
|
2870
|
+
updateField={updateField}
|
|
2871
|
+
onChange={event => {
|
|
2872
|
+
handleEditorChanges('toggleDownloadImgButton', event.target.checked)
|
|
2873
|
+
}}
|
|
2874
|
+
/>
|
|
2816
2875
|
|
|
2817
2876
|
{/* <label className='checkbox'>
|
|
2818
2877
|
<input
|
|
@@ -2877,47 +2936,32 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2877
2936
|
<AccordionItemButton>Visual</AccordionItemButton>
|
|
2878
2937
|
</AccordionItemHeading>
|
|
2879
2938
|
<AccordionItemPanel>
|
|
2880
|
-
<
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
</label>
|
|
2897
|
-
<label className='checkbox'>
|
|
2898
|
-
<input
|
|
2899
|
-
type='checkbox'
|
|
2900
|
-
checked={config.general.showTitle || false}
|
|
2901
|
-
onChange={event => {
|
|
2902
|
-
handleEditorChanges('showTitle', event.target.checked)
|
|
2903
|
-
}}
|
|
2904
|
-
/>
|
|
2905
|
-
<span className='edit-label'>Show Title</span>
|
|
2906
|
-
</label>
|
|
2939
|
+
<HeaderThemeSelector
|
|
2940
|
+
selectedTheme={config.general.headerColor}
|
|
2941
|
+
onThemeSelect={palette => handleEditorChanges('headerColor', palette)}
|
|
2942
|
+
label='Header Theme'
|
|
2943
|
+
/>
|
|
2944
|
+
<CheckBox
|
|
2945
|
+
value={config.general.showTitle || false}
|
|
2946
|
+
section='general'
|
|
2947
|
+
subsection={null}
|
|
2948
|
+
fieldName='showTitle'
|
|
2949
|
+
label='Show Title'
|
|
2950
|
+
updateField={updateField}
|
|
2951
|
+
onChange={event => {
|
|
2952
|
+
handleEditorChanges('showTitle', event.target.checked)
|
|
2953
|
+
}}
|
|
2954
|
+
/>
|
|
2907
2955
|
|
|
2908
2956
|
{'navigation' === config.general.type && (
|
|
2909
|
-
<
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
}}
|
|
2918
|
-
/>
|
|
2919
|
-
<span className='edit-label'>Add border around map</span>
|
|
2920
|
-
</label>
|
|
2957
|
+
<CheckBox
|
|
2958
|
+
value={config.general.fullBorder || false}
|
|
2959
|
+
section='general'
|
|
2960
|
+
subsection={null}
|
|
2961
|
+
fieldName='fullBorder'
|
|
2962
|
+
label='Add border around map'
|
|
2963
|
+
updateField={updateField}
|
|
2964
|
+
/>
|
|
2921
2965
|
)}
|
|
2922
2966
|
<Select
|
|
2923
2967
|
label='Geo Border Color'
|
|
@@ -2933,6 +2977,15 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2933
2977
|
<label>
|
|
2934
2978
|
<span className='edit-label'>Map Color Palette</span>
|
|
2935
2979
|
</label>
|
|
2980
|
+
<div className='mb-2'>
|
|
2981
|
+
<small className='text-muted'>
|
|
2982
|
+
Review color contrasts{' '}
|
|
2983
|
+
<a href='https://webaim.org/resources/contrastchecker/' target='_blank' rel='noopener noreferrer'>
|
|
2984
|
+
here
|
|
2985
|
+
</a>
|
|
2986
|
+
</small>
|
|
2987
|
+
</div>
|
|
2988
|
+
<DeveloperPaletteRollback config={config} updateConfig={setConfig} />
|
|
2936
2989
|
<InputToggle
|
|
2937
2990
|
type='3d'
|
|
2938
2991
|
section='general'
|
|
@@ -2941,127 +2994,136 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
2941
2994
|
size='small'
|
|
2942
2995
|
label='Use selected palette in reverse order'
|
|
2943
2996
|
onClick={() => {
|
|
2944
|
-
const _state =
|
|
2997
|
+
const _state = cloneConfig(config)
|
|
2998
|
+
const currentPaletteName = config.general.palette?.name || ''
|
|
2945
2999
|
_state.general.palette.isReversed = !_state.general.palette.isReversed
|
|
2946
3000
|
let paletteName = ''
|
|
2947
|
-
if (_state.general.palette.isReversed && !
|
|
2948
|
-
paletteName =
|
|
3001
|
+
if (_state.general.palette.isReversed && !currentPaletteName.endsWith('reverse')) {
|
|
3002
|
+
paletteName = currentPaletteName + 'reverse'
|
|
2949
3003
|
}
|
|
2950
|
-
if (!_state.general.palette.isReversed &&
|
|
2951
|
-
paletteName =
|
|
3004
|
+
if (!_state.general.palette.isReversed && currentPaletteName.endsWith('reverse')) {
|
|
3005
|
+
paletteName = currentPaletteName.slice(0, -7)
|
|
2952
3006
|
}
|
|
2953
3007
|
if (paletteName) {
|
|
2954
|
-
_state.
|
|
3008
|
+
_state.general.palette.name = paletteName
|
|
2955
3009
|
}
|
|
2956
3010
|
setConfig(_state)
|
|
2957
3011
|
}}
|
|
2958
3012
|
value={config.general.palette.isReversed}
|
|
2959
3013
|
/>
|
|
2960
3014
|
<span>Sequential</span>
|
|
2961
|
-
<
|
|
2962
|
-
{sequential
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
backgroundColor: colorPalettes[palette][6]
|
|
2973
|
-
}
|
|
2974
|
-
|
|
2975
|
-
return (
|
|
2976
|
-
<li
|
|
2977
|
-
title={palette}
|
|
2978
|
-
key={palette}
|
|
2979
|
-
onClick={() => {
|
|
2980
|
-
const _newConfig = _.cloneDeep(config)
|
|
2981
|
-
_newConfig.color = palette
|
|
2982
|
-
setConfig(_newConfig)
|
|
2983
|
-
}}
|
|
2984
|
-
className={config.color === palette ? 'selected' : ''}
|
|
2985
|
-
>
|
|
2986
|
-
<span style={colorOne}></span>
|
|
2987
|
-
<span style={colorTwo}></span>
|
|
2988
|
-
<span style={colorThree}></span>
|
|
2989
|
-
</li>
|
|
2990
|
-
)
|
|
2991
|
-
})}
|
|
2992
|
-
</ul>
|
|
3015
|
+
<PaletteSelector
|
|
3016
|
+
palettes={sequential}
|
|
3017
|
+
colorPalettes={colorPalettes}
|
|
3018
|
+
config={config}
|
|
3019
|
+
onPaletteSelect={handlePaletteSelection}
|
|
3020
|
+
selectedPalette={getCurrentPaletteName(config)}
|
|
3021
|
+
colorIndices={[2, 3, 5]}
|
|
3022
|
+
className='color-palette'
|
|
3023
|
+
element='button'
|
|
3024
|
+
getItemClassName={getPaletteClassName}
|
|
3025
|
+
/>
|
|
2993
3026
|
<span>Non-Sequential</span>
|
|
2994
|
-
<
|
|
2995
|
-
{nonSequential
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3027
|
+
<PaletteSelector
|
|
3028
|
+
palettes={nonSequential}
|
|
3029
|
+
colorPalettes={colorPalettes}
|
|
3030
|
+
config={config}
|
|
3031
|
+
onPaletteSelect={handlePaletteSelection}
|
|
3032
|
+
selectedPalette={getCurrentPaletteName(config)}
|
|
3033
|
+
colorIndices={[2, 3, 5]}
|
|
3034
|
+
className='color-palette'
|
|
3035
|
+
element='button'
|
|
3036
|
+
getItemClassName={getPaletteClassName}
|
|
3037
|
+
minColorsForFilter={(_, paletteAccessor, config) => {
|
|
3038
|
+
if (paletteAccessor.length <= 8 && config.general.geoType === 'us-region') {
|
|
3039
|
+
return false
|
|
3002
3040
|
}
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
}
|
|
3007
|
-
|
|
3008
|
-
// hide palettes with too few colors for region maps
|
|
3009
|
-
if (colorPalettes[palette].length <= 8 && config.general.geoType === 'us-region') {
|
|
3010
|
-
return ''
|
|
3011
|
-
}
|
|
3012
|
-
return (
|
|
3013
|
-
<li
|
|
3014
|
-
title={palette}
|
|
3015
|
-
key={palette}
|
|
3016
|
-
onClick={() => {
|
|
3017
|
-
const _newConfig = _.cloneDeep(config)
|
|
3018
|
-
_newConfig.color = palette
|
|
3019
|
-
setConfig(_newConfig)
|
|
3020
|
-
}}
|
|
3021
|
-
className={config.color === palette ? 'selected' : ''}
|
|
3022
|
-
>
|
|
3023
|
-
<span style={colorOne}></span>
|
|
3024
|
-
<span style={colorTwo}></span>
|
|
3025
|
-
<span style={colorThree}></span>
|
|
3026
|
-
</li>
|
|
3027
|
-
)
|
|
3028
|
-
})}
|
|
3029
|
-
</ul>
|
|
3041
|
+
return true
|
|
3042
|
+
}}
|
|
3043
|
+
/>
|
|
3030
3044
|
<span>Colorblind Safe</span>
|
|
3031
|
-
<
|
|
3032
|
-
{accessibleColors
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3045
|
+
<PaletteSelector
|
|
3046
|
+
palettes={accessibleColors}
|
|
3047
|
+
colorPalettes={colorPalettes}
|
|
3048
|
+
config={config}
|
|
3049
|
+
onPaletteSelect={handlePaletteSelection}
|
|
3050
|
+
selectedPalette={getCurrentPaletteName(config)}
|
|
3051
|
+
colorIndices={[2, 3, 5]}
|
|
3052
|
+
className='color-palette'
|
|
3053
|
+
element='button'
|
|
3054
|
+
getItemClassName={getPaletteClassName}
|
|
3055
|
+
minColorsForFilter={(_, paletteAccessor, config) => {
|
|
3056
|
+
if (paletteAccessor.length <= 8 && config.general.geoType === 'us-region') {
|
|
3057
|
+
return false
|
|
3039
3058
|
}
|
|
3059
|
+
return true
|
|
3060
|
+
}}
|
|
3061
|
+
/>
|
|
3040
3062
|
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3063
|
+
{isCoveDeveloperMode() && (
|
|
3064
|
+
<>
|
|
3065
|
+
<div className='mt-3'>
|
|
3066
|
+
<label className='checkbox'>
|
|
3067
|
+
<input
|
|
3068
|
+
type='checkbox'
|
|
3069
|
+
checked={!!config.general.palette.customColorsOrdered}
|
|
3070
|
+
onChange={e => {
|
|
3071
|
+
const _state = cloneConfig(config)
|
|
3072
|
+
if (e.target.checked) {
|
|
3073
|
+
// Extract actual colors from runtime legend if available
|
|
3074
|
+
if (runtimeLegend?.items && runtimeLegend.items.length > 0) {
|
|
3075
|
+
const extractedColors = []
|
|
3076
|
+
for (const item of runtimeLegend.items) {
|
|
3077
|
+
// Skip special classes (like "No Data")
|
|
3078
|
+
if (item.special) continue
|
|
3079
|
+
// Add the color if it exists and hasn't been added yet
|
|
3080
|
+
if (item.color && !extractedColors.includes(item.color)) {
|
|
3081
|
+
extractedColors.push(item.color)
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
_state.general.palette.customColorsOrdered =
|
|
3085
|
+
extractedColors.length > 0
|
|
3086
|
+
? extractedColors
|
|
3087
|
+
: ['#3366cc', '#5588dd', '#77aaee', '#99ccff']
|
|
3088
|
+
} else {
|
|
3089
|
+
// Fallback to default colors if runtime legend not available
|
|
3090
|
+
_state.general.palette.customColorsOrdered = ['#3366cc', '#5588dd', '#77aaee', '#99ccff']
|
|
3091
|
+
}
|
|
3092
|
+
} else {
|
|
3093
|
+
// Remove custom colors and revert to default palette
|
|
3094
|
+
delete _state.general.palette.customColorsOrdered
|
|
3095
|
+
delete _state.general.palette.customColors
|
|
3096
|
+
// Set default palette if none exists
|
|
3097
|
+
if (!_state.general.palette.name) {
|
|
3098
|
+
_state.general.palette.name = 'sequential_blue_green'
|
|
3099
|
+
_state.general.palette.version = '2.0'
|
|
3100
|
+
}
|
|
3101
|
+
}
|
|
3102
|
+
setConfig(_state)
|
|
3103
|
+
}}
|
|
3104
|
+
/>
|
|
3105
|
+
Use Custom Colors
|
|
3106
|
+
</label>
|
|
3107
|
+
</div>
|
|
3108
|
+
|
|
3109
|
+
{config.general.palette.customColorsOrdered && (
|
|
3110
|
+
<div className='mt-2'>
|
|
3111
|
+
<CustomColorsEditor
|
|
3112
|
+
colors={config.general.palette.customColorsOrdered}
|
|
3113
|
+
onChange={newColors => {
|
|
3114
|
+
const _state = cloneConfig(config)
|
|
3115
|
+
_state.general.palette.customColorsOrdered = newColors
|
|
3116
|
+
setConfig(_state)
|
|
3117
|
+
}}
|
|
3118
|
+
label='Custom Color Order'
|
|
3119
|
+
minColors={1}
|
|
3120
|
+
maxColors={20}
|
|
3121
|
+
/>
|
|
3122
|
+
</div>
|
|
3123
|
+
)}
|
|
3124
|
+
</>
|
|
3125
|
+
)}
|
|
3044
3126
|
|
|
3045
|
-
// hide palettes with too few colors for region maps
|
|
3046
|
-
if (colorPalettes[palette].length <= 8 && config.general.geoType === 'us-region') {
|
|
3047
|
-
return ''
|
|
3048
|
-
}
|
|
3049
|
-
return (
|
|
3050
|
-
<li
|
|
3051
|
-
title={palette}
|
|
3052
|
-
key={palette}
|
|
3053
|
-
onClick={() => {
|
|
3054
|
-
handleEditorChanges('color', palette)
|
|
3055
|
-
}}
|
|
3056
|
-
className={config.color === palette ? 'selected' : ''}
|
|
3057
|
-
>
|
|
3058
|
-
<span style={colorOne}></span>
|
|
3059
|
-
<span style={colorTwo}></span>
|
|
3060
|
-
<span style={colorThree}></span>
|
|
3061
|
-
</li>
|
|
3062
|
-
)
|
|
3063
|
-
})}
|
|
3064
|
-
</ul>
|
|
3065
3127
|
<label>
|
|
3066
3128
|
Geocode Settings
|
|
3067
3129
|
<TextField
|
|
@@ -3116,7 +3178,7 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
3116
3178
|
type='checkbox'
|
|
3117
3179
|
checked={config.general.allowMapZoom}
|
|
3118
3180
|
onChange={event => {
|
|
3119
|
-
const _newConfig =
|
|
3181
|
+
const _newConfig = cloneConfig(config)
|
|
3120
3182
|
_newConfig.general.allowMapZoom = event.target.checked
|
|
3121
3183
|
_newConfig.mapPosition.coordinates = config.general.geoType === 'world' ? [0, 30] : [0, 0]
|
|
3122
3184
|
_newConfig.mapPosition.zoom = 1
|
|
@@ -3132,7 +3194,7 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
3132
3194
|
type='checkbox'
|
|
3133
3195
|
checked={config.visual.extraBubbleBorder}
|
|
3134
3196
|
onChange={event => {
|
|
3135
|
-
const _newConfig =
|
|
3197
|
+
const _newConfig = cloneConfig(config)
|
|
3136
3198
|
_newConfig.visual.extraBubbleBorder = event.target.checked
|
|
3137
3199
|
setConfig(_newConfig)
|
|
3138
3200
|
}}
|
|
@@ -3144,22 +3206,21 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
3144
3206
|
config.general.geoType === 'us-county' ||
|
|
3145
3207
|
config.general.geoType === 'world') && (
|
|
3146
3208
|
<>
|
|
3147
|
-
<
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
}
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
</label>
|
|
3209
|
+
<Select
|
|
3210
|
+
label='Default City Style'
|
|
3211
|
+
value={config.visual.cityStyle || 'circle'}
|
|
3212
|
+
options={[
|
|
3213
|
+
{ value: 'circle', label: 'Circle' },
|
|
3214
|
+
{ value: 'pin', label: 'Pin' },
|
|
3215
|
+
{ value: 'square', label: 'Square' },
|
|
3216
|
+
{ value: 'triangle', label: 'Triangle' },
|
|
3217
|
+
{ value: 'diamond', label: 'Diamond' },
|
|
3218
|
+
{ value: 'star', label: 'Star' }
|
|
3219
|
+
]}
|
|
3220
|
+
onChange={event => {
|
|
3221
|
+
handleEditorChanges('handleCityStyle', event.target.value)
|
|
3222
|
+
}}
|
|
3223
|
+
/>
|
|
3163
3224
|
<TextField
|
|
3164
3225
|
value={config.visual.cityStyleLabel}
|
|
3165
3226
|
section='visual'
|
|
@@ -3195,17 +3256,14 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
3195
3256
|
Remove
|
|
3196
3257
|
</button>
|
|
3197
3258
|
<p>City Style {i + 1}</p>
|
|
3198
|
-
<
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
{columnsOptions}
|
|
3207
|
-
</select>
|
|
3208
|
-
</label>
|
|
3259
|
+
<Select
|
|
3260
|
+
label='Column with configuration value'
|
|
3261
|
+
value={column}
|
|
3262
|
+
options={columnsOptions.map(c => c.key)}
|
|
3263
|
+
onChange={e => {
|
|
3264
|
+
editCityStyles('update', i, 'column', e.target.value)
|
|
3265
|
+
}}
|
|
3266
|
+
/>
|
|
3209
3267
|
<label>
|
|
3210
3268
|
<span className='edit-label column-heading'>Value to Trigger</span>
|
|
3211
3269
|
<input
|
|
@@ -3216,17 +3274,19 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
3216
3274
|
}}
|
|
3217
3275
|
></input>
|
|
3218
3276
|
</label>
|
|
3219
|
-
<
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3277
|
+
<Select
|
|
3278
|
+
label='Shape'
|
|
3279
|
+
value={shape}
|
|
3280
|
+
options={[
|
|
3281
|
+
{ value: '', label: '- Select Option -' },
|
|
3282
|
+
...['Circle', 'Square', 'Triangle', 'Diamond', 'Star', 'Pin']
|
|
3283
|
+
.filter(val => String(config.visual.cityStyle).toLowerCase() !== val.toLowerCase())
|
|
3284
|
+
.map(val => ({ value: val, label: val }))
|
|
3285
|
+
]}
|
|
3286
|
+
onChange={e => {
|
|
3287
|
+
editCityStyles('update', i, 'shape', e.target.value)
|
|
3288
|
+
}}
|
|
3289
|
+
/>
|
|
3230
3290
|
<label>
|
|
3231
3291
|
<span className='edit-label column-heading'>Label</span>
|
|
3232
3292
|
<input
|
|
@@ -3371,9 +3431,27 @@ const EditorPanel: React.FC<MapEditorPanelProps> = ({ datasets }) => {
|
|
|
3371
3431
|
</AccordionItem>
|
|
3372
3432
|
{config.general.geoType === 'us' && <Panels.PatternSettings name='Pattern Settings' />}
|
|
3373
3433
|
{config.general.geoType !== 'us-county' && <Panels.Annotate name='Text Annotations' />}
|
|
3434
|
+
<PanelMarkup
|
|
3435
|
+
name='Markup Variables'
|
|
3436
|
+
markupVariables={config.markupVariables || []}
|
|
3437
|
+
data={config.data || []}
|
|
3438
|
+
enableMarkupVariables={config.enableMarkupVariables || false}
|
|
3439
|
+
onMarkupVariablesChange={variables => setConfig({ ...config, markupVariables: variables })}
|
|
3440
|
+
onToggleEnable={enabled => setConfig({ ...config, enableMarkupVariables: enabled })}
|
|
3441
|
+
/>
|
|
3442
|
+
<Panels.SmallMultiples name='Small Multiples' />
|
|
3374
3443
|
</Accordion>
|
|
3375
3444
|
<AdvancedEditor loadConfig={setConfig} config={config} convertStateToConfig={convertStateToConfig} />
|
|
3376
3445
|
</Layout.Sidebar>
|
|
3446
|
+
|
|
3447
|
+
{showConversionModal && (
|
|
3448
|
+
<PaletteConversionModal
|
|
3449
|
+
onConfirm={handleConversionConfirm}
|
|
3450
|
+
onCancel={handleConversionCancel}
|
|
3451
|
+
onReturnToV1={handleReturnToV1}
|
|
3452
|
+
paletteName={pendingPaletteSelection?.palette}
|
|
3453
|
+
/>
|
|
3454
|
+
)}
|
|
3377
3455
|
</ErrorBoundary>
|
|
3378
3456
|
)
|
|
3379
3457
|
}
|