@cdc/map 4.26.2 → 4.26.4
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 +235 -0
- package/README.md +70 -24
- package/dist/cdcmap-CY9IcPSi.es.js +6 -0
- package/dist/cdcmap-DlpiY3fQ.es.js +4 -0
- package/dist/cdcmap.js +31260 -27946
- 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 +3 -3
- package/examples/minimal-example.json +69 -0
- package/examples/private/annotation-bug.json +642 -0
- 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/CdcMap.tsx +3 -14
- package/src/CdcMapComponent.tsx +302 -164
- package/src/_stories/CdcMap.Defaults.smoke.stories.tsx +76 -0
- package/src/_stories/CdcMap.Editor.ColumnsSectionTests.stories.tsx +601 -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.stories.tsx → CdcMap.smoke.stories.tsx} +23 -1
- package/src/_stories/Map.HTMLInDataTable.stories.tsx +385 -0
- package/src/_stories/_mock/legends/legend-tests.json +3 -3
- 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/Annotation/AnnotationList.tsx +1 -1
- package/src/components/EditorPanel/components/EditorPanel.tsx +905 -416
- 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-style.css +1 -1
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +31 -15
- package/src/components/EditorPanel/components/editorPanel.styles.css +55 -25
- package/src/components/Legend/components/Legend.tsx +12 -7
- package/src/components/Legend/components/LegendGroup/legend.group.css +5 -5
- package/src/components/Legend/components/LegendItem.Hex.tsx +4 -2
- 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/SmallMultiples/SynchronizedTooltip.tsx +1 -1
- 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 +629 -231
- 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 +14 -9
- 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 +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 +15 -5
- package/src/data/legacy-defaults.ts +8 -0
- package/src/data/supported-counties.json +1 -1
- package/src/data/supported-geos.js +19 -0
- package/src/helpers/colors.ts +2 -1
- package/src/helpers/countyTerritories.ts +38 -0
- package/src/helpers/dataTableHelpers.ts +85 -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/countyTerritories.test.ts +87 -0
- 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/useApplyTooltipsToGeo.tsx +7 -4
- package/src/hooks/useMapLayers.tsx +1 -1
- package/src/hooks/useResizeObserver.ts +36 -22
- package/src/hooks/useTooltip.test.tsx +64 -0
- package/src/hooks/useTooltip.ts +46 -15
- 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 +5 -0
- package/src/store/map.reducer.ts +13 -0
- package/src/test/CdcMap.test.jsx +26 -2
- package/src/types/MapConfig.ts +28 -4
- package/src/types/MapContext.ts +5 -1
- package/topojson-updater/README.txt +1 -1
- package/dist/cdcmap-Cf9_fbQf.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 -3475
- package/src/helpers/componentHelpers.ts +0 -8
- 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.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/scss/main.scss
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
@import '@cdc/core/styles/
|
|
1
|
+
@import '@cdc/core/styles/utils/breakpoints';
|
|
2
2
|
@import 'editor-panel';
|
|
3
|
-
@import '@cdc/core/styles/accessibility';
|
|
3
|
+
@import '@cdc/core/styles/utils/accessibility';
|
|
4
|
+
@import '@cdc/core/styles/layout/wrapper-padding';
|
|
4
5
|
|
|
5
6
|
.type-map--has-error {
|
|
6
7
|
.waiting {
|
|
@@ -21,7 +22,7 @@
|
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
@include breakpointClass(md) {
|
|
24
|
-
.
|
|
25
|
+
.visualization-container.modal-background::before {
|
|
25
26
|
border-bottom: var(--lightGray) 1px solid;
|
|
26
27
|
margin-bottom: -1px;
|
|
27
28
|
bottom: 1px;
|
|
@@ -37,6 +38,129 @@
|
|
|
37
38
|
max-width: 100%;
|
|
38
39
|
background-color: white;
|
|
39
40
|
|
|
41
|
+
.cove-visualization__title,
|
|
42
|
+
.cove-visualization__header {
|
|
43
|
+
margin-bottom: 0 !important;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&.theme-blue {
|
|
47
|
+
--map-theme-color: #005eaa;
|
|
48
|
+
--map-theme-bg: #d9ebf9;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
&.theme-purple {
|
|
52
|
+
--map-theme-color: #712177;
|
|
53
|
+
--map-theme-bg: #f3e4f4;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&.theme-brown {
|
|
57
|
+
--map-theme-color: #705043;
|
|
58
|
+
--map-theme-bg: #f0e6e1;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
&.theme-teal {
|
|
62
|
+
--map-theme-color: #00695c;
|
|
63
|
+
--map-theme-bg: #d9f2ef;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
&.theme-pink {
|
|
67
|
+
--map-theme-color: #af4448;
|
|
68
|
+
--map-theme-bg: #fde7e8;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&.theme-orange {
|
|
72
|
+
--map-theme-color: #bb4d00;
|
|
73
|
+
--map-theme-bg: #fff0dd;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
&.theme-slate {
|
|
77
|
+
--map-theme-color: #29434e;
|
|
78
|
+
--map-theme-bg: #e3e8ea;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
&.theme-indigo {
|
|
82
|
+
--map-theme-color: #26418f;
|
|
83
|
+
--map-theme-bg: #e5eaf8;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
&.theme-cyan {
|
|
87
|
+
--map-theme-color: #007b91;
|
|
88
|
+
--map-theme-bg: #dff3f7;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
&.theme-green {
|
|
92
|
+
--map-theme-color: #4b830d;
|
|
93
|
+
--map-theme-bg: #e8f3dc;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
&.theme-amber {
|
|
97
|
+
--map-theme-color: #fbab18;
|
|
98
|
+
--map-theme-bg: #fff6da;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.cove-visualization__body {
|
|
102
|
+
@include cove-visualization-body-padding;
|
|
103
|
+
|
|
104
|
+
&:not(.no-borders) {
|
|
105
|
+
border: 1px solid var(--lightGray);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
&.component--has-border-color-theme:not(.no-borders) {
|
|
109
|
+
border-color: var(--map-theme-color, var(--lightGray));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
&.component--has-accent {
|
|
113
|
+
border-left: 0.5rem solid var(--map-theme-color, var(--blue));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
&.component--has-background:not(.component--hide-background-color) {
|
|
117
|
+
background-color: var(--map-theme-bg, var(--lightestGray));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
&.component--hide-background-color {
|
|
121
|
+
background-color: transparent;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
&.component--tp5-treatment {
|
|
125
|
+
background: transparent;
|
|
126
|
+
|
|
127
|
+
.cdc-callout {
|
|
128
|
+
box-shadow: 0 2px 4px rgb(159 159 159 / 10%);
|
|
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
|
+
}
|
|
143
|
+
|
|
144
|
+
.cove-visualization__title,
|
|
145
|
+
.cove-visualization__header {
|
|
146
|
+
background: transparent;
|
|
147
|
+
border: 0;
|
|
148
|
+
color: var(--cool-gray-90, #1f2937);
|
|
149
|
+
margin: 0 0 1rem;
|
|
150
|
+
padding: 0;
|
|
151
|
+
border-radius: 0;
|
|
152
|
+
|
|
153
|
+
h2 {
|
|
154
|
+
color: var(--cool-gray-90, #1f2937);
|
|
155
|
+
font-family: var(--fonts-nunito, var(--app-font-secondary));
|
|
156
|
+
font-size: 1.1rem;
|
|
157
|
+
font-weight: 700;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
40
164
|
header.hidden {
|
|
41
165
|
display: none;
|
|
42
166
|
}
|
|
@@ -45,17 +169,23 @@
|
|
|
45
169
|
border: 0;
|
|
46
170
|
}
|
|
47
171
|
|
|
48
|
-
.
|
|
172
|
+
.visualization-container {
|
|
49
173
|
display: flex;
|
|
50
174
|
position: relative;
|
|
51
175
|
flex-direction: column;
|
|
52
176
|
|
|
53
177
|
&.bottom {
|
|
54
178
|
flex-direction: column;
|
|
179
|
+
row-gap: var(--cove-visualization-section-gap, 1.5rem);
|
|
180
|
+
|
|
181
|
+
>.legends {
|
|
182
|
+
margin-top: var(--cove-visualization-section-gap, 1.5rem) !important;
|
|
183
|
+
}
|
|
55
184
|
}
|
|
56
185
|
|
|
57
186
|
&.top {
|
|
58
187
|
flex-direction: column-reverse;
|
|
188
|
+
row-gap: var(--cove-visualization-section-gap, 1.5rem);
|
|
59
189
|
}
|
|
60
190
|
|
|
61
191
|
&.modal-background {
|
|
@@ -88,7 +218,6 @@
|
|
|
88
218
|
/* Constrain the modal's height to 90% of the viewport */
|
|
89
219
|
overflow-y: auto;
|
|
90
220
|
/* Enable vertical scrolling if content overflows */
|
|
91
|
-
font-size: 1rem;
|
|
92
221
|
line-height: 1.4em;
|
|
93
222
|
}
|
|
94
223
|
|
|
@@ -142,6 +271,11 @@
|
|
|
142
271
|
}
|
|
143
272
|
}
|
|
144
273
|
|
|
274
|
+
.visualization-container.legend-wrapped-bottom>.legends,
|
|
275
|
+
.legends.legend-wrapped-bottom {
|
|
276
|
+
margin-top: var(--cove-visualization-section-gap, 1.5rem) !important;
|
|
277
|
+
}
|
|
278
|
+
|
|
145
279
|
p.subtext {
|
|
146
280
|
em {
|
|
147
281
|
font-style: italic;
|
|
@@ -213,4 +347,4 @@
|
|
|
213
347
|
[tabIndex]:focus {
|
|
214
348
|
outline-color: rgb(0, 95, 204);
|
|
215
349
|
}
|
|
216
|
-
}
|
|
350
|
+
}
|
package/src/scss/map.scss
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
@include breakpointClass(md) {
|
|
2
2
|
// Data Specific
|
|
3
|
-
.
|
|
3
|
+
.visualization-container.data {
|
|
4
4
|
&.side {
|
|
5
5
|
flex-direction: row;
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
|
-
.
|
|
8
|
+
.visualization-container.map {
|
|
9
9
|
&.side {
|
|
10
10
|
flex-direction: row;
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
// Bubble Specific
|
|
14
|
-
.
|
|
14
|
+
.visualization-container.bubble {
|
|
15
15
|
&.side {
|
|
16
16
|
flex-direction: row;
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
.
|
|
20
|
+
.visualization-container.us-geocode {
|
|
21
21
|
&.side {
|
|
22
22
|
flex-direction: row;
|
|
23
23
|
}
|
|
@@ -114,3 +114,8 @@ canvas {
|
|
|
114
114
|
pointer-events: none;
|
|
115
115
|
display: none;
|
|
116
116
|
}
|
|
117
|
+
|
|
118
|
+
.county-map-canvas {
|
|
119
|
+
touch-action: none;
|
|
120
|
+
cursor: move;
|
|
121
|
+
}
|
package/src/store/map.actions.ts
CHANGED
|
@@ -11,6 +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 SET_FILTERED_STATE_COUNTY_CODE = Action<
|
|
15
|
+
'SET_FILTERED_STATE_COUNTY_CODE',
|
|
16
|
+
{ stateCode?: string; countyCode?: string }
|
|
17
|
+
>
|
|
14
18
|
type SET_IS_DRAGGING_ANNOTATION = Action<'SET_IS_DRAGGING_ANNOTATION', boolean>
|
|
15
19
|
type SET_LOADING = Action<'SET_LOADING', boolean>
|
|
16
20
|
type SET_MODAL = Action<'SET_MODAL', Modal>
|
|
@@ -30,6 +34,7 @@ type MapActions =
|
|
|
30
34
|
| SET_COVE_LOADED_HAS_RAN
|
|
31
35
|
| SET_DISPLAY_PANEL
|
|
32
36
|
| SET_FILTERED_COUNTRY_CODE
|
|
37
|
+
| SET_FILTERED_STATE_COUNTY_CODE
|
|
33
38
|
| SET_IS_DRAGGING_ANNOTATION
|
|
34
39
|
| SET_LOADING
|
|
35
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,6 +27,8 @@ export const getInitialState = (configObj = {}): MapState => {
|
|
|
24
27
|
coveLoadedHasRan: false,
|
|
25
28
|
displayPanel: false,
|
|
26
29
|
filteredCountryCode: '',
|
|
30
|
+
filteredCountyCode,
|
|
31
|
+
filteredStateCode,
|
|
27
32
|
isDraggingAnnotation: false,
|
|
28
33
|
topoData: null,
|
|
29
34
|
translate: [0, 0],
|
|
@@ -46,6 +51,8 @@ export type MapState = {
|
|
|
46
51
|
coveLoadedHasRan: boolean
|
|
47
52
|
displayPanel: boolean
|
|
48
53
|
filteredCountryCode: string
|
|
54
|
+
filteredCountyCode: string
|
|
55
|
+
filteredStateCode: string
|
|
49
56
|
isDraggingAnnotation: boolean
|
|
50
57
|
topoData: object | null
|
|
51
58
|
translate: number[]
|
|
@@ -75,6 +82,12 @@ const reducer = (state: MapState, action: MapActions): MapState => {
|
|
|
75
82
|
return { ...state, displayPanel: action.payload }
|
|
76
83
|
case 'SET_FILTERED_COUNTRY_CODE':
|
|
77
84
|
return { ...state, filteredCountryCode: action.payload }
|
|
85
|
+
case 'SET_FILTERED_STATE_COUNTY_CODE':
|
|
86
|
+
return {
|
|
87
|
+
...state,
|
|
88
|
+
filteredStateCode: action.payload.stateCode || '',
|
|
89
|
+
filteredCountyCode: action.payload.countyCode || ''
|
|
90
|
+
}
|
|
78
91
|
case 'SET_IS_DRAGGING_ANNOTATION':
|
|
79
92
|
return { ...state, isDraggingAnnotation: action.payload }
|
|
80
93
|
case 'SET_TOPO_DATA':
|
package/src/test/CdcMap.test.jsx
CHANGED
|
@@ -1,11 +1,35 @@
|
|
|
1
|
-
import path from 'path'
|
|
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
|
-
const result = testStandaloneBuild(pkgDir)
|
|
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
|
@@ -10,6 +10,20 @@ import { MarkupConfig } from '@cdc/core/types/MarkupVariable'
|
|
|
10
10
|
export type RuntimeFilters = VizFilter[] & { fromHash?: number }
|
|
11
11
|
|
|
12
12
|
type MapVisualSettings = {
|
|
13
|
+
/** border - shows or hides component border */
|
|
14
|
+
border?: boolean
|
|
15
|
+
/** borderColorTheme - use themed border color */
|
|
16
|
+
borderColorTheme?: boolean
|
|
17
|
+
/** accent - use accent styling */
|
|
18
|
+
accent?: boolean
|
|
19
|
+
/** background - use themed background color */
|
|
20
|
+
background?: boolean
|
|
21
|
+
/** hideBackgroundColor - hide default background color */
|
|
22
|
+
hideBackgroundColor?: boolean
|
|
23
|
+
/** tp5Treatment - render the TP5 callout shell */
|
|
24
|
+
tp5Treatment?: boolean
|
|
25
|
+
/** tp5Background - enable the TP5 cyan background */
|
|
26
|
+
tp5Background?: boolean
|
|
13
27
|
/** minBubbleSize - Minimum Circle Size when the map has a type of bubble */
|
|
14
28
|
minBubbleSize: number
|
|
15
29
|
/** maxBubbleSize - Maximum Circle Size when the map has a type of bubble */
|
|
@@ -29,9 +43,9 @@ type MapVisualSettings = {
|
|
|
29
43
|
}
|
|
30
44
|
|
|
31
45
|
export type PatternSelection = {
|
|
32
|
-
//
|
|
46
|
+
// column used to match patterns; empty string means match dataValue across all row columns
|
|
33
47
|
dataKey: string
|
|
34
|
-
//
|
|
48
|
+
// value to match (numeric-like values are compared numerically)
|
|
35
49
|
dataValue: string
|
|
36
50
|
// style of pattern to use
|
|
37
51
|
pattern: 'lines' | 'circles' | 'waves'
|
|
@@ -51,7 +65,8 @@ type BaseColumnProperties = Pick<EditorColumnProperties, 'name'> &
|
|
|
51
65
|
type SimpleColumnProperties = Pick<EditorColumnProperties, 'name'>
|
|
52
66
|
|
|
53
67
|
// Specific column types for better semantics
|
|
54
|
-
type GeoColumnProperties = BaseColumnProperties
|
|
68
|
+
type GeoColumnProperties = BaseColumnProperties & { displayColumn?: string }
|
|
69
|
+
type HSAColumnProperties = SimpleColumnProperties
|
|
55
70
|
type LatitudeColumnProperties = SimpleColumnProperties
|
|
56
71
|
type LongitudeColumnProperties = SimpleColumnProperties
|
|
57
72
|
type NavigateColumnProperties = SimpleColumnProperties
|
|
@@ -100,6 +115,7 @@ export type MapConfig = Visualization & {
|
|
|
100
115
|
color: string
|
|
101
116
|
columns: {
|
|
102
117
|
geo: GeoColumnProperties
|
|
118
|
+
hsa: HSAColumnProperties
|
|
103
119
|
primary: PrimaryColumnProperties
|
|
104
120
|
navigate: NavigateColumnProperties
|
|
105
121
|
latitude: LatitudeColumnProperties
|
|
@@ -150,12 +166,16 @@ export type MapConfig = Visualization & {
|
|
|
150
166
|
showDownloadImgButton: boolean
|
|
151
167
|
includeContextInDownload?: boolean
|
|
152
168
|
showDownloadPdfButton: boolean
|
|
169
|
+
showHSABoundaries?: boolean
|
|
170
|
+
showNeighboringStates?: boolean
|
|
153
171
|
showSidebar: boolean
|
|
172
|
+
showStateDropdown?: boolean
|
|
154
173
|
showTitle: boolean
|
|
155
174
|
statesPicked: {
|
|
156
175
|
fipsCode: string
|
|
157
176
|
stateName: string
|
|
158
177
|
}[]
|
|
178
|
+
hideUnselectedStates?: boolean
|
|
159
179
|
countriesPicked?: {
|
|
160
180
|
iso: string
|
|
161
181
|
name: string
|
|
@@ -197,16 +217,20 @@ export type MapConfig = Visualization & {
|
|
|
197
217
|
limitHeight: boolean
|
|
198
218
|
height: string
|
|
199
219
|
caption: string
|
|
220
|
+
download: boolean
|
|
221
|
+
downloadDataLabel?: string
|
|
222
|
+
downloadImageLabel?: string
|
|
223
|
+
downloadUrlLabel?: string
|
|
200
224
|
showDownloadUrl: boolean
|
|
201
225
|
showFullGeoNameInCSV: boolean
|
|
202
226
|
forceDisplay: boolean
|
|
203
|
-
download: boolean
|
|
204
227
|
indexLabel: string
|
|
205
228
|
cellMinWidth: string
|
|
206
229
|
}
|
|
207
230
|
tooltips: {
|
|
208
231
|
appearanceType: 'hover' | 'click'
|
|
209
232
|
linkLabel: string
|
|
233
|
+
noDataLabel?: string
|
|
210
234
|
opacity: number
|
|
211
235
|
}
|
|
212
236
|
runtime: {
|
package/src/types/MapContext.ts
CHANGED
|
@@ -7,12 +7,15 @@ 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
|
-
displayGeoName: (key: string,
|
|
15
|
+
displayGeoName: (key: string, displayOverride?: string) => string
|
|
15
16
|
filteredCountryCode: string
|
|
17
|
+
filteredCountyCode: string
|
|
18
|
+
filteredStateCode: string
|
|
16
19
|
generateRuntimeData: (
|
|
17
20
|
configObj: MapConfig,
|
|
18
21
|
filters: VizFilter[],
|
|
@@ -36,6 +39,7 @@ export type MapContext = {
|
|
|
36
39
|
runtimeLegend
|
|
37
40
|
setParentConfig: Function
|
|
38
41
|
setRuntimeData: Function
|
|
42
|
+
setFilteredStateCountyCode: (stateCode: string, countyCode?: string) => void
|
|
39
43
|
setSharedFilterValue: Function
|
|
40
44
|
setConfig: (newState: MapConfig) => MapConfig
|
|
41
45
|
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
|