@cdc/map 4.25.8 → 4.25.10
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/.claude/settings.local.json +30 -0
- package/dist/cdcmap.js +54263 -52600
- package/examples/private/c.json +290 -0
- package/examples/private/canvas-city-hover.json +787 -0
- package/examples/private/d.json +345 -0
- package/examples/private/g.json +1 -0
- package/examples/private/h.json +105911 -0
- package/examples/private/measles-data.json +378 -0
- package/examples/private/measles.json +211 -0
- package/examples/private/north-dakota.json +1132 -0
- package/examples/private/state-with-pattern.json +883 -0
- package/index.html +35 -34
- package/package.json +26 -5
- package/src/CdcMap.tsx +23 -8
- package/src/CdcMapComponent.tsx +215 -309
- package/src/_stories/CdcMap.Filters.stories.tsx +2 -2
- package/src/_stories/CdcMap.Legend.Gradient.stories.tsx +3 -3
- package/src/_stories/CdcMap.Legend.stories.tsx +7 -4
- package/src/_stories/CdcMap.Patterns.stories.tsx +2 -2
- package/src/_stories/CdcMap.Table.stories.tsx +2 -2
- package/src/_stories/CdcMap.stories.tsx +15 -5
- package/src/_stories/GoogleMap.stories.tsx +2 -2
- package/src/_stories/UsaMap.NoData.stories.tsx +2 -2
- package/src/_stories/_mock/equal-number.json +1109 -0
- package/src/_stories/_mock/us-bubble-cities.json +306 -0
- package/src/components/BubbleList.tsx +16 -12
- package/src/components/CityList.tsx +85 -107
- package/src/components/DataTable.tsx +37 -9
- package/src/components/EditorPanel/components/EditorPanel.tsx +177 -165
- package/src/components/EditorPanel/components/HexShapeSettings.tsx +3 -2
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +7 -5
- package/src/components/Geo.tsx +2 -0
- package/src/components/Legend/components/Legend.tsx +109 -73
- package/src/components/Legend/components/LegendGroup/Legend.Group.tsx +10 -7
- package/src/components/MapContainer.tsx +52 -0
- package/src/components/MapControls.tsx +44 -0
- package/src/components/NavigationMenu.tsx +11 -2
- package/src/components/UsaMap/components/SingleState/SingleState.CountyOutput.tsx +24 -7
- package/src/components/UsaMap/components/UsaMap.County.tsx +111 -37
- package/src/components/UsaMap/components/UsaMap.Region.tsx +23 -5
- package/src/components/UsaMap/components/UsaMap.SingleState.tsx +6 -6
- package/src/components/UsaMap/components/UsaMap.State.tsx +28 -10
- package/src/components/UsaMap/helpers/map.ts +2 -2
- package/src/components/WorldMap/WorldMap.tsx +113 -25
- package/src/components/ZoomControls.tsx +6 -9
- package/src/context/LegendMemoContext.tsx +30 -0
- package/src/context.ts +1 -40
- package/src/data/initial-state.js +143 -130
- package/src/data/supported-geos.js +17 -2
- package/src/helpers/applyColorToLegend.ts +116 -20
- package/src/helpers/applyLegendToRow.ts +10 -6
- package/src/helpers/componentHelpers.ts +8 -0
- package/src/helpers/constants.ts +12 -0
- package/src/helpers/dataTableHelpers.ts +6 -0
- package/src/helpers/displayGeoName.ts +1 -1
- package/src/helpers/generateRuntimeLegend.ts +44 -8
- package/src/helpers/generateRuntimeLegendHash.ts +4 -2
- package/src/helpers/getColumnNames.ts +1 -1
- package/src/helpers/getPatternForRow.ts +36 -0
- package/src/helpers/getStatesPicked.ts +8 -5
- package/src/helpers/index.ts +11 -3
- package/src/helpers/isLegendItemDisabled.ts +16 -0
- package/src/helpers/mapObserverHelpers.ts +40 -0
- package/src/helpers/resetLegendToggles.ts +3 -2
- package/src/helpers/toggleLegendActive.ts +6 -11
- package/src/helpers/urlDataHelpers.ts +70 -0
- package/src/hooks/useGeoClickHandler.ts +35 -1
- package/src/hooks/useLegendMemo.ts +17 -0
- package/src/hooks/useMapLayers.tsx +5 -4
- package/src/hooks/useStateZoom.tsx +25 -6
- package/src/hooks/useTooltip.ts +1 -2
- package/src/index.jsx +0 -2
- package/src/store/map.reducer.ts +17 -6
- package/src/test/CdcMap.test.jsx +11 -0
- package/src/types/MapConfig.ts +23 -14
- package/src/types/MapContext.ts +0 -7
- package/src/types/runtimeLegend.ts +17 -1
- package/vite.config.js +2 -7
- package/vitest.config.ts +16 -0
- package/src/coreStyles_map.scss +0 -3
- package/src/helpers/colorDistributions.ts +0 -12
- package/src/helpers/generateColorsArray.ts +0 -14
- package/src/helpers/tests/generateColorsArray.test.ts +0 -18
- package/src/helpers/tests/generateRuntimeLegendHash.test.ts +0 -11
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import ConfigContext, { MapDispatchContext } from '../context'
|
|
2
2
|
import { navigationHandler } from '../helpers'
|
|
3
3
|
import { useContext } from 'react'
|
|
4
|
+
import { publishAnalyticsEvent } from '@cdc/core/helpers/metrics/helpers'
|
|
5
|
+
import { getVizTitle } from '@cdc/core/helpers/metrics/utils'
|
|
4
6
|
|
|
5
7
|
const useGeoClickHandler = () => {
|
|
6
|
-
const {
|
|
8
|
+
const {
|
|
9
|
+
config: state,
|
|
10
|
+
setConfig,
|
|
11
|
+
setSharedFilter,
|
|
12
|
+
customNavigationHandler,
|
|
13
|
+
interactionLabel
|
|
14
|
+
} = useContext(ConfigContext)
|
|
7
15
|
const dispatch = useContext(MapDispatchContext)
|
|
8
16
|
|
|
9
17
|
const geoClickHandler = (geoDisplayName: string, geoData: object): void => {
|
|
@@ -30,11 +38,37 @@ const useGeoClickHandler = () => {
|
|
|
30
38
|
}
|
|
31
39
|
dispatch({ type: 'SET_MODAL', payload: modalData })
|
|
32
40
|
|
|
41
|
+
// Track modal click analytics event
|
|
42
|
+
if (interactionLabel) {
|
|
43
|
+
const locationName = geoDisplayName.replace(/[^a-zA-Z0-9]/g, '_')
|
|
44
|
+
publishAnalyticsEvent({
|
|
45
|
+
vizType: 'map',
|
|
46
|
+
eventType: `modal_trigger` as any,
|
|
47
|
+
eventAction: 'click',
|
|
48
|
+
eventLabel: interactionLabel,
|
|
49
|
+
vizTitle: getVizTitle(state),
|
|
50
|
+
specifics: `clicked on: ${String(locationName).toLowerCase()}`
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
33
54
|
return
|
|
34
55
|
}
|
|
35
56
|
|
|
36
57
|
// Otherwise if this item has a link specified for it, do regular navigation.
|
|
37
58
|
if (state.columns.navigate && geoData[state.columns.navigate.name]) {
|
|
59
|
+
// Track navigation click analytics event
|
|
60
|
+
if (interactionLabel) {
|
|
61
|
+
const locationName = geoDisplayName.replace(/[^a-zA-Z0-9]/g, '_')
|
|
62
|
+
publishAnalyticsEvent({
|
|
63
|
+
vizType: 'map',
|
|
64
|
+
eventType: `map_trigger` as any,
|
|
65
|
+
eventAction: 'click',
|
|
66
|
+
eventLabel: interactionLabel,
|
|
67
|
+
vizTitle: getVizTitle(state),
|
|
68
|
+
specifics: `clicked on: ${String(locationName).toLowerCase()}`
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
38
72
|
navigationHandler(state.general.navigationTarget, geoData[state.columns.navigate.name], customNavigationHandler)
|
|
39
73
|
}
|
|
40
74
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { useRef } from 'react'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Custom hook to manage legend memoization refs
|
|
5
|
+
* Extracted from context to reduce context props and improve performance
|
|
6
|
+
*/
|
|
7
|
+
export const useLegendMemo = () => {
|
|
8
|
+
const legendMemo = useRef(new Map())
|
|
9
|
+
const legendSpecialClassLastMemo = useRef(new Map())
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
legendMemo,
|
|
13
|
+
legendSpecialClassLastMemo
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default useLegendMemo
|
|
@@ -3,6 +3,7 @@ import { feature } from 'topojson-client'
|
|
|
3
3
|
import { Group } from '@visx/group'
|
|
4
4
|
import { MapConfig } from '../types/MapConfig'
|
|
5
5
|
import _ from 'lodash'
|
|
6
|
+
import { cloneConfig } from '@cdc/core/helpers/cloneConfig'
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* This is the starting structure for adding custom geoJSON shape layers to a projection.
|
|
@@ -46,10 +47,10 @@ export default function useMapLayers(config: MapConfig, setConfig, pathGenerator
|
|
|
46
47
|
|
|
47
48
|
const handleRemoveLayer = (e: MouseEvent<HTMLButtonElement>, index: number) => {
|
|
48
49
|
e.preventDefault()
|
|
49
|
-
const newConfig =
|
|
50
|
+
const newConfig = cloneConfig(config)
|
|
50
51
|
const layers = newConfig.map.layers.filter((_layer, i) => i !== index)
|
|
51
52
|
newConfig.map.layers = layers
|
|
52
|
-
setConfig(newConfig
|
|
53
|
+
setConfig(newConfig)
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
const handleAddLayer = (e: Event) => {
|
|
@@ -58,9 +59,9 @@ export default function useMapLayers(config: MapConfig, setConfig, pathGenerator
|
|
|
58
59
|
name: 'New Custom Layer',
|
|
59
60
|
url: ''
|
|
60
61
|
}
|
|
61
|
-
const newConfig =
|
|
62
|
+
const newConfig = cloneConfig(config)
|
|
62
63
|
newConfig.map.layers.unshift(placeHolderLayer)
|
|
63
|
-
setConfig(
|
|
64
|
+
setConfig(newConfig)
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
const handleMapLayer = (e: ChangeEvent<HTMLInputElement>, index: number, layerKey: string) => {
|
|
@@ -7,6 +7,7 @@ import { getFilterControllingStatesPicked } from '../components/UsaMap/helpers/m
|
|
|
7
7
|
import { supportedStatesFipsCodes } from '../data/supported-geos'
|
|
8
8
|
import { SVG_HEIGHT, SVG_WIDTH, SVG_PADDING } from '../helpers'
|
|
9
9
|
import { publishAnalyticsEvent } from '@cdc/core/helpers/metrics/helpers'
|
|
10
|
+
import { getVizTitle, getVizSubType } from '@cdc/core/helpers/metrics/utils'
|
|
10
11
|
|
|
11
12
|
interface StateData {
|
|
12
13
|
geometry: { type: 'MultiPolygon'; coordinates: number[][][][] }
|
|
@@ -80,7 +81,15 @@ const useSetScaleAndTranslate = (topoData: { states: StateData[] }) => {
|
|
|
80
81
|
_prevPosition.coordinates[0] !== 0 && _prevPosition.coordinates[1] !== 0
|
|
81
82
|
? _prevPosition.coordinates
|
|
82
83
|
: projectionData.stateCenter
|
|
83
|
-
publishAnalyticsEvent(
|
|
84
|
+
publishAnalyticsEvent({
|
|
85
|
+
vizType: 'map',
|
|
86
|
+
vizSubType: getVizSubType(config),
|
|
87
|
+
eventType: 'zoom_in',
|
|
88
|
+
eventAction: 'click',
|
|
89
|
+
eventLabel: interactionLabel,
|
|
90
|
+
vizTitle: getVizTitle(config),
|
|
91
|
+
specifics: `zoom: ${newZoom}, coordinates:${newCoordinates}`
|
|
92
|
+
})
|
|
84
93
|
} else if (zoomFunction === 'zoomOut' && _prevPosition.zoom > 1) {
|
|
85
94
|
newZoom = _prevPosition.zoom / 1.5
|
|
86
95
|
newCoordinates =
|
|
@@ -97,7 +106,14 @@ const useSetScaleAndTranslate = (topoData: { states: StateData[] }) => {
|
|
|
97
106
|
if (zoomFunction === 'reset') {
|
|
98
107
|
dispatch({ type: 'SET_TRANSLATE', payload: [0, 0] }) // needed for state switcher
|
|
99
108
|
dispatch({ type: 'SET_SCALE', payload: 1 }) // needed for state switcher
|
|
100
|
-
publishAnalyticsEvent(
|
|
109
|
+
publishAnalyticsEvent({
|
|
110
|
+
vizType: 'map',
|
|
111
|
+
vizSubType: getVizSubType(config),
|
|
112
|
+
eventType: 'map_reset_zoom_level',
|
|
113
|
+
eventAction: 'click',
|
|
114
|
+
eventLabel: interactionLabel,
|
|
115
|
+
vizTitle: getVizTitle(config)
|
|
116
|
+
})
|
|
101
117
|
}
|
|
102
118
|
},
|
|
103
119
|
[config.mapPosition, projectionData.stateCenter, interactionLabel, dispatch]
|
|
@@ -145,9 +161,12 @@ const useSetScaleAndTranslate = (topoData: { states: StateData[] }) => {
|
|
|
145
161
|
[dispatch]
|
|
146
162
|
)
|
|
147
163
|
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
164
|
+
const handleZoomReset = useCallback(
|
|
165
|
+
_setRuntimeData => {
|
|
166
|
+
setScaleAndTranslate('reset')
|
|
167
|
+
},
|
|
168
|
+
[setScaleAndTranslate]
|
|
169
|
+
)
|
|
151
170
|
|
|
152
171
|
return {
|
|
153
172
|
statesPicked,
|
|
@@ -156,7 +175,7 @@ const useSetScaleAndTranslate = (topoData: { states: StateData[] }) => {
|
|
|
156
175
|
handleZoomIn,
|
|
157
176
|
handleZoomOut,
|
|
158
177
|
handleMoveEnd,
|
|
159
|
-
|
|
178
|
+
handleZoomReset,
|
|
160
179
|
projection: projectionData.projection
|
|
161
180
|
}
|
|
162
181
|
}
|
package/src/hooks/useTooltip.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { displayDataAsText } from '
|
|
1
|
+
import { displayDataAsText } from '@cdc/core/helpers/displayDataAsText'
|
|
2
2
|
import { displayGeoName } from '../helpers/displayGeoName'
|
|
3
3
|
|
|
4
4
|
const useTooltip = props => {
|
|
5
5
|
const { config, supportedStatesFipsCodes } = props
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* On county maps there's a need to append the state name
|
|
10
9
|
* @param {String} toolTipText - previous tooltip text to build upon
|
package/src/index.jsx
CHANGED
package/src/store/map.reducer.ts
CHANGED
|
@@ -1,13 +1,24 @@
|
|
|
1
|
-
import { MapConfig } from '../types/MapConfig'
|
|
1
|
+
import { MapConfig, RuntimeFilters } from '../types/MapConfig'
|
|
2
2
|
import MapActions from './map.actions'
|
|
3
3
|
import defaults from './../data/initial-state'
|
|
4
4
|
import { devToolsWrapper } from '@cdc/core/helpers/withDevTools'
|
|
5
5
|
import _ from 'lodash'
|
|
6
|
+
import { Modal } from '../types/Modal'
|
|
7
|
+
import { GeneratedLegend } from '../helpers/generateRuntimeLegend'
|
|
8
|
+
import { RuntimeData } from '../types/RuntimeData'
|
|
6
9
|
|
|
7
10
|
export const getInitialState = (configObj = {}): MapState => {
|
|
11
|
+
// Create defaults without palette version to avoid overriding legacy configs
|
|
12
|
+
const defaultsWithoutPaletteaName = { ...defaults }
|
|
13
|
+
|
|
14
|
+
// Only apply palette defaults if the loaded config explicitly has general.palette
|
|
15
|
+
// if (!configObj?.general?.palette?.name) {
|
|
16
|
+
// delete defaultsWithoutPaletteaName.general?.palette.name
|
|
17
|
+
// }
|
|
18
|
+
|
|
8
19
|
return {
|
|
9
20
|
dataUrl: configObj.dataUrl || '',
|
|
10
|
-
config: _.merge({},
|
|
21
|
+
config: _.merge({}, defaultsWithoutPaletteaName, configObj),
|
|
11
22
|
loading: false,
|
|
12
23
|
accessibleStatus: '',
|
|
13
24
|
coveLoadedHasRan: false,
|
|
@@ -42,10 +53,10 @@ export type MapState = {
|
|
|
42
53
|
projection: object | null
|
|
43
54
|
requiredColumns: string[]
|
|
44
55
|
scale: number
|
|
45
|
-
modal:
|
|
46
|
-
runtimeData:
|
|
47
|
-
runtimeFilters:
|
|
48
|
-
runtimeLegend:
|
|
56
|
+
modal: Modal | null
|
|
57
|
+
runtimeData: RuntimeData | { init: boolean }
|
|
58
|
+
runtimeFilters: RuntimeFilters
|
|
59
|
+
runtimeLegend: GeneratedLegend | []
|
|
49
60
|
statesToShow: string[]
|
|
50
61
|
dataUrl: string
|
|
51
62
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import { testStandaloneBuild } from '@cdc/core/helpers/tests/testStandaloneBuild.ts'
|
|
3
|
+
import { describe, it, expect } from 'vitest'
|
|
4
|
+
|
|
5
|
+
describe('Map', () => {
|
|
6
|
+
it('Can be built in isolation', async () => {
|
|
7
|
+
const pkgDir = path.join(__dirname, '..')
|
|
8
|
+
const result = testStandaloneBuild(pkgDir)
|
|
9
|
+
expect(result).toBe(true)
|
|
10
|
+
})
|
|
11
|
+
})
|
package/src/types/MapConfig.ts
CHANGED
|
@@ -3,6 +3,10 @@ import { type Visualization } from '@cdc/core/types/Visualization'
|
|
|
3
3
|
import { type EditorColumnProperties } from '@cdc/core/types/EditorColumnProperties'
|
|
4
4
|
import { type Version } from '@cdc/core/types/Version'
|
|
5
5
|
import { type VizFilter } from '@cdc/core/types/VizFilter'
|
|
6
|
+
import { MarkupConfig } from '@cdc/core/types/MarkupVariable'
|
|
7
|
+
|
|
8
|
+
// Runtime data types
|
|
9
|
+
export type RuntimeFilters = VizFilter[] & { fromHash?: number }
|
|
6
10
|
|
|
7
11
|
export type MapVisualSettings = {
|
|
8
12
|
/** minBubbleSize - Minimum Circle Size when the map has a type of bubble */
|
|
@@ -38,14 +42,19 @@ export type PatternSelection = {
|
|
|
38
42
|
contrastCheck: boolean
|
|
39
43
|
}
|
|
40
44
|
|
|
41
|
-
|
|
42
|
-
export type
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
// Base column properties with name required, all others optional
|
|
46
|
+
export type BaseColumnProperties = Pick<EditorColumnProperties, 'name'> &
|
|
47
|
+
Partial<Pick<EditorColumnProperties, 'label' | 'tooltip' | 'dataTable' | 'prefix' | 'suffix'>>
|
|
48
|
+
|
|
49
|
+
// Simple column type for name-only columns
|
|
50
|
+
export type SimpleColumnProperties = Pick<EditorColumnProperties, 'name'>
|
|
51
|
+
|
|
52
|
+
// Specific column types for better semantics
|
|
53
|
+
export type GeoColumnProperties = BaseColumnProperties
|
|
54
|
+
export type LatitudeColumnProperties = SimpleColumnProperties
|
|
55
|
+
export type LongitudeColumnProperties = SimpleColumnProperties
|
|
56
|
+
export type NavigateColumnProperties = SimpleColumnProperties
|
|
57
|
+
export type PrimaryColumnProperties = BaseColumnProperties
|
|
49
58
|
|
|
50
59
|
export type LegendShapeItem = {
|
|
51
60
|
column: string
|
|
@@ -70,15 +79,13 @@ export type Coordinate = [number, number]
|
|
|
70
79
|
|
|
71
80
|
export type DataRow = {
|
|
72
81
|
uid?: string // optional 'uid' property
|
|
73
|
-
[key: string]:
|
|
82
|
+
[key: string]: string | number | boolean | null | undefined // allowing primitive data types for dynamic columns
|
|
74
83
|
}
|
|
75
84
|
|
|
76
85
|
export type MapConfig = Visualization & {
|
|
77
86
|
annotations: Annotation[]
|
|
78
87
|
// map color palette
|
|
79
88
|
color: string
|
|
80
|
-
// custom color palette
|
|
81
|
-
customColors: string[]
|
|
82
89
|
columns: {
|
|
83
90
|
geo: GeoColumnProperties
|
|
84
91
|
primary: PrimaryColumnProperties
|
|
@@ -93,6 +100,7 @@ export type MapConfig = Visualization & {
|
|
|
93
100
|
filters: VizFilter[]
|
|
94
101
|
general: {
|
|
95
102
|
navigationTarget: '_self' | '_blank'
|
|
103
|
+
noDataMessage: string // single-state no data message
|
|
96
104
|
subtext: string
|
|
97
105
|
introText: string
|
|
98
106
|
allowMapZoom: boolean
|
|
@@ -121,6 +129,9 @@ export type MapConfig = Visualization & {
|
|
|
121
129
|
language: string
|
|
122
130
|
palette: {
|
|
123
131
|
isReversed: boolean
|
|
132
|
+
name: string
|
|
133
|
+
version: string
|
|
134
|
+
customColors?: string[]
|
|
124
135
|
}
|
|
125
136
|
showDownloadMediaButton: boolean
|
|
126
137
|
showDownloadImgButton: boolean
|
|
@@ -180,8 +191,6 @@ export type MapConfig = Visualization & {
|
|
|
180
191
|
}
|
|
181
192
|
runtime: {
|
|
182
193
|
editorErrorMessage: string[]
|
|
183
|
-
// when a single state map doesn't include a fips code show a message...
|
|
184
|
-
noStateFoundMessage: string
|
|
185
194
|
}
|
|
186
195
|
mapPosition: { coordinates: Coordinate; zoom: number }
|
|
187
196
|
map: {
|
|
@@ -196,4 +205,4 @@ export type MapConfig = Visualization & {
|
|
|
196
205
|
type: 'map'
|
|
197
206
|
// version of the map
|
|
198
207
|
version: Version
|
|
199
|
-
}
|
|
208
|
+
} & MarkupConfig
|
package/src/types/MapContext.ts
CHANGED
|
@@ -2,12 +2,10 @@ import { DataRow, type MapConfig } from './MapConfig'
|
|
|
2
2
|
import { type ViewPort } from '@cdc/core/types/ViewPort'
|
|
3
3
|
import { DimensionsType } from '@cdc/core/types/Dimensions'
|
|
4
4
|
import { VizFilter } from '@cdc/core/types/VizFilter'
|
|
5
|
-
import { type RefObject } from 'react'
|
|
6
5
|
|
|
7
6
|
export type MapContext = {
|
|
8
7
|
currentViewport: ViewPort
|
|
9
8
|
content: { geoName: string; keyedData: Record<string, any> }
|
|
10
|
-
data: DataRow[]
|
|
11
9
|
dimensions: DimensionsType
|
|
12
10
|
displayDataAsText: string | number
|
|
13
11
|
displayGeoName: (key: string, convertFipsCodes: boolean) => string
|
|
@@ -22,7 +20,6 @@ export type MapContext = {
|
|
|
22
20
|
handleCircleClick: Function
|
|
23
21
|
handleDragStateChange: Function
|
|
24
22
|
isDraggingAnnotation: boolean
|
|
25
|
-
innerContainerRef: RefObject<HTMLDivElement>
|
|
26
23
|
isDashboard: boolean
|
|
27
24
|
isEditor: boolean
|
|
28
25
|
isFilterValueSupported: boolean
|
|
@@ -32,13 +29,9 @@ export type MapContext = {
|
|
|
32
29
|
position: 'side' | 'top' | 'bottom'
|
|
33
30
|
resetLegendToggles: Function
|
|
34
31
|
runtimeFilters: Function
|
|
35
|
-
legendMemo: Function
|
|
36
|
-
legendSpecialClassLastMemo: Function
|
|
37
32
|
runtimeLegend
|
|
38
33
|
setParentConfig: Function
|
|
39
34
|
setRuntimeData: Function
|
|
40
|
-
setRuntimeFilters: Function
|
|
41
|
-
setRuntimeLegend: Function
|
|
42
35
|
setSharedFilterValue: Function
|
|
43
36
|
setConfig: (newState: MapConfig) => MapConfig
|
|
44
37
|
config: MapConfig
|
|
@@ -1 +1,17 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type RuntimeLegendItem = {
|
|
2
|
+
disabled?: boolean
|
|
3
|
+
bin?: number
|
|
4
|
+
color?: string
|
|
5
|
+
special?: boolean
|
|
6
|
+
value?: string | number
|
|
7
|
+
label?: string
|
|
8
|
+
min?: number
|
|
9
|
+
max?: number
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type RuntimeLegend = {
|
|
13
|
+
items: RuntimeLegendItem[]
|
|
14
|
+
disabledAmt?: number
|
|
15
|
+
fromHash?: number
|
|
16
|
+
runtimeDataHash?: number
|
|
17
|
+
}
|
package/vite.config.js
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import GenerateViteConfig from '
|
|
1
|
+
import GenerateViteConfig from '@cdc/core/generateViteConfig.js'
|
|
2
2
|
import { moduleName } from './package.json'
|
|
3
3
|
|
|
4
|
-
export default GenerateViteConfig(moduleName
|
|
5
|
-
jsxImportSource: '@emotion/react',
|
|
6
|
-
babel: {
|
|
7
|
-
plugins: ['@emotion/babel-plugin']
|
|
8
|
-
}
|
|
9
|
-
})
|
|
4
|
+
export default GenerateViteConfig(moduleName)
|
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config'
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
environment: 'jsdom',
|
|
6
|
+
globals: true,
|
|
7
|
+
setupFiles: ['../../vitest.setup.ts'],
|
|
8
|
+
exclude: [
|
|
9
|
+
'**/node_modules/**',
|
|
10
|
+
'**/dist/**',
|
|
11
|
+
'**/.storybook/**',
|
|
12
|
+
'**/*.stories.*',
|
|
13
|
+
'**/storybook-static/**'
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
})
|
package/src/coreStyles_map.scss
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export const colorDistributions = {
|
|
2
|
-
1: [1],
|
|
3
|
-
2: [1, 3],
|
|
4
|
-
3: [1, 3, 5],
|
|
5
|
-
4: [0, 2, 4, 6],
|
|
6
|
-
5: [0, 2, 4, 6, 7],
|
|
7
|
-
6: [0, 2, 3, 4, 5, 7],
|
|
8
|
-
7: [0, 2, 3, 4, 5, 6, 7],
|
|
9
|
-
8: [0, 2, 3, 4, 5, 6, 7, 8],
|
|
10
|
-
9: [0, 1, 2, 3, 4, 5, 6, 7, 8],
|
|
11
|
-
10: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
12
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import chroma from 'chroma-js'
|
|
2
|
-
import { DEFAULT_MAP_BACKGROUND } from './constants'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Generate an array of colors based on a given color [color, hoverColor, darkColor]
|
|
6
|
-
* @param {string} color - The base color to generate the array from
|
|
7
|
-
* @param {boolean} special - A flag to determine if the hover color should be brighter or saturated
|
|
8
|
-
* @returns {string[]} - An array of colors
|
|
9
|
-
*/
|
|
10
|
-
export const generateColorsArray = (color: string = DEFAULT_MAP_BACKGROUND, special: boolean = false) => {
|
|
11
|
-
let colorObj = chroma(color)
|
|
12
|
-
let hoverColor = special ? colorObj.brighten(0.5).hex() : colorObj.saturate(1.3).hex()
|
|
13
|
-
return [color, hoverColor, colorObj.darken(0.3).hex()]
|
|
14
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { generateColorsArray } from '../generateColorsArray'
|
|
2
|
-
|
|
3
|
-
describe('generateColorsArray', () => {
|
|
4
|
-
it('should return an array of colors', () => {
|
|
5
|
-
const colors = generateColorsArray('#fde0dd', false)
|
|
6
|
-
expect(colors).toEqual(expect.arrayContaining(['#fde0dd', '#ffd0c9', '#edd1ce']))
|
|
7
|
-
})
|
|
8
|
-
|
|
9
|
-
it('should return a brighter hover color when special flag is true', () => {
|
|
10
|
-
const colors = generateColorsArray('#fde0dd', true)
|
|
11
|
-
expect(colors[1]).toEqual('#fffaf7')
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
it('should return a darker color for the third element in the array', () => {
|
|
15
|
-
const colors = generateColorsArray('#fde0dd', false)
|
|
16
|
-
expect(colors[2]).toBe('#edd1ce')
|
|
17
|
-
})
|
|
18
|
-
})
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { generateRuntimeLegendHash } from '../generateRuntimeLegendHash'
|
|
2
|
-
import usaExample from './../../../examples/default-usa.json'
|
|
3
|
-
|
|
4
|
-
describe('generateRuntimeLegendHash', () => {
|
|
5
|
-
it('should return a hash value for a given state and runtime filters', () => {
|
|
6
|
-
const runtimeFilters = []
|
|
7
|
-
const expectedHash = 1253406922
|
|
8
|
-
const result = generateRuntimeLegendHash(usaExample, runtimeFilters)
|
|
9
|
-
expect(result).toBe(expectedHash)
|
|
10
|
-
})
|
|
11
|
-
})
|