@cfasim-ui/docs 0.4.0 → 0.4.2

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.
@@ -130,13 +130,17 @@ menu, and CSV export wiring with [`LineChart`](./line-chart).
130
130
 
131
131
  ### Custom value tick format
132
132
 
133
+ Use `value-tick-format` to format the value-axis labels. `tooltip-value-format` controls the tooltip values independently; if omitted, the tooltip uses `value-tick-format`.
134
+
133
135
  <ComponentDemo>
134
136
  <BarChart
135
137
  :data="[0.12, 0.34, 0.56, 0.78]"
136
138
  :categories="['A', 'B', 'C', 'D']"
137
139
  :value-tick-format="(v) => `${(v * 100).toFixed(0)}%`"
140
+ :tooltip-value-format="(v) => `${(v * 100).toFixed(1)}%`"
138
141
  :height="220"
139
142
  y-label="Coverage"
143
+ tooltip-trigger="hover"
140
144
  />
141
145
 
142
146
  <template #code>
@@ -146,8 +150,10 @@ menu, and CSV export wiring with [`LineChart`](./line-chart).
146
150
  :data="[0.12, 0.34, 0.56, 0.78]"
147
151
  :categories="['A', 'B', 'C', 'D']"
148
152
  :value-tick-format="(v) => `${(v * 100).toFixed(0)}%`"
153
+ :tooltip-value-format="(v) => `${(v * 100).toFixed(1)}%`"
149
154
  :height="220"
150
155
  y-label="Coverage"
156
+ tooltip-trigger="hover"
151
157
  />
