@cdc/map 4.25.11 → 4.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdcmap.js +29879 -29091
- package/examples/private/city_styles_variable.json +877 -0
- package/examples/private/map-filter-issue.json +2260 -0
- package/examples/private/map-legend.json +5303 -0
- package/index.html +27 -37
- package/package.json +5 -4
- package/src/CdcMapComponent.tsx +42 -6
- package/src/_stories/CdcMap.Editor.stories.tsx +92 -37
- package/src/_stories/CdcMap.stories.tsx +94 -0
- package/src/_stories/_mock/usa-state-gradient.json +1 -0
- package/src/components/CityList.tsx +24 -18
- package/src/components/EditorPanel/components/EditorPanel.tsx +2320 -2212
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +0 -19
- package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.tsx +14 -17
- package/src/components/Legend/components/Legend.tsx +24 -41
- package/src/components/Legend/components/LegendGroup/Legend.Group.tsx +1 -1
- package/src/components/Legend/components/index.scss +22 -5
- package/src/components/UsaMap/components/Territory/Territory.Rectangle.tsx +6 -5
- package/src/components/UsaMap/components/Territory/TerritoryShape.ts +1 -0
- package/src/components/UsaMap/components/UsaMap.County.tsx +2 -2
- package/src/components/UsaMap/components/UsaMap.SingleState.tsx +4 -7
- package/src/components/UsaMap/components/UsaMap.State.tsx +4 -2
- package/src/data/initial-state.js +1 -0
- package/src/helpers/applyLegendToRow.ts +5 -3
- package/src/helpers/constants.ts +2 -0
- package/src/helpers/displayGeoName.ts +8 -5
- package/src/helpers/generateRuntimeFilters.ts +1 -1
- package/src/helpers/generateRuntimeLegend.ts +1 -1
- package/src/helpers/generateRuntimeLegendHash.ts +1 -1
- package/src/helpers/index.ts +9 -3
- package/src/helpers/isLegendItemDisabled.ts +2 -2
- package/src/helpers/resetLegendToggles.ts +1 -0
- package/src/helpers/tests/hashObj.test.ts +1 -1
- package/src/helpers/toggleLegendActive.ts +76 -8
- package/src/hooks/useResizeObserver.ts +3 -0
- package/src/hooks/useStateZoom.tsx +2 -2
- package/src/test/CdcMap.test.jsx +1 -1
- package/src/types/MapConfig.ts +2 -0
- package/src/types/runtimeLegend.ts +1 -0
- package/LICENSE +0 -201
- package/src/components/MapControls.tsx +0 -44
- package/src/helpers/getUniqueValues.ts +0 -19
- package/src/helpers/hashObj.ts +0 -25
- package/src/hooks/useLegendSeparators.ts +0 -26
|
@@ -13,25 +13,6 @@ import { setConfig } from 'dompurify'
|
|
|
13
13
|
|
|
14
14
|
const PanelAnnotate: React.FC = props => {
|
|
15
15
|
const { config, setConfig, dimensions, isDraggingAnnotation } = useContext<MapContext>(ConfigContext)
|
|
16
|
-
const getColumns = (filter = true) => {
|
|
17
|
-
const columns = {}
|
|
18
|
-
config.data.forEach(row => {
|
|
19
|
-
Object.keys(row).forEach(columnName => (columns[columnName] = true))
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
if (filter) {
|
|
23
|
-
Object.keys(columns).forEach(key => {
|
|
24
|
-
if (
|
|
25
|
-
(config.series && config.series.filter(series => series.dataKey === key).length > 0) ||
|
|
26
|
-
(config.confidenceKeys && Object.keys(config.confidenceKeys).includes(key))
|
|
27
|
-
) {
|
|
28
|
-
delete columns[key]
|
|
29
|
-
}
|
|
30
|
-
})
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return Object.keys(columns)
|
|
34
|
-
}
|
|
35
16
|
|
|
36
17
|
const handleAnnotationUpdate = (value, property, index) => {
|
|
37
18
|
const annotations = [...config?.annotations]
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { TextField, Select, CheckBox } from '@cdc/core/components/EditorPanel/Inputs'
|
|
12
12
|
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
13
13
|
import Icon from '@cdc/core/components/ui/Icon'
|
|
14
|
+
import { useDataColumns } from '@cdc/core/hooks/useDataColumns'
|
|
14
15
|
|
|
15
16
|
// contexts
|
|
16
17
|
import ConfigContext from '../../../../context'
|
|
@@ -25,22 +26,11 @@ const PanelSmallMultiples: FC<PanelSmallMultiplesProps> = props => {
|
|
|
25
26
|
const { config, setConfig } = useContext<MapContext>(ConfigContext)
|
|
26
27
|
const { general } = config
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// Filter out geo and primary columns
|
|
35
|
-
if (config.columns?.geo?.name) {
|
|
36
|
-
delete columns[config.columns.geo.name]
|
|
37
|
-
}
|
|
38
|
-
if (config.columns?.primary?.name) {
|
|
39
|
-
delete columns[config.columns.primary.name]
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return Object.keys(columns)
|
|
43
|
-
}
|
|
29
|
+
// Extract column names from data with memoization (replaces getColumns)
|
|
30
|
+
// Filter out geo and primary columns
|
|
31
|
+
const columns = useDataColumns(config.data, {
|
|
32
|
+
excludeColumns: [config.columns?.geo?.name, config.columns?.primary?.name].filter(Boolean)
|
|
33
|
+
})
|
|
44
34
|
|
|
45
35
|
const updateField = (section, subsection, fieldName, value) => {
|
|
46
36
|
const newConfig = { ...config }
|
|
@@ -82,6 +72,11 @@ const PanelSmallMultiples: FC<PanelSmallMultiplesProps> = props => {
|
|
|
82
72
|
setConfig(newConfig)
|
|
83
73
|
}
|
|
84
74
|
|
|
75
|
+
// Small multiples only supported for us, single-state, and us-region map types
|
|
76
|
+
if (!['us', 'single-state', 'us-region'].includes(general.geoType)) {
|
|
77
|
+
return null
|
|
78
|
+
}
|
|
79
|
+
|
|
85
80
|
return (
|
|
86
81
|
<AccordionItem>
|
|
87
82
|
<AccordionItemHeading>
|
|
@@ -95,7 +90,7 @@ const PanelSmallMultiples: FC<PanelSmallMultiplesProps> = props => {
|
|
|
95
90
|
label='Tile By Column'
|
|
96
91
|
initial='Select Column'
|
|
97
92
|
updateField={handleColumnChange}
|
|
98
|
-
options={
|
|
93
|
+
options={columns}
|
|
99
94
|
tooltip={
|
|
100
95
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
101
96
|
<Tooltip.Target>
|
|
@@ -199,6 +194,8 @@ const PanelSmallMultiples: FC<PanelSmallMultiplesProps> = props => {
|
|
|
199
194
|
value={currentOrderType}
|
|
200
195
|
options={tileOrderOptions}
|
|
201
196
|
label='Tile Order'
|
|
197
|
+
fieldName='tileOrderType'
|
|
198
|
+
section='smallMultiples'
|
|
202
199
|
updateField={(_section, _subsection, _fieldName, value) => {
|
|
203
200
|
handleOrderTypeChange(value)
|
|
204
201
|
}}
|
|
@@ -99,6 +99,7 @@ const Legend = forwardRef<HTMLDivElement, LegendProps>((props, ref) => {
|
|
|
99
99
|
color: entry.color,
|
|
100
100
|
label: parse(legendLabel),
|
|
101
101
|
disabled: entry.disabled,
|
|
102
|
+
hidden: entry.hidden,
|
|
102
103
|
special: entry.hasOwnProperty('special'),
|
|
103
104
|
value: [entry.min, entry.max]
|
|
104
105
|
}
|
|
@@ -111,56 +112,40 @@ const Legend = forwardRef<HTMLDivElement, LegendProps>((props, ref) => {
|
|
|
111
112
|
|
|
112
113
|
const legendList = (patternsOnly = false) => {
|
|
113
114
|
const formattedItems = patternsOnly ? [] : getFormattedLegendItems()
|
|
114
|
-
const
|
|
115
|
-
const hasDisabledItems = formattedItems.some(item => item.disabled)
|
|
115
|
+
const hasDisabledItems = runtimeLegend.disabledAmt > 0
|
|
116
116
|
let legendItems
|
|
117
117
|
|
|
118
118
|
legendItems = formattedItems.map((item, idx) => {
|
|
119
119
|
const handleListItemClass = () => {
|
|
120
120
|
let classes = ['legend-container__li', 'd-flex', 'align-items-center']
|
|
121
|
-
if (item.disabled) classes.push('legend-container__li--disabled')
|
|
121
|
+
if (item.disabled || item.hidden) classes.push('legend-container__li--disabled')
|
|
122
122
|
else if (hasDisabledItems) classes.push('legend-container__li--not-disabled')
|
|
123
123
|
if (item.special) classes.push('legend-container__li--special-class')
|
|
124
124
|
return classes.join(' ')
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
return (
|
|
128
|
-
<li
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
vizType: config.type,
|
|
136
|
-
vizSubType: getVizSubType(config),
|
|
137
|
-
eventType: `map_legend_item_toggled`,
|
|
138
|
-
eventAction: 'click',
|
|
139
|
-
eventLabel: `${interactionLabel}`,
|
|
140
|
-
vizTitle: getVizTitle(config),
|
|
141
|
-
specifics: `mode: isolate, label: ${item.label}`
|
|
142
|
-
})
|
|
143
|
-
}}
|
|
144
|
-
onKeyDown={e => {
|
|
145
|
-
if (e.key === 'Enter') {
|
|
146
|
-
e.preventDefault()
|
|
147
|
-
toggleLegendActive(idx, item.label, runtimeLegend, dispatch)
|
|
128
|
+
<li className={handleListItemClass()} key={idx}>
|
|
129
|
+
<button
|
|
130
|
+
type='button'
|
|
131
|
+
className='legend-container__li-btn'
|
|
132
|
+
title={`Legend item ${item.label} - Click to disable`}
|
|
133
|
+
onClick={() => {
|
|
134
|
+
toggleLegendActive(idx, item.label, runtimeLegend, dispatch, config.legend.behavior)
|
|
148
135
|
publishAnalyticsEvent({
|
|
149
136
|
vizType: config.type,
|
|
150
137
|
vizSubType: getVizSubType(config),
|
|
151
138
|
eventType: `map_legend_item_toggled`,
|
|
152
|
-
eventAction: '
|
|
139
|
+
eventAction: 'click',
|
|
153
140
|
eventLabel: `${interactionLabel}`,
|
|
154
141
|
vizTitle: getVizTitle(config),
|
|
155
142
|
specifics: `mode: isolate, label: ${item.label}`
|
|
156
143
|
})
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
<LegendShape shape={config.legend.style === 'boxes' ? 'square' : 'circle'} fill={item.color} />
|
|
163
|
-
<span>{item.label}</span>
|
|
144
|
+
}}
|
|
145
|
+
>
|
|
146
|
+
<LegendShape shape={config.legend.style === 'boxes' ? 'square' : 'circle'} fill={item.color} />
|
|
147
|
+
<span>{item.label}</span>
|
|
148
|
+
</button>
|
|
164
149
|
</li>
|
|
165
150
|
)
|
|
166
151
|
})
|
|
@@ -180,12 +165,12 @@ const Legend = forwardRef<HTMLDivElement, LegendProps>((props, ref) => {
|
|
|
180
165
|
|
|
181
166
|
legendItems.push(
|
|
182
167
|
<>
|
|
183
|
-
<li
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
168
|
+
<li className={`legend-container__li legend-container__li--geo-pattern`}>
|
|
169
|
+
<button
|
|
170
|
+
type='button'
|
|
171
|
+
className='legend-container__li-btn legend-container__li-btn--pattern'
|
|
172
|
+
aria-label='Pattern legend item. Toggling patterns is not currently supported.'
|
|
173
|
+
>
|
|
189
174
|
<svg width={legendSize} height={legendSize}>
|
|
190
175
|
{pattern === 'waves' && (
|
|
191
176
|
<PatternWaves
|
|
@@ -225,10 +210,8 @@ const Legend = forwardRef<HTMLDivElement, LegendProps>((props, ref) => {
|
|
|
225
210
|
strokeWidth={1}
|
|
226
211
|
/>
|
|
227
212
|
</svg>
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
{patternData.label || patternData.dataValue || ''}
|
|
231
|
-
</p>
|
|
213
|
+
<span>{patternData.label || patternData.dataValue || ''}</span>
|
|
214
|
+
</button>
|
|
232
215
|
</li>
|
|
233
216
|
</>
|
|
234
217
|
)
|
|
@@ -112,7 +112,7 @@ const LegendGroup = ({ legendItems }) => {
|
|
|
112
112
|
onKeyDown={e => {
|
|
113
113
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
114
114
|
e.preventDefault()
|
|
115
|
-
toggleLegendActive(index, item.label, runtimeLegend, dispatch)
|
|
115
|
+
toggleLegendActive(index, item.label, runtimeLegend, dispatch, config.legend.behavior)
|
|
116
116
|
}
|
|
117
117
|
}}
|
|
118
118
|
>
|
|
@@ -103,11 +103,33 @@
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
.legend-container__ul {
|
|
106
|
+
list-style: none;
|
|
106
107
|
line-height: 1;
|
|
107
108
|
row-gap: var(--space-between-legend-item-rows);
|
|
108
109
|
column-gap: var(--space-between-legend-item-columns);
|
|
109
110
|
}
|
|
110
111
|
|
|
112
|
+
.legend-container__li-btn {
|
|
113
|
+
display: flex;
|
|
114
|
+
align-items: center;
|
|
115
|
+
gap: 0.5em;
|
|
116
|
+
width: 100%;
|
|
117
|
+
background: none;
|
|
118
|
+
border: none;
|
|
119
|
+
padding: 0;
|
|
120
|
+
margin: 0;
|
|
121
|
+
font: inherit;
|
|
122
|
+
color: inherit;
|
|
123
|
+
cursor: pointer;
|
|
124
|
+
text-align: left;
|
|
125
|
+
|
|
126
|
+
&--pattern {
|
|
127
|
+
cursor: default;
|
|
128
|
+
}
|
|
129
|
+
&:focus {
|
|
130
|
+
outline: none;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
111
133
|
|
|
112
134
|
.legend-container__ul:not(.single-row, .legend-container__ul--single-column) {
|
|
113
135
|
list-style: none;
|
|
@@ -118,11 +140,6 @@
|
|
|
118
140
|
grid-template-columns: 1fr 1fr;
|
|
119
141
|
}
|
|
120
142
|
|
|
121
|
-
button {
|
|
122
|
-
font-size: unset;
|
|
123
|
-
background: transparent;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
143
|
&.vertical-sorted {
|
|
127
144
|
// Remove the grid overrides - let the existing column rules handle this
|
|
128
145
|
display: block !important; // Switch from grid to block to enable columns
|
|
@@ -18,6 +18,7 @@ const TerritoryRectangle: React.FC<TerritoryShape> = ({
|
|
|
18
18
|
territory,
|
|
19
19
|
textColor,
|
|
20
20
|
backgroundColor,
|
|
21
|
+
mapId,
|
|
21
22
|
svgStyle,
|
|
22
23
|
getSyncProps,
|
|
23
24
|
syncHandlers,
|
|
@@ -70,7 +71,7 @@ const TerritoryRectangle: React.FC<TerritoryShape> = ({
|
|
|
70
71
|
{label}
|
|
71
72
|
</text>
|
|
72
73
|
|
|
73
|
-
{config.map
|
|
74
|
+
{config.map?.patterns?.map((patternData, patternIndex) => {
|
|
74
75
|
const patternColor = patternData.color || getContrastColor('#FFF', backgroundColor)
|
|
75
76
|
const hasMatchingValues = patternData.dataValue === territoryData?.[patternData.dataKey]
|
|
76
77
|
|
|
@@ -81,7 +82,7 @@ const TerritoryRectangle: React.FC<TerritoryShape> = ({
|
|
|
81
82
|
<>
|
|
82
83
|
{patternData?.pattern === 'waves' && (
|
|
83
84
|
<PatternWaves
|
|
84
|
-
id={
|
|
85
|
+
id={`${mapId}--territory-${territory}-${patternData?.dataKey}--${patternIndex}`}
|
|
85
86
|
height={patternSizes[patternData?.size] ?? 10}
|
|
86
87
|
width={patternSizes[patternData?.size] ?? 10}
|
|
87
88
|
fill={patternColor}
|
|
@@ -91,7 +92,7 @@ const TerritoryRectangle: React.FC<TerritoryShape> = ({
|
|
|
91
92
|
)}
|
|
92
93
|
{patternData?.pattern === 'circles' && (
|
|
93
94
|
<PatternCircles
|
|
94
|
-
id={
|
|
95
|
+
id={`${mapId}--territory-${territory}-${patternData?.dataKey}--${patternIndex}`}
|
|
95
96
|
height={patternSizes[patternData?.size] ?? 10}
|
|
96
97
|
width={patternSizes[patternData?.size] ?? 10}
|
|
97
98
|
fill={patternColor}
|
|
@@ -102,7 +103,7 @@ const TerritoryRectangle: React.FC<TerritoryShape> = ({
|
|
|
102
103
|
)}
|
|
103
104
|
{patternData?.pattern === 'lines' && (
|
|
104
105
|
<PatternLines
|
|
105
|
-
id={
|
|
106
|
+
id={`${mapId}--territory-${territory}-${patternData?.dataKey}--${patternIndex}`}
|
|
106
107
|
height={patternSizes[patternData?.size] ?? 6}
|
|
107
108
|
width={patternSizes[patternData?.size] ?? 6}
|
|
108
109
|
stroke={patternColor}
|
|
@@ -114,7 +115,7 @@ const TerritoryRectangle: React.FC<TerritoryShape> = ({
|
|
|
114
115
|
stroke={stroke}
|
|
115
116
|
strokeWidth={strokeWidth}
|
|
116
117
|
d={rectanglePath}
|
|
117
|
-
fill={`url(
|
|
118
|
+
fill={`url(#${mapId}--territory-${territory}-${patternData?.dataKey}--${patternIndex})`}
|
|
118
119
|
style={{ pointerEvents: 'none' }}
|
|
119
120
|
className={[
|
|
120
121
|
`territory-pattern-${patternData?.dataKey}`,
|
|
@@ -15,7 +15,7 @@ import useGeoClickHandler from '../../../hooks/useGeoClickHandler'
|
|
|
15
15
|
import { applyLegendToRow } from '../../../helpers/applyLegendToRow'
|
|
16
16
|
import useApplyTooltipsToGeo from '../../../hooks/useApplyTooltipsToGeo'
|
|
17
17
|
import { MapConfig } from '../../../types/MapConfig'
|
|
18
|
-
import { DEFAULT_MAP_BACKGROUND } from '../../../helpers/constants'
|
|
18
|
+
import { DEFAULT_MAP_BACKGROUND, DISABLED_MAP_COLOR } from '../../../helpers/constants'
|
|
19
19
|
import { publishAnalyticsEvent } from '@cdc/core/helpers/metrics/helpers'
|
|
20
20
|
import { getVizTitle, getVizSubType } from '@cdc/core/helpers/metrics/utils'
|
|
21
21
|
|
|
@@ -708,7 +708,7 @@ const CountyMap = () => {
|
|
|
708
708
|
? applyLegendToRow(runtimeData[key], config, runtimeLegend, legendMemo, legendSpecialClassLastMemo)
|
|
709
709
|
: false
|
|
710
710
|
if (legendValues) {
|
|
711
|
-
if (legendValues?.[0] === '#000000' || legendValues?.[0] ===
|
|
711
|
+
if (legendValues?.[0] === '#000000' || legendValues?.[0] === DISABLED_MAP_COLOR) return
|
|
712
712
|
const shapeType = config.visual.cityStyle.toLowerCase()
|
|
713
713
|
const shapeProperties = createShapeProperties(shapeType, pixelCoords, legendValues, config, geoRadius)
|
|
714
714
|
if (shapeProperties) {
|
|
@@ -58,9 +58,6 @@ const SingleStateMap: React.FC = () => {
|
|
|
58
58
|
|
|
59
59
|
const { geoClickHandler } = useGeoClickHandler()
|
|
60
60
|
|
|
61
|
-
const cityListProjection = geoAlbersUsaTerritories()
|
|
62
|
-
.translate([SVG_WIDTH / 2, SVG_HEIGHT / 2])
|
|
63
|
-
.scale(1)
|
|
64
61
|
const geoStrokeColor = getGeoStrokeColor(config)
|
|
65
62
|
const path = geoPath().projection(projection)
|
|
66
63
|
|
|
@@ -132,10 +129,10 @@ const SingleStateMap: React.FC = () => {
|
|
|
132
129
|
/>
|
|
133
130
|
)
|
|
134
131
|
|
|
135
|
-
// Push city list
|
|
132
|
+
// Push city list - use projection from useStateZoom which is fitted to ALL selected states
|
|
136
133
|
geosJsx.push(
|
|
137
134
|
<CityList
|
|
138
|
-
projection={
|
|
135
|
+
projection={projection}
|
|
139
136
|
key='cities'
|
|
140
137
|
geoClickHandler={geoClickHandler}
|
|
141
138
|
titleCase={titleCase}
|
|
@@ -192,7 +189,7 @@ const SingleStateMap: React.FC = () => {
|
|
|
192
189
|
statesToShow
|
|
193
190
|
]}
|
|
194
191
|
>
|
|
195
|
-
{({ features
|
|
192
|
+
{({ features }) => {
|
|
196
193
|
return (
|
|
197
194
|
<g
|
|
198
195
|
id='mapGroup'
|
|
@@ -203,7 +200,7 @@ const SingleStateMap: React.FC = () => {
|
|
|
203
200
|
data-scale=''
|
|
204
201
|
key='countyMapGroup'
|
|
205
202
|
>
|
|
206
|
-
{constructGeoJsx(features
|
|
203
|
+
{constructGeoJsx(features)}
|
|
207
204
|
</g>
|
|
208
205
|
)
|
|
209
206
|
}}
|
|
@@ -44,9 +44,9 @@ import {
|
|
|
44
44
|
displayGeoName,
|
|
45
45
|
SVG_HEIGHT,
|
|
46
46
|
SVG_VIEWBOX,
|
|
47
|
-
SVG_WIDTH
|
|
48
|
-
hashObj
|
|
47
|
+
SVG_WIDTH
|
|
49
48
|
} from '../../../helpers'
|
|
49
|
+
import { hashObj } from '@cdc/core/helpers/hashObj'
|
|
50
50
|
const { features: unitedStatesHex } = topoFeature(hexTopoJSON, hexTopoJSON.objects.states)
|
|
51
51
|
|
|
52
52
|
const offsets = {
|
|
@@ -200,6 +200,7 @@ const UsaMap = () => {
|
|
|
200
200
|
strokeColor='#fff'
|
|
201
201
|
territoryData={territoryData}
|
|
202
202
|
backgroundColor={styles.fill}
|
|
203
|
+
mapId={mapId}
|
|
203
204
|
getSyncProps={getSyncProps}
|
|
204
205
|
syncHandlers={syncHandlers}
|
|
205
206
|
/>
|
|
@@ -254,6 +255,7 @@ const UsaMap = () => {
|
|
|
254
255
|
territoryData={territoryData}
|
|
255
256
|
tabIndex={-1}
|
|
256
257
|
backgroundColor={styles.fill}
|
|
258
|
+
mapId={mapId}
|
|
257
259
|
getSyncProps={getSyncProps}
|
|
258
260
|
syncHandlers={syncHandlers}
|
|
259
261
|
/>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { generateColorsArray } from '@cdc/core/helpers/generateColorsArray'
|
|
2
|
-
import { hashObj
|
|
2
|
+
import { hashObj } from '@cdc/core/helpers/hashObj'
|
|
3
|
+
import { DEFAULT_MAP_BACKGROUND, DISABLED_MAP_COLOR } from '../helpers'
|
|
3
4
|
import { mapColorPalettes as colorPalettes } from '@cdc/core/data/colorPalettes'
|
|
4
5
|
import { MapConfig } from '../types/MapConfig'
|
|
5
6
|
import { type RuntimeLegend } from '../types/runtimeLegend'
|
|
@@ -42,8 +43,9 @@ export const applyLegendToRow = (
|
|
|
42
43
|
const idx = legendMemo.current.get(hash)!
|
|
43
44
|
const disabledIdx = showSpecialClassesLast ? legendSpecialClassLastMemo.current.get(hash) ?? idx : idx
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
// Note: DISABLED_MAP_COLOR is used in UsaMap.County.tsx to check for hidden bubbles. Should be refactored to use the hidden value when that is implemented.
|
|
47
|
+
if (runtimeLegend.items?.[disabledIdx]?.disabled || runtimeLegend.items?.[disabledIdx]?.hidden) {
|
|
48
|
+
return generateColorsArray(DISABLED_MAP_COLOR)
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
const legendBinColor = runtimeLegend.items.find(o => o.bin === idx)?.color
|
package/src/helpers/constants.ts
CHANGED
|
@@ -48,16 +48,14 @@ export const displayGeoName = (key: string, convertFipsCodes = true): string =>
|
|
|
48
48
|
wasLookedUp = true
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
value = titleCase(String(value) || '')
|
|
53
|
-
wasLookedUp = true
|
|
54
|
-
}
|
|
55
|
-
|
|
51
|
+
// Check dictionary replacements before city lookup to handle special cases like DC
|
|
56
52
|
const dict = {
|
|
57
53
|
'Washington D.C.': 'District of Columbia',
|
|
58
54
|
'WASHINGTON DC': 'District of Columbia',
|
|
59
55
|
DC: 'District of Columbia',
|
|
60
56
|
'WASHINGTON DC.': 'District of Columbia',
|
|
57
|
+
'DISTRICT OF COLUMBIA': 'District of Columbia',
|
|
58
|
+
Dc: 'District of Columbia',
|
|
61
59
|
Congo: 'Republic of the Congo'
|
|
62
60
|
}
|
|
63
61
|
|
|
@@ -66,6 +64,11 @@ export const displayGeoName = (key: string, convertFipsCodes = true): string =>
|
|
|
66
64
|
wasLookedUp = true
|
|
67
65
|
}
|
|
68
66
|
|
|
67
|
+
if (cityKeys.includes(value)) {
|
|
68
|
+
value = titleCase(String(value) || '')
|
|
69
|
+
wasLookedUp = true
|
|
70
|
+
}
|
|
71
|
+
|
|
69
72
|
// If value was looked up from our dictionaries and needs formatting, or if it's a 2-letter abbreviation, return as-is
|
|
70
73
|
if (value?.length === 2 || value === 'U.S. Virgin Islands' || wasLookedUp) {
|
|
71
74
|
return value
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
addUIDs,
|
|
5
5
|
applyColorToLegend,
|
|
6
6
|
getGeoFillColor,
|
|
7
|
-
hashObj,
|
|
8
7
|
indexOfIgnoreType,
|
|
9
8
|
setBinNumbers,
|
|
10
9
|
sortSpecialClassesLast
|
|
11
10
|
} from '.'
|
|
11
|
+
import { hashObj } from '@cdc/core/helpers/hashObj'
|
|
12
12
|
|
|
13
13
|
import _ from 'lodash'
|
|
14
14
|
import * as d3 from 'd3'
|
package/src/helpers/index.ts
CHANGED
|
@@ -5,10 +5,8 @@ export { formatLegendLocation } from './formatLegendLocation'
|
|
|
5
5
|
export { generateColorsArray } from '@cdc/core/helpers/generateColorsArray'
|
|
6
6
|
export { generateRuntimeLegendHash } from './generateRuntimeLegendHash'
|
|
7
7
|
export { getGeoStrokeColor, getGeoFillColor } from './colors'
|
|
8
|
-
export { getUniqueValues } from './getUniqueValues'
|
|
9
8
|
export { handleMapAriaLabels } from './handleMapAriaLabels'
|
|
10
9
|
export { handleMapTabbing } from './handleMapTabbing'
|
|
11
|
-
export { hashObj } from './hashObj'
|
|
12
10
|
export { indexOfIgnoreType } from './indexOfIgnoreType'
|
|
13
11
|
export { isLegendItemDisabled } from './isLegendItemDisabled'
|
|
14
12
|
export { navigationHandler } from './navigationHandler'
|
|
@@ -19,4 +17,12 @@ export { titleCase as toTitleCase } from './toTitleCase'
|
|
|
19
17
|
export { titleCase } from './titleCase'
|
|
20
18
|
export { validateFipsCodeLength } from './validateFipsCodeLength'
|
|
21
19
|
export { getMapContainerClasses } from './getMapContainerClasses'
|
|
22
|
-
export {
|
|
20
|
+
export {
|
|
21
|
+
SVG_HEIGHT,
|
|
22
|
+
SVG_WIDTH,
|
|
23
|
+
SVG_PADDING,
|
|
24
|
+
SVG_VIEWBOX,
|
|
25
|
+
MAX_ZOOM_LEVEL,
|
|
26
|
+
DEFAULT_MAP_BACKGROUND,
|
|
27
|
+
DISABLED_MAP_COLOR
|
|
28
|
+
} from './constants'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { hashObj } from '
|
|
1
|
+
import { hashObj } from '@cdc/core/helpers/hashObj'
|
|
2
2
|
|
|
3
3
|
export const isLegendItemDisabled = (
|
|
4
4
|
dataForCheck: any,
|
|
@@ -12,5 +12,5 @@ export const isLegendItemDisabled = (
|
|
|
12
12
|
if (!legendMemo.current.has(hash)) return false
|
|
13
13
|
const idx = legendMemo.current.get(hash)
|
|
14
14
|
const disabledIdx = config.legend.showSpecialClassesLast ? legendSpecialClassLastMemo.current.get(hash) ?? idx : idx
|
|
15
|
-
return runtimeLegend.items[disabledIdx]?.disabled || false
|
|
15
|
+
return runtimeLegend.items[disabledIdx]?.disabled || runtimeLegend.items[disabledIdx]?.hidden || false
|
|
16
16
|
}
|