@cfasim-ui/charts 0.6.4 → 0.7.0

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.
@@ -1,3 +1,4 @@
1
+ import { nextTick } from 'vue';
1
2
  import { Topology } from 'topojson-specification';
2
3
  import { NumberFormat } from '@cfasim-ui/shared';
3
4
  import { TitleStyle, LabelStyle } from '../_shared/index.js';
@@ -110,18 +111,45 @@ type __VLS_Props = {
110
111
  legend?: boolean;
111
112
  /** Title displayed next to the legend */
112
113
  legendTitle?: string;
113
- /** Enable mouse-wheel zooming. Default: false */
114
+ /**
115
+ * Enable the activate-to-zoom interaction. Default `false` — the map
116
+ * is fully static (tooltips and click-select still work, and
117
+ * programmatic `focus` zoom still applies). When enabled, the map
118
+ * stays static until the user double-clicks (desktop) or taps (touch):
119
+ * desktop double-click zooms in place alongside always-visible
120
+ * +/−/reset controls, with drag-pan once zoomed; on touch a tap
121
+ * expands the map to fill the window, where one finger pans, pinch
122
+ * zooms, and a tap selects. The scroll wheel never zooms inline, so
123
+ * the map can't hijack page scrolling.
124
+ */
114
125
  zoom?: boolean;
115
- /** Enable click-and-drag panning. Default: false */
116
- pan?: boolean;
117
126
  /**
118
- * Require two fingers to pan/zoom on touch devices. Default `false`.
119
- * When `true`, a single finger scrolls the page (the map sets
120
- * `touch-action: pan-y` and ignores one-finger drags) while two fingers
121
- * pan and pinch-zoom the map. Single-finger tap-to-select still works.
122
- * Has no effect with a mouse.
127
+ * Interaction style when `zoom` is enabled. `"activate"` (default)
128
+ * keeps the map static until a double-click / tap / feature click, so
129
+ * the page scrolls freely past it. `"scroll"` makes the map immediately
130
+ * interactive the wheel zooms, dragging pans, and touch gestures work
131
+ * inline with no tap-to-expand step. Use it for full-page experiences
132
+ * where the map is the main surface and there's no page scroll to
133
+ * hijack.
134
+ */
135
+ zoomMode?: "activate" | "scroll";
136
+ /**
137
+ * On touch devices, expand the map to fill the window when tapped.
138
+ * Default `true`. Set `false` to zoom in place instead: the first tap
139
+ * zooms the inline map in on the tapped point (like a desktop
140
+ * double-click), after which one-finger pan / pinch work and taps
141
+ * select features; the +/−/reset controls render inline. Note the
142
+ * activated map captures touch scrolling over it. No effect on desktop
143
+ * or when `zoom` is off; `zoom-mode="scroll"` already implies inline
144
+ * interaction.
145
+ */
146
+ touchExpand?: boolean;
147
+ /**
148
+ * Show the grey "Double click to zoom" / "Tap to zoom" affordance over
149
+ * the top of the map while the zoom gesture hasn't been used yet.
150
+ * Default `true`; set `false` to hide it. No effect when `zoom` is off.
123
151
  */
124
- twoFingerPan?: boolean;
152
+ zoomHint?: boolean;
125
153
  /** Tooltip activation mode */
126
154
  tooltipTrigger?: "hover" | "click";
127
155
  /**
@@ -158,7 +186,7 @@ type __VLS_Props = {
158
186
  * current pan/zoom transform is preserved; only the highlight is
159
187
  * removed. Works with `v-model:focus`: clicking an unfocused feature
160
188
  * (in the base geoType) emits its id; clicking the focused feature
161
- * emits `null`. The built-in Reset button clears focus *and* resets
189
+ * emits `null`. The built-in reset button clears focus *and* resets
162
190
  * the zoom. If a tooltip is configured, focusing a feature in the
163
191
  * base geoType shows its tooltip.
164
192
  */
@@ -170,7 +198,7 @@ type __VLS_Props = {
170
198
  * Default `true`. Set `false` to highlight (and draw cross-geoType
171
199
  * overlays) without changing the current pan/zoom — useful for a
172
200
  * click-to-select interaction where the map should stay put. The
173
- * built-in Reset button is unaffected.
201
+ * built-in reset button is unaffected.
174
202
  */
175
203
  focusZoom?: boolean;
176
204
  /**
@@ -245,7 +273,7 @@ declare function __VLS_template(): {
245
273
  errorCaptured?: ((err: unknown, instance: import('vue').ComponentPublicInstance | null, info: string) => boolean | void) | ((err: unknown, instance: import('vue').ComponentPublicInstance | null, info: string) => boolean | void)[];
246
274
  };
247
275
  $forceUpdate: () => void;
248
- $nextTick: typeof import('vue').nextTick;
276
+ $nextTick: typeof nextTick;
249
277
  $watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any) => infer R ? (...args: [R, R, import('@vue/reactivity').OnCleanup]) => any : (...args: [any, any, import('@vue/reactivity').OnCleanup]) => any, options?: import('vue').WatchOptions): import('vue').WatchStopHandle;
250
278
  } & Readonly<{}> & Omit<Readonly<{}> & Readonly<{}>, "setData" | "getEl"> & {
251
279
  setData: (next: import('./ChoroplethTooltip').ChoroplethTooltipData | null) => void;
@@ -294,8 +322,9 @@ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}
294
322
  noDataColor: string;
295
323
  strokeColor: string;
296
324
  zoom: boolean;
297
- pan: boolean;
298
- twoFingerPan: boolean;
325
+ zoomMode: "activate" | "scroll";
326
+ touchExpand: boolean;
327
+ zoomHint: boolean;
299
328
  focusZoomLevel: number;
300
329
  focusZoom: boolean;
301
330
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
@@ -343,7 +372,7 @@ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}
343
372
  errorCaptured?: ((err: unknown, instance: import('vue').ComponentPublicInstance | null, info: string) => boolean | void) | ((err: unknown, instance: import('vue').ComponentPublicInstance | null, info: string) => boolean | void)[];
344
373
  };
345
374
  $forceUpdate: () => void;
346
- $nextTick: typeof import('vue').nextTick;
375
+ $nextTick: typeof nextTick;
347
376
  $watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any) => infer R ? (...args: [R, R, import('@vue/reactivity').OnCleanup]) => any : (...args: [any, any, import('@vue/reactivity').OnCleanup]) => any, options?: import('vue').WatchOptions): import('vue').WatchStopHandle;
348
377
  } & Readonly<{}> & Omit<Readonly<{}> & Readonly<{}>, "setData" | "getEl"> & {
349
378
  setData: (next: import('./ChoroplethTooltip').ChoroplethTooltipData | null) => void;
@@ -0,0 +1,24 @@
1
+ type __VLS_Props = {
2
+ canZoomIn?: boolean;
3
+ canZoomOut?: boolean;
4
+ /** Reset is a no-op at the identity transform — disable it there. */
5
+ canReset?: boolean;
6
+ /** Insets the stack further from the corner while the chart fills the
7
+ * window, matching the ChartMenu trigger area. */
8
+ isFullscreen?: boolean;
9
+ };
10
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
11
+ reset: () => any;
12
+ zoomIn: () => any;
13
+ zoomOut: () => any;
14
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
15
+ onReset?: (() => any) | undefined;
16
+ onZoomIn?: (() => any) | undefined;
17
+ onZoomOut?: (() => any) | undefined;
18
+ }>, {
19
+ isFullscreen: boolean;
20
+ canZoomIn: boolean;
21
+ canZoomOut: boolean;
22
+ canReset: boolean;
23
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
24
+ export default _default;
@@ -1,15 +1,17 @@
1
- export { snap, niceStep, intervalValues, formatTick, type ChartData, } from './axes.js';
1
+ export { snap, formatTick, type ChartData } from './axes.js';
2
2
  export { computeTickValues, type TickValueOptions } from './computeTicks.js';
3
- export { scaleFraction, clampExtentForScale, computeLogTickValues, LOG_FLOOR, type ScaleType, } from './scale.js';
3
+ export { scaleFraction, clampExtentForScale, computeLogTickValues, type ScaleType, } from './scale.js';
4
4
  export { useChartSize, type ChartSizeOptions } from './useChartSize.js';
5
5
  export { useChartPadding, resolveLabelStyle, INLINE_LEGEND_ROW_HEIGHT, TITLE_LINE_HEIGHT, TITLE_FONT_SIZE, TITLE_FONT_WEIGHT, AXIS_LABEL_FONT_SIZE, TICK_LABEL_FONT_SIZE, TICK_LABEL_OPACITY, LEGEND_FONT_SIZE, type ChartPaddingOptions, type ChartPadding, type ChartBounds, type PositionedLegendItem, } from './useChartPadding.js';
6
6
  export { useChartTooltip, type ChartTooltipOptions, } from './useChartTooltip.js';
7
7
  export { useChartMenu, type ChartMenuOptions } from './useChartMenu.js';
8
8
  export { useChartFullscreen } from './useChartFullscreen.js';
9
+ export { isTouchDevice } from './touch.js';
10
+ export { default as ChartZoomControls } from './ChartZoomControls';
9
11
  export { seriesToCsv, categoricalToCsv, type CsvSeries } from './seriesCsv.js';
10
12
  export { default as ChartAnnotations } from './ChartAnnotations';
11
13
  export type { ChartAnnotation } from './annotations.js';
12
14
  export { useChartFoundation, makeTooltipValueFormatter, type ChartFoundationOptions, } from './useChartFoundation.js';
13
15
  export type { ChartCommonProps, ChartHoverPayload, ChartTooltipValue, ChartTooltipBaseProps, TitleStyle, LabelStyle, BlendMode, LineMarkStyle, } from './chartProps.js';
14
- export { parseRgb, relativeLuminance, resolveColorToRgb, pickContrastColor, type Rgb, } from './contrast.js';
16
+ export { resolveColorToRgb, pickContrastColor, type Rgb } from './contrast.js';
15
17
  export { parseDate, isDateLike, isAllDates, pickDateTicks, formatDate, DATE_FORMAT_PRESETS, type DateFormat, type DateFormatPreset, type DateTickUnit, type DateTimezone, } from './dateAxis.js';
@@ -18,3 +18,4 @@ export declare function categoricalToCsv(categories: readonly string[], series:
18
18
  label?: string;
19
19
  data: ChartData;
20
20
  }[], categoryHeader?: string): string;
