@cdc/map 4.26.2 → 4.26.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/dist/cdcmap-vr9HZwRt.es.js +6 -0
- package/dist/cdcmap.js +26781 -24615
- package/examples/private/annotation-bug.json +642 -0
- package/package.json +3 -3
- package/src/CdcMap.tsx +3 -14
- package/src/CdcMapComponent.tsx +214 -159
- package/src/_stories/CdcMap.Defaults.stories.tsx +76 -0
- package/src/_stories/CdcMap.Editor.stories.tsx +187 -14
- package/src/_stories/CdcMap.stories.tsx +11 -1
- package/src/_stories/Map.HTMLInDataTable.stories.tsx +385 -0
- package/src/_stories/_mock/multi-state-show-unselected.json +82 -0
- package/src/cdcMapComponent.styles.css +2 -2
- package/src/components/Annotation/Annotation.Draggable.styles.css +4 -4
- package/src/components/Annotation/AnnotationDropdown.styles.css +1 -1
- package/src/components/Annotation/AnnotationList.styles.css +13 -13
- package/src/components/EditorPanel/components/EditorPanel.tsx +426 -58
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings-style.css +1 -1
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +5 -2
- package/src/components/EditorPanel/components/editorPanel.styles.css +34 -24
- package/src/components/Legend/components/Legend.tsx +9 -4
- package/src/components/Legend/components/LegendGroup/legend.group.css +5 -5
- package/src/components/Legend/components/index.scss +2 -3
- package/src/components/NavigationMenu.tsx +2 -1
- package/src/components/SmallMultiples/SmallMultiples.css +5 -5
- package/src/components/UsaMap/components/SingleState/SingleState.StateOutput.tsx +32 -17
- package/src/components/UsaMap/components/TerritoriesSection.tsx +3 -2
- package/src/components/UsaMap/components/Territory/Territory.Rectangle.tsx +13 -8
- package/src/components/UsaMap/components/UsaMap.County.tsx +410 -183
- package/src/components/UsaMap/components/UsaMap.Region.styles.css +1 -1
- package/src/components/UsaMap/components/UsaMap.SingleState.styles.css +2 -2
- package/src/components/UsaMap/components/UsaMap.State.tsx +13 -8
- package/src/components/WorldMap/WorldMap.tsx +10 -13
- package/src/components/WorldMap/data/world-topo-updated.json +1 -0
- package/src/components/WorldMap/data/world-topo.json +1 -1
- package/src/components/WorldMap/worldMap.styles.css +1 -1
- package/src/components/ZoomControls.tsx +49 -18
- package/src/components/zoomControls.styles.css +27 -11
- package/src/data/initial-state.js +14 -5
- package/src/data/legacy-defaults.ts +8 -0
- package/src/data/supported-geos.js +19 -0
- package/src/helpers/colors.ts +2 -1
- package/src/helpers/dataTableHelpers.ts +56 -0
- package/src/helpers/displayGeoName.ts +19 -11
- package/src/helpers/getMapContainerClasses.ts +8 -2
- package/src/helpers/getMatchingPatternForRow.ts +67 -0
- package/src/helpers/getPatternForRow.ts +11 -18
- package/src/helpers/tests/dataTableHelpers.test.ts +78 -0
- package/src/helpers/tests/displayGeoName.test.ts +17 -0
- package/src/helpers/tests/getMatchingPatternForRow.test.ts +150 -0
- package/src/helpers/tests/getPatternForRow.test.ts +140 -2
- package/src/helpers/urlDataHelpers.ts +7 -1
- package/src/hooks/useResizeObserver.ts +36 -22
- package/src/hooks/useTooltip.test.tsx +64 -0
- package/src/hooks/useTooltip.ts +28 -8
- package/src/scss/editor-panel.scss +1 -1
- package/src/scss/main.scss +140 -6
- package/src/scss/map.scss +9 -4
- package/src/store/map.actions.ts +2 -0
- package/src/store/map.reducer.ts +4 -0
- package/src/test/CdcMap.test.jsx +2 -2
- package/src/types/MapConfig.ts +22 -4
- package/src/types/MapContext.ts +3 -1
- package/dist/cdcmap-Cf9_fbQf.es.js +0 -6
- package/src/helpers/componentHelpers.ts +0 -8
|
@@ -15,7 +15,7 @@ import Icon from '@cdc/core/components/ui/Icon'
|
|
|
15
15
|
import { Select } from '@cdc/core/components/EditorPanel/Inputs'
|
|
16
16
|
import './Panel.PatternSettings-style.css'
|
|
17
17
|
import Alert from '@cdc/core/components/Alert'
|
|
18
|
-
import
|
|
18
|
+
import cloneDeep from 'lodash/cloneDeep'
|
|
19
19
|
import { cloneConfig } from '@cdc/core/helpers/cloneConfig'
|
|
20
20
|
|
|
21
21
|
// topojson helpers for checking color contrasts
|
|
@@ -65,7 +65,7 @@ const PatternSettings = ({ name }: PanelProps) => {
|
|
|
65
65
|
|
|
66
66
|
/** Updates the map config with a new pattern item */
|
|
67
67
|
const handleAddGeoPattern = () => {
|
|
68
|
-
const patterns =
|
|
68
|
+
const patterns = cloneDeep(config.map.patterns)
|
|
69
69
|
patterns.push({ dataKey: '', pattern: defaultPattern, contrastCheck: true })
|
|
70
70
|
setConfig({
|
|
71
71
|
...config,
|
|
@@ -217,6 +217,9 @@ const PatternSettings = ({ name }: PanelProps) => {
|
|
|
217
217
|
handlePatternFieldUpdate('dataKey', value, patternIndex)
|
|
218
218
|
}
|
|
219
219
|
/>
|
|
220
|
+
<p className='edit-label mb-2'>
|
|
221
|
+
Leave Data Key as "Select" to match this value across all columns.
|
|
222
|
+
</p>
|
|
220
223
|
<label htmlFor={`pattern-dataValue--${patternIndex}`}>
|
|
221
224
|
Data Value:
|
|
222
225
|
<input
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
.geo-buttons {
|
|
2
|
-
list-style: none;
|
|
3
2
|
color: var(--mediumGray);
|
|
4
3
|
display: grid;
|
|
4
|
+
list-style: none;
|
|
5
5
|
button { width: 100% !important; }
|
|
6
6
|
svg {
|
|
7
|
+
box-sizing: border-box;
|
|
7
8
|
display: block;
|
|
8
|
-
max-width: 80px;
|
|
9
|
-
max-height: 40px;
|
|
10
9
|
margin: 0.5em auto;
|
|
11
|
-
|
|
10
|
+
max-height: 40px;
|
|
11
|
+
max-width: 80px;
|
|
12
12
|
path {
|
|
13
13
|
fill: currentColor;
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
button {
|
|
17
|
+
align-items: center;
|
|
17
18
|
background: transparent;
|
|
18
|
-
padding: 0.3em 0.75em;
|
|
19
|
-
display: flex;
|
|
20
19
|
border: var(--lightGray) 1px solid;
|
|
21
|
-
width: 40%;
|
|
22
|
-
align-items: center;
|
|
23
|
-
margin-right: 1em;
|
|
24
20
|
cursor: pointer;
|
|
25
|
-
|
|
21
|
+
display: flex;
|
|
26
22
|
flex-direction: column;
|
|
23
|
+
margin-right: 1em;
|
|
24
|
+
overflow: hidden;
|
|
25
|
+
padding: 0.3em 0.75em;
|
|
27
26
|
transition: 0.2s all;
|
|
27
|
+
width: 40%;
|
|
28
28
|
svg {
|
|
29
29
|
display: block;
|
|
30
30
|
height: 25px;
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
max-width: 100%;
|
|
33
33
|
}
|
|
34
34
|
span {
|
|
35
|
-
text-transform: none;
|
|
36
35
|
font-size: 1em;
|
|
36
|
+
text-transform: none;
|
|
37
37
|
}
|
|
38
38
|
&:hover {
|
|
39
39
|
background: #f2f2f2;
|
|
@@ -48,13 +48,13 @@
|
|
|
48
48
|
fill: #005eaa;
|
|
49
49
|
}
|
|
50
50
|
&:before {
|
|
51
|
-
content: ' ';
|
|
52
|
-
width: 5px;
|
|
53
51
|
background: #005eaa;
|
|
54
|
-
left: 0;
|
|
55
|
-
top: 0;
|
|
56
52
|
bottom: 0;
|
|
53
|
+
content: ' ';
|
|
54
|
+
left: 0;
|
|
57
55
|
position: absolute;
|
|
56
|
+
top: 0;
|
|
57
|
+
width: 5px;
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -62,24 +62,24 @@
|
|
|
62
62
|
|
|
63
63
|
.editor-toggle {
|
|
64
64
|
background: #f2f2f2;
|
|
65
|
+
border: 0;
|
|
65
66
|
border-radius: 60px;
|
|
67
|
+
box-shadow: rgba(0, 0, 0, 0.5) 0 1px 2px;
|
|
66
68
|
color: #000;
|
|
69
|
+
cursor: pointer;
|
|
67
70
|
font-size: 1em;
|
|
68
|
-
|
|
71
|
+
height: 25px;
|
|
72
|
+
left: 307px;
|
|
69
73
|
position: fixed;
|
|
70
|
-
z-index: 100;
|
|
71
74
|
transition: 0.1s background;
|
|
72
|
-
cursor: pointer;
|
|
73
75
|
width: 25px;
|
|
74
|
-
|
|
75
|
-
left: 307px;
|
|
76
|
-
box-shadow: rgba(0, 0, 0, 0.5) 0 1px 2px;
|
|
76
|
+
z-index: 100;
|
|
77
77
|
&:before {
|
|
78
|
-
|
|
78
|
+
content: '\00ab';
|
|
79
79
|
left: 50%;
|
|
80
|
-
transform: translate(-50%, -50%);
|
|
81
80
|
position: absolute;
|
|
82
|
-
|
|
81
|
+
top: 43%;
|
|
82
|
+
transform: translate(-50%, -50%);
|
|
83
83
|
}
|
|
84
84
|
&.collapsed {
|
|
85
85
|
left: 1em;
|
|
@@ -93,3 +93,13 @@
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
.column-section__header {
|
|
97
|
+
align-items: center;
|
|
98
|
+
display: flex;
|
|
99
|
+
gap: 0.5rem;
|
|
100
|
+
margin-bottom: 1rem;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.column-section__title {
|
|
104
|
+
font-weight: 600;
|
|
105
|
+
}
|
|
@@ -56,7 +56,8 @@ const Legend = forwardRef<HTMLDivElement, LegendProps>((props, ref) => {
|
|
|
56
56
|
const isLegendGradient = legend.style === 'gradient'
|
|
57
57
|
const boxDynamicallyHidden = isBelowBreakpoint('md', viewport)
|
|
58
58
|
const legendWrapping =
|
|
59
|
-
(legend.position === 'left' || legend.position === 'right') &&
|
|
59
|
+
(legend.position === 'left' || legend.position === 'right') &&
|
|
60
|
+
(viewport === 'md' || isBelowBreakpoint('md', viewport))
|
|
60
61
|
const legendOnBottom = legend.position === 'bottom' || legendWrapping
|
|
61
62
|
const needsTopMargin = legend.hideBorder && legendOnBottom
|
|
62
63
|
|
|
@@ -274,7 +275,7 @@ const Legend = forwardRef<HTMLDivElement, LegendProps>((props, ref) => {
|
|
|
274
275
|
|
|
275
276
|
return (
|
|
276
277
|
<ErrorBoundary component='Sidebar'>
|
|
277
|
-
<div className={`legends ${needsTopMargin ? 'mt-4' : ''}`}>
|
|
278
|
+
<div className={`legends ${needsTopMargin ? 'mt-4' : ''} ${legendWrapping ? 'legend-wrapped-bottom' : ''}`}>
|
|
278
279
|
<aside
|
|
279
280
|
id={skipId || 'legend'}
|
|
280
281
|
className={legendClasses.aside.join(' ') || ''}
|
|
@@ -292,7 +293,9 @@ const Legend = forwardRef<HTMLDivElement, LegendProps>((props, ref) => {
|
|
|
292
293
|
config.enableMarkupVariables && config.markupVariables?.length > 0
|
|
293
294
|
? processMarkupVariables(legend.title, config.data || [], config.markupVariables, {
|
|
294
295
|
isEditor: false,
|
|
295
|
-
filters: config.filters || []
|
|
296
|
+
filters: config.filters || [],
|
|
297
|
+
locale: config.locale,
|
|
298
|
+
dataMetadata: config.dataMetadata
|
|
296
299
|
}).processedContent
|
|
297
300
|
: legend.title
|
|
298
301
|
)}
|
|
@@ -304,7 +307,9 @@ const Legend = forwardRef<HTMLDivElement, LegendProps>((props, ref) => {
|
|
|
304
307
|
config.enableMarkupVariables && config.markupVariables?.length > 0
|
|
305
308
|
? processMarkupVariables(legend.description, config.data || [], config.markupVariables, {
|
|
306
309
|
isEditor: false,
|
|
307
|
-
filters: config.filters || []
|
|
310
|
+
filters: config.filters || [],
|
|
311
|
+
locale: config.locale,
|
|
312
|
+
dataMetadata: config.dataMetadata
|
|
308
313
|
}).processedContent
|
|
309
314
|
: legend.description
|
|
310
315
|
)}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
.group-label {
|
|
2
|
-
font-weight: 500;
|
|
3
2
|
font-family: Nunito, sans-serif;
|
|
4
3
|
font-size: 1rem;
|
|
4
|
+
font-weight: 500;
|
|
5
5
|
margin-bottom: 0.5rem;
|
|
6
6
|
}
|
|
7
7
|
.group-list-item {
|
|
8
|
-
|
|
9
|
-
font-weight: 400;
|
|
8
|
+
cursor: pointer;
|
|
10
9
|
font-size: 0.889rem;
|
|
10
|
+
font-weight: 400;
|
|
11
|
+
list-style: none;
|
|
11
12
|
margin-top: 0.5rem !important;
|
|
12
|
-
cursor: pointer;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
.group-container {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
.legend-group-item-not-disable {
|
|
24
|
+
border-radius: 1px;
|
|
24
25
|
outline: 1px solid #005ea2;
|
|
25
26
|
outline-offset: 5px;
|
|
26
|
-
border-radius: 1px;
|
|
27
27
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
@import '@cdc/core/styles/
|
|
1
|
+
@import '@cdc/core/styles/utils/breakpoints';
|
|
2
2
|
|
|
3
3
|
.cdc-map-inner-container {
|
|
4
4
|
.map-container.world aside.side {
|
|
@@ -30,8 +30,6 @@
|
|
|
30
30
|
z-index: 1;
|
|
31
31
|
box-sizing: content-box;
|
|
32
32
|
max-width: 450px;
|
|
33
|
-
margin-top: 2em;
|
|
34
|
-
margin-bottom: 2em;
|
|
35
33
|
align-self: flex-start;
|
|
36
34
|
z-index: 4;
|
|
37
35
|
right: 1em;
|
|
@@ -126,6 +124,7 @@
|
|
|
126
124
|
&--pattern {
|
|
127
125
|
cursor: default;
|
|
128
126
|
}
|
|
127
|
+
|
|
129
128
|
&:focus {
|
|
130
129
|
outline: none;
|
|
131
130
|
}
|
|
@@ -47,7 +47,8 @@ const NavigationMenu = ({ data, navigationHandler, options, columns, displayGeoN
|
|
|
47
47
|
const processedDropdown = {}
|
|
48
48
|
|
|
49
49
|
Object.keys(data).forEach(val => {
|
|
50
|
-
const
|
|
50
|
+
const displayOverride = data[val]?.[columns.geo?.displayColumn]
|
|
51
|
+
const fullName = displayGeoName(val, displayOverride)
|
|
51
52
|
|
|
52
53
|
processedDropdown[fullName] = val
|
|
53
54
|
})
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
.small-multiples-container {
|
|
2
|
-
width: 100%;
|
|
3
2
|
display: flex;
|
|
4
3
|
flex-direction: column;
|
|
4
|
+
width: 100%;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
.small-multiples-grid {
|
|
8
8
|
display: grid;
|
|
9
|
-
width: 100%;
|
|
10
9
|
flex: 1;
|
|
10
|
+
width: 100%;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
.small-multiple-tile {
|
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
.tile-title {
|
|
23
|
-
margin: 0;
|
|
24
23
|
font-weight: 700;
|
|
25
|
-
text-align: left;
|
|
26
24
|
line-height: 1.3;
|
|
25
|
+
margin: 0;
|
|
26
|
+
text-align: left;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
.tile-map {
|
|
30
|
-
width: 100%;
|
|
31
30
|
flex-shrink: 0;
|
|
31
|
+
width: 100%;
|
|
32
32
|
}
|
|
@@ -4,6 +4,8 @@ import ConfigContext from '../../../../context'
|
|
|
4
4
|
import { getGeoStrokeColor } from '../../../../helpers/colors'
|
|
5
5
|
import { getStatesPicked } from '../../../../helpers/getStatesPicked'
|
|
6
6
|
|
|
7
|
+
const GRAYED_OUT_COLOR = '#d3d3d3'
|
|
8
|
+
|
|
7
9
|
type StateOutputProps = {
|
|
8
10
|
topoData: Topology
|
|
9
11
|
path: any
|
|
@@ -15,29 +17,42 @@ const StateOutput: React.FC<StateOutputProps> = ({ topoData, path, scale, runtim
|
|
|
15
17
|
const { config } = useContext(ConfigContext)
|
|
16
18
|
if (!topoData?.states) return null
|
|
17
19
|
|
|
18
|
-
// Use filter-aware state selection instead of direct config access
|
|
19
20
|
const statesPickedData = getStatesPicked(config, runtimeData)
|
|
20
21
|
const stateNames = statesPickedData.map(sp => sp.stateName)
|
|
21
22
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
const showUnselected = config.general.hideUnselectedStates === false
|
|
24
|
+
|
|
25
|
+
const selectedStates = topoData.states.filter(s => stateNames.includes(s.properties.name))
|
|
26
|
+
const unselectedStates = showUnselected ? topoData.states.filter(s => !stateNames.includes(s.properties.name)) : []
|
|
25
27
|
|
|
26
28
|
const geoStrokeColor = getGeoStrokeColor(config)
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
30
|
+
return (
|
|
31
|
+
<>
|
|
32
|
+
{unselectedStates.map((s, index) => (
|
|
33
|
+
<g
|
|
34
|
+
key={`unselected-state-${index}`}
|
|
35
|
+
className='single-state unselected'
|
|
36
|
+
style={{ fill: GRAYED_OUT_COLOR, opacity: 0.3, pointerEvents: 'none' }}
|
|
37
|
+
stroke={geoStrokeColor}
|
|
38
|
+
strokeWidth={1 / scale}
|
|
39
|
+
>
|
|
40
|
+
<path tabIndex={-1} className='state-path' d={path(s.geometry)} />
|
|
41
|
+
</g>
|
|
42
|
+
))}
|
|
43
|
+
{selectedStates.map((s, index) => (
|
|
44
|
+
<g
|
|
45
|
+
key={`single-state-${index}`}
|
|
46
|
+
className='single-state'
|
|
47
|
+
style={{ fill: 'transparent', pointerEvents: 'none' }}
|
|
48
|
+
stroke={geoStrokeColor}
|
|
49
|
+
strokeWidth={2 / scale}
|
|
50
|
+
>
|
|
51
|
+
<path tabIndex={-1} className='state-path' d={path(s.geometry)} />
|
|
52
|
+
</g>
|
|
53
|
+
))}
|
|
54
|
+
</>
|
|
55
|
+
)
|
|
41
56
|
}
|
|
42
57
|
|
|
43
58
|
export default StateOutput
|
|
@@ -39,6 +39,7 @@ const TerritoriesSection: React.FC<TerritoriesSectionProps> = ({ territories, lo
|
|
|
39
39
|
})
|
|
40
40
|
|
|
41
41
|
const isMobileViewport = isMobileTerritoryViewport(vizViewport)
|
|
42
|
+
const useCompactTerritorySpacing = isMobileViewport || currentViewport === 'sm' || currentViewport === 'md'
|
|
42
43
|
const SVG_GAP = 9
|
|
43
44
|
const SVG_WIDTH = isMobileViewport ? 30 : 45
|
|
44
45
|
|
|
@@ -59,7 +60,7 @@ const TerritoriesSection: React.FC<TerritoriesSectionProps> = ({ territories, lo
|
|
|
59
60
|
U.S. territories
|
|
60
61
|
</span>
|
|
61
62
|
<span
|
|
62
|
-
className={`${
|
|
63
|
+
className={`${useCompactTerritorySpacing ? 'mt-1 mb-3' : 'mt-2 '} d-flex territories`}
|
|
63
64
|
style={
|
|
64
65
|
{
|
|
65
66
|
minWidth: `${usTerritories.length * SVG_WIDTH + (usTerritories.length - 1) * SVG_GAP}px`,
|
|
@@ -78,7 +79,7 @@ const TerritoriesSection: React.FC<TerritoriesSectionProps> = ({ territories, lo
|
|
|
78
79
|
Freely associated states
|
|
79
80
|
</span>
|
|
80
81
|
<span
|
|
81
|
-
className={`${
|
|
82
|
+
className={`${useCompactTerritorySpacing ? 'mt-1 mb-3' : 'mt-2'} d-flex territories`}
|
|
82
83
|
style={
|
|
83
84
|
{
|
|
84
85
|
minWidth: `${
|
|
@@ -6,7 +6,7 @@ import { patternSizes } from '../../helpers/patternSizes'
|
|
|
6
6
|
import { getContrastColor } from '@cdc/core/helpers/cove/accessibility'
|
|
7
7
|
import { sanitizeToSvgId } from '@cdc/core/helpers/cove/string'
|
|
8
8
|
import { type TerritoryShape } from './TerritoryShape'
|
|
9
|
-
import {
|
|
9
|
+
import { getMatchingPatternForRow } from '../../../../helpers/getMatchingPatternForRow'
|
|
10
10
|
|
|
11
11
|
const TerritoryRectangle: React.FC<TerritoryShape> = ({
|
|
12
12
|
dataTooltipId,
|
|
@@ -73,14 +73,19 @@ const TerritoryRectangle: React.FC<TerritoryShape> = ({
|
|
|
73
73
|
{label}
|
|
74
74
|
</text>
|
|
75
75
|
|
|
76
|
-
{
|
|
76
|
+
{(() => {
|
|
77
|
+
const matchedPattern = getMatchingPatternForRow(territoryData, config.map?.patterns)
|
|
78
|
+
|
|
79
|
+
if (!matchedPattern) {
|
|
80
|
+
return null
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const { pattern: patternData, patternIndex, matchedDataKey } = matchedPattern
|
|
77
84
|
const patternColor = patternData.color || getContrastColor('#FFF', backgroundColor)
|
|
78
|
-
const hasMatchingValues = patternValuesMatch(patternData.dataValue, territoryData?.[patternData.dataKey])
|
|
79
85
|
const sanitizedTerritory = sanitizeToSvgId(territory || label)
|
|
80
|
-
const sanitizedDataKey = sanitizeToSvgId(
|
|
86
|
+
const sanitizedDataKey = sanitizeToSvgId(matchedDataKey)
|
|
81
87
|
const patternId = `${mapId}--territory-${sanitizedTerritory}-${sanitizedDataKey}--${patternIndex}`
|
|
82
88
|
|
|
83
|
-
if (!hasMatchingValues) return null
|
|
84
89
|
if (!patternData.pattern) return null
|
|
85
90
|
|
|
86
91
|
return (
|
|
@@ -123,8 +128,8 @@ const TerritoryRectangle: React.FC<TerritoryShape> = ({
|
|
|
123
128
|
fill={`url(#${patternId})`}
|
|
124
129
|
style={{ pointerEvents: 'none' }}
|
|
125
130
|
className={[
|
|
126
|
-
`territory-pattern-${
|
|
127
|
-
`territory-pattern-${
|
|
131
|
+
`territory-pattern-${matchedDataKey}`,
|
|
132
|
+
`territory-pattern-${matchedDataKey}--${patternData.dataValue}`
|
|
128
133
|
].join(' ')}
|
|
129
134
|
/>
|
|
130
135
|
<text
|
|
@@ -144,7 +149,7 @@ const TerritoryRectangle: React.FC<TerritoryShape> = ({
|
|
|
144
149
|
</text>
|
|
145
150
|
</>
|
|
146
151
|
)
|
|
147
|
-
})}
|
|
152
|
+
})()}
|
|
148
153
|
</g>
|
|
149
154
|
</svg>
|
|
150
155
|
)
|