@cfasim-ui/charts 0.4.5 → 0.4.6

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,4 +1,4 @@
1
- import { ChartData } from '../_shared/index.js';
1
+ import { ChartData, ChartCommonProps, ChartHoverPayload, ChartTooltipBaseProps } from '../_shared/index.js';
2
2
  export type BarChartData = ChartData;
3
3
  export interface BarSeries {
4
4
  /** Bar values; one entry per category. `y` is accepted as an alias. */
@@ -9,7 +9,7 @@ export interface BarSeries {
9
9
  /** Label shown in the inline legend. */
10
10
  legend?: string;
11
11
  }
12
- type __VLS_Props = {
12
+ interface BarChartProps extends ChartCommonProps {
13
13
  /** Single-series values. Equivalent to `y`. */
14
14
  data?: BarChartData;
15
15
  /** Single-series values (alias for `data`). */
@@ -25,11 +25,6 @@ type __VLS_Props = {
25
25
  orientation?: "vertical" | "horizontal";
26
26
  /** "grouped" (default) places series side-by-side; "stacked" stacks them. */
27
27
  layout?: "grouped" | "stacked";
28
- width?: number;
29
- height?: number;
30
- title?: string;
31
- xLabel?: string;
32
- yLabel?: string;
33
28
  /** Force the value axis to start at this value or lower (default 0). */
34
29
  valueMin?: number;
35
30
  /**
@@ -39,11 +34,6 @@ type __VLS_Props = {
39
34
  valueTicks?: number | number[];
40
35
  /** Formatter for value-axis tick labels. */
41
36
  valueTickFormat?: (value: number) => string;
42
- /**
43
- * Formatter for numeric values shown in the default tooltip. Receives
44
- * the raw value. Defaults to the same tick formatter used for axes.
45
- */
46
- tooltipValueFormat?: (value: number) => string;
47
37
  /** Formatter for category-axis labels. Receives the resolved category string. */
48
38
  categoryFormat?: (label: string, index: number) => string;
49
39
  /**
@@ -56,49 +46,17 @@ type __VLS_Props = {
56
46
  * Default 1.
57
47
  */
58
48
  groupGap?: number;
59
- debounce?: number;
60
- menu?: boolean | string;
61
49
  valueGrid?: boolean;
62
- /**
63
- * Custom per-index data passed to the tooltip slot. Accepts a plain
64
- * array or any `ArrayLike` (e.g. a typed array column from a
65
- * `ModelOutput`).
66
- */
67
- tooltipData?: ArrayLike<unknown>;
68
- /** Tooltip activation mode. */
69
- tooltipTrigger?: "hover" | "click";
70
- /** Boundary for tooltip flip/clamp. Default "chart". */
71
- tooltipClamp?: "none" | "chart" | "window";
72
- /** Custom CSV content (string or function). When omitted, generated from the bars. */
73
- csv?: string | (() => string);
74
- /** Filename (without extension) for downloaded SVG, PNG, CSV. */
75
- filename?: string;
76
- /** Show a plain text link below the chart to download the CSV. */
77
- downloadLink?: boolean | string;
78
- };
50
+ }
79
51
  declare function __VLS_template(): {
80
52
  attrs: Partial<{}>;
81
53
  slots: Readonly<{
82
- tooltip?(props: {
83
- index: number;
54
+ tooltip?(props: ChartTooltipBaseProps & {
84
55
  category: string;
85
- values: {
86
- value: number;
87
- color: string;
88
- seriesIndex: number;
89
- }[];
90
- data: unknown;
91
56
  }): unknown;
92
57
  }> & {
93
- tooltip?(props: {
94
- index: number;
58
+ tooltip?(props: ChartTooltipBaseProps & {
95
59
  category: string;
96
- values: {
97
- value: number;
98
- color: string;
99
- seriesIndex: number;
100
- }[];
101
- data: unknown;
102
60
  }): unknown;
103
61
  };
104
62
  refs: {
@@ -109,14 +67,10 @@ declare function __VLS_template(): {
109
67
  rootEl: HTMLDivElement;
110
68
  };
111
69
  type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
112
- declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
113
- hover: (payload: {
114
- index: number;
115
- } | null) => any;
116
- }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
117
- onHover?: ((payload: {
118
- index: number;
119
- } | null) => any) | undefined;
70
+ declare const __VLS_component: import('vue').DefineComponent<BarChartProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
71
+ hover: (payload: ChartHoverPayload) => any;
72
+ }, string, import('vue').PublicProps, Readonly<BarChartProps> & Readonly<{
73
+ onHover?: ((payload: ChartHoverPayload) => any) | undefined;
120
74
  }>, {
121
75
  menu: boolean | string;
122
76
  tooltipClamp: "none" | "chart" | "window";
@@ -1,4 +1,4 @@
1
- import { ChartData } from '../_shared/index.js';
1
+ import { ChartData, ChartCommonProps, ChartHoverPayload, ChartTooltipBaseProps } from '../_shared/index.js';
2
2
  /**
3
3
  * Numeric input accepted by the chart. `number[]` and any standard numeric
4
4
  * typed array are supported, so the output of
@@ -64,7 +64,7 @@ export interface AreaSection {
64
64
  /** Label placement: "below" (default) renders below chart, "inline" renders in legend row, false hides label */
65
65
  legend?: "inline" | "below" | false;
66
66
  }
67
- type __VLS_Props = {
67
+ interface LineChartProps extends ChartCommonProps {
68
68
  /** Y-values. Equivalent to `data`. If both are set, `y` wins. */
69
69
  y?: LineChartData;
70
70
  /** Y-values (alternative name for `y`). */
@@ -78,12 +78,7 @@ type __VLS_Props = {
78
78
  series?: Series[];
79
79
  areas?: Area[];
80
80
  areaSections?: AreaSection[];
81
- width?: number;
82
- height?: number;
83
81
  lineOpacity?: number;
84
- title?: string;
85
- xLabel?: string;
86
- yLabel?: string;
87
82
  yMin?: number;
88
83
  /**
89
84
  * Offset applied to index-based x values (e.g. `xMin: 10` starts the
@@ -108,73 +103,24 @@ type __VLS_Props = {
108
103
  xTickFormat?: (value: number, index: number) => string;
109
104
  /** Formatter for y-axis tick labels. Receives the raw numeric value. */
110
105
  yTickFormat?: (value: number) => string;
111
- /**
112
- * Formatter for numeric values shown in the default tooltip. Receives
113
- * the raw value. Defaults to the same tick formatter used for axes.
114
- */
115
- tooltipValueFormat?: (value: number) => string;
116
106
  /**
117
107
  * @deprecated Use `xTickFormat` (e.g. `(_, i) => labels[i]`) together
118
108
  * with `xTicks` for explicit control. Still honored for tooltip x-labels
119
109
  * and as a default x-tick formatter when `xTickFormat` is not provided.
120
110
  */
121
111
  xLabels?: string[];
122
- debounce?: number;
123
- menu?: boolean | string;
124
112
  xGrid?: boolean;
125
113
  yGrid?: boolean;
126
- /**
127
- * Custom per-index data passed to the tooltip slot. Accepts a plain
128
- * array or any `ArrayLike` (e.g. a typed array column from a
129
- * `ModelOutput`).
130
- */
131
- tooltipData?: ArrayLike<unknown>;
132
- /** Tooltip activation mode. Default: 'hover' */
133
- tooltipTrigger?: "hover" | "click";
134
- /**
135
- * Boundary for tooltip flip/clamp. `"none"` always places to the right of
136
- * the pointer with no clamping. `"chart"` (default) uses the chart
137
- * container's bounding box. `"window"` uses the viewport.
138
- */
139
- tooltipClamp?: "none" | "chart" | "window";
140
- /**
141
- * Custom CSV content for the Download CSV menu item. Can be a raw CSV
142
- * string or a function returning one. When omitted, CSV is generated
143
- * from the chart series.
144
- */
145
- csv?: string | (() => string);
146
- /** Filename (without extension) for downloaded SVG, PNG and CSV files. */
147
- filename?: string;
148
- /**
149
- * Show a plain text link below the chart to download the CSV data.
150
- * Pass `true` for the default label ("Download data (CSV)") or a string
151
- * to customize the link text.
152
- */
153
- downloadLink?: boolean | string;
154
- };
114
+ }
155
115
  declare function __VLS_template(): {
156
116
  attrs: Partial<{}>;
157
117
  slots: Readonly<{
158
- tooltip?(props: {
159
- index: number;
118
+ tooltip?(props: ChartTooltipBaseProps & {
160
119
  xLabel?: string;
161
- values: {
162
- value: number;
163
- color: string;
164
- seriesIndex: number;
165
- }[];
166
- data: unknown;
167
120
  }): unknown;
168
121
  }> & {
169
- tooltip?(props: {
170
- index: number;
122
+ tooltip?(props: ChartTooltipBaseProps & {
171
123
  xLabel?: string;
172
- values: {
173
- value: number;
174
- color: string;
175
- seriesIndex: number;
176
- }[];
177
- data: unknown;
178
124
  }): unknown;
179
125
  };
180
126
  refs: {
@@ -185,14 +131,10 @@ declare function __VLS_template(): {
185
131
  rootEl: HTMLDivElement;
186
132
  };
187
133
  type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
188
- declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
189
- hover: (payload: {
190
- index: number;
191
- } | null) => any;
192
- }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
193
- onHover?: ((payload: {
194
- index: number;
195
- } | null) => any) | undefined;
134
+ declare const __VLS_component: import('vue').DefineComponent<LineChartProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
135
+ hover: (payload: ChartHoverPayload) => any;
136
+ }, string, import('vue').PublicProps, Readonly<LineChartProps> & Readonly<{
137
+ onHover?: ((payload: ChartHoverPayload) => any) | undefined;
196
138
  }>, {
197
139
  menu: boolean | string;
198
140
  lineOpacity: number;
@@ -0,0 +1,25 @@
1
+ import { ChartAnnotation } from './annotations.js';
2
+ import { ChartBounds } from './useChartPadding.js';
3
+ type __VLS_Props = {
4
+ annotations?: readonly ChartAnnotation[];
5
+ /**
6
+ * Project an annotation's `(x, y)` (data coordinates) to pixel
7
+ * coordinates on the chart canvas. Return `null` to drop the
8
+ * annotation (e.g. an off-projection point on a map).
9
+ */
10
+ project: (x: number, y: number) => {
11
+ x: number;
12
+ y: number;
13
+ } | null;
14
+ /**
15
+ * Pixel-space bounds of the plot area. Required for rule annotations
16
+ * so the line can span the full plot. When omitted, rule annotations
17
+ * are skipped.
18
+ */
19
+ bounds?: ChartBounds;
20
+ };
21
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
22
+ annotations: readonly ChartAnnotation[];
23
+ bounds: ChartBounds;
24
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
25
+ export default _default;
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Shared annotation API for charts. Each chart projects an annotation's
3
+ * data-space `(x, y)` to pixels with its own scales and hands the resolved
4
+ * positions to `ChartAnnotations.vue` for rendering.
5
+ */
6
+ export interface ChartAnnotation {
7
+ /**
8
+ * Anchor x position in data coordinates. For `LineChart` this is the
9
+ * same x-space as the series data; for `BarChart` it's the category
10
+ * index (fractional values land between categories).
11
+ */
12
+ x: number;
13
+ /** Anchor y position in data coordinates (value axis). */
14
+ y: number;
15
+ /**
16
+ * Label text.
17
+ * - `\n` produces a line break.
18
+ * - `**bold**` renders a run in bold.
19
+ * - `_italic_` renders a run in italic.
20
+ * - The two compose: `**_both_**`.
21
+ */
22
+ text: string;
23
+ /**
24
+ * Pixel offset from the anchor to the label's reference position.
25
+ * Positive `x` = right, positive `y` = down (screen-space).
26
+ */
27
+ offset: {
28
+ x: number;
29
+ y: number;
30
+ };
31
+ /** Text and pointer-line color. Defaults to `currentColor`. */
32
+ color?: string;
33
+ /** Font size in pixels. Default: 13 (matches axis labels). */
34
+ fontSize?: number;
35
+ /**
36
+ * Base font weight applied to all non-bold runs. Default: `"normal"`
37
+ * (matches axis labels). `**bold**` runs in `text` always render at
38
+ * weight 700.
39
+ */
40
+ fontWeight?: string | number;
41
+ /**
42
+ * Halo (stroke) color drawn behind the text so the label stays legible
43
+ * against busy chart elements. Defaults to `var(--color-bg-0, #fff)` so
44
+ * it matches the page background out of the box.
45
+ */
46
+ haloColor?: string;
47
+ /** Halo stroke width in pixels. Default: 3. */
48
+ haloWidth?: number;
49
+ /**
50
+ * SVG text-anchor for the label. When omitted, derived from the sign of
51
+ * `offset.x`: positive → `start`, negative → `end`, zero → `middle`.
52
+ */
53
+ textAnchor?: "start" | "middle" | "end";
54
+ /** Pointer- or rule-line color override. Defaults to `color`. */
55
+ lineColor?: string;
56
+ /** Pointer- or rule-line width in pixels. Default: 1. */
57
+ lineWidth?: number;
58
+ /**
59
+ * SVG `stroke-dasharray` for the pointer or rule line. Accepts the
60
+ * raw string form (`"4 4"`), a single number (uniform dash/gap), or
61
+ * an array of numbers. Default: solid line.
62
+ */
63
+ lineDash?: string | number | readonly number[];
64
+ /**
65
+ * Connector shape between anchor and label.
66
+ * - `"curved"` (default): quarter-arc emerging vertically from the
67
+ * anchor, landing horizontally at the label.
68
+ * - `"straight"`: single straight line from anchor to label.
69
+ * - `"none"`: no connector — just the text label is rendered.
70
+ * - `"ruleX"`: vertical rule at the annotation's `x` value spanning
71
+ * the full plot height. Label still positions via `offset`.
72
+ * - `"ruleY"`: horizontal rule at the annotation's `y` value spanning
73
+ * the full plot width.
74
+ * - `"ruleUp"`: vertical rule from the plot's bottom edge up to the
75
+ * anchor.
76
+ * - `"ruleDown"`: vertical rule from the plot's top edge down to the
77
+ * anchor.
78
+ * - `"ruleFromLeft"`: horizontal rule from the plot's left edge in to
79
+ * the anchor.
80
+ * - `"ruleFromRight"`: horizontal rule from the plot's right edge in
81
+ * to the anchor.
82
+ *
83
+ * When the offset is purely horizontal or vertical (and `pointer`
84
+ * isn't `"none"` or a rule), the pointer is always straight regardless
85
+ * of this setting. Rule pointers ignore `arrow`.
86
+ */
87
+ pointer?: "curved" | "straight" | "none" | "ruleX" | "ruleY" | "ruleUp" | "ruleDown" | "ruleFromLeft" | "ruleFromRight";
88
+ /**
89
+ * Whether to draw a small filled triangle at the anchor end of the
90
+ * connector line. Defaults to `true`. Set to `false` for an
91
+ * uncapped line. Ignored for rule pointers.
92
+ */
93
+ arrow?: boolean;
94
+ }
@@ -0,0 +1,67 @@
1
+ import { ChartAnnotation } from './annotations.js';
2
+ import { ChartPadding } from './useChartPadding.js';
3
+ /**
4
+ * Props common to every cartesian chart component. Anything specific to
5
+ * the chart type (series shape, layout, value-axis details) lives on the
6
+ * component itself.
7
+ */
8
+ export interface ChartCommonProps {
9
+ width?: number;
10
+ height?: number;
11
+ title?: string;
12
+ xLabel?: string;
13
+ yLabel?: string;
14
+ debounce?: number;
15
+ menu?: boolean | string;
16
+ /**
17
+ * Custom per-index data forwarded to the `tooltip` slot. Accepts a
18
+ * plain array or any `ArrayLike` (e.g. a typed-array column).
19
+ */
20
+ tooltipData?: ArrayLike<unknown>;
21
+ /** Tooltip activation mode. */
22
+ tooltipTrigger?: "hover" | "click";
23
+ /** Boundary for tooltip flip/clamp. Default: `"chart"`. */
24
+ tooltipClamp?: "none" | "chart" | "window";
25
+ /**
26
+ * Formatter for numeric values shown in the default tooltip. Receives
27
+ * the raw value. When omitted, the chart falls back to its value-axis
28
+ * tick formatter, then `formatTick`.
29
+ */
30
+ tooltipValueFormat?: (value: number) => string;
31
+ /**
32
+ * Custom CSV content (string or function) for the Download CSV menu
33
+ * item. When omitted, CSV is generated from the chart's series.
34
+ */
35
+ csv?: string | (() => string);
36
+ /** Filename (without extension) for SVG, PNG, and CSV downloads. */
37
+ filename?: string;
38
+ /**
39
+ * Show a plain text link below the chart to download CSV. Pass `true`
40
+ * for the default label or a string to customize.
41
+ */
42
+ downloadLink?: boolean | string;
43
+ /** Annotations rendered as the top layer of the chart. */
44
+ annotations?: readonly ChartAnnotation[];
45
+ /**
46
+ * Extra padding (pixels) added around the plot. Number = same on all
47
+ * sides; object = per-side. Useful for giving annotations or other
48
+ * overlays room to extend past the data area without clipping.
49
+ */
50
+ chartPadding?: ChartPadding;
51
+ }
52
+ /** Payload emitted on `hover` from a cartesian chart. */
53
+ export type ChartHoverPayload = {
54
+ index: number;
55
+ } | null;
56
+ /** One per-series value passed to the tooltip slot. */
57
+ export interface ChartTooltipValue {
58
+ value: number;
59
+ color: string;
60
+ seriesIndex: number;
61
+ }
62
+ /** Properties common to every chart's tooltip slot. */
63
+ export interface ChartTooltipBaseProps {
64
+ index: number;
65
+ values: ChartTooltipValue[];
66
+ data: unknown;
67
+ }
@@ -1,7 +1,11 @@
1
1
  export { snap, niceStep, intervalValues, formatTick, type ChartData, } from './axes.js';
2
2
  export { computeTickValues, type TickValueOptions } from './computeTicks.js';
3
3
  export { useChartSize, type ChartSizeOptions } from './useChartSize.js';
4
- export { useChartPadding, INLINE_LEGEND_HEIGHT, type ChartPaddingOptions, } from './useChartPadding.js';
4
+ export { useChartPadding, INLINE_LEGEND_HEIGHT, type ChartPaddingOptions, type ChartPadding, type ChartBounds, } from './useChartPadding.js';
5
5
  export { useChartTooltip, type ChartTooltipOptions, } from './useChartTooltip.js';
6
6
  export { useChartMenu, type ChartMenuOptions } from './useChartMenu.js';
7
7
  export { seriesToCsv, categoricalToCsv, type CsvSeries } from './seriesCsv.js';
8
+ export { default as ChartAnnotations } from './ChartAnnotations';
9
+ export type { ChartAnnotation } from './annotations.js';
10
+ export { useChartFoundation, makeTooltipValueFormatter, type ChartFoundationOptions, } from './useChartFoundation.js';
11
+ export type { ChartCommonProps, ChartHoverPayload, ChartTooltipValue, ChartTooltipBaseProps, } from './chartProps.js';
@@ -0,0 +1,82 @@
1
+ import { ChartPadding } from './useChartPadding.js';
2
+ import { TooltipClamp } from '../tooltip-position.js';
3
+ export interface ChartFoundationOptions {
4
+ width: () => number | undefined;
5
+ height: () => number | undefined;
6
+ title: () => string | undefined;
7
+ xLabel: () => string | undefined;
8
+ yLabel: () => string | undefined;
9
+ debounce: () => number | undefined;
10
+ menu: () => boolean | string | undefined;
11
+ tooltipTrigger: () => "hover" | "click" | undefined;
12
+ tooltipClamp: () => TooltipClamp | undefined;
13
+ filename: () => string | undefined;
14
+ downloadLink: () => boolean | string | undefined;
15
+ chartPadding: () => ChartPadding | undefined;
16
+ hasInlineLegend: () => boolean;
17
+ hasTooltipSlot: () => boolean;
18
+ getCsv: () => string;
19
+ pointerToIndex: (clientX: number, clientY: number) => number | null;
20
+ onHover: (payload: {
21
+ index: number;
22
+ } | null) => void;
23
+ }
24
+ /**
25
+ * Wires up the shared chart plumbing — size measurement, padding, tooltip
26
+ * interaction, and the menu/download wiring — that every cartesian chart
27
+ * needs. Returns the reactive values and refs each chart's template
28
+ * consumes.
29
+ */
30
+ export declare function useChartFoundation(opts: ChartFoundationOptions): {
31
+ containerRef: import('vue').Ref<HTMLElement | null, HTMLElement | null>;
32
+ svgRef: import('vue').Ref<SVGSVGElement | null, SVGSVGElement | null>;
33
+ width: import('vue').ComputedRef<number>;
34
+ height: import('vue').ComputedRef<number>;
35
+ padding: import('vue').ComputedRef<{
36
+ top: number;
37
+ right: number;
38
+ bottom: number;
39
+ left: number;
40
+ }>;
41
+ legendY: import('vue').ComputedRef<number>;
42
+ innerW: import('vue').ComputedRef<number>;
43
+ innerH: import('vue').ComputedRef<number>;
44
+ bounds: import('vue').ComputedRef<{
45
+ left: number;
46
+ top: number;
47
+ right: number;
48
+ bottom: number;
49
+ width: number;
50
+ height: number;
51
+ }>;
52
+ hoverIndex: import('vue').Ref<number | null, number | null>;
53
+ tooltipRef: import('vue').Ref<HTMLElement | null, HTMLElement | null>;
54
+ tooltipPos: import('vue').Ref<{
55
+ left: number;
56
+ top: number;
57
+ } | null, {
58
+ left: number;
59
+ top: number;
60
+ } | {
61
+ left: number;
62
+ top: number;
63
+ } | null>;
64
+ tooltipHandlers: {
65
+ mousemove: (event: MouseEvent) => void;
66
+ mouseleave: () => void;
67
+ click: (event: MouseEvent) => void;
68
+ touchstart: (event: TouchEvent) => void;
69
+ touchmove: (event: TouchEvent) => void;
70
+ touchend: () => void;
71
+ };
72
+ menuItems: import('vue').ComputedRef<import('../ChartMenu/ChartMenu').ChartMenuItem[]>;
73
+ downloadLinkText: import('vue').ComputedRef<string | null>;
74
+ csvHref: import('vue').ComputedRef<string | null>;
75
+ menuFilename: () => string;
76
+ };
77
+ /**
78
+ * Build a tooltip value formatter that prefers `tooltipValueFormat`,
79
+ * falls back to the chart's axis tick formatter, and finally to
80
+ * `formatTick`. Both chart components use the same precedence order.
81
+ */
82
+ export declare function makeTooltipValueFormatter(tooltipFormat: () => ((v: number) => string) | undefined, axisFormat: () => ((v: number) => string) | undefined): (v: number) => string;
@@ -1,5 +1,17 @@
1
1
  /** Vertical space reserved at the top of the chart for inline legend swatches. */
2
2
  export declare const INLINE_LEGEND_HEIGHT = 20;
3
+ /**
4
+ * Extra space added around the chart's standard layout. A number applies
5
+ * the same amount to all four sides; an object lets you pad sides
6
+ * independently (e.g. `{ top: 24 }` to make room for annotations above
7
+ * the plot). Named to match Altair's `padding` (outer view padding).
8
+ */
9
+ export type ChartPadding = number | {
10
+ top?: number;
11
+ right?: number;
12
+ bottom?: number;
13
+ left?: number;
14
+ };
3
15
  export interface ChartPaddingOptions {
4
16
  title: () => string | undefined;
5
17
  xLabel: () => string | undefined;
@@ -7,12 +19,16 @@ export interface ChartPaddingOptions {
7
19
  hasInlineLegend: () => boolean;
8
20
  width: () => number;
9
21
  height: () => number;
22
+ /** Extra pixels added on top of the standard axis spacing. */
23
+ extraPadding?: () => ChartPadding | undefined;
10
24
  }
11
25
  /**
12
26
  * Computes the standard chart padding (top/right/bottom/left) and the
13
27
  * derived inner plotting region (innerW, innerH). Shared by LineChart
14
28
  * and BarChart so the axis label spacing and inline legend strip stay
15
- * consistent.
29
+ * consistent. `extraPadding` adds extra space outside the plot — useful
30
+ * for annotations that need to extend past the data area without
31
+ * clipping.
16
32
  */
17
33
  export declare function useChartPadding(opts: ChartPaddingOptions): {
18
34
  padding: import('vue').ComputedRef<{
@@ -21,6 +37,23 @@ export declare function useChartPadding(opts: ChartPaddingOptions): {
21
37
  bottom: number;
22
38
  left: number;
23
39
  }>;
40
+ legendY: import('vue').ComputedRef<number>;
24
41
  innerW: import('vue').ComputedRef<number>;
25
42
  innerH: import('vue').ComputedRef<number>;
43
+ bounds: import('vue').ComputedRef<{
44
+ left: number;
45
+ top: number;
46
+ right: number;
47
+ bottom: number;
48
+ width: number;
49
+ height: number;
50
+ }>;
51
+ };
52
+ export type ChartBounds = {
53
+ left: number;
54
+ top: number;
55
+ right: number;
56
+ bottom: number;
57
+ width: number;
58
+ height: number;
26
59
  };
package/dist/index.css CHANGED
@@ -1,2 +1,2 @@
1
- .chart-menu-trigger-area[data-v-b3c563e8]{z-index:1;position:absolute;top:0;right:0}.chart-menu-button[data-v-b3c563e8]{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-b3c563e8]{opacity:1}.chart-menu-button[data-v-b3c563e8]:hover{background:var(--color-bg-1,#0000000d);color:var(--color-text)}.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-083d1c2f]{width:100%;position:relative}.line-chart-wrapper[data-v-083d1c2f]:hover .chart-menu-button{opacity:1}.line-chart-tooltip-label[data-v-083d1c2f]{margin-bottom:.25em;font-weight:600}.line-chart-tooltip-row[data-v-083d1c2f]{align-items:center;gap:.375em;display:flex}.line-chart-download-link[data-v-083d1c2f]{text-align:right;font-size:var(--font-size-sm);margin-top:.25em;display:block}.line-chart-tooltip-swatch[data-v-083d1c2f]{border-radius:50%;flex-shrink:0;width:.625em;height:.625em;display:inline-block}.bar-chart-wrapper[data-v-4f604d9f]{width:100%;position:relative}.bar-chart-wrapper[data-v-4f604d9f]:hover .chart-menu-button{opacity:1}.bar-chart-tooltip-label[data-v-4f604d9f]{margin-bottom:.25em;font-weight:600}.bar-chart-tooltip-row[data-v-4f604d9f]{align-items:center;gap:.375em;display:flex}.bar-chart-download-link[data-v-4f604d9f]{text-align:right;font-size:var(--font-size-sm);margin-top:.25em;display:block}.bar-chart-tooltip-swatch[data-v-4f604d9f]{border-radius:50%;flex-shrink:0;width:.625em;height:.625em;display:inline-block}.choropleth-wrapper[data-v-f0f75b22]{--choropleth-legend-bg:var(--color-bg-0,#fff);width:100%;position:relative}.choropleth-wrapper svg[data-v-f0f75b22]{width:100%;height:auto;display:block}.choropleth-wrapper.pannable svg[data-v-f0f75b22]{cursor:grab}.choropleth-wrapper.pannable svg[data-v-f0f75b22]:active{cursor:grabbing}.choropleth-wrapper[data-v-f0f75b22]:hover .chart-menu-button{opacity:1}.state-path[data-v-f0f75b22]{cursor:pointer}.choropleth-reset[data-v-f0f75b22]{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-f0f75b22]:hover{background:var(--color-bg-1,#f8f9fa);color:var(--color-text,#212529)}.choropleth-header[data-v-f0f75b22]{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-f0f75b22]{font-size:14px;font-weight:600;line-height:1.2}.choropleth-legend[data-v-f0f75b22]{align-items:center;gap:14px;font-size:13px;line-height:1.2;display:flex}.choropleth-legend-title[data-v-f0f75b22]{font-weight:600}.choropleth-legend-item[data-v-f0f75b22]{align-items:center;gap:6px;display:inline-flex}.choropleth-legend-swatch[data-v-f0f75b22]{border-radius:3px;width:12px;height:12px;display:inline-block}.choropleth-legend-continuous[data-v-f0f75b22]{flex-direction:column;width:160px;display:flex}.choropleth-legend-gradient[data-v-f0f75b22]{border-radius:2px;height:12px}.choropleth-legend-ticks[data-v-f0f75b22]{opacity:.7;height:14px;margin-top:4px;font-size:11px;position:relative}.choropleth-legend-ticks>span[data-v-f0f75b22]{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-d5c290dc]{display:inline-block;position:relative}.TableOuter.full-width[data-v-d5c290dc]{display:block}.TableWrapper[data-v-d5c290dc]{font-size:var(--font-size-sm);overflow-x:auto}.Table[data-v-d5c290dc]{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-d5c290dc]{width:100%}.Table tr[data-v-d5c290dc],.Table th[data-v-d5c290dc],.Table td[data-v-d5c290dc]{background:0 0;border:none}.Table th[data-v-d5c290dc],.Table td[data-v-d5c290dc]{white-space:nowrap;text-align:left;padding:.75em 1.25em}.Table th[data-v-d5c290dc]{border-bottom:1px solid var(--color-border-header);font-weight:600;position:sticky;top:0}.Table tbody td[data-v-d5c290dc]{border-bottom:1px solid var(--color-border)}.Table tbody tr:last-child td[data-v-d5c290dc]{border-bottom:none}.TableOuter[data-v-d5c290dc] .chart-menu-trigger-area{top:4px;right:4px}.TableOuter[data-v-d5c290dc] .chart-menu-button{opacity:1}.TableOuter.has-menu .Table thead th[data-v-d5c290dc]:last-child{padding-right:2.5em}
1
+ .chart-menu-trigger-area[data-v-b3c563e8]{z-index:1;position:absolute;top:0;right:0}.chart-menu-button[data-v-b3c563e8]{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-b3c563e8]{opacity:1}.chart-menu-button[data-v-b3c563e8]:hover{background:var(--color-bg-1,#0000000d);color:var(--color-text)}.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-ebe2731e]{width:100%;position:relative}.line-chart-wrapper[data-v-ebe2731e]:hover .chart-menu-button{opacity:1}.line-chart-tooltip-label[data-v-ebe2731e]{margin-bottom:.25em;font-weight:600}.line-chart-tooltip-row[data-v-ebe2731e]{align-items:center;gap:.375em;display:flex}.line-chart-download-link[data-v-ebe2731e]{text-align:right;font-size:var(--font-size-sm);margin-top:.25em;display:block}.line-chart-tooltip-swatch[data-v-ebe2731e]{border-radius:50%;flex-shrink:0;width:.625em;height:.625em;display:inline-block}.bar-chart-wrapper[data-v-690ebb3c]{width:100%;position:relative}.bar-chart-wrapper[data-v-690ebb3c]:hover .chart-menu-button{opacity:1}.bar-chart-tooltip-label[data-v-690ebb3c]{margin-bottom:.25em;font-weight:600}.bar-chart-tooltip-row[data-v-690ebb3c]{align-items:center;gap:.375em;display:flex}.bar-chart-download-link[data-v-690ebb3c]{text-align:right;font-size:var(--font-size-sm);margin-top:.25em;display:block}.bar-chart-tooltip-swatch[data-v-690ebb3c]{border-radius:50%;flex-shrink:0;width:.625em;height:.625em;display:inline-block}.choropleth-wrapper[data-v-f0f75b22]{--choropleth-legend-bg:var(--color-bg-0,#fff);width:100%;position:relative}.choropleth-wrapper svg[data-v-f0f75b22]{width:100%;height:auto;display:block}.choropleth-wrapper.pannable svg[data-v-f0f75b22]{cursor:grab}.choropleth-wrapper.pannable svg[data-v-f0f75b22]:active{cursor:grabbing}.choropleth-wrapper[data-v-f0f75b22]:hover .chart-menu-button{opacity:1}.state-path[data-v-f0f75b22]{cursor:pointer}.choropleth-reset[data-v-f0f75b22]{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-f0f75b22]:hover{background:var(--color-bg-1,#f8f9fa);color:var(--color-text,#212529)}.choropleth-header[data-v-f0f75b22]{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-f0f75b22]{font-size:14px;font-weight:600;line-height:1.2}.choropleth-legend[data-v-f0f75b22]{align-items:center;gap:14px;font-size:13px;line-height:1.2;display:flex}.choropleth-legend-title[data-v-f0f75b22]{font-weight:600}.choropleth-legend-item[data-v-f0f75b22]{align-items:center;gap:6px;display:inline-flex}.choropleth-legend-swatch[data-v-f0f75b22]{border-radius:3px;width:12px;height:12px;display:inline-block}.choropleth-legend-continuous[data-v-f0f75b22]{flex-direction:column;width:160px;display:flex}.choropleth-legend-gradient[data-v-f0f75b22]{border-radius:2px;height:12px}.choropleth-legend-ticks[data-v-f0f75b22]{opacity:.7;height:14px;margin-top:4px;font-size:11px;position:relative}.choropleth-legend-ticks>span[data-v-f0f75b22]{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-d5c290dc]{display:inline-block;position:relative}.TableOuter.full-width[data-v-d5c290dc]{display:block}.TableWrapper[data-v-d5c290dc]{font-size:var(--font-size-sm);overflow-x:auto}.Table[data-v-d5c290dc]{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-d5c290dc]{width:100%}.Table tr[data-v-d5c290dc],.Table th[data-v-d5c290dc],.Table td[data-v-d5c290dc]{background:0 0;border:none}.Table th[data-v-d5c290dc],.Table td[data-v-d5c290dc]{white-space:nowrap;text-align:left;padding:.75em 1.25em}.Table th[data-v-d5c290dc]{border-bottom:1px solid var(--color-border-header);font-weight:600;position:sticky;top:0}.Table tbody td[data-v-d5c290dc]{border-bottom:1px solid var(--color-border)}.Table tbody tr:last-child td[data-v-d5c290dc]{border-bottom:none}.TableOuter[data-v-d5c290dc] .chart-menu-trigger-area{top:4px;right:4px}.TableOuter[data-v-d5c290dc] .chart-menu-button{opacity:1}.TableOuter.has-menu .Table thead th[data-v-d5c290dc]:last-child{padding-right:2.5em}
2
2
  /*$vite$:1*/
package/dist/index.d.ts CHANGED
@@ -4,3 +4,4 @@ export { default as ChoroplethMap, type GeoType, type StateData, type Choropleth
4
4
  export { fipsToHsa, hsaNames } from './ChoroplethMap/hsaMapping.js';
5
5
  export { default as ChartTooltip } from './ChartTooltip/ChartTooltip';
6
6
  export { default as DataTable, type TableData, type TableRecord, type ColumnAlign, type ColumnConfig, type ColumnWidth, } from './DataTable/DataTable';
7
+ export type { ChartAnnotation } from './_shared/annotations.js';