21
+ export declare function escapeCsvField(value: string): string;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Whether the current device has a touch screen. A function (not a
3
+ * module-level constant) so unit tests can mock it per-case and so SSR
4
+ * evaluation is deferred until an event actually needs the answer.
5
+ */
6
+ export declare function isTouchDevice(): boolean;
@@ -105,7 +105,6 @@ export declare function useChartFoundation(opts: ChartFoundationOptions): {
105
105
  fullscreenStyle: import('vue').ComputedRef<Record<string, string> | undefined>;
106
106
  teleportTarget: import('vue').ComputedRef<string | HTMLElement>;
107
107
  exitFullscreen: () => void;
108
- measuredHeight: import('vue').Ref<number, number>;
109
108
  };
110
109
  /**
111
110
  * Build a tooltip value formatter that prefers `tooltipValueFormat`,
package/dist/index.css CHANGED
@@ -1,2 +1,2 @@
1
- .chart-menu-trigger-area[data-v-f5743494]{z-index:1;position:absolute;top:.5em;right:.5em}.chart-menu-trigger-area--expanded[data-v-f5743494]{top:1.25em;right:1.25em}.chart-menu-button[data-v-f5743494]{border:1px solid var(--color-border);background:var(--color-bg-0,#fff);width:28px;height:28px;color:var(--color-text-secondary);cursor:pointer;opacity:0;border-radius:.25em;justify-content:center;align-items:center;transition:opacity .15s;display:flex}.chart-menu-button[data-state=open][data-v-f5743494],.chart-close-button[data-v-f5743494]{opacity:1}.chart-menu-button[data-v-f5743494]:hover{background:var(--color-bg-1,#0000000d);color:var(--color-text)}.line-chart-wrapper:hover .chart-menu-button,.bar-chart-wrapper:hover .chart-menu-button,.choropleth-wrapper:hover .chart-menu-button,.line-chart-wrapper:focus-within .chart-menu-button,.bar-chart-wrapper:focus-within .chart-menu-button,.choropleth-wrapper:focus-within .chart-menu-button{opacity:1}.chart-sr-only{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.chart-menu-content{z-index:100;background:var(--color-bg-0);border:1px solid var(--color-border);border-radius:.25em;min-width:140px;padding:.25em;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.chart-menu-item{font-size:var(--font-size-sm);cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap;border-radius:.25em;outline:none;align-items:center;padding:.375em .5em;display:flex}.chart-menu-item[data-highlighted]{background:var(--color-primary);color:#fff}.line-chart-wrapper[data-v-a3132bed]{width:100%;position:relative}.line-chart-tooltip-label[data-v-a3132bed]{margin-bottom:.25em;font-weight:600}.line-chart-tooltip-row[data-v-a3132bed]{align-items:center;gap:.375em;display:flex}.line-chart-download-link[data-v-a3132bed]{text-align:right;font-size:var(--font-size-sm);margin-top:.25em;display:block}.line-chart-tooltip-swatch[data-v-a3132bed]{border-radius:50%;flex-shrink:0;width:.625em;height:.625em;display:inline-block}.line-chart-download-button{border:1px solid var(--color-border);background:var(--color-bg-0,#fff);color:var(--color-text);font-size:var(--font-size-sm);cursor:pointer;border-radius:.25em;align-items:center;margin-top:.5em;padding:.5em 1em;display:inline-flex}.line-chart-download-button:hover{background:var(--color-bg-1,#0000000d)}.line-chart-download-button:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.bar-chart-wrapper[data-v-251f7945]{width:100%;position:relative}.bar-chart-tooltip-label[data-v-251f7945]{margin-bottom:.25em;font-weight:600}.bar-chart-tooltip-row[data-v-251f7945]{align-items:center;gap:.375em;display:flex}.bar-chart-download-link[data-v-251f7945]{text-align:right;font-size:var(--font-size-sm);margin-top:.25em;display:block}.bar-chart-tooltip-swatch[data-v-251f7945]{border-radius:50%;flex-shrink:0;width:.625em;height:.625em;display:inline-block}.bar-chart-download-button{border:1px solid var(--color-border);background:var(--color-bg-0,#fff);color:var(--color-text);font-size:var(--font-size-sm);cursor:pointer;border-radius:.25em;align-items:center;margin-top:.5em;padding:.5em 1em;display:inline-flex}.bar-chart-download-button:hover{background:var(--color-bg-1,#0000000d)}.bar-chart-download-button:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.choropleth-wrapper[data-v-7bd9e073]{--choropleth-legend-bg:var(--color-bg-0,#fff);width:100%;position:relative}.choropleth-wrapper svg[data-v-7bd9e073]{width:100%;height:auto;display:block}.choropleth-wrapper.pannable svg[data-v-7bd9e073]{cursor:grab}.choropleth-wrapper.is-fullscreen svg[data-v-7bd9e073]{flex:auto;width:100%;height:100%;min-height:0}.choropleth-wrapper.pannable svg[data-v-7bd9e073]:active{cursor:grabbing}.state-path[data-v-7bd9e073]{cursor:pointer}.choropleth-reset[data-v-7bd9e073]{font:inherit;color:var(--color-text-secondary,#555);background:var(--color-bg-0,#fff);border:1px solid var(--color-border,#e5e7eb);cursor:pointer;border-radius:4px;padding:4px 10px;font-size:12px;position:absolute;bottom:8px;left:8px;box-shadow:0 1px 2px #0000000d}.choropleth-reset[data-v-7bd9e073]:hover{background:var(--color-bg-1,#f8f9fa);color:var(--color-text,#212529)}.choropleth-header[data-v-7bd9e073]{background:var(--choropleth-legend-bg);color:currentColor;border-radius:4px;flex-direction:column;align-items:center;gap:10px;width:fit-content;margin:0 auto;padding:8px 14px;display:flex}.choropleth-title[data-v-7bd9e073]{white-space:pre-line;font-size:14px;font-weight:600;line-height:1.2}.choropleth-legend[data-v-7bd9e073]{align-items:center;gap:14px;font-size:13px;line-height:1.2;display:flex}.choropleth-legend-title[data-v-7bd9e073]{font-weight:600}.choropleth-legend-item[data-v-7bd9e073]{align-items:center;gap:6px;display:inline-flex}.choropleth-legend-swatch[data-v-7bd9e073]{border-radius:3px;width:12px;height:12px;display:inline-block}.choropleth-legend-continuous[data-v-7bd9e073]{flex-direction:column;width:160px;display:flex}.choropleth-legend-gradient[data-v-7bd9e073]{border-radius:2px;height:12px}.choropleth-legend-ticks[data-v-7bd9e073]{opacity:.7;height:14px;margin-top:4px;font-size:11px;position:relative}.choropleth-legend-ticks>span[data-v-7bd9e073]{position:absolute;transform:translate(-50%)}.chart-tooltip-anchor[data-v-44377f70]{pointer-events:none;width:1px;height:1px;position:absolute}.chart-tooltip-content{z-index:100;background:var(--color-bg-0,#fff);border:1px solid var(--color-border,#e5e7eb);font-size:var(--font-size-sm,.875rem);pointer-events:none;border-radius:.375em;padding:.5em .75em;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.TableOuter[data-v-21721f41]{display:inline-block;position:relative}.TableOuter.full-width[data-v-21721f41]{display:block}.TableWrapper[data-v-21721f41]{font-size:var(--font-size-sm);overflow-x:auto}.Table[data-v-21721f41]{border-collapse:collapse;font-variant-numeric:tabular-nums;border:1px solid var(--color-border);table-layout:fixed;margin:0;display:table}.Table.full-width[data-v-21721f41]{width:100%}.Table tr[data-v-21721f41],.Table th[data-v-21721f41],.Table td[data-v-21721f41]{background:0 0;border:none}.Table th[data-v-21721f41],.Table td[data-v-21721f41]{white-space:nowrap;text-overflow:ellipsis;text-align:left;padding:.75em 1.25em;overflow:hidden}.Table th.cell-wrap[data-v-21721f41],.Table td.cell-wrap[data-v-21721f41]{white-space:normal;text-overflow:clip;overflow:visible}.Table th[data-v-21721f41]{border-bottom:1px solid var(--color-border-header);font-weight:600;position:sticky;top:0}.Table tbody td[data-v-21721f41]{border-bottom:1px solid var(--color-border)}.Table tbody tr:last-child td[data-v-21721f41]{border-bottom:none}.TableOuter[data-v-21721f41] .chart-menu-trigger-area{top:4px;right:4px}.TableOuter[data-v-21721f41] .chart-menu-button{opacity:1}.TableOuter.has-menu .Table thead th[data-v-21721f41]:last-child{padding-right:2.5em}.data-table-download-button{border:1px solid var(--color-border);background:var(--color-bg-0,#fff);color:var(--color-text);font-size:var(--font-size-sm);cursor:pointer;border-radius:.25em;align-items:center;margin-top:.75em;padding:.5em 1em;display:inline-flex}.data-table-download-button:hover{background:var(--color-bg-1,#0000000d)}.data-table-download-button:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.data-table-download-link{text-align:right;font-size:var(--font-size-sm);margin-top:.25em;display:block}
1
+ .chart-menu-trigger-area[data-v-f5743494]{z-index:1;position:absolute;top:.5em;right:.5em}.chart-menu-trigger-area--expanded[data-v-f5743494]{top:1.25em;right:1.25em}.chart-menu-button[data-v-f5743494]{border:1px solid var(--color-border);background:var(--color-bg-0,#fff);width:28px;height:28px;color:var(--color-text-secondary);cursor:pointer;opacity:0;border-radius:.25em;justify-content:center;align-items:center;transition:opacity .15s;display:flex}.chart-menu-button[data-state=open][data-v-f5743494],.chart-close-button[data-v-f5743494]{opacity:1}.chart-menu-button[data-v-f5743494]:hover{background:var(--color-bg-1,#0000000d);color:var(--color-text)}.line-chart-wrapper:hover .chart-menu-button,.bar-chart-wrapper:hover .chart-menu-button,.choropleth-wrapper:hover .chart-menu-button,.line-chart-wrapper:focus-within .chart-menu-button,.bar-chart-wrapper:focus-within .chart-menu-button,.choropleth-wrapper:focus-within .chart-menu-button{opacity:1}.chart-sr-only{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.chart-menu-content{z-index:100;background:var(--color-bg-0);border:1px solid var(--color-border);border-radius:.25em;min-width:140px;padding:.25em;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.chart-menu-item{font-size:var(--font-size-sm);cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap;border-radius:.25em;outline:none;align-items:center;padding:.375em .5em;display:flex}.chart-menu-item[data-highlighted]{background:var(--color-primary);color:#fff}.chart-zoom-controls[data-v-87ceeada]{z-index:1;flex-direction:column;gap:4px;display:flex;position:absolute;top:.5em;left:.5em}.chart-zoom-controls--expanded[data-v-87ceeada]{top:1.25em;left:1.25em}.chart-zoom-button[data-v-87ceeada]{border:1px solid var(--color-border,#e5e7eb);background:var(--color-bg-0,#fff);width:28px;height:28px;color:var(--color-text-secondary,#555);cursor:pointer;border-radius:.25em;justify-content:center;align-items:center;padding:0;display:flex}.chart-zoom-button[data-v-87ceeada]:hover:not(:disabled){background:var(--color-bg-1,#0000000d);color:var(--color-text)}.chart-zoom-button[data-v-87ceeada]:disabled{opacity:.4;cursor:default}.line-chart-wrapper[data-v-a3132bed]{width:100%;position:relative}.line-chart-tooltip-label[data-v-a3132bed]{margin-bottom:.25em;font-weight:600}.line-chart-tooltip-row[data-v-a3132bed]{align-items:center;gap:.375em;display:flex}.line-chart-download-link[data-v-a3132bed]{text-align:right;font-size:var(--font-size-sm);margin-top:.25em;display:block}.line-chart-tooltip-swatch[data-v-a3132bed]{border-radius:50%;flex-shrink:0;width:.625em;height:.625em;display:inline-block}.line-chart-download-button{border:1px solid var(--color-border);background:var(--color-bg-0,#fff);color:var(--color-text);font-size:var(--font-size-sm);cursor:pointer;border-radius:.25em;align-items:center;margin-top:.5em;padding:.5em 1em;display:inline-flex}.line-chart-download-button:hover{background:var(--color-bg-1,#0000000d)}.line-chart-download-button:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.bar-chart-wrapper[data-v-251f7945]{width:100%;position:relative}.bar-chart-tooltip-label[data-v-251f7945]{margin-bottom:.25em;font-weight:600}.bar-chart-tooltip-row[data-v-251f7945]{align-items:center;gap:.375em;display:flex}.bar-chart-download-link[data-v-251f7945]{text-align:right;font-size:var(--font-size-sm);margin-top:.25em;display:block}.bar-chart-tooltip-swatch[data-v-251f7945]{border-radius:50%;flex-shrink:0;width:.625em;height:.625em;display:inline-block}.bar-chart-download-button{border:1px solid var(--color-border);background:var(--color-bg-0,#fff);color:var(--color-text);font-size:var(--font-size-sm);cursor:pointer;border-radius:.25em;align-items:center;margin-top:.5em;padding:.5em 1em;display:inline-flex}.bar-chart-download-button:hover{background:var(--color-bg-1,#0000000d)}.bar-chart-download-button:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.choropleth-wrapper[data-v-1fc9b944]{--choropleth-legend-bg:var(--color-bg-0,#fff);width:100%;position:relative}.choropleth-wrapper svg[data-v-1fc9b944]{width:100%;height:auto;display:block}.choropleth-wrapper.pannable svg[data-v-1fc9b944]{cursor:grab}.choropleth-wrapper.is-fullscreen svg[data-v-1fc9b944]{flex:auto;width:100%;height:100%;min-height:0}.choropleth-wrapper.pannable svg[data-v-1fc9b944]:active{cursor:grabbing}.state-path[data-v-1fc9b944]{cursor:pointer}.choropleth-zoom-hint[data-v-1fc9b944]{text-align:center;color:var(--color-text-secondary,#777);opacity:.6;pointer-events:none;padding-top:6px;font-size:12px;line-height:1.4;position:absolute;left:0;right:0}.choropleth-header[data-v-1fc9b944]{background:var(--choropleth-legend-bg);color:currentColor;border-radius:4px;flex-direction:column;align-items:center;gap:10px;width:fit-content;margin:0 auto;padding:8px 14px;display:flex}.choropleth-title[data-v-1fc9b944]{white-space:pre-line;font-size:14px;font-weight:600;line-height:1.2}.choropleth-legend[data-v-1fc9b944]{align-items:center;gap:14px;font-size:13px;line-height:1.2;display:flex}.choropleth-legend-title[data-v-1fc9b944]{font-weight:600}.choropleth-legend[data-v-1fc9b944]:has(.choropleth-legend-continuous){align-items:flex-start}.choropleth-legend:has(.choropleth-legend-continuous) .choropleth-legend-title[data-v-1fc9b944]{line-height:12px}.choropleth-legend-item[data-v-1fc9b944]{align-items:center;gap:6px;display:inline-flex}.choropleth-legend-swatch[data-v-1fc9b944]{border-radius:3px;width:12px;height:12px;display:inline-block}.choropleth-legend-continuous[data-v-1fc9b944]{flex-direction:column;width:160px;display:flex}.choropleth-legend-gradient[data-v-1fc9b944]{border-radius:2px;height:12px}.choropleth-legend-ticks[data-v-1fc9b944]{opacity:.7;height:14px;margin-top:4px;font-size:11px;position:relative}.choropleth-legend-ticks>span[data-v-1fc9b944]{position:absolute;transform:translate(-50%)}.chart-tooltip-anchor[data-v-44377f70]{pointer-events:none;width:1px;height:1px;position:absolute}.chart-tooltip-content{z-index:100;background:var(--color-bg-0,#fff);border:1px solid var(--color-border,#e5e7eb);font-size:var(--font-size-sm,.875rem);pointer-events:none;border-radius:.375em;padding:.5em .75em;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.TableOuter[data-v-9b1b6a76]{display:inline-block;position:relative}.TableOuter.full-width[data-v-9b1b6a76]{display:block}.TableWrapper[data-v-9b1b6a76]{font-size:var(--font-size-sm);overflow-x:auto}.Table[data-v-9b1b6a76]{border-collapse:collapse;font-variant-numeric:tabular-nums;border:1px solid var(--color-border);table-layout:fixed;margin:0;display:table}.Table.full-width[data-v-9b1b6a76]{width:100%}.Table tr[data-v-9b1b6a76],.Table th[data-v-9b1b6a76],.Table td[data-v-9b1b6a76]{background:0 0;border:none}.Table th[data-v-9b1b6a76],.Table td[data-v-9b1b6a76]{white-space:nowrap;text-overflow:ellipsis;text-align:left;padding:.75em 1.25em;overflow:hidden}.Table th.cell-wrap[data-v-9b1b6a76],.Table td.cell-wrap[data-v-9b1b6a76]{white-space:normal;text-overflow:clip;overflow:visible}.Table th[data-v-9b1b6a76]{border-bottom:1px solid var(--color-border-header);font-weight:600;position:sticky;top:0}.Table tbody td[data-v-9b1b6a76]{border-bottom:1px solid var(--color-border)}.Table tbody tr:last-child td[data-v-9b1b6a76]{border-bottom:none}.TableOuter[data-v-9b1b6a76] .chart-menu-trigger-area{top:4px;right:4px}.TableOuter[data-v-9b1b6a76] .chart-menu-button{opacity:1}.TableOuter.has-menu .Table thead th[data-v-9b1b6a76]:last-child{padding-right:2.5em}.data-table-download-button{border:1px solid var(--color-border);background:var(--color-bg-0,#fff);color:var(--color-text);font-size:var(--font-size-sm);cursor:pointer;border-radius:.25em;align-items:center;margin-top:.75em;padding:.5em 1em;display:inline-flex}.data-table-download-button:hover{background:var(--color-bg-1,#0000000d)}.data-table-download-button:focus-visible{outline:2px solid var(--color-primary);outline-offset:2px}.data-table-download-link{text-align:right;font-size:var(--font-size-sm);margin-top:.25em;display:block}
2
2
  /*$vite$:1*/