152
158
  ```
153
159
 
@@ -174,13 +180,14 @@ menu, and CSV export wiring with [`LineChart`](./line-chart).
174
180
  | `valueMin` | `number` | No | `0` |
175
181
  | `valueTicks` | `number \| number[]` | No | — |
176
182
  | `valueTickFormat` | `(value: number) =&gt; string` | No | — |
183
+ | `tooltipValueFormat` | `(value: number) =&gt; string` | No | — |
177
184
  | `categoryFormat` | `(label: string, index: number) =&gt; string` | No | — |
178
185
  | `barPadding` | `number` | No | `0.2` |
179
186
  | `groupGap` | `number` | No | `1` |
180
187
  | `debounce` | `number` | No | — |
181
188
  | `menu` | `boolean \| string` | No | `true` |
182
189
  | `valueGrid` | `boolean` | No | `true` |
183
- | `tooltipData` | `unknown[]` | No | — |
190
+ | `tooltipData` | `ArrayLike&lt;unknown&gt;` | No | — |
184
191
  | `tooltipTrigger` | `"hover" \| "click"` | No | — |
185
192
  | `tooltipClamp` | `"none" \| "chart" \| "window"` | No | `"chart"` |
186
193
  | `csv` | `string \| (() =&gt; string)` | No | — |
@@ -57,6 +57,11 @@ const props = withDefaults(
57
57
  valueTicks?: number | number[];
58
58
  /** Formatter for value-axis tick labels. */
59
59
  valueTickFormat?: (value: number) => string;
60
+ /**
61
+ * Formatter for numeric values shown in the default tooltip. Receives
62
+ * the raw value. Defaults to the same tick formatter used for axes.
63
+ */
64
+ tooltipValueFormat?: (value: number) => string;
60
65
  /** Formatter for category-axis labels. Receives the resolved category string. */
61
66
  categoryFormat?: (label: string, index: number) => string;
62
67
  /**
@@ -72,8 +77,12 @@ const props = withDefaults(
72
77
  debounce?: number;
73
78
  menu?: boolean | string;
74
79
  valueGrid?: boolean;
75
- /** Custom per-index data passed to the tooltip slot. */
76
- tooltipData?: unknown[];
80
+ /**
81
+ * Custom per-index data passed to the tooltip slot. Accepts a plain
82
+ * array or any `ArrayLike` (e.g. a typed array column from a
83
+ * `ModelOutput`).
84
+ */
85
+ tooltipData?: ArrayLike<unknown>;
77
86
  /** Tooltip activation mode. */
78
87
  tooltipTrigger?: "hover" | "click";
79
88
  /** Boundary for tooltip flip/clamp. Default "chart". */
@@ -399,6 +408,12 @@ function defaultColor(i: number): string {
399
408
  return DEFAULT_COLORS[i % DEFAULT_COLORS.length];
400
409
  }
401
410
 
411
+ function formatTooltipValue(v: number): string {
412
+ if (props.tooltipValueFormat) return props.tooltipValueFormat(v);
413
+ if (props.valueTickFormat) return props.valueTickFormat(v);
414
+ return formatTick(v);
415
+ }
416
+
402
417
  const valueTickItems = computed(() => {
403
418
  const { min, max } = valueExtent.value;
404
419
  const fmt = (v: number) =>
@@ -775,7 +790,7 @@ const hoverBand = computed(() => {
775
790
  class="bar-chart-tooltip-swatch"
776
791
  :style="{ background: v.color }"
777
792
  />
778
- {{ isFinite(v.value) ? formatTick(v.value) : "—" }}
793
+ {{ isFinite(v.value) ? formatTooltipValue(v.value) : "—" }}
779
794
  </div>
780
795
  </div>
781
796
  </slot>
@@ -12,16 +12,23 @@ export interface ChartMenuItem {
12
12
  action: () => void;
13
13
  }
14
14
 
15
- defineProps<{
16
- items: ChartMenuItem[];
17
- }>();
15
+ const props = withDefaults(
16
+ defineProps<{
17
+ items: ChartMenuItem[];
18
+ /** Force the dropdown style even when only one item is provided. */
19
+ forceDropdown?: boolean;
20
+ }>(),
21
+ { forceDropdown: false },
22
+ );
23
+
24
+ const useDropdown = () => props.forceDropdown || props.items.length > 1;
18
25
  </script>
19
26
 
20
27
  <template>
21
28
  <div class="chart-menu-trigger-area">
22
29
  <!-- Single item: plain button -->
23
30
  <button
24
- v-if="items.length === 1"
31
+ v-if="!useDropdown()"
25
32
  class="chart-menu-button chart-menu-single"
26
33
  :aria-label="items[0].label"
27
34
  @click="items[0].action"
@@ -1,3 +1,18 @@
1
+ <script setup>
2
+ import { computed } from "vue";
3
+ import countiesTopoForPerf from "us-atlas/counties-10m.json";
4
+
5
+ // Build one row per county (~3,143) with a deterministic-ish value so the
6
+ // perf example can render every region with a custom tooltip.
7
+ const denseCountyData = computed(() => {
8
+ const geoms = countiesTopoForPerf.objects.counties.geometries;
9
+ return geoms.map((g, i) => ({
10
+ id: String(g.id).padStart(5, "0"),
11
+ value: (i * 37) % 100,
12
+ }));
13
+ });
14
+ </script>
15
+
1
16
  # ChoroplethMap
2
17
 
3
18
  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.
@@ -322,6 +337,150 @@ Set `geoType="hsas"` to render Health Service Area boundaries. HSAs are dissolve
322
337
  </template>
323
338
  </ComponentDemo>
324
339
 
340
+ ### Custom tooltip number format
341
+
342
+ Pass `tooltip-value-format` to format numeric values shown in the tooltip
343
+ (both the native SVG `<title>` and the interactive HTML tooltip). Use the
344
+ `#tooltip` slot if you want full control over the tooltip's content.
345
+
346
+ <ComponentDemo>
347
+ <ChoroplethMap
348
+ :topology="statesTopo"
349
+ :data="[
350
+ { id: '06', value: 39538223 },
351
+ { id: '48', value: 29145505 },
352
+ { id: '12', value: 21538187 },
353
+ { id: '36', value: 20201249 },
354
+ ]"
355
+ :tooltip-value-format="(v) => v.toLocaleString('en-US')"
356
+ title="US population (2020)"
357
+ :height="300"
358
+ />
359
+
360
+ <template #code>
361
+
362
+ ```vue
363
+ <ChoroplethMap
364
+ :topology="statesTopo"
365
+ :data="[
366
+ { id: '06', value: 39538223 },
367
+ { id: '48', value: 29145505 },
368
+ { id: '12', value: 21538187 },
369
+ { id: '36', value: 20201249 },
370
+ ]"
371
+ :tooltip-value-format="(v) => v.toLocaleString('en-US')"
372
+ title="US population (2020)"
373
+ :height="300"
374
+ />
375
+ ```
376
+
377
+ </template>
378
+ </ComponentDemo>
379
+
380
+ ### Dense county map (~3,143 features) for tooltip perf profiling
381
+
382
+ Renders every US county with a value and a custom tooltip slot. Useful as a
383
+ manual perf harness — open DevTools Performance, record a hover/sweep across
384
+ many counties, and inspect tooltip update cost. The tooltip element is
385
+ mounted once and patched in place; `mousemove` writes the position
386
+ straight to the DOM.
387
+
388
+ <ComponentDemo>
389
+ <ChoroplethMap
390
+ :topology="countiesTopo"
391
+ geo-type="counties"
392
+ :data="denseCountyData"
393
+ :pan="true"
394
+ :zoom="true"
395
+ :color-scale="{ min: '#f0f5ff', max: '#08306b' }"
396
+ title="All US counties — tooltip perf demo"
397
+ :height="500"
398
+ >
399
+ <template #tooltip="{ id, name, value }">
400
+ <div style="font-weight: 600">{{ name }}</div>
401
+ <div style="opacity: 0.7; font-size: 0.85em">FIPS {{ id }}</div>
402
+ <div>Value: {{ value }}</div>
403
+ </template>
404
+ </ChoroplethMap>
405
+
406
+ <template #code>
407
+
408
+ ```vue
409
+ <script setup>
410
+ import countiesTopo from "us-atlas/counties-10m.json";
411
+
412
+ // One row per county
413
+ const data = countiesTopo.objects.counties.geometries.map((g, i) => ({
414
+ id: String(g.id).padStart(5, "0"),
415
+ value: (i * 37) % 100,
416
+ }));
417
+ </script>
418
+
419
+ <ChoroplethMap
420
+ :topology="countiesTopo"
421
+ geo-type="counties"
422
+ :data="data"
423
+ pan
424
+ zoom
425
+ >
426
+ <template #tooltip="{ id, name, value }">
427
+ <div style="font-weight: 600">{{ name }}</div>
428
+ <div style="opacity: 0.7; font-size: 0.85em">FIPS {{ id }}</div>
429
+ <div>Value: {{ value }}</div>
430
+ </template>
431
+ </ChoroplethMap>
432
+ ```
433
+
434
+ </template>
435
+ </ComponentDemo>
436
+
437
+ ### Custom tooltip content (`#tooltip` slot)
438
+
439
+ Use the `#tooltip` slot to render any Vue template — components, scoped
440
+ styles, multi-line layouts — instead of the default `name: value`. The slot
441
+ receives `{ id, name, value, feature }` for the hovered region. Providing the
442
+ slot automatically enables interactive (HTML) tooltips, so you don't need to
443
+ set `tooltip-trigger`.
444
+
445
+ <ComponentDemo>
446
+ <ChoroplethMap
447
+ :topology="statesTopo"
448
+ :data="[
449
+ { id: '06', value: 39538223 },
450
+ { id: '48', value: 29145505 },
451
+ { id: '12', value: 21538187 },
452
+ { id: '36', value: 20201249 },
453
+ { id: '17', value: 12812508 },
454
+ ]"
455
+ title="US population (2020)"
456
+ :height="300"
457
+ >
458
+ <template #tooltip="{ name, value }">
459
+ <div style="font-weight:600">{{ name }}</div>
460
+ <div v-if="typeof value === 'number'">
461
+ Pop: {{ value.toLocaleString('en-US') }}
462
+ </div>
463
+ <div v-else style="opacity:0.6">No data</div>
464
+ </template>
465
+ </ChoroplethMap>
466
+
467
+ <template #code>
468
+
469
+ ```vue
470
+ <ChoroplethMap :topology="statesTopo" :data="data" title="US population (2020)">
471
+ <template #tooltip="{ name, value }">
472
+ <div style="font-weight: 600">{{ name }}</div>
473
+ <div v-if="typeof value === 'number'">
474
+ Pop: {{ value.toLocaleString("en-US") }}
475
+ </div>
476
+ <div v-else style="opacity: 0.6">No data</div>
477
+ </template>
478
+ </ChoroplethMap>
479
+ ```
480
+
481
+ </template>
482
+ </ComponentDemo>
483
+
325
484
  ## Props
326
485
 
327
486
  | Prop | Type | Required | Default |
@@ -346,6 +505,7 @@ Set `geoType="hsas"` to render Health Service Area boundaries. HSAs are dissolve
346
505
  id: string` | No | — |
347
506
  | `name` | `string` | Yes | — |
348
507
  | `value` | `number \| string` | No | — |
508
+ | `tooltipValueFormat` | `(value: number) =&gt; string` | No | — |
349
509
  | `tooltipClamp` | `"none" \| "chart" \| "window"` | No | `"chart"` |
350
510
 
351
511