@cfasim-ui/charts 0.1.1 → 0.1.3
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/package.json +12 -2
- package/src/ChoroplethMap/ChoroplethMap.md +330 -0
- package/src/ChoroplethMap/ChoroplethMap.test.ts +468 -0
- package/src/ChoroplethMap/ChoroplethMap.vue +629 -0
- package/src/ChoroplethMap/hsaMapping.ts +4116 -0
- package/src/LineChart/LineChart.spec.ts +3 -2
- package/src/index.ts +8 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cfasim-ui/charts",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Chart visualization components for cfasim-ui",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -16,13 +16,23 @@
|
|
|
16
16
|
".": "./src/index.ts"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
+
"d3-geo": "^3.1.1",
|
|
20
|
+
"d3-selection": "^3.0.0",
|
|
21
|
+
"d3-zoom": "^3.0.0",
|
|
19
22
|
"reka-ui": "^2.9.2",
|
|
20
|
-
"
|
|
23
|
+
"topojson-client": "^3.1.0",
|
|
24
|
+
"us-atlas": "^3.0.1",
|
|
25
|
+
"@cfasim-ui/shared": "0.1.3"
|
|
21
26
|
},
|
|
22
27
|
"peerDependencies": {
|
|
23
28
|
"vue": "^3.5.0"
|
|
24
29
|
},
|
|
25
30
|
"devDependencies": {
|
|
31
|
+
"@types/d3-geo": "^3.1.0",
|
|
32
|
+
"@types/d3-selection": "^3.0.11",
|
|
33
|
+
"@types/d3-zoom": "^3.0.8",
|
|
34
|
+
"@types/topojson-client": "^3.1.5",
|
|
35
|
+
"@types/topojson-specification": "^1.0.5",
|
|
26
36
|
"@vitejs/plugin-vue": "^6.0.5",
|
|
27
37
|
"@vue/test-utils": "^2.4.6",
|
|
28
38
|
"happy-dom": "^20.8.4",
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
# ChoroplethMap
|
|
2
|
+
|
|
3
|
+
A US choropleth map using D3's Albers USA projection, which repositions Alaska and Hawaii to the bottom left. Supports state-level, county-level, and HSA-level (Health Service Areas) rendering via the `geoType` prop. Includes built-in GeoJSON for all US states, territories, counties, and 949 HSAs.
|
|
4
|
+
|
|
5
|
+
## Examples
|
|
6
|
+
|
|
7
|
+
### Basic with state data
|
|
8
|
+
|
|
9
|
+
<ComponentDemo>
|
|
10
|
+
<ChoroplethMap
|
|
11
|
+
:data="[
|
|
12
|
+
{ id: '06', value: 100 },
|
|
13
|
+
{ id: '36', value: 80 },
|
|
14
|
+
{ id: '48', value: 90 },
|
|
15
|
+
{ id: '12', value: 70 },
|
|
16
|
+
{ id: '17', value: 60 },
|
|
17
|
+
{ id: '37', value: 50 },
|
|
18
|
+
{ id: '42', value: 55 },
|
|
19
|
+
{ id: '39', value: 45 },
|
|
20
|
+
{ id: '13', value: 40 },
|
|
21
|
+
{ id: '26', value: 35 },
|
|
22
|
+
]"
|
|
23
|
+
title="Cases by State"
|
|
24
|
+
:legend-title="'Cases'"
|
|
25
|
+
:height="400"
|
|
26
|
+
/>
|
|
27
|
+
|
|
28
|
+
<template #code>
|
|
29
|
+
|
|
30
|
+
```vue
|
|
31
|
+
<ChoroplethMap
|
|
32
|
+
:data="[
|
|
33
|
+
{ id: '06', value: 100 },
|
|
34
|
+
{ id: '36', value: 80 },
|
|
35
|
+
{ id: '48', value: 90 },
|
|
36
|
+
{ id: '12', value: 70 },
|
|
37
|
+
{ id: '17', value: 60 },
|
|
38
|
+
]"
|
|
39
|
+
title="Cases by State"
|
|
40
|
+
:legend-title="'Cases'"
|
|
41
|
+
:height="400"
|
|
42
|
+
/>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
</template>
|
|
46
|
+
</ComponentDemo>
|
|
47
|
+
|
|
48
|
+
### Custom color scale
|
|
49
|
+
|
|
50
|
+
<ComponentDemo>
|
|
51
|
+
<ChoroplethMap
|
|
52
|
+
:data="[
|
|
53
|
+
{ id: 'California', value: 100 },
|
|
54
|
+
{ id: 'Texas', value: 85 },
|
|
55
|
+
{ id: 'Florida', value: 70 },
|
|
56
|
+
{ id: 'New York', value: 90 },
|
|
57
|
+
{ id: 'Pennsylvania', value: 50 },
|
|
58
|
+
{ id: 'Illinois', value: 60 },
|
|
59
|
+
{ id: 'Ohio', value: 40 },
|
|
60
|
+
{ id: 'Georgia', value: 55 },
|
|
61
|
+
{ id: 'North Carolina', value: 45 },
|
|
62
|
+
{ id: 'Michigan', value: 35 },
|
|
63
|
+
]"
|
|
64
|
+
:color-scale="{ min: '#fff5f0', max: '#a50f15' }"
|
|
65
|
+
:legend-title="'Severity'"
|
|
66
|
+
:height="400"
|
|
67
|
+
/>
|
|
68
|
+
|
|
69
|
+
<template #code>
|
|
70
|
+
|
|
71
|
+
```vue
|
|
72
|
+
<ChoroplethMap
|
|
73
|
+
:data="[
|
|
74
|
+
{ id: 'California', value: 100 },
|
|
75
|
+
{ id: 'Texas', value: 85 },
|
|
76
|
+
{ id: 'Florida', value: 70 },
|
|
77
|
+
{ id: 'New York', value: 90 },
|
|
78
|
+
]"
|
|
79
|
+
:color-scale="{ min: '#fff5f0', max: '#a50f15' }"
|
|
80
|
+
:legend-title="'Severity'"
|
|
81
|
+
:height="400"
|
|
82
|
+
/>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
</template>
|
|
86
|
+
</ComponentDemo>
|
|
87
|
+
|
|
88
|
+
### Threshold color scale
|
|
89
|
+
|
|
90
|
+
Use an array of `ThresholdStop` objects instead of a linear scale. Each stop defines a `min` threshold — values at or above that threshold get the stop's color. The highest matching stop wins.
|
|
91
|
+
|
|
92
|
+
<ComponentDemo>
|
|
93
|
+
<ChoroplethMap
|
|
94
|
+
:data="[
|
|
95
|
+
{ id: 'California', value: 80 },
|
|
96
|
+
{ id: 'Texas', value: 45 },
|
|
97
|
+
{ id: 'Florida', value: 60 },
|
|
98
|
+
{ id: 'New York', value: 25 },
|
|
99
|
+
{ id: 'Pennsylvania', value: 8 },
|
|
100
|
+
{ id: 'Illinois', value: 55 },
|
|
101
|
+
{ id: 'Ohio', value: 30 },
|
|
102
|
+
{ id: 'Georgia', value: 70 },
|
|
103
|
+
{ id: 'North Carolina', value: 15 },
|
|
104
|
+
{ id: 'Michigan', value: 3 },
|
|
105
|
+
]"
|
|
106
|
+
:color-scale="[
|
|
107
|
+
{ min: 0, color: '#fee5d9', label: 'Low' },
|
|
108
|
+
{ min: 10, color: '#fcae91', label: 'Some' },
|
|
109
|
+
{ min: 30, color: '#fb6a4a', label: 'Moderate' },
|
|
110
|
+
{ min: 60, color: '#cb181d', label: 'High' },
|
|
111
|
+
]"
|
|
112
|
+
title="Risk Level"
|
|
113
|
+
:legend-title="'Risk'"
|
|
114
|
+
:height="400"
|
|
115
|
+
/>
|
|
116
|
+
|
|
117
|
+
<template #code>
|
|
118
|
+
|
|
119
|
+
```vue
|
|
120
|
+
<ChoroplethMap
|
|
121
|
+
:data="stateData"
|
|
122
|
+
:color-scale="[
|
|
123
|
+
{ min: 0, color: '#fee5d9', label: 'Low' },
|
|
124
|
+
{ min: 10, color: '#fcae91', label: 'Some' },
|
|
125
|
+
{ min: 30, color: '#fb6a4a', label: 'Moderate' },
|
|
126
|
+
{ min: 60, color: '#cb181d', label: 'High' },
|
|
127
|
+
]"
|
|
128
|
+
title="Risk Level"
|
|
129
|
+
:legend-title="'Risk'"
|
|
130
|
+
:height="400"
|
|
131
|
+
/>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
</template>
|
|
135
|
+
</ComponentDemo>
|
|
136
|
+
|
|
137
|
+
### Categorical color scale
|
|
138
|
+
|
|
139
|
+
Use an array of `CategoricalStop` objects to map string values to colors. Each stop defines a `value` to match and a `color` to apply.
|
|
140
|
+
|
|
141
|
+
<ComponentDemo>
|
|
142
|
+
<ChoroplethMap
|
|
143
|
+
:data="[
|
|
144
|
+
{ id: 'California', value: 'high' },
|
|
145
|
+
{ id: 'Texas', value: 'medium' },
|
|
146
|
+
{ id: 'Florida', value: 'high' },
|
|
147
|
+
{ id: 'New York', value: 'low' },
|
|
148
|
+
{ id: 'Pennsylvania', value: 'low' },
|
|
149
|
+
{ id: 'Illinois', value: 'medium' },
|
|
150
|
+
{ id: 'Ohio', value: 'low' },
|
|
151
|
+
{ id: 'Georgia', value: 'high' },
|
|
152
|
+
{ id: 'North Carolina', value: 'medium' },
|
|
153
|
+
{ id: 'Michigan', value: 'low' },
|
|
154
|
+
]"
|
|
155
|
+
:color-scale="[
|
|
156
|
+
{ value: 'low', color: '#fee5d9' },
|
|
157
|
+
{ value: 'medium', color: '#fb6a4a' },
|
|
158
|
+
{ value: 'high', color: '#cb181d' },
|
|
159
|
+
]"
|
|
160
|
+
title="Risk Category"
|
|
161
|
+
:legend-title="'Risk'"
|
|
162
|
+
:height="400"
|
|
163
|
+
/>
|
|
164
|
+
|
|
165
|
+
<template #code>
|
|
166
|
+
|
|
167
|
+
```vue
|
|
168
|
+
<ChoroplethMap
|
|
169
|
+
:data="stateData"
|
|
170
|
+
:color-scale="[
|
|
171
|
+
{ value: 'low', color: '#fee5d9' },
|
|
172
|
+
{ value: 'medium', color: '#fb6a4a' },
|
|
173
|
+
{ value: 'high', color: '#cb181d' },
|
|
174
|
+
]"
|
|
175
|
+
title="Risk Category"
|
|
176
|
+
:legend-title="'Risk'"
|
|
177
|
+
:height="400"
|
|
178
|
+
/>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
</template>
|
|
182
|
+
</ComponentDemo>
|
|
183
|
+
|
|
184
|
+
### County-level map with pan and zoom
|
|
185
|
+
|
|
186
|
+
Set `geoType="counties"` to render county-level data using 5-digit FIPS codes. State borders are drawn on top for context. Use `pan` and `zoom` props to enable interactive navigation — useful for dense county data.
|
|
187
|
+
|
|
188
|
+
<ComponentDemo>
|
|
189
|
+
<ChoroplethMap
|
|
190
|
+
geo-type="counties"
|
|
191
|
+
:pan="true"
|
|
192
|
+
:zoom="true"
|
|
193
|
+
:data="[
|
|
194
|
+
{ id: '06037', value: 100 },
|
|
195
|
+
{ id: '06073', value: 80 },
|
|
196
|
+
{ id: '06059', value: 70 },
|
|
197
|
+
{ id: '36061', value: 90 },
|
|
198
|
+
{ id: '36047', value: 75 },
|
|
199
|
+
{ id: '17031', value: 85 },
|
|
200
|
+
{ id: '48201', value: 65 },
|
|
201
|
+
{ id: '04013', value: 60 },
|
|
202
|
+
{ id: '12086', value: 55 },
|
|
203
|
+
{ id: '53033', value: 50 },
|
|
204
|
+
]"
|
|
205
|
+
title="Cases by County"
|
|
206
|
+
:legend-title="'Cases'"
|
|
207
|
+
:height="400"
|
|
208
|
+
/>
|
|
209
|
+
|
|
210
|
+
<template #code>
|
|
211
|
+
|
|
212
|
+
```vue
|
|
213
|
+
<ChoroplethMap
|
|
214
|
+
geo-type="counties"
|
|
215
|
+
pan
|
|
216
|
+
zoom
|
|
217
|
+
:data="[
|
|
218
|
+
{ id: '06037', value: 100 },
|
|
219
|
+
{ id: '36061', value: 90 },
|
|
220
|
+
{ id: '17031', value: 85 },
|
|
221
|
+
{ id: '48201', value: 65 },
|
|
222
|
+
{ id: '04013', value: 60 },
|
|
223
|
+
]"
|
|
224
|
+
title="Cases by County"
|
|
225
|
+
:legend-title="'Cases'"
|
|
226
|
+
:height="400"
|
|
227
|
+
/>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
</template>
|
|
231
|
+
</ComponentDemo>
|
|
232
|
+
|
|
233
|
+
### HSA-level map
|
|
234
|
+
|
|
235
|
+
Set `geoType="hsas"` to render Health Service Area boundaries. HSAs are dissolved from county boundaries using a built-in FIPS-to-HSA mapping. Use 6-digit HSA codes as IDs. State borders are overlaid for context.
|
|
236
|
+
|
|
237
|
+
<ComponentDemo>
|
|
238
|
+
<ChoroplethMap
|
|
239
|
+
geo-type="hsas"
|
|
240
|
+
:pan="true"
|
|
241
|
+
:zoom="true"
|
|
242
|
+
:data="[
|
|
243
|
+
{ id: '010259', value: 100 },
|
|
244
|
+
{ id: '060766', value: 90 },
|
|
245
|
+
{ id: '120159', value: 85 },
|
|
246
|
+
{ id: '090121', value: 70 },
|
|
247
|
+
{ id: '110061', value: 60 },
|
|
248
|
+
{ id: '040765', value: 55 },
|
|
249
|
+
{ id: '080731', value: 50 },
|
|
250
|
+
{ id: '050527', value: 45 },
|
|
251
|
+
{ id: '100075', value: 40 },
|
|
252
|
+
{ id: '020820', value: 35 },
|
|
253
|
+
]"
|
|
254
|
+
title="Cases by HSA"
|
|
255
|
+
:legend-title="'Cases'"
|
|
256
|
+
:height="400"
|
|
257
|
+
/>
|
|
258
|
+
|
|
259
|
+
<template #code>
|
|
260
|
+
|
|
261
|
+
```vue
|
|
262
|
+
<ChoroplethMap
|
|
263
|
+
geo-type="hsas"
|
|
264
|
+
pan
|
|
265
|
+
zoom
|
|
266
|
+
:data="[
|
|
267
|
+
{ id: '010259', value: 100 },
|
|
268
|
+
{ id: '060766', value: 90 },
|
|
269
|
+
{ id: '120159', value: 85 },
|
|
270
|
+
{ id: '090121', value: 70 },
|
|
271
|
+
{ id: '110061', value: 60 },
|
|
272
|
+
]"
|
|
273
|
+
title="Cases by HSA"
|
|
274
|
+
:legend-title="'Cases'"
|
|
275
|
+
:height="400"
|
|
276
|
+
/>
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
</template>
|
|
280
|
+
</ComponentDemo>
|
|
281
|
+
|
|
282
|
+
<!--@include: ./_api/choropleth-map.md-->
|
|
283
|
+
|
|
284
|
+
### StateData
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
interface StateData {
|
|
288
|
+
/** FIPS code (e.g. "06" for California, "06037" for LA County) or name */
|
|
289
|
+
id: string;
|
|
290
|
+
value: number | string;
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### ChoroplethColorScale
|
|
295
|
+
|
|
296
|
+
```ts
|
|
297
|
+
interface ChoroplethColorScale {
|
|
298
|
+
/** Minimum color (CSS color string). Default: "#e5f0fa" */
|
|
299
|
+
min?: string;
|
|
300
|
+
/** Maximum color (CSS color string). Default: "#08519c" */
|
|
301
|
+
max?: string;
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### ThresholdStop
|
|
306
|
+
|
|
307
|
+
Pass an array of `ThresholdStop` as `colorScale` for discrete color buckets instead of a linear gradient. The highest matching `min` wins.
|
|
308
|
+
|
|
309
|
+
```ts
|
|
310
|
+
interface ThresholdStop {
|
|
311
|
+
/** Lower bound (inclusive). Values at or above this get this color. */
|
|
312
|
+
min: number;
|
|
313
|
+
color: string;
|
|
314
|
+
/** Optional label for the legend (defaults to the min value) */
|
|
315
|
+
label?: string;
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### CategoricalStop
|
|
320
|
+
|
|
321
|
+
Pass an array of `CategoricalStop` as `colorScale` to map string values to colors. States whose `value` matches a stop's `value` get that color; unmatched values get `noDataColor`.
|
|
322
|
+
|
|
323
|
+
```ts
|
|
324
|
+
interface CategoricalStop {
|
|
325
|
+
/** The categorical value to match */
|
|
326
|
+
value: string;
|
|
327
|
+
/** CSS color string */
|
|
328
|
+
color: string;
|
|
329
|
+
}
|
|
330
|
+
```
|