@cdc/map 4.24.10 → 4.24.12
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 +27324 -27152
- package/examples/default-geocode.json +13 -4
- package/examples/default-usa-regions.json +267 -117
- package/examples/example-city-state.json +6 -3
- package/examples/pattern.json +861 -0
- package/examples/private/DEV-9644.json +184 -0
- package/examples/private/default-patterns.json +867 -0
- package/index.html +4 -5
- package/package.json +3 -3
- package/src/CdcMap.tsx +53 -52
- package/src/_stories/CdcMap.Legend.Gradient.stories.tsx +67 -0
- package/src/_stories/CdcMap.Legend.stories.tsx +40 -0
- package/src/_stories/CdcMap.Patterns.stories.tsx +29 -0
- package/src/_stories/CdcMap.stories.tsx +59 -0
- package/src/_stories/UsaMap.NoData.stories.tsx +19 -0
- package/src/_stories/_mock/custom-layer-map.json +1117 -0
- package/src/_stories/_mock/default-patterns.json +865 -0
- package/src/_stories/_mock/example-city-state.json +858 -0
- package/src/_stories/_mock/usa-state-gradient.json +238 -0
- package/src/_stories/_mock/wastewater-map.json +208 -0
- package/src/components/CityList.tsx +5 -2
- package/src/components/EditorPanel/components/EditorPanel.tsx +81 -61
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +27 -23
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +75 -16
- package/src/components/Legend/components/Legend.tsx +42 -20
- package/src/components/Legend/components/index.scss +24 -24
- package/src/components/UsaMap/components/HexIcon.tsx +7 -1
- package/src/components/UsaMap/components/SingleState/SingleState.CountyOutput.tsx +40 -6
- package/src/components/UsaMap/components/SingleState/SingleState.StateOutput.tsx +10 -2
- package/src/components/UsaMap/components/Territory/Territory.Hexagon.tsx +57 -12
- package/src/components/UsaMap/components/Territory/Territory.Rectangle.tsx +95 -21
- package/src/components/UsaMap/components/Territory/TerritoryShape.ts +13 -0
- package/src/components/UsaMap/components/UsaMap.County.tsx +11 -13
- package/src/components/UsaMap/components/UsaMap.Region.tsx +59 -16
- package/src/components/UsaMap/components/UsaMap.SingleState.tsx +2 -1
- package/src/components/UsaMap/components/UsaMap.State.tsx +60 -62
- package/src/components/UsaMap/helpers/shapes.ts +5 -4
- package/src/components/WorldMap/WorldMap.tsx +77 -16
- package/src/data/initial-state.js +2 -1
- package/src/helpers/applyColorToLegend.ts +80 -0
- package/src/helpers/colors.ts +23 -0
- package/src/hooks/useTooltip.ts +9 -6
- package/src/scss/editor-panel.scss +0 -3
- package/src/scss/filters.scss +1 -9
- package/src/scss/main.scss +0 -5
- package/src/scss/map.scss +11 -63
- package/src/types/MapConfig.ts +6 -1
- package/src/types/MapContext.ts +1 -0
- package/examples/default-patterns.json +0 -579
- package/src/scss/datatable.scss +0 -6
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
drawShape,
|
|
22
22
|
createShapeProperties
|
|
23
23
|
} from '../helpers/shapes'
|
|
24
|
+
import { getGeoStrokeColor } from '../../../helpers/colors'
|
|
24
25
|
|
|
25
26
|
const getCountyTopoURL = year => {
|
|
26
27
|
return `https://www.cdc.gov/TemplatePackage/contrib/data/county-topography/cb_${year}_us_county_20m.json`
|
|
@@ -131,22 +132,23 @@ const CountyMap = props => {
|
|
|
131
132
|
const {
|
|
132
133
|
applyLegendToRow,
|
|
133
134
|
applyTooltipsToGeo,
|
|
135
|
+
container,
|
|
134
136
|
containerEl,
|
|
135
137
|
data,
|
|
136
138
|
displayGeoName,
|
|
137
139
|
geoClickHandler,
|
|
138
140
|
handleMapAriaLabels,
|
|
141
|
+
runtimeFilters,
|
|
139
142
|
runtimeLegend,
|
|
143
|
+
setState,
|
|
140
144
|
state,
|
|
141
|
-
runtimeFilters,
|
|
142
145
|
tooltipId,
|
|
143
146
|
tooltipRef,
|
|
144
|
-
container,
|
|
145
|
-
setState
|
|
146
147
|
} = useContext(ConfigContext)
|
|
147
148
|
|
|
148
149
|
// CREATE STATE LINES
|
|
149
150
|
const projection = geoAlbersUsaTerritories()
|
|
151
|
+
const geoStrokeColor = getGeoStrokeColor(state)
|
|
150
152
|
|
|
151
153
|
const [focus, setFocus] = useState({})
|
|
152
154
|
const [topoData, setTopoData] = useState({})
|
|
@@ -210,9 +212,7 @@ const CountyMap = props => {
|
|
|
210
212
|
}
|
|
211
213
|
|
|
212
214
|
const runtimeKeys = Object.keys(data)
|
|
213
|
-
|
|
214
|
-
const geoStrokeColor = state.general.geoBorderColor === 'darkGray' ? 'rgb(90, 90, 90)' : 'rgb(255, 255, 255)'
|
|
215
|
-
const lineWidth = 0.3
|
|
215
|
+
const lineWidth = 1
|
|
216
216
|
|
|
217
217
|
const onReset = () => {
|
|
218
218
|
setState({
|
|
@@ -449,7 +449,7 @@ const CountyMap = props => {
|
|
|
449
449
|
}
|
|
450
450
|
|
|
451
451
|
if (focus.index !== -1) {
|
|
452
|
-
context.strokeStyle =
|
|
452
|
+
context.strokeStyle = geoStrokeColor
|
|
453
453
|
context.lineWidth = 1
|
|
454
454
|
context.beginPath()
|
|
455
455
|
path(topoData.mapData[focus.index])
|
|
@@ -493,7 +493,6 @@ const CountyMap = props => {
|
|
|
493
493
|
|
|
494
494
|
// Enforces stroke style of the county lines
|
|
495
495
|
context.strokeStyle = geoStrokeColor
|
|
496
|
-
context.lineWidth = lineWidth
|
|
497
496
|
|
|
498
497
|
// Iterates through each state/county topo and renders it
|
|
499
498
|
topoData.mapData.forEach((geo, i) => {
|
|
@@ -518,7 +517,7 @@ const CountyMap = props => {
|
|
|
518
517
|
|
|
519
518
|
// If the focused state is found in the geo data, render it with a thicker outline
|
|
520
519
|
if (focus.index !== -1) {
|
|
521
|
-
context.strokeStyle =
|
|
520
|
+
context.strokeStyle = geoStrokeColor
|
|
522
521
|
context.lineWidth = 2
|
|
523
522
|
context.beginPath()
|
|
524
523
|
path(topoData.mapData[focus.index])
|
|
@@ -531,8 +530,7 @@ const CountyMap = props => {
|
|
|
531
530
|
context.beginPath()
|
|
532
531
|
path(layer)
|
|
533
532
|
context.fillStyle = layer.properties.fill
|
|
534
|
-
context.
|
|
535
|
-
context.strokeStyle = layer.properties['stroke']
|
|
533
|
+
context.strokeStyle = geoStrokeColor
|
|
536
534
|
context.lineWidth = layer.properties['stroke-width']
|
|
537
535
|
context.fill()
|
|
538
536
|
context.stroke()
|
|
@@ -540,7 +538,7 @@ const CountyMap = props => {
|
|
|
540
538
|
}
|
|
541
539
|
|
|
542
540
|
if (state.general.type === 'us-geocode') {
|
|
543
|
-
context.strokeStyle =
|
|
541
|
+
context.strokeStyle = geoStrokeColor
|
|
544
542
|
const geoRadius = (state.visual.geoCodeCircleSize || 5) * (focus.id ? 2 : 1)
|
|
545
543
|
const { additionalCityStyles } = state.visual || []
|
|
546
544
|
const cityStyles = Object.values(data)
|
|
@@ -604,7 +602,7 @@ const CountyMap = props => {
|
|
|
604
602
|
className='county-map-canvas'
|
|
605
603
|
></canvas>
|
|
606
604
|
|
|
607
|
-
<button className={`btn btn--reset`} onClick={onReset} ref={resetButton} tabIndex='0'>
|
|
605
|
+
<button className={`btn btn--reset btn-primary`} onClick={onReset} ref={resetButton} tabIndex='0'>
|
|
608
606
|
Reset Zoom
|
|
609
607
|
</button>
|
|
610
608
|
</ErrorBoundary>
|
|
@@ -11,6 +11,7 @@ import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
|
|
|
11
11
|
import topoJSON from '../data/us-regions-topo-2.json'
|
|
12
12
|
import ConfigContext from '../../../context'
|
|
13
13
|
import Annotation from '../../Annotation'
|
|
14
|
+
import { getGeoFillColor, getGeoStrokeColor } from '../../../helpers/colors'
|
|
14
15
|
|
|
15
16
|
const { features: unitedStates } = feature(topoJSON, topoJSON.objects.regions)
|
|
16
17
|
|
|
@@ -69,7 +70,8 @@ const UsaRegionMap = props => {
|
|
|
69
70
|
setTerritoriesData(territoriesList)
|
|
70
71
|
}, [data])
|
|
71
72
|
|
|
72
|
-
const geoStrokeColor = state
|
|
73
|
+
const geoStrokeColor = getGeoStrokeColor(state)
|
|
74
|
+
const geoFillColor = getGeoFillColor(state)
|
|
73
75
|
|
|
74
76
|
const territories = territoriesData.map(territory => {
|
|
75
77
|
const Shape = Rect
|
|
@@ -79,7 +81,7 @@ const UsaRegionMap = props => {
|
|
|
79
81
|
let toolTip
|
|
80
82
|
|
|
81
83
|
let styles: React.CSSProperties = {
|
|
82
|
-
fill:
|
|
84
|
+
fill: geoFillColor,
|
|
83
85
|
color: '#202020'
|
|
84
86
|
}
|
|
85
87
|
|
|
@@ -97,7 +99,10 @@ const UsaRegionMap = props => {
|
|
|
97
99
|
let needsPointer = false
|
|
98
100
|
|
|
99
101
|
// If we need to add a pointer cursor
|
|
100
|
-
if (
|
|
102
|
+
if (
|
|
103
|
+
(state.columns.navigate && territoryData[state.columns.navigate.name]) ||
|
|
104
|
+
state.tooltips.appearanceType === 'click'
|
|
105
|
+
) {
|
|
101
106
|
needsPointer = true
|
|
102
107
|
}
|
|
103
108
|
|
|
@@ -113,7 +118,19 @@ const UsaRegionMap = props => {
|
|
|
113
118
|
}
|
|
114
119
|
}
|
|
115
120
|
|
|
116
|
-
return
|
|
121
|
+
return (
|
|
122
|
+
<Shape
|
|
123
|
+
key={label}
|
|
124
|
+
label={label}
|
|
125
|
+
css={styles}
|
|
126
|
+
text={styles.color}
|
|
127
|
+
stroke={geoStrokeColor}
|
|
128
|
+
strokeWidth={1}
|
|
129
|
+
onClick={() => geoClickHandler(territory, territoryData)}
|
|
130
|
+
data-tooltip-id={`tooltip__${tooltipId}`}
|
|
131
|
+
data-tooltip-html={toolTip}
|
|
132
|
+
/>
|
|
133
|
+
)
|
|
117
134
|
}
|
|
118
135
|
})
|
|
119
136
|
|
|
@@ -130,8 +147,22 @@ const UsaRegionMap = props => {
|
|
|
130
147
|
|
|
131
148
|
return (
|
|
132
149
|
<g>
|
|
133
|
-
<line
|
|
134
|
-
|
|
150
|
+
<line
|
|
151
|
+
x1={centroid[0]}
|
|
152
|
+
y1={centroid[1]}
|
|
153
|
+
x2={centroid[0] + dx}
|
|
154
|
+
y2={centroid[1] + dy}
|
|
155
|
+
stroke='rgba(0,0,0,.5)'
|
|
156
|
+
strokeWidth={1}
|
|
157
|
+
/>
|
|
158
|
+
<text
|
|
159
|
+
x={4}
|
|
160
|
+
strokeWidth='0'
|
|
161
|
+
fontSize={13}
|
|
162
|
+
style={{ fill: '#202020' }}
|
|
163
|
+
alignmentBaseline='middle'
|
|
164
|
+
transform={`translate(${centroid[0] + dx}, ${centroid[1] + dy})`}
|
|
165
|
+
>
|
|
135
166
|
{abbr.substring(3)}
|
|
136
167
|
</text>
|
|
137
168
|
</g>
|
|
@@ -146,7 +177,7 @@ const UsaRegionMap = props => {
|
|
|
146
177
|
const key = isHex ? geo.properties.iso + '-hex-group' : geo.properties.iso + '-group'
|
|
147
178
|
|
|
148
179
|
let styles = {
|
|
149
|
-
fill:
|
|
180
|
+
fill: geoFillColor,
|
|
150
181
|
cursor: 'default'
|
|
151
182
|
}
|
|
152
183
|
|
|
@@ -172,28 +203,32 @@ const UsaRegionMap = props => {
|
|
|
172
203
|
const toolTip = applyTooltipsToGeo(geoDisplayName, geoData)
|
|
173
204
|
|
|
174
205
|
styles = {
|
|
175
|
-
fill: state.general.type !== 'bubble' ? legendColors[0] :
|
|
206
|
+
fill: state.general.type !== 'bubble' ? legendColors[0] : geoFillColor,
|
|
176
207
|
cursor: 'default',
|
|
177
208
|
'&:hover': {
|
|
178
|
-
fill: state.general.type !== 'bubble' ? legendColors[1] :
|
|
209
|
+
fill: state.general.type !== 'bubble' ? legendColors[1] : geoFillColor
|
|
179
210
|
},
|
|
180
211
|
'&:active': {
|
|
181
|
-
fill: state.general.type !== 'bubble' ? legendColors[2] :
|
|
212
|
+
fill: state.general.type !== 'bubble' ? legendColors[2] : geoFillColor
|
|
182
213
|
}
|
|
183
214
|
}
|
|
184
215
|
|
|
185
216
|
// When to add pointer cursor
|
|
186
|
-
if (
|
|
217
|
+
if (
|
|
218
|
+
(state.columns.navigate && geoData[state.columns.navigate.name]) ||
|
|
219
|
+
state.tooltips.appearanceType === 'click'
|
|
220
|
+
) {
|
|
187
221
|
styles.cursor = 'pointer'
|
|
188
222
|
}
|
|
189
223
|
|
|
190
224
|
const TerratoryRect = props => {
|
|
191
225
|
const { posX = 0, tName } = props
|
|
192
226
|
const textColor = getContrastColor('#FFF', legendColors[0])
|
|
227
|
+
const geoStrokeColor = getGeoStrokeColor(state)
|
|
193
228
|
return (
|
|
194
229
|
<>
|
|
195
|
-
<rect x={posX} width='36' height='24' rx='
|
|
196
|
-
<text x={
|
|
230
|
+
<rect x={posX} width='36' height='24' rx='2' stroke={geoStrokeColor} strokeWidth='1' />
|
|
231
|
+
<text textAnchor='middle' x={36 / 2 + posX} y='17' fill={textColor}>
|
|
197
232
|
{tName}
|
|
198
233
|
</text>
|
|
199
234
|
</>
|
|
@@ -203,8 +238,16 @@ const UsaRegionMap = props => {
|
|
|
203
238
|
const circleRadius = 15
|
|
204
239
|
|
|
205
240
|
return (
|
|
206
|
-
<g
|
|
207
|
-
|
|
241
|
+
<g
|
|
242
|
+
key={key}
|
|
243
|
+
className='geo-group'
|
|
244
|
+
style={styles}
|
|
245
|
+
onClick={() => geoClickHandler(geoDisplayName, geoData)}
|
|
246
|
+
data-tooltip-id={`tooltip__${tooltipId}`}
|
|
247
|
+
data-tooltip-html={toolTip}
|
|
248
|
+
tabIndex={-1}
|
|
249
|
+
>
|
|
250
|
+
<path tabIndex={-1} className='single-geo' stroke={geoStrokeColor} strokeWidth={1} d={path} />
|
|
208
251
|
<g id={`region-${index + 1}-label`}>
|
|
209
252
|
<circle fill='#fff' stroke='#999' cx={circleRadius} cy={circleRadius} r={circleRadius} />
|
|
210
253
|
<text fill='#333' x='15px' y='20px' textAnchor='middle'>
|
|
@@ -239,7 +282,7 @@ const UsaRegionMap = props => {
|
|
|
239
282
|
// Default return state, just geo with no additional information
|
|
240
283
|
return (
|
|
241
284
|
<g key={key} className='geo-group' style={styles}>
|
|
242
|
-
<path tabIndex={-1} className='single-geo' stroke={geoStrokeColor} strokeWidth={1
|
|
285
|
+
<path tabIndex={-1} className='single-geo' stroke={geoStrokeColor} strokeWidth={1} d={path} />
|
|
243
286
|
{(isHex || showLabel) && geoLabel(geo, styles.fill, projection)}
|
|
244
287
|
</g>
|
|
245
288
|
)
|
|
@@ -14,6 +14,7 @@ import ZoomControls from '../../ZoomControls'
|
|
|
14
14
|
import { MapContext } from '../../../types/MapContext'
|
|
15
15
|
import useStateZoom from '../../../hooks/useStateZoom'
|
|
16
16
|
import { Text } from '@visx/text'
|
|
17
|
+
import { getGeoStrokeColor } from '../../../helpers/colors'
|
|
17
18
|
|
|
18
19
|
// SVG ITEMS
|
|
19
20
|
const WIDTH = 880
|
|
@@ -49,7 +50,7 @@ const SingleStateMap = props => {
|
|
|
49
50
|
const cityListProjection = geoAlbersUsaTerritories()
|
|
50
51
|
.translate([WIDTH / 2, HEIGHT / 2])
|
|
51
52
|
.scale(1)
|
|
52
|
-
const geoStrokeColor = state
|
|
53
|
+
const geoStrokeColor = getGeoStrokeColor(state)
|
|
53
54
|
const path = geoPath().projection(projection)
|
|
54
55
|
|
|
55
56
|
useEffect(() => {
|
|
@@ -19,11 +19,13 @@ import { patternSizes } from '../helpers/patternSizes'
|
|
|
19
19
|
import Annotation from '../../Annotation'
|
|
20
20
|
|
|
21
21
|
import Territory from './Territory'
|
|
22
|
+
import { cityKeys } from '../../../data/supported-geos'
|
|
22
23
|
|
|
23
24
|
import useMapLayers from '../../../hooks/useMapLayers'
|
|
24
25
|
import ConfigContext from '../../../context'
|
|
25
26
|
import { MapContext } from '../../../types/MapContext'
|
|
26
27
|
import { checkColorContrast, getContrastColor, getColorContrast } from '@cdc/core/helpers/cove/accessibility'
|
|
28
|
+
import { getGeoFillColor, getGeoStrokeColor } from '../../../helpers/colors'
|
|
27
29
|
|
|
28
30
|
const { features: unitedStates } = feature(topoJSON, topoJSON.objects.states)
|
|
29
31
|
const { features: unitedStatesHex } = feature(hexTopoJSON, hexTopoJSON.objects.states)
|
|
@@ -59,7 +61,6 @@ const UsaMap = () => {
|
|
|
59
61
|
data,
|
|
60
62
|
displayGeoName,
|
|
61
63
|
geoClickHandler,
|
|
62
|
-
handleCircleClick,
|
|
63
64
|
handleMapAriaLabels,
|
|
64
65
|
setSharedFilterValue,
|
|
65
66
|
state,
|
|
@@ -67,11 +68,12 @@ const UsaMap = () => {
|
|
|
67
68
|
titleCase,
|
|
68
69
|
tooltipId,
|
|
69
70
|
handleDragStateChange,
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
mapId,
|
|
72
|
+
logo,
|
|
72
73
|
} = useContext<MapContext>(ConfigContext)
|
|
73
74
|
|
|
74
75
|
let isFilterValueSupported = false
|
|
76
|
+
const { general, columns, feature, tooltips, hexMap, map, annotations } = state
|
|
75
77
|
|
|
76
78
|
if (setSharedFilterValue) {
|
|
77
79
|
Object.keys(supportedStates).forEach(supportedState => {
|
|
@@ -101,16 +103,16 @@ const UsaMap = () => {
|
|
|
101
103
|
useEffect(() => {
|
|
102
104
|
setTranslate([455, 250])
|
|
103
105
|
setExtent(null)
|
|
104
|
-
}, [
|
|
106
|
+
}, [general.geoType])
|
|
105
107
|
|
|
106
|
-
const isHex =
|
|
108
|
+
const isHex = general.displayAsHex
|
|
107
109
|
|
|
108
110
|
const [territoriesData, setTerritoriesData] = useState([])
|
|
109
111
|
|
|
110
112
|
const territoriesKeys = Object.keys(supportedTerritories) // data will have already mapped abbreviated territories to their full names
|
|
111
113
|
|
|
112
114
|
useEffect(() => {
|
|
113
|
-
if (
|
|
115
|
+
if (general.territoriesAlwaysShow) {
|
|
114
116
|
// show all Territories whether in the data or not
|
|
115
117
|
setTerritoriesData(territoriesKeys)
|
|
116
118
|
} else {
|
|
@@ -118,17 +120,10 @@ const UsaMap = () => {
|
|
|
118
120
|
const territoriesList = territoriesKeys.filter(key => data[key])
|
|
119
121
|
setTerritoriesData(territoriesList)
|
|
120
122
|
}
|
|
121
|
-
}, [data,
|
|
123
|
+
}, [data, general.territoriesAlwaysShow])
|
|
122
124
|
|
|
123
|
-
const geoStrokeColor = state
|
|
124
|
-
|
|
125
|
-
const getTerritoriesClasses = () => {
|
|
126
|
-
const screenWidth = window?.visualViewport?.width
|
|
127
|
-
let className = 'territories'
|
|
128
|
-
if (screenWidth < 700) return 'territories--mobile'
|
|
129
|
-
if (screenWidth < 900) return 'territories--tablet'
|
|
130
|
-
return className
|
|
131
|
-
}
|
|
125
|
+
const geoStrokeColor = getGeoStrokeColor(state)
|
|
126
|
+
const geoFillColor = getGeoFillColor(state)
|
|
132
127
|
|
|
133
128
|
const territories = territoriesData.map((territory, territoryIndex) => {
|
|
134
129
|
const Shape = isHex ? Territory.Hexagon : Territory.Rectangle
|
|
@@ -138,13 +133,24 @@ const UsaMap = () => {
|
|
|
138
133
|
let toolTip
|
|
139
134
|
|
|
140
135
|
let styles = {
|
|
141
|
-
fill:
|
|
136
|
+
fill: geoFillColor,
|
|
137
|
+
stroke: geoStrokeColor,
|
|
142
138
|
color: '#202020'
|
|
143
139
|
}
|
|
144
140
|
|
|
145
141
|
const label = supportedTerritories[territory][1]
|
|
146
142
|
|
|
147
|
-
if (!territoryData)
|
|
143
|
+
if (!territoryData)
|
|
144
|
+
return (
|
|
145
|
+
<Shape
|
|
146
|
+
key={label}
|
|
147
|
+
label={label}
|
|
148
|
+
style={styles}
|
|
149
|
+
text={styles.color}
|
|
150
|
+
territoryData={territoryData}
|
|
151
|
+
backgroundColor={styles.fill}
|
|
152
|
+
/>
|
|
153
|
+
)
|
|
148
154
|
|
|
149
155
|
toolTip = applyTooltipsToGeo(displayGeoName(territory), territoryData)
|
|
150
156
|
|
|
@@ -156,10 +162,7 @@ const UsaMap = () => {
|
|
|
156
162
|
let needsPointer = false
|
|
157
163
|
|
|
158
164
|
// If we need to add a pointer cursor
|
|
159
|
-
if (
|
|
160
|
-
(state.columns.navigate && territoryData[state.columns.navigate.name]) ||
|
|
161
|
-
state.tooltips.appearanceType === 'click'
|
|
162
|
-
) {
|
|
165
|
+
if ((columns.navigate && territoryData[columns.navigate.name]) || tooltips.appearanceType === 'click') {
|
|
163
166
|
needsPointer = true
|
|
164
167
|
}
|
|
165
168
|
|
|
@@ -167,15 +170,11 @@ const UsaMap = () => {
|
|
|
167
170
|
color: textColor,
|
|
168
171
|
fill: legendColors[0],
|
|
169
172
|
opacity:
|
|
170
|
-
setSharedFilterValue &&
|
|
171
|
-
isFilterValueSupported &&
|
|
172
|
-
setSharedFilterValue !== territoryData[state.columns.geo.name]
|
|
173
|
+
setSharedFilterValue && isFilterValueSupported && setSharedFilterValue !== territoryData[columns.geo.name]
|
|
173
174
|
? 0.5
|
|
174
175
|
: 1,
|
|
175
176
|
stroke:
|
|
176
|
-
setSharedFilterValue &&
|
|
177
|
-
isFilterValueSupported &&
|
|
178
|
-
setSharedFilterValue === territoryData[state.columns.geo.name]
|
|
177
|
+
setSharedFilterValue && isFilterValueSupported && setSharedFilterValue === territoryData[columns.geo.name]
|
|
179
178
|
? 'rgba(0, 0, 0, 1)'
|
|
180
179
|
: geoStrokeColor,
|
|
181
180
|
cursor: needsPointer ? 'pointer' : 'default',
|
|
@@ -193,14 +192,15 @@ const UsaMap = () => {
|
|
|
193
192
|
label={label}
|
|
194
193
|
style={styles}
|
|
195
194
|
text={styles.color}
|
|
196
|
-
strokeWidth={1
|
|
195
|
+
strokeWidth={1}
|
|
197
196
|
textColor={textColor}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
197
|
+
handleShapeClick={() => geoClickHandler(territory, territoryData)}
|
|
198
|
+
dataTooltipId={`tooltip__${tooltipId}`}
|
|
199
|
+
dataTooltipHtml={toolTip}
|
|
201
200
|
territory={territory}
|
|
202
201
|
territoryData={territoryData}
|
|
203
202
|
tabIndex={-1}
|
|
203
|
+
backgroundColor={styles.fill}
|
|
204
204
|
/>
|
|
205
205
|
)
|
|
206
206
|
}
|
|
@@ -213,7 +213,7 @@ const UsaMap = () => {
|
|
|
213
213
|
|
|
214
214
|
// Constructs and displays markup for all geos on the map (except territories right now)
|
|
215
215
|
const constructGeoJsx = (geographies, projection) => {
|
|
216
|
-
let showLabel =
|
|
216
|
+
let showLabel = general.displayStateLabels
|
|
217
217
|
|
|
218
218
|
// Order alphabetically. Important for accessibility if ever read out loud.
|
|
219
219
|
geographies.map(state => {
|
|
@@ -239,7 +239,7 @@ const UsaMap = () => {
|
|
|
239
239
|
const key = isHex ? geo.properties.iso + '-hex-group' : geo.properties.iso + '-group'
|
|
240
240
|
|
|
241
241
|
let styles = {
|
|
242
|
-
fill:
|
|
242
|
+
fill: geoFillColor,
|
|
243
243
|
cursor: 'default'
|
|
244
244
|
}
|
|
245
245
|
|
|
@@ -247,8 +247,6 @@ const UsaMap = () => {
|
|
|
247
247
|
let geoKey = geo.properties.iso
|
|
248
248
|
let geoName = geo.properties.name
|
|
249
249
|
|
|
250
|
-
// Manually add Washington D.C. in for Hex maps
|
|
251
|
-
|
|
252
250
|
if (!geoKey) return
|
|
253
251
|
|
|
254
252
|
const geoData = data[geoKey]
|
|
@@ -267,29 +265,26 @@ const UsaMap = () => {
|
|
|
267
265
|
const tooltip = applyTooltipsToGeo(geoDisplayName, geoData)
|
|
268
266
|
|
|
269
267
|
styles = {
|
|
270
|
-
fill: state.general.type !== 'bubble' ? legendColors[0] :
|
|
268
|
+
fill: state.general.type !== 'bubble' ? legendColors[0] : geoFillColor,
|
|
271
269
|
opacity:
|
|
272
|
-
setSharedFilterValue && isFilterValueSupported && setSharedFilterValue !== geoData[
|
|
270
|
+
setSharedFilterValue && isFilterValueSupported && setSharedFilterValue !== geoData[columns.geo.name]
|
|
273
271
|
? 0.5
|
|
274
272
|
: 1,
|
|
275
273
|
stroke:
|
|
276
|
-
setSharedFilterValue && isFilterValueSupported && setSharedFilterValue === geoData[
|
|
274
|
+
setSharedFilterValue && isFilterValueSupported && setSharedFilterValue === geoData[columns.geo.name]
|
|
277
275
|
? 'rgba(0, 0, 0, 1)'
|
|
278
276
|
: geoStrokeColor,
|
|
279
277
|
cursor: 'default',
|
|
280
278
|
'&:hover': {
|
|
281
|
-
fill: state.general.type !== 'bubble' ? legendColors[1] :
|
|
279
|
+
fill: state.general.type !== 'bubble' ? legendColors[1] : geoFillColor
|
|
282
280
|
},
|
|
283
281
|
'&:active': {
|
|
284
|
-
fill: state.general.type !== 'bubble' ? legendColors[2] :
|
|
282
|
+
fill: state.general.type !== 'bubble' ? legendColors[2] : geoFillColor
|
|
285
283
|
}
|
|
286
284
|
}
|
|
287
285
|
|
|
288
286
|
// When to add pointer cursor
|
|
289
|
-
if (
|
|
290
|
-
(state.columns.navigate && geoData[state.columns.navigate.name]) ||
|
|
291
|
-
state.tooltips.appearanceType === 'click'
|
|
292
|
-
) {
|
|
287
|
+
if ((columns.navigate && geoData[columns.navigate.name]) || tooltips.appearanceType === 'click') {
|
|
293
288
|
styles.cursor = 'pointer'
|
|
294
289
|
}
|
|
295
290
|
|
|
@@ -302,7 +297,7 @@ const UsaMap = () => {
|
|
|
302
297
|
|
|
303
298
|
return (
|
|
304
299
|
<>
|
|
305
|
-
{
|
|
300
|
+
{hexMap.shapeGroups.map((group, groupIndex) => {
|
|
306
301
|
return group.items.map((item, itemIndex) => {
|
|
307
302
|
switch (item.operator) {
|
|
308
303
|
case '=':
|
|
@@ -406,10 +401,10 @@ const UsaMap = () => {
|
|
|
406
401
|
tabIndex={-1}
|
|
407
402
|
>
|
|
408
403
|
{/* state path */}
|
|
409
|
-
<path tabIndex={-1} className='single-geo' strokeWidth={1
|
|
404
|
+
<path tabIndex={-1} className='single-geo' strokeWidth={1} d={path} />
|
|
410
405
|
|
|
411
406
|
{/* apply patterns on top of state path*/}
|
|
412
|
-
{
|
|
407
|
+
{map.patterns.map((patternData, patternIndex) => {
|
|
413
408
|
const { pattern, dataKey, size } = patternData
|
|
414
409
|
const currentFill = styles.fill
|
|
415
410
|
const hasMatchingValues = patternData.dataValue === geoData[patternData.dataKey]
|
|
@@ -422,7 +417,7 @@ const UsaMap = () => {
|
|
|
422
417
|
<>
|
|
423
418
|
{pattern === 'waves' && (
|
|
424
419
|
<PatternWaves
|
|
425
|
-
id={`${mapId}--${dataKey}--${geoIndex}`}
|
|
420
|
+
id={`${mapId}--${String(dataKey).replace(' ', '-')}--${geoIndex}`}
|
|
426
421
|
height={patternSizes[size] ?? 10}
|
|
427
422
|
width={patternSizes[size] ?? 10}
|
|
428
423
|
fill={patternColor}
|
|
@@ -430,7 +425,7 @@ const UsaMap = () => {
|
|
|
430
425
|
)}
|
|
431
426
|
{pattern === 'circles' && (
|
|
432
427
|
<PatternCircles
|
|
433
|
-
id={`${mapId}--${dataKey}--${geoIndex}`}
|
|
428
|
+
id={`${mapId}--${String(dataKey).replace(' ', '-')}--${geoIndex}`}
|
|
434
429
|
height={patternSizes[size] ?? 10}
|
|
435
430
|
width={patternSizes[size] ?? 10}
|
|
436
431
|
fill={patternColor}
|
|
@@ -438,7 +433,7 @@ const UsaMap = () => {
|
|
|
438
433
|
)}
|
|
439
434
|
{pattern === 'lines' && (
|
|
440
435
|
<PatternLines
|
|
441
|
-
id={`${mapId}--${dataKey}--${geoIndex}`}
|
|
436
|
+
id={`${mapId}--${String(dataKey).replace(' ', '-')}--${geoIndex}`}
|
|
442
437
|
height={patternSizes[size] ?? 6}
|
|
443
438
|
width={patternSizes[size] ?? 6}
|
|
444
439
|
stroke={patternColor}
|
|
@@ -451,13 +446,13 @@ const UsaMap = () => {
|
|
|
451
446
|
tabIndex={-1}
|
|
452
447
|
stroke='transparent'
|
|
453
448
|
d={path}
|
|
454
|
-
fill={`url(#${mapId}--${dataKey}--${geoIndex})`}
|
|
449
|
+
fill={`url(#${mapId}--${String(dataKey).replace(' ', '-')}--${geoIndex})`}
|
|
455
450
|
/>
|
|
456
451
|
</>
|
|
457
452
|
)
|
|
458
453
|
})}
|
|
459
454
|
{(isHex || showLabel) && geoLabel(geo, legendColors[0], projection)}
|
|
460
|
-
{isHex &&
|
|
455
|
+
{isHex && hexMap.type === 'shapes' && getArrowDirection(geoData, geo, legendColors[0])}
|
|
461
456
|
</g>
|
|
462
457
|
</g>
|
|
463
458
|
)
|
|
@@ -495,7 +490,7 @@ const UsaMap = () => {
|
|
|
495
490
|
)
|
|
496
491
|
|
|
497
492
|
// Bubbles
|
|
498
|
-
if (
|
|
493
|
+
if (general.type === 'bubble') {
|
|
499
494
|
geosJsx.push(
|
|
500
495
|
<BubbleList
|
|
501
496
|
key='bubbles'
|
|
@@ -529,12 +524,12 @@ const UsaMap = () => {
|
|
|
529
524
|
let textColor = getContrastColor('#FFF', bgColor)
|
|
530
525
|
|
|
531
526
|
// always make HI black since it is off to the side
|
|
532
|
-
if (abbr === 'US-HI' && !
|
|
527
|
+
if (abbr === 'US-HI' && !general.displayAsHex) {
|
|
533
528
|
textColor = '#000'
|
|
534
529
|
}
|
|
535
530
|
|
|
536
531
|
let x = 0,
|
|
537
|
-
y =
|
|
532
|
+
y = hexMap.type === 'shapes' && general.displayAsHex ? -10 : 5
|
|
538
533
|
|
|
539
534
|
// used to nudge/move some of the labels for better readability
|
|
540
535
|
if (nudges[abbr] && false === isHex) {
|
|
@@ -581,7 +576,7 @@ const UsaMap = () => {
|
|
|
581
576
|
return (
|
|
582
577
|
<ErrorBoundary component='UsaMap'>
|
|
583
578
|
<svg viewBox='0 0 880 500' role='img' aria-label={handleMapAriaLabels(state)}>
|
|
584
|
-
{
|
|
579
|
+
{general.displayAsHex ? (
|
|
585
580
|
<Mercator data={unitedStatesHex} scale={650} translate={[1600, 775]}>
|
|
586
581
|
{({ features, projection }) => constructGeoJsx(features, projection)}
|
|
587
582
|
</Mercator>
|
|
@@ -590,18 +585,21 @@ const UsaMap = () => {
|
|
|
590
585
|
{({ features, projection }) => constructGeoJsx(features, projection)}
|
|
591
586
|
</AlbersUsa>
|
|
592
587
|
)}
|
|
593
|
-
{
|
|
588
|
+
{annotations.length > 0 && <Annotation.Draggable onDragStateChange={handleDragStateChange} />}
|
|
594
589
|
</svg>
|
|
595
590
|
|
|
596
591
|
{territories.length > 0 && (
|
|
597
592
|
<>
|
|
598
593
|
{/* Temporarily make the max width fit the image width */}
|
|
599
|
-
<div
|
|
600
|
-
<div>
|
|
601
|
-
<
|
|
594
|
+
<div>
|
|
595
|
+
<div className='d-flex mt-2'>
|
|
596
|
+
<h5>{general.territoriesLabel}</h5>
|
|
597
|
+
{'data' === general.type && logo && (
|
|
598
|
+
<img src={logo} alt='' className='map-logo' style={{ maxWidth: '50px' }} />
|
|
599
|
+
)}
|
|
602
600
|
</div>
|
|
603
601
|
<div>
|
|
604
|
-
<span className=
|
|
602
|
+
<span className='mt-1 mb-2 d-flex flex-wrap territories'>{territories}</span>
|
|
605
603
|
</div>
|
|
606
604
|
</div>
|
|
607
605
|
</>
|
|
@@ -2,7 +2,7 @@ export const drawCircle = (circle, context, state) => {
|
|
|
2
2
|
const percentOfOriginalSize = 0.75
|
|
3
3
|
const adjustedGeoRadius =
|
|
4
4
|
state.mapPosition.zoom > 1 ? Number(circle.geoRadius) * percentOfOriginalSize : circle.geoRadius
|
|
5
|
-
context.lineWidth =
|
|
5
|
+
context.lineWidth = 1
|
|
6
6
|
context.fillStyle = circle.color
|
|
7
7
|
context.beginPath()
|
|
8
8
|
context.arc(circle.x, circle.y, adjustedGeoRadius, 0, 2 * Math.PI)
|
|
@@ -145,7 +145,7 @@ export const drawPin = (pin, ctx) => {
|
|
|
145
145
|
ctx.fillStyle = pin.color
|
|
146
146
|
ctx.fill()
|
|
147
147
|
ctx.strokeStyle = 'black'
|
|
148
|
-
ctx.lineWidth = 1
|
|
148
|
+
ctx.lineWidth = 1
|
|
149
149
|
ctx.stroke()
|
|
150
150
|
ctx.beginPath()
|
|
151
151
|
ctx.arc(0, -21, 3, 0, Math.PI * 2)
|
|
@@ -178,12 +178,13 @@ export const createShapeProperties = (type, pixelCoords, legendValues, state, ge
|
|
|
178
178
|
x: pixelCoords[0],
|
|
179
179
|
y: pixelCoords[1],
|
|
180
180
|
color: legendValues[0],
|
|
181
|
-
size: geoRadius
|
|
181
|
+
size: geoRadius,
|
|
182
|
+
lineWidth: 1
|
|
182
183
|
}
|
|
183
184
|
|
|
184
185
|
switch (type) {
|
|
185
186
|
case 'circle':
|
|
186
|
-
return { ...baseProps, geoRadius: geoRadius
|
|
187
|
+
return { ...baseProps, geoRadius: geoRadius, type: 'circle' }
|
|
187
188
|
case 'pin':
|
|
188
189
|
return { ...baseProps, type: 'pin' }
|
|
189
190
|
case 'square':
|