@cdc/map 4.26.3 → 4.26.5
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/CONFIG.md +268 -0
- package/README.md +74 -24
- package/dist/cdcmap-CY9IcPSi.es.js +6 -0
- package/dist/cdcmap-DlpiY3fQ.es.js +4 -0
- package/dist/cdcmap.js +29168 -27482
- package/examples/{testing-layer-2.json → __data__/testing-layer-2.json} +1 -1
- package/examples/{testing-layer.json → __data__/testing-layer.json} +1 -1
- package/examples/county-hsa-toggle.json +51993 -0
- package/examples/custom-map-layers.json +2 -2
- package/examples/default-county.json +6 -3
- package/examples/minimal-example.json +73 -0
- package/examples/private/annotation-bug.json +2 -2
- package/examples/private/css-issue.json +314 -0
- package/examples/private/region-breaking.json +1639 -0
- package/examples/private/test1.json +27247 -0
- package/package.json +4 -4
- package/src/CdcMapComponent.tsx +107 -14
- package/src/_stories/CdcMap.AltText.stories.tsx +122 -0
- package/src/_stories/CdcMap.Editor.ColumnsSectionTests.stories.tsx +600 -0
- package/src/_stories/CdcMap.Editor.DataTableSectionTests.stories.tsx +404 -0
- package/src/_stories/CdcMap.Editor.FiltersSectionTests.stories.tsx +229 -0
- package/src/_stories/CdcMap.Editor.GeneralSectionTests.stories.tsx +262 -0
- package/src/_stories/CdcMap.Editor.LegendSectionTests.stories.tsx +541 -0
- package/src/_stories/CdcMap.Editor.MultiCountryWorldMapTests.stories.tsx +359 -0
- package/src/_stories/CdcMap.Editor.PatternSettingsSectionTests.stories.tsx +516 -0
- package/src/_stories/CdcMap.Editor.SmallMultiplesSectionTests.stories.tsx +165 -0
- package/src/_stories/CdcMap.Editor.TextAnnotationsSectionTests.stories.tsx +145 -0
- package/src/_stories/CdcMap.Editor.TypeSectionTests.stories.tsx +312 -0
- package/src/_stories/CdcMap.Editor.VisualSectionTests.stories.tsx +359 -0
- package/src/_stories/CdcMap.Editor.ZoomControlsTests.stories.tsx +88 -0
- package/src/_stories/CdcMap.FocusVisibility.stories.tsx +87 -0
- package/src/_stories/CdcMap.HiddenMount.stories.tsx +69 -0
- package/src/_stories/CdcMap.ResetBehavior.stories.tsx +32 -0
- package/src/_stories/CdcMap.Zoom.stories.tsx +111 -0
- package/src/_stories/{CdcMap.stories.tsx → CdcMap.smoke.stories.tsx} +60 -0
- package/src/_stories/_mock/alt_text_metadata.json +65 -0
- package/src/_stories/_mock/legends/legend-tests.json +3 -3
- package/src/_stories/_mock/world-bubble-reset.json +138 -0
- package/src/_stories/_mock/world-data-zoom-filters.json +166 -0
- package/src/components/Annotation/AnnotationList.tsx +1 -1
- package/src/components/BubbleList.tsx +13 -0
- package/src/components/EditorPanel/components/EditorPanel.tsx +637 -382
- package/src/components/EditorPanel/components/HexShapeSettings.tsx +1 -1
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +112 -117
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +26 -13
- package/src/components/EditorPanel/components/editorPanel.styles.css +22 -2
- package/src/components/FilterControls.tsx +21 -0
- package/src/components/Legend/components/Legend.tsx +3 -3
- package/src/components/Legend/components/LegendItem.Hex.tsx +4 -2
- package/src/components/SmallMultiples/SmallMultiples.tsx +2 -2
- package/src/components/SmallMultiples/SynchronizedTooltip.tsx +1 -1
- package/src/components/UsaMap/components/UsaMap.County.tsx +309 -108
- package/src/components/UsaMap/components/UsaMap.Region.tsx +5 -2
- package/src/components/UsaMap/components/UsaMap.SingleState.tsx +33 -10
- package/src/components/UsaMap/components/UsaMap.State.tsx +10 -3
- package/src/components/UsaMap/data/cb_2019_us_county_20m.json +75817 -1
- package/src/components/UsaMap/data/hsa_fips_mapping.json +3144 -0
- package/src/components/WorldMap/WorldMap.tsx +37 -4
- package/src/components/WorldMap/data/world-topo.json +1 -1
- package/src/components/ZoomableGroup.tsx +23 -3
- package/src/components/filterControls.styles.css +6 -0
- package/src/data/initial-state.js +3 -0
- package/src/data/supported-counties.json +1 -1
- package/src/helpers/countyTerritories.ts +38 -0
- package/src/helpers/dataTableHelpers.ts +35 -6
- package/src/helpers/generateRuntimeFilters.ts +2 -1
- package/src/helpers/handleMapAriaLabels.ts +45 -30
- package/src/helpers/shouldAutoResetSingleStateZoom.ts +22 -0
- package/src/helpers/tests/countyTerritories.test.ts +87 -0
- package/src/helpers/tests/handleMapAriaLabels.test.ts +71 -0
- package/src/helpers/tests/shouldAutoResetSingleStateZoom.test.ts +71 -0
- package/src/hooks/useApplyTooltipsToGeo.tsx +7 -4
- package/src/hooks/useGeoClickHandler.ts +13 -1
- package/src/hooks/useMapLayers.tsx +1 -1
- package/src/hooks/useStateZoom.tsx +39 -20
- package/src/hooks/useTooltip.test.tsx +2 -16
- package/src/hooks/useTooltip.ts +18 -7
- package/src/index.jsx +5 -2
- package/src/scss/main.scss +6 -21
- package/src/scss/map.scss +20 -0
- package/src/store/map.actions.ts +5 -2
- package/src/store/map.reducer.ts +12 -3
- package/src/test/CdcMap.test.jsx +24 -0
- package/src/types/MapConfig.ts +11 -0
- package/src/types/MapContext.ts +6 -1
- package/topojson-updater/README.txt +1 -1
- package/dist/cdcmap-vr9HZwRt.es.js +0 -6
- package/examples/__data__/city-state-data.json +0 -668
- package/examples/city-state.json +0 -434
- package/examples/default-world-data.json +0 -1450
- package/examples/new-cities.json +0 -656
- package/src/_stories/CdcMap.Editor.stories.tsx +0 -3648
- package/topojson-updater/package-lock.json +0 -223
- /package/src/_stories/{CdcMap.ColumnWrap.stories.tsx → CdcMap.ColumnWrap.smoke.stories.tsx} +0 -0
- /package/src/_stories/{CdcMap.Defaults.stories.tsx → CdcMap.Defaults.smoke.stories.tsx} +0 -0
- /package/src/_stories/{CdcMap.DistrictOfColumbia.stories.tsx → CdcMap.DistrictOfColumbia.smoke.stories.tsx} +0 -0
- /package/src/_stories/{CdcMap.Filters.stories.tsx → CdcMap.Filters.smoke.stories.tsx} +0 -0
- /package/src/_stories/{CdcMap.Legend.Gradient.stories.tsx → CdcMap.Legend.Gradient.smoke.stories.tsx} +0 -0
- /package/src/_stories/{CdcMap.Legend.stories.tsx → CdcMap.Legend.smoke.stories.tsx} +0 -0
- /package/src/_stories/{CdcMap.Patterns.stories.tsx → CdcMap.Patterns.smoke.stories.tsx} +0 -0
- /package/src/_stories/{CdcMap.SmallMultiples.stories.tsx → CdcMap.SmallMultiples.smoke.stories.tsx} +0 -0
- /package/src/_stories/{CdcMap.Table.stories.tsx → CdcMap.Table.smoke.stories.tsx} +0 -0
- /package/src/_stories/{CdcMap.ZeroColor.stories.tsx → CdcMap.ZeroColor.smoke.stories.tsx} +0 -0
- /package/src/_stories/{GoogleMap.stories.tsx → GoogleMap.smoke.stories.tsx} +0 -0
- /package/src/_stories/{UsaMap.NoData.stories.tsx → UsaMap.NoData.smoke.stories.tsx} +0 -0
package/src/hooks/useTooltip.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { displayDataAsText } from '@cdc/core/helpers/displayDataAsText'
|
|
2
2
|
import { displayGeoName } from '../helpers/displayGeoName'
|
|
3
|
+
import { MapConfig } from '../types/MapConfig'
|
|
4
|
+
import { supportedStatesFipsCodes } from '../data/supported-geos'
|
|
3
5
|
|
|
4
|
-
const useTooltip =
|
|
5
|
-
const { config, supportedStatesFipsCodes } = props
|
|
6
|
-
|
|
6
|
+
const useTooltip = (config: MapConfig) => {
|
|
7
7
|
/**
|
|
8
8
|
* On county maps there's a need to append the state name
|
|
9
9
|
* @param {String} toolTipText - previous tooltip text to build upon
|
|
@@ -11,17 +11,25 @@ const useTooltip = props => {
|
|
|
11
11
|
* @returns {String} toolTipText - new toolTipText
|
|
12
12
|
*/
|
|
13
13
|
const handleTooltipStateNameColumn = (toolTipText, row) => {
|
|
14
|
-
const { geoType, type, hideGeoColumnInTooltip } = config.general
|
|
14
|
+
const { geoType, type, hideGeoColumnInTooltip, showHSABoundaries } = config.general
|
|
15
15
|
if (geoType === 'us-county' && type !== 'us-geocode') {
|
|
16
16
|
let stateFipsCode = row[config.columns.geo.name].substring(0, 2)
|
|
17
17
|
const stateName = supportedStatesFipsCodes[stateFipsCode]
|
|
18
|
-
toolTipText +=
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
toolTipText +=
|
|
19
|
+
hideGeoColumnInTooltip || showHSABoundaries
|
|
20
|
+
? `<strong>${stateName}</strong><br/>`
|
|
21
|
+
: `<strong>Location: ${stateName}</strong><br/>`
|
|
21
22
|
}
|
|
22
23
|
return toolTipText
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
const getHSAColumnText = (config: MapConfig, row: Object) => {
|
|
27
|
+
const { hsa } = config.columns
|
|
28
|
+
if (!hsa || !config.general.showHSABoundaries) return ''
|
|
29
|
+
const hsaDescription = row[hsa.name]
|
|
30
|
+
return `<p class="tooltip-heading">HSA: ${hsaDescription}</p>`
|
|
31
|
+
}
|
|
32
|
+
|
|
25
33
|
/**
|
|
26
34
|
* On county and state maps, adds the ability to hide the geo column name (prefix)
|
|
27
35
|
* @param {String} geoName - feature name
|
|
@@ -144,6 +152,9 @@ const useTooltip = props => {
|
|
|
144
152
|
// Handle County Location Columns
|
|
145
153
|
toolTipText += handleTooltipStateNameColumn(toolTipText, row)
|
|
146
154
|
|
|
155
|
+
// Handle HSA Column
|
|
156
|
+
toolTipText += getHSAColumnText(config, row)
|
|
157
|
+
|
|
147
158
|
// Handle Columns > Data Column In tooltips
|
|
148
159
|
toolTipText += handleTooltipGeoColumn(geoName, row)
|
|
149
160
|
|
package/src/index.jsx
CHANGED
|
@@ -8,13 +8,16 @@ import CdcMap from './CdcMap'
|
|
|
8
8
|
|
|
9
9
|
let isEditor = window.location.href.includes('editor=true')
|
|
10
10
|
let domContainer = document.getElementsByClassName('react-container')[0]
|
|
11
|
+
let configUrl = domContainer.dataset.configUrl
|
|
12
|
+
let injectedConfig = domContainer.coveConfig
|
|
11
13
|
|
|
12
14
|
ReactDOM.createRoot(domContainer).render(
|
|
13
15
|
<React.StrictMode>
|
|
14
16
|
<CdcMap
|
|
15
17
|
isEditor={isEditor}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
config={injectedConfig}
|
|
19
|
+
configUrl={injectedConfig ? undefined : configUrl}
|
|
20
|
+
interactionLabel={configUrl}
|
|
18
21
|
containerEl={domContainer}
|
|
19
22
|
/>
|
|
20
23
|
</React.StrictMode>
|
package/src/scss/main.scss
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
@import 'editor-panel';
|
|
3
3
|
@import '@cdc/core/styles/utils/accessibility';
|
|
4
4
|
@import '@cdc/core/styles/layout/wrapper-padding';
|
|
5
|
+
@import '@cdc/core/styles/layout/callout';
|
|
5
6
|
|
|
6
7
|
.type-map--has-error {
|
|
7
8
|
.waiting {
|
|
@@ -17,7 +18,7 @@
|
|
|
17
18
|
position: relative;
|
|
18
19
|
display: flex; // Needed for the main content
|
|
19
20
|
|
|
20
|
-
.loading>div.la-ball-beat {
|
|
21
|
+
.loading > div.la-ball-beat {
|
|
21
22
|
margin-top: 20%;
|
|
22
23
|
}
|
|
23
24
|
|
|
@@ -125,33 +126,17 @@
|
|
|
125
126
|
background: transparent;
|
|
126
127
|
|
|
127
128
|
.cdc-callout {
|
|
128
|
-
|
|
129
|
-
border: 1px solid #dff2f6;
|
|
130
|
-
margin: 0;
|
|
131
|
-
padding: 1.25rem;
|
|
132
|
-
border-radius: 0.25rem;
|
|
133
|
-
position: relative;
|
|
134
|
-
background: transparent;
|
|
135
|
-
|
|
136
|
-
.cdc-callout__flag {
|
|
137
|
-
position: absolute;
|
|
138
|
-
top: -0.36rem;
|
|
139
|
-
right: 1.08rem;
|
|
140
|
-
width: 1.84rem;
|
|
141
|
-
height: auto;
|
|
142
|
-
}
|
|
129
|
+
--cdc-callout-background: transparent;
|
|
143
130
|
|
|
144
131
|
.cove-visualization__title,
|
|
145
132
|
.cove-visualization__header {
|
|
146
133
|
background: transparent;
|
|
147
134
|
border: 0;
|
|
148
|
-
color: var(--cool-gray-90, #1f2937);
|
|
149
135
|
margin: 0 0 1rem;
|
|
150
136
|
padding: 0;
|
|
151
137
|
border-radius: 0;
|
|
152
138
|
|
|
153
139
|
h2 {
|
|
154
|
-
color: var(--cool-gray-90, #1f2937);
|
|
155
140
|
font-family: var(--fonts-nunito, var(--app-font-secondary));
|
|
156
141
|
font-size: 1.1rem;
|
|
157
142
|
font-weight: 700;
|
|
@@ -178,7 +163,7 @@
|
|
|
178
163
|
flex-direction: column;
|
|
179
164
|
row-gap: var(--cove-visualization-section-gap, 1.5rem);
|
|
180
165
|
|
|
181
|
-
|
|
166
|
+
> .legends {
|
|
182
167
|
margin-top: var(--cove-visualization-section-gap, 1.5rem) !important;
|
|
183
168
|
}
|
|
184
169
|
}
|
|
@@ -271,7 +256,7 @@
|
|
|
271
256
|
}
|
|
272
257
|
}
|
|
273
258
|
|
|
274
|
-
.visualization-container.legend-wrapped-bottom
|
|
259
|
+
.visualization-container.legend-wrapped-bottom > .legends,
|
|
275
260
|
.legends.legend-wrapped-bottom {
|
|
276
261
|
margin-top: var(--cove-visualization-section-gap, 1.5rem) !important;
|
|
277
262
|
}
|
|
@@ -311,7 +296,7 @@
|
|
|
311
296
|
label {
|
|
312
297
|
flex-grow: 1;
|
|
313
298
|
|
|
314
|
-
>div.select-heading {
|
|
299
|
+
> div.select-heading {
|
|
315
300
|
font-size: 1.1em;
|
|
316
301
|
font-weight: 600;
|
|
317
302
|
margin-bottom: 0.75em;
|
package/src/scss/map.scss
CHANGED
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
flex-direction: row;
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
|
+
|
|
8
9
|
.visualization-container.map {
|
|
9
10
|
&.side {
|
|
10
11
|
flex-direction: row;
|
|
11
12
|
}
|
|
12
13
|
}
|
|
14
|
+
|
|
13
15
|
// Bubble Specific
|
|
14
16
|
.visualization-container.bubble {
|
|
15
17
|
&.side {
|
|
@@ -30,6 +32,7 @@ $medium: 768px;
|
|
|
30
32
|
.single-geo {
|
|
31
33
|
transition: 0.2s fill;
|
|
32
34
|
cursor: pointer;
|
|
35
|
+
|
|
33
36
|
&:focus {
|
|
34
37
|
outline: 0;
|
|
35
38
|
}
|
|
@@ -45,6 +48,20 @@ $medium: 768px;
|
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
50
|
|
|
51
|
+
.svg-container,
|
|
52
|
+
.county,
|
|
53
|
+
.state-path,
|
|
54
|
+
.bubble,
|
|
55
|
+
.geo-point,
|
|
56
|
+
.marker,
|
|
57
|
+
.bubble *,
|
|
58
|
+
.geo-point * {
|
|
59
|
+
&:focus,
|
|
60
|
+
&:focus-visible {
|
|
61
|
+
outline: none;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
48
65
|
.territories-label {
|
|
49
66
|
font-weight: 700;
|
|
50
67
|
}
|
|
@@ -52,6 +69,7 @@ $medium: 768px;
|
|
|
52
69
|
// Cities and Territories
|
|
53
70
|
.territories {
|
|
54
71
|
gap: 0.5em;
|
|
72
|
+
|
|
55
73
|
svg {
|
|
56
74
|
max-width: var(--territory-svg-max-width, 30px);
|
|
57
75
|
min-width: var(--territory-svg-min-width, 30px);
|
|
@@ -60,6 +78,7 @@ $medium: 768px;
|
|
|
60
78
|
text {
|
|
61
79
|
font-size: var(--territory-label-font-size);
|
|
62
80
|
font-weight: 900;
|
|
81
|
+
|
|
63
82
|
@include breakpointClass(sm) {
|
|
64
83
|
font-size: var(--territory-label-font-size-mobile);
|
|
65
84
|
}
|
|
@@ -71,6 +90,7 @@ $medium: 768px;
|
|
|
71
90
|
.zoom-controls > button:not(.reset) {
|
|
72
91
|
height: 2.5em;
|
|
73
92
|
width: 2.5em;
|
|
93
|
+
|
|
74
94
|
svg {
|
|
75
95
|
height: 2.5em;
|
|
76
96
|
width: 2.5em;
|
package/src/store/map.actions.ts
CHANGED
|
@@ -11,7 +11,10 @@ type SET_CONFIG = Action<'SET_CONFIG', MapConfig>
|
|
|
11
11
|
type SET_COVE_LOADED_HAS_RAN = Action<'SET_COVE_LOADED_HAS_RAN', boolean>
|
|
12
12
|
type SET_DISPLAY_PANEL = Action<'SET_DISPLAY_PANEL', boolean>
|
|
13
13
|
type SET_FILTERED_COUNTRY_CODE = Action<'SET_FILTERED_COUNTRY_CODE', string>
|
|
14
|
-
type
|
|
14
|
+
type SET_FILTERED_STATE_COUNTY_CODE = Action<
|
|
15
|
+
'SET_FILTERED_STATE_COUNTY_CODE',
|
|
16
|
+
{ stateCode?: string; countyCode?: string }
|
|
17
|
+
>
|
|
15
18
|
type SET_IS_DRAGGING_ANNOTATION = Action<'SET_IS_DRAGGING_ANNOTATION', boolean>
|
|
16
19
|
type SET_LOADING = Action<'SET_LOADING', boolean>
|
|
17
20
|
type SET_MODAL = Action<'SET_MODAL', Modal>
|
|
@@ -31,7 +34,7 @@ type MapActions =
|
|
|
31
34
|
| SET_COVE_LOADED_HAS_RAN
|
|
32
35
|
| SET_DISPLAY_PANEL
|
|
33
36
|
| SET_FILTERED_COUNTRY_CODE
|
|
34
|
-
|
|
|
37
|
+
| SET_FILTERED_STATE_COUNTY_CODE
|
|
35
38
|
| SET_IS_DRAGGING_ANNOTATION
|
|
36
39
|
| SET_LOADING
|
|
37
40
|
| SET_MODAL
|
package/src/store/map.reducer.ts
CHANGED
|
@@ -6,8 +6,11 @@ import _ from 'lodash'
|
|
|
6
6
|
import { Modal } from '../types/Modal'
|
|
7
7
|
import { GeneratedLegend } from '../helpers/generateRuntimeLegend'
|
|
8
8
|
import { RuntimeData } from '../types/RuntimeData'
|
|
9
|
+
import { getQueryParam } from '@cdc/core/helpers/queryStringUtils'
|
|
9
10
|
|
|
10
11
|
export const getInitialState = (configObj = {}): MapState => {
|
|
12
|
+
const filteredStateCode = typeof window !== 'undefined' ? getQueryParam('state-code') || '' : ''
|
|
13
|
+
const filteredCountyCode = typeof window !== 'undefined' ? getQueryParam('county-code') || '' : ''
|
|
11
14
|
// Create defaults without palette version to avoid overriding legacy configs
|
|
12
15
|
const defaultsWithoutPaletteaName = { ...defaults }
|
|
13
16
|
|
|
@@ -24,7 +27,8 @@ export const getInitialState = (configObj = {}): MapState => {
|
|
|
24
27
|
coveLoadedHasRan: false,
|
|
25
28
|
displayPanel: false,
|
|
26
29
|
filteredCountryCode: '',
|
|
27
|
-
|
|
30
|
+
filteredCountyCode,
|
|
31
|
+
filteredStateCode,
|
|
28
32
|
isDraggingAnnotation: false,
|
|
29
33
|
topoData: null,
|
|
30
34
|
translate: [0, 0],
|
|
@@ -47,6 +51,7 @@ export type MapState = {
|
|
|
47
51
|
coveLoadedHasRan: boolean
|
|
48
52
|
displayPanel: boolean
|
|
49
53
|
filteredCountryCode: string
|
|
54
|
+
filteredCountyCode: string
|
|
50
55
|
filteredStateCode: string
|
|
51
56
|
isDraggingAnnotation: boolean
|
|
52
57
|
topoData: object | null
|
|
@@ -77,8 +82,12 @@ const reducer = (state: MapState, action: MapActions): MapState => {
|
|
|
77
82
|
return { ...state, displayPanel: action.payload }
|
|
78
83
|
case 'SET_FILTERED_COUNTRY_CODE':
|
|
79
84
|
return { ...state, filteredCountryCode: action.payload }
|
|
80
|
-
case '
|
|
81
|
-
return {
|
|
85
|
+
case 'SET_FILTERED_STATE_COUNTY_CODE':
|
|
86
|
+
return {
|
|
87
|
+
...state,
|
|
88
|
+
filteredStateCode: action.payload.stateCode || '',
|
|
89
|
+
filteredCountyCode: action.payload.countyCode || ''
|
|
90
|
+
}
|
|
82
91
|
case 'SET_IS_DRAGGING_ANNOTATION':
|
|
83
92
|
return { ...state, isDraggingAnnotation: action.payload }
|
|
84
93
|
case 'SET_TOPO_DATA':
|
package/src/test/CdcMap.test.jsx
CHANGED
|
@@ -1,11 +1,35 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
|
+
import fs from 'node:fs'
|
|
3
|
+
import vm from 'node:vm'
|
|
2
4
|
import { testStandaloneBuild } from '@cdc/core/helpers/tests/testStandaloneBuild.ts'
|
|
3
5
|
import { describe, it, expect } from 'vitest'
|
|
4
6
|
|
|
7
|
+
const extractMarkedExampleConfig = (content, label) => {
|
|
8
|
+
const match = content.match(
|
|
9
|
+
/<!-- README_EXAMPLE_CONFIG_START -->\s*```jsx\s*([\s\S]*?)\s*```\s*<!-- README_EXAMPLE_CONFIG_END -->/
|
|
10
|
+
)
|
|
11
|
+
expect(match, `${label} should contain a marked README example block`).toBeTruthy()
|
|
12
|
+
const configMatch = match[1].match(/const config = (\{[\s\S]*?\})\n\nfunction App\(\)/)
|
|
13
|
+
expect(configMatch, `${label} should define const config before function App()`).toBeTruthy()
|
|
14
|
+
return vm.runInNewContext(`(${configMatch[1]})`)
|
|
15
|
+
}
|
|
16
|
+
|
|
5
17
|
describe('Map', () => {
|
|
6
18
|
it('Can be built in isolation', async () => {
|
|
7
19
|
const pkgDir = path.join(__dirname, '..')
|
|
8
20
|
const result = await testStandaloneBuild(pkgDir)
|
|
9
21
|
expect(result).toBe(true)
|
|
10
22
|
}, 300000)
|
|
23
|
+
|
|
24
|
+
it('keeps the minimal example in sync with the README docs', () => {
|
|
25
|
+
const pkgRoot = path.join(__dirname, '..', '..')
|
|
26
|
+
const minimalExamplePath = path.join(pkgRoot, 'examples', 'minimal-example.json')
|
|
27
|
+
const readmePath = path.join(pkgRoot, 'README.md')
|
|
28
|
+
|
|
29
|
+
const minimalExample = JSON.parse(fs.readFileSync(minimalExamplePath, 'utf8'))
|
|
30
|
+
const readmeBlock = extractMarkedExampleConfig(fs.readFileSync(readmePath, 'utf8'), 'README.md')
|
|
31
|
+
|
|
32
|
+
expect(readmeBlock).toEqual(minimalExample)
|
|
33
|
+
expect(minimalExample.version).toBeTruthy()
|
|
34
|
+
})
|
|
11
35
|
})
|
package/src/types/MapConfig.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { type Version } from '@cdc/core/types/Version'
|
|
|
5
5
|
import { type VizFilter } from '@cdc/core/types/VizFilter'
|
|
6
6
|
import { type Annotation } from '@cdc/core/types/Annotation'
|
|
7
7
|
import { MarkupConfig } from '@cdc/core/types/MarkupVariable'
|
|
8
|
+
import { AltTextConfig } from '@cdc/core/types/AltText'
|
|
8
9
|
|
|
9
10
|
// Runtime data types
|
|
10
11
|
export type RuntimeFilters = VizFilter[] & { fromHash?: number }
|
|
@@ -66,6 +67,7 @@ type SimpleColumnProperties = Pick<EditorColumnProperties, 'name'>
|
|
|
66
67
|
|
|
67
68
|
// Specific column types for better semantics
|
|
68
69
|
type GeoColumnProperties = BaseColumnProperties & { displayColumn?: string }
|
|
70
|
+
type HSAColumnProperties = SimpleColumnProperties
|
|
69
71
|
type LatitudeColumnProperties = SimpleColumnProperties
|
|
70
72
|
type LongitudeColumnProperties = SimpleColumnProperties
|
|
71
73
|
type NavigateColumnProperties = SimpleColumnProperties
|
|
@@ -109,11 +111,13 @@ export type SmallMultiples = {
|
|
|
109
111
|
}
|
|
110
112
|
|
|
111
113
|
export type MapConfig = Visualization & {
|
|
114
|
+
altText?: AltTextConfig
|
|
112
115
|
annotations: Annotation[]
|
|
113
116
|
// map color palette
|
|
114
117
|
color: string
|
|
115
118
|
columns: {
|
|
116
119
|
geo: GeoColumnProperties
|
|
120
|
+
hsa: HSAColumnProperties
|
|
117
121
|
primary: PrimaryColumnProperties
|
|
118
122
|
navigate: NavigateColumnProperties
|
|
119
123
|
latitude: LatitudeColumnProperties
|
|
@@ -130,6 +134,7 @@ export type MapConfig = Visualization & {
|
|
|
130
134
|
subtext: string
|
|
131
135
|
introText: string
|
|
132
136
|
allowMapZoom: boolean
|
|
137
|
+
showClearSelectionButton?: boolean
|
|
133
138
|
convertFipsCodes: boolean
|
|
134
139
|
displayAsHex: boolean
|
|
135
140
|
displayStateLabels: boolean
|
|
@@ -164,7 +169,10 @@ export type MapConfig = Visualization & {
|
|
|
164
169
|
showDownloadImgButton: boolean
|
|
165
170
|
includeContextInDownload?: boolean
|
|
166
171
|
showDownloadPdfButton: boolean
|
|
172
|
+
showHSABoundaries?: boolean
|
|
173
|
+
showNeighboringStates?: boolean
|
|
167
174
|
showSidebar: boolean
|
|
175
|
+
showStateDropdown?: boolean
|
|
168
176
|
showTitle: boolean
|
|
169
177
|
statesPicked: {
|
|
170
178
|
fipsCode: string
|
|
@@ -215,11 +223,14 @@ export type MapConfig = Visualization & {
|
|
|
215
223
|
download: boolean
|
|
216
224
|
downloadDataLabel?: string
|
|
217
225
|
downloadImageLabel?: string
|
|
226
|
+
downloadUrlLabel?: string
|
|
218
227
|
showDownloadUrl: boolean
|
|
219
228
|
showFullGeoNameInCSV: boolean
|
|
220
229
|
forceDisplay: boolean
|
|
221
230
|
indexLabel: string
|
|
222
231
|
cellMinWidth: string
|
|
232
|
+
search?: boolean
|
|
233
|
+
searchPlaceholder?: string
|
|
223
234
|
}
|
|
224
235
|
tooltips: {
|
|
225
236
|
appearanceType: 'hover' | 'click'
|
package/src/types/MapContext.ts
CHANGED
|
@@ -7,12 +7,14 @@ import { MutableRefObject } from 'react'
|
|
|
7
7
|
|
|
8
8
|
export type MapContext = {
|
|
9
9
|
currentViewport: ViewPort
|
|
10
|
+
customNavigationHandler?: Function
|
|
10
11
|
vizViewport?: ViewPort
|
|
11
12
|
content: { geoName: string; keyedData: Record<string, any> }
|
|
12
13
|
dimensions: DimensionsType
|
|
13
14
|
displayDataAsText: string | number
|
|
14
15
|
displayGeoName: (key: string, displayOverride?: string) => string
|
|
15
16
|
filteredCountryCode: string
|
|
17
|
+
filteredCountyCode: string
|
|
16
18
|
filteredStateCode: string
|
|
17
19
|
generateRuntimeData: (
|
|
18
20
|
configObj: MapConfig,
|
|
@@ -37,7 +39,10 @@ export type MapContext = {
|
|
|
37
39
|
runtimeLegend
|
|
38
40
|
setParentConfig: Function
|
|
39
41
|
setRuntimeData: Function
|
|
40
|
-
|
|
42
|
+
setFilteredStateCountyCode: (stateCode: string, countyCode?: string) => void
|
|
43
|
+
setSharedFilter?: Function
|
|
44
|
+
clearSharedFilter?: (key: string) => void
|
|
45
|
+
hasActiveSharedFilter?: boolean
|
|
41
46
|
setSharedFilterValue: Function
|
|
42
47
|
setConfig: (newState: MapConfig) => MapConfig
|
|
43
48
|
config: MapConfig
|
|
@@ -4,7 +4,7 @@ Node script to convert shapefile data from census.gov to topojson, and format/op
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
Usage
|
|
7
|
-
1. Run yarn install
|
|
7
|
+
1. Run "yarn install" inside the packages/map/topojson-updater folder (this package is not part of the root Yarn workspace)
|
|
8
8
|
2. Download shapefiles from census.gov (https://www.census.gov/geographies/mapping-files/time-series/geo/cartographic-boundary.html) for the year that needs to be supported to the "shapefiles" folder of the project
|
|
9
9
|
- Always choose the options with the smallest file size
|
|
10
10
|
- Shapefiles for both states and counties should be downloaded for each year being added
|