@fundar/data-chart-telling 0.0.1

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.
Files changed (106) hide show
  1. package/README.md +250 -0
  2. package/dist/charts/Chart.svelte +125 -0
  3. package/dist/charts/Chart.svelte.d.ts +42 -0
  4. package/dist/charts/bar/Chart.svelte +104 -0
  5. package/dist/charts/bar/Chart.svelte.d.ts +27 -0
  6. package/dist/charts/container/ChartContainer.svelte +127 -0
  7. package/dist/charts/container/ChartContainer.svelte.d.ts +14 -0
  8. package/dist/charts/heatmap/Chart.svelte +107 -0
  9. package/dist/charts/heatmap/Chart.svelte.d.ts +30 -0
  10. package/dist/charts/line/Chart.svelte +106 -0
  11. package/dist/charts/line/Chart.svelte.d.ts +27 -0
  12. package/dist/charts/pyramid/Chart.svelte +127 -0
  13. package/dist/charts/pyramid/Chart.svelte.d.ts +31 -0
  14. package/dist/configuration/config.svelte.d.ts +12 -0
  15. package/dist/configuration/config.svelte.js +159 -0
  16. package/dist/configuration/themes/compact.d.ts +2 -0
  17. package/dist/configuration/themes/compact.js +9 -0
  18. package/dist/configuration/themes/dark.d.ts +2 -0
  19. package/dist/configuration/themes/dark.js +17 -0
  20. package/dist/configuration/themes/default.d.ts +3 -0
  21. package/dist/configuration/themes/default.js +2 -0
  22. package/dist/configuration/themes/editorial.d.ts +2 -0
  23. package/dist/configuration/themes/editorial.js +14 -0
  24. package/dist/configuration/themes/index.d.ts +481 -0
  25. package/dist/configuration/themes/index.js +16 -0
  26. package/dist/index.d.ts +32 -0
  27. package/dist/index.js +27 -0
  28. package/dist/layout/facet/FacetLayout.svelte +97 -0
  29. package/dist/layout/facet/FacetLayout.svelte.d.ts +35 -0
  30. package/dist/layout/legend/ContinuousSection.svelte +95 -0
  31. package/dist/layout/legend/ContinuousSection.svelte.d.ts +7 -0
  32. package/dist/layout/legend/DiscreteSection.svelte +87 -0
  33. package/dist/layout/legend/DiscreteSection.svelte.d.ts +7 -0
  34. package/dist/layout/legend/LegendLayout.svelte +47 -0
  35. package/dist/layout/legend/LegendLayout.svelte.d.ts +7 -0
  36. package/dist/layout/plot/PlotLayout.svelte +236 -0
  37. package/dist/layout/plot/PlotLayout.svelte.d.ts +70 -0
  38. package/dist/layout/timeline/Timeline.svelte +86 -0
  39. package/dist/layout/timeline/Timeline.svelte.d.ts +11 -0
  40. package/dist/layout/timeline/TimelineLayout.svelte +181 -0
  41. package/dist/layout/timeline/TimelineLayout.svelte.d.ts +38 -0
  42. package/dist/layout/tooltip/Tooltip.svelte +55 -0
  43. package/dist/layout/tooltip/Tooltip.svelte.d.ts +12 -0
  44. package/dist/layout/tooltip/controller.svelte.d.ts +52 -0
  45. package/dist/layout/tooltip/controller.svelte.js +128 -0
  46. package/dist/layout/tooltip/hover.svelte.d.ts +7 -0
  47. package/dist/layout/tooltip/hover.svelte.js +28 -0
  48. package/dist/layout/tooltip/utils.d.ts +41 -0
  49. package/dist/layout/tooltip/utils.js +78 -0
  50. package/dist/plots/bar/Plot.svelte +176 -0
  51. package/dist/plots/bar/Plot.svelte.d.ts +26 -0
  52. package/dist/plots/heatmap/Plot.svelte +175 -0
  53. package/dist/plots/heatmap/Plot.svelte.d.ts +26 -0
  54. package/dist/plots/line/Plot.svelte +232 -0
  55. package/dist/plots/line/Plot.svelte.d.ts +26 -0
  56. package/dist/plots/markers/DeltaMarker.svelte +104 -0
  57. package/dist/plots/markers/DeltaMarker.svelte.d.ts +30 -0
  58. package/dist/plots/markers/DotMarker.svelte +41 -0
  59. package/dist/plots/markers/DotMarker.svelte.d.ts +31 -0
  60. package/dist/plots/markers/HoverMarker.svelte +78 -0
  61. package/dist/plots/markers/HoverMarker.svelte.d.ts +22 -0
  62. package/dist/plots/markers/PeakMarker.svelte +80 -0
  63. package/dist/plots/markers/PeakMarker.svelte.d.ts +13 -0
  64. package/dist/plots/markers/TextMarker.svelte +55 -0
  65. package/dist/plots/markers/TextMarker.svelte.d.ts +32 -0
  66. package/dist/plots/pyramid/Plot.svelte +282 -0
  67. package/dist/plots/pyramid/Plot.svelte.d.ts +26 -0
  68. package/dist/plots/utils/accessors.d.ts +6 -0
  69. package/dist/plots/utils/accessors.js +10 -0
  70. package/dist/plots/utils/delta.d.ts +12 -0
  71. package/dist/plots/utils/delta.js +69 -0
  72. package/dist/plots/utils/segments.d.ts +33 -0
  73. package/dist/plots/utils/segments.js +153 -0
  74. package/dist/stores/device.d.ts +7 -0
  75. package/dist/stores/device.js +39 -0
  76. package/dist/types/charts/common.d.ts +64 -0
  77. package/dist/types/charts/common.js +1 -0
  78. package/dist/types/charts/interpolate.d.ts +2 -0
  79. package/dist/types/charts/interpolate.js +1 -0
  80. package/dist/types/charts/legend.d.ts +29 -0
  81. package/dist/types/charts/legend.js +1 -0
  82. package/dist/types/charts/props.d.ts +35 -0
  83. package/dist/types/charts/props.js +1 -0
  84. package/dist/types/configuration/styling.d.ts +97 -0
  85. package/dist/types/configuration/styling.js +1 -0
  86. package/dist/types/layout/tooltip.d.ts +88 -0
  87. package/dist/types/layout/tooltip.js +1 -0
  88. package/dist/types/plots/common.d.ts +100 -0
  89. package/dist/types/plots/common.js +1 -0
  90. package/dist/types/plots/delta.d.ts +19 -0
  91. package/dist/types/plots/delta.js +1 -0
  92. package/dist/types/plots/markers.d.ts +56 -0
  93. package/dist/types/plots/markers.js +1 -0
  94. package/dist/types/plots/props.d.ts +23 -0
  95. package/dist/types/plots/props.js +1 -0
  96. package/dist/types/plots/styles.d.ts +176 -0
  97. package/dist/types/plots/styles.js +1 -0
  98. package/dist/types/viewport.d.ts +4 -0
  99. package/dist/types/viewport.js +1 -0
  100. package/dist/utils/color.d.ts +5 -0
  101. package/dist/utils/color.js +42 -0
  102. package/dist/utils/grouping.d.ts +14 -0
  103. package/dist/utils/grouping.js +36 -0
  104. package/dist/utils/interpolate.d.ts +30 -0
  105. package/dist/utils/interpolate.js +71 -0
  106. package/package.json +76 -0
@@ -0,0 +1,176 @@
1
+ import type { AxisValue, Series } from './common';
2
+ /**
3
+ * Unified positional anchor for value labels across all plot kinds.
4
+ *
5
+ * - `'outside'` — beyond the tip of the mark (above a vertical bar, to the
6
+ * far end of a horizontal bar or line). This is the only value with no
7
+ * direct svelteplot equivalent; the plot computes dx/dy internally.
8
+ * - `'start'` — at the tip of the mark, just inside (top of a bar, far end
9
+ * of a pyramid bar from zero, right of a line's last point).
10
+ * - `'middle'` — centred on the mark.
11
+ * - `'end'` — at the baseline/zero end of the mark.
12
+ */
13
+ export type ValueAnchor = 'outside' | 'start' | 'middle' | 'end';
14
+ /**
15
+ * Controls if and how value labels are rendered on a plot. The high-level
16
+ * `anchor` sets sensible defaults for placement; the low-level svelteplot
17
+ * Text-mark fields (`dx`, `dy`, `textAnchor`, `lineAnchor`, `lineHeight`,
18
+ * `rotate`, `class`, `textClass`) override those defaults when provided.
19
+ */
20
+ export type ValuesStyle = {
21
+ show?: boolean;
22
+ anchor?: ValueAnchor;
23
+ /** Called with the numeric value and the series name. Return a string to render. */
24
+ format?: (value: number, seriesName: string) => string;
25
+ dx?: number;
26
+ dy?: number;
27
+ textAnchor?: 'start' | 'end' | 'middle';
28
+ lineAnchor?: 'top' | 'bottom' | 'middle';
29
+ lineHeight?: number;
30
+ rotate?: number;
31
+ class?: string;
32
+ textClass?: string;
33
+ };
34
+ /**
35
+ * Color overrides for plots that derive their palette from data.
36
+ * Each plot uses only the fields relevant to its kind; unused fields are
37
+ * silently ignored.
38
+ *
39
+ * - `min` / `max` — sequential colour ramp endpoints (heatmap).
40
+ * - `left` / `right` — diverging bar sides (pyramid).
41
+ */
42
+ export type ColorsStyle = {
43
+ min?: string;
44
+ max?: string;
45
+ left?: string;
46
+ right?: string;
47
+ };
48
+ /**
49
+ * Top-level rendering style overrides shared by all plot kinds. Passed as the
50
+ * `styles` prop. Each plot reads only the fields it cares about.
51
+ */
52
+ export type PlotStyles = {
53
+ values?: ValuesStyle;
54
+ colors?: ColorsStyle;
55
+ };
56
+ export type SymbolType = 'circle' | 'square' | 'triangle' | 'line';
57
+ export type LineStyle = 'solid' | 'dashed' | 'dotted' | 'dashdot';
58
+ export type LineCap = 'butt' | 'round' | 'square';
59
+ export type LineJoin = 'arcs' | 'bevel' | 'miter' | 'miter-clip' | 'round';
60
+ /** Stroke styling for any line-ish mark — a line, a rule, a marker's connector. */
61
+ export type StrokeStyle = {
62
+ stroke?: string;
63
+ strokeWidth?: number;
64
+ strokeOpacity?: number;
65
+ strokeDasharray?: string | LineStyle;
66
+ strokeLinecap?: LineCap;
67
+ strokeLinejoin?: LineJoin;
68
+ };
69
+ /**
70
+ * Dot styling for any point mark — a line's endpoint dots, a marker's dot.
71
+ * Carries its own `dotStroke*` fields rather than nesting a {@link StrokeStyle},
72
+ * because a dot's outline is a distinct style from the stroke of the line (or
73
+ * other mark) it sits next to — e.g. a {@link LineSegmentStyle} styles its
74
+ * line's stroke and its dots' outline independently.
75
+ */
76
+ export type DotStyle = {
77
+ dotRadius?: number;
78
+ dotFill?: string;
79
+ dotFillOpacity?: number;
80
+ dotSymbol?: SymbolType;
81
+ dotStroke?: string;
82
+ dotStrokeWidth?: number;
83
+ dotStrokeOpacity?: number;
84
+ dotStrokeDasharray?: string | LineStyle;
85
+ };
86
+ /** Text/label styling for any text mark — a marker's label, an annotation. */
87
+ export type FontStyle = {
88
+ fill?: string;
89
+ fontSize?: number;
90
+ fontWeight?: 'normal' | 'bold';
91
+ fontStyle?: 'normal' | 'italic';
92
+ textAnchor?: 'start' | 'middle' | 'end';
93
+ lineAnchor?: 'top' | 'middle' | 'bottom';
94
+ stroke?: string;
95
+ strokeWidth?: number;
96
+ paintOrder?: string;
97
+ dx?: number;
98
+ dy?: number;
99
+ };
100
+ /** Per-segment styling for a line: its stroke and/or its endpoint dots. */
101
+ export type LineSegmentStyle = {
102
+ stroke?: StrokeStyle;
103
+ dots?: DotStyle;
104
+ };
105
+ /** Per-segment styling for a bar: its fill. */
106
+ export type BarSegmentStyle = {
107
+ fill?: string;
108
+ fillOpacity?: number;
109
+ };
110
+ /** Per-cell styling override for a heatmap cell. */
111
+ export type CellSegmentStyle = {
112
+ fill?: string;
113
+ fillOpacity?: number;
114
+ stroke?: string;
115
+ strokeWidth?: number;
116
+ };
117
+ /** A half-open interval on one axis. Both bounds are inclusive; omit either to leave that end open. */
118
+ export type Range = {
119
+ from?: AxisValue;
120
+ to?: AxisValue;
121
+ };
122
+ /**
123
+ * A 2-D rectangular area on the plot, addressed by optional x and y intervals.
124
+ * Omitting an interval leaves that axis unrestricted (matches all values).
125
+ *
126
+ * - For line/bar/pyramid plots only the `x` interval is used (the series' primary
127
+ * axis); `y` is evaluated but filters by the series' value axis.
128
+ * - For heatmaps both `x` (column) and `y` (row) are used to address cells.
129
+ */
130
+ export type Area = {
131
+ x?: Range;
132
+ y?: Range;
133
+ };
134
+ /**
135
+ * One styled rule for a plot. A data point (or cell) is styled when it falls
136
+ * inside **any** of the listed `areas`. Omitting `areas` (or passing an empty
137
+ * array) makes the segment match **all** data — useful as a baseline style.
138
+ * `TStyle` is the per-mark shape ({@link LineSegmentStyle}, {@link BarSegmentStyle},
139
+ * {@link CellSegmentStyle}, …).
140
+ *
141
+ * Segments are applied in order; later ones are rendered on top of earlier ones.
142
+ */
143
+ export type Segment<TStyle> = {
144
+ areas?: Area[];
145
+ style?: TStyle;
146
+ };
147
+ /** Per-series list of {@link Segment}s, keyed by series name. */
148
+ export type SeriesAwareSegmentsMap<TStyle> = Record<string, Segment<TStyle>[]>;
149
+ /**
150
+ * Unified segments prop accepted by every plot kind.
151
+ *
152
+ * - **Array form** (`Segment<TStyle>[]`): segments are applied to **all** series
153
+ * (or to the implicit single dataset of a heatmap). Only form supported by
154
+ * `HeatmapPlot` / `HeatmapChart`.
155
+ * - **Record form** (`SeriesAwareSegmentsMap<TStyle>`): each key is a series
156
+ * name; segments apply only to that series. Supported by line, bar, and
157
+ * pyramid plots; when an array is passed to those plots the same segments
158
+ * apply to every series.
159
+ */
160
+ export type SegmentsMap<TStyle> = Segment<TStyle>[] | SeriesAwareSegmentsMap<TStyle>;
161
+ /** One contiguous, styled slice of a series' data — ready to draw as its own mark. */
162
+ export type VisualSegment<T extends Record<string, unknown>, TStyle = LineSegmentStyle> = {
163
+ data: T[];
164
+ style: TStyle;
165
+ };
166
+ /**
167
+ * A series split into its styled visual segments. `S` is the full series
168
+ * type Series<T> — its row type is read off `S['data']`
169
+ * rather than taken as a separate parameter, since TypeScript can't reliably
170
+ * infer a type parameter that only appears inside another parameter's
171
+ * constraint.
172
+ */
173
+ export type VisualGroup<S extends Series<any>, TStyle = LineSegmentStyle> = {
174
+ series: S;
175
+ visualSegments: VisualSegment<S['data'][number], TStyle>[];
176
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export type Viewport = {
2
+ width: number;
3
+ height: number;
4
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ export declare function resolveCssColor(color: string): string;
2
+ export declare function normalize(v: number, min: number, max: number): number;
3
+ /** Cycles through a discrete palette by series index — the default colour for an unstyled series. */
4
+ export declare function paletteColor(index: number, palette: string[]): string;
5
+ export declare function makeColorScale(min: number, max: number, colorMin: string, colorMax: string): (v: number) => string;
@@ -0,0 +1,42 @@
1
+ import { interpolateRgb } from 'd3-interpolate';
2
+ import { isBrowser } from '../stores/device';
3
+ export function resolveCssColor(color) {
4
+ if (!isBrowser)
5
+ return color;
6
+ if (!color.startsWith('var('))
7
+ return color;
8
+ const varName = color.slice(4, -1).trim();
9
+ const value = getComputedStyle(document.documentElement)
10
+ .getPropertyValue(varName)
11
+ .trim();
12
+ return value || color;
13
+ }
14
+ export function normalize(v, min, max) {
15
+ if (v == null)
16
+ return 0;
17
+ const denom = max - min || 1;
18
+ return Math.max(0, Math.min(1, (v - min) / denom));
19
+ }
20
+ /** Cycles through a discrete palette by series index — the default colour for an unstyled series. */
21
+ export function paletteColor(index, palette) {
22
+ if (palette.length === 0)
23
+ return 'currentColor';
24
+ return palette[index % palette.length];
25
+ }
26
+ export function makeColorScale(min, max, colorMin, colorMax) {
27
+ const resolvedMin = resolveCssColor(colorMin);
28
+ const resolvedMax = resolveCssColor(colorMax);
29
+ let interpolator;
30
+ try {
31
+ interpolator = interpolateRgb(resolvedMin, resolvedMax);
32
+ }
33
+ catch {
34
+ return () => '#ccc';
35
+ }
36
+ return (v) => {
37
+ if (v == null)
38
+ return '#ccc';
39
+ const t = normalize(v, min, max);
40
+ return interpolator(t);
41
+ };
42
+ }
@@ -0,0 +1,14 @@
1
+ import type { Series, AxisValue, Accessor } from '../types/plots/common';
2
+ /**
3
+ * Splits rows into ordered groups keyed by the stringified accessor value.
4
+ * Insertion order of first appearance is preserved, which keeps colours stable
5
+ * across re-renders without forcing the caller to pre-sort.
6
+ */
7
+ export declare function groupBy<TRow extends Record<string, unknown>>(data: TRow[], by: Accessor<TRow, unknown>): Map<string, TRow[]>;
8
+ /**
9
+ * Adapts flat rows into the `Series[]` shape the plot expects.
10
+ * When `z` is given, one series is produced per group (series `name` = group
11
+ * value), which is exactly how the plot's `segments` map is keyed — so the
12
+ * caller styles each group by its `z` value.
13
+ */
14
+ export declare function buildSeries<TRow extends Record<string, unknown>>(data: TRow[], x: Accessor<TRow, AxisValue>, y: Accessor<TRow, AxisValue>, z: Accessor<TRow, unknown> | undefined, defaultName?: string): Series<TRow>[];
@@ -0,0 +1,36 @@
1
+ import { resolveAccessor } from '../plots/utils/accessors';
2
+ /**
3
+ * Splits rows into ordered groups keyed by the stringified accessor value.
4
+ * Insertion order of first appearance is preserved, which keeps colours stable
5
+ * across re-renders without forcing the caller to pre-sort.
6
+ */
7
+ export function groupBy(data, by) {
8
+ const get = resolveAccessor(by);
9
+ const groups = new Map();
10
+ for (const row of data) {
11
+ const key = String(get(row));
12
+ const bucket = groups.get(key);
13
+ if (bucket)
14
+ bucket.push(row);
15
+ else
16
+ groups.set(key, [row]);
17
+ }
18
+ return groups;
19
+ }
20
+ /**
21
+ * Adapts flat rows into the `Series[]` shape the plot expects.
22
+ * When `z` is given, one series is produced per group (series `name` = group
23
+ * value), which is exactly how the plot's `segments` map is keyed — so the
24
+ * caller styles each group by its `z` value.
25
+ */
26
+ export function buildSeries(data, x, y, z, defaultName = 'series') {
27
+ if (z === undefined) {
28
+ return [{ name: defaultName, x, y, data }];
29
+ }
30
+ return [...groupBy(data, z).entries()].map(([name, rows]) => ({
31
+ name,
32
+ x,
33
+ y,
34
+ data: rows,
35
+ }));
36
+ }
@@ -0,0 +1,30 @@
1
+ import type { EasingName, EasingFn } from '../types/charts/interpolate';
2
+ import type { TimeValue, TimelineInterpolation } from '../types/charts/common';
3
+ import type { Accessor, AxisValue } from '../types/plots/common';
4
+ export declare function resolveEasing(easing?: EasingName | EasingFn): EasingFn;
5
+ /**
6
+ * Brackets a continuous target position `x` within one key-group's sorted
7
+ * rows and tweens between the two real rows it falls between — the leading
8
+ * edge moves continuously instead of snapping between steps. Returns every
9
+ * already-passed real row plus the synthetic tween row (or just the clamped
10
+ * first/last row when `x` is outside the group's range). A caller that wants
11
+ * a single replacing "frame" (e.g. a bar snapshot) takes just the last entry.
12
+ */
13
+ export declare function interpolateSeries<TRow>({ rows, x, getTime, getValue, create, segmentEasing, }: {
14
+ rows: TRow[];
15
+ x: TimeValue;
16
+ getTime: (row: TRow) => TimeValue;
17
+ getValue: (row: TRow) => number;
18
+ create: (lower: TRow, upper: TRow, x: TimeValue, value: number) => TRow;
19
+ segmentEasing: EasingFn;
20
+ }): TRow[];
21
+ /**
22
+ * Resolves `TimelineConfig.interpolate` (`true` | a partial config | unset)
23
+ * into a fully-populated {@link TimelineInterpolation}, falling back to the
24
+ * chart-supplied `value`/`key` defaults — used by `LineChart`/`BarChart` so
25
+ * consumers can write `interpolate: true` instead of repeating their own `y`/`z`.
26
+ */
27
+ export declare function resolveTimelineInterpolation<TRow extends Record<string, unknown>>(interpolate: boolean | TimelineInterpolation<TRow> | undefined, defaults: {
28
+ value: Accessor<TRow, AxisValue>;
29
+ key?: Accessor<TRow, unknown>;
30
+ }): TimelineInterpolation<TRow> | undefined;
@@ -0,0 +1,71 @@
1
+ const EASINGS = {
2
+ linear: (t) => t,
3
+ quadIn: (t) => t * t,
4
+ quadOut: (t) => 1 - (1 - t) * (1 - t),
5
+ cubicIn: (t) => t * t * t,
6
+ cubicOut: (t) => 1 - Math.pow(1 - t, 3),
7
+ quartIn: (t) => t * t * t * t,
8
+ quartOut: (t) => 1 - Math.pow(1 - t, 4),
9
+ expoOut: (t) => (t === 1 ? 1 : 1 - Math.pow(2, -10 * t)),
10
+ };
11
+ export function resolveEasing(easing) {
12
+ if (!easing)
13
+ return EASINGS.linear;
14
+ if (typeof easing === 'function')
15
+ return easing;
16
+ return EASINGS[easing] ?? EASINGS.linear;
17
+ }
18
+ /**
19
+ * Brackets a continuous target position `x` within one key-group's sorted
20
+ * rows and tweens between the two real rows it falls between — the leading
21
+ * edge moves continuously instead of snapping between steps. Returns every
22
+ * already-passed real row plus the synthetic tween row (or just the clamped
23
+ * first/last row when `x` is outside the group's range). A caller that wants
24
+ * a single replacing "frame" (e.g. a bar snapshot) takes just the last entry.
25
+ */
26
+ export function interpolateSeries({ rows, x, getTime, getValue, create, segmentEasing, }) {
27
+ if (!rows.length)
28
+ return [];
29
+ const sorted = [...rows].sort((a, b) => Number(getTime(a)) - Number(getTime(b)));
30
+ if (x <= getTime(sorted[0]))
31
+ return [sorted[0]];
32
+ const result = [];
33
+ for (let i = 0; i < sorted.length - 1; i++) {
34
+ const d0 = sorted[i];
35
+ const d1 = sorted[i + 1];
36
+ const t0 = getTime(d0);
37
+ const t1 = getTime(d1);
38
+ if (x >= t1) {
39
+ result.push(d0);
40
+ continue;
41
+ }
42
+ if (x >= t0 && x < t1) {
43
+ const tRaw = (Number(x) - Number(t0)) / (Number(t1) - Number(t0));
44
+ const t = segmentEasing(tRaw);
45
+ const value = getValue(d0) + (getValue(d1) - getValue(d0)) * t;
46
+ result.push(d0);
47
+ result.push(create(d0, d1, x, value));
48
+ return result;
49
+ }
50
+ }
51
+ const last = sorted[sorted.length - 1];
52
+ if (x >= getTime(last))
53
+ result.push(last);
54
+ return result;
55
+ }
56
+ /**
57
+ * Resolves `TimelineConfig.interpolate` (`true` | a partial config | unset)
58
+ * into a fully-populated {@link TimelineInterpolation}, falling back to the
59
+ * chart-supplied `value`/`key` defaults — used by `LineChart`/`BarChart` so
60
+ * consumers can write `interpolate: true` instead of repeating their own `y`/`z`.
61
+ */
62
+ export function resolveTimelineInterpolation(interpolate, defaults) {
63
+ if (!interpolate)
64
+ return undefined;
65
+ const config = interpolate === true ? {} : interpolate;
66
+ return {
67
+ ...config,
68
+ value: config.value ?? defaults.value,
69
+ key: config.key ?? defaults.key,
70
+ };
71
+ }
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "@fundar/data-chart-telling",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "files": [
6
+ "dist"
7
+ ],
8
+ "sideEffects": [
9
+ "**/*.css"
10
+ ],
11
+ "svelte": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "svelte": "./dist/index.js",
17
+ "default": "./dist/index.js"
18
+ }
19
+ },
20
+ "dependencies": {
21
+ "d3-interpolate": "^3.0.1"
22
+ },
23
+ "peerDependencies": {
24
+ "svelte": "^5.0.0",
25
+ "svelteplot": "^0.14.0"
26
+ },
27
+ "devDependencies": {
28
+ "@eslint/compat": "^2.0.4",
29
+ "@eslint/js": "^10.0.1",
30
+ "@sveltejs/package": "^2.5.7",
31
+ "@sveltejs/vite-plugin-svelte": "^7.0.0",
32
+ "@types/d3-interpolate": "^3.0.4",
33
+ "@types/node": "^22",
34
+ "@vitest/browser": "^4.1.7",
35
+ "@vitest/browser-playwright": "^4.1.7",
36
+ "eslint": "^10.2.0",
37
+ "eslint-config-prettier": "^10.1.8",
38
+ "eslint-plugin-svelte": "^3.17.0",
39
+ "globals": "^17.4.0",
40
+ "playwright": "^1.60.0",
41
+ "prettier": "^3.8.1",
42
+ "prettier-plugin-svelte": "^3.5.1",
43
+ "publint": "^0.3.18",
44
+ "svelte": "^5.55.2",
45
+ "svelte-check": "^4.4.6",
46
+ "svelteplot": "^0.14.0",
47
+ "typescript": "^6.0.2",
48
+ "typescript-eslint": "^8.58.1",
49
+ "vite": "^8.0.7",
50
+ "vitest": "^4.1.3",
51
+ "vitest-browser-svelte": "^2.1.1",
52
+ "storybook": "^10.4.1",
53
+ "@storybook/svelte-vite": "^10.4.1",
54
+ "@storybook/addon-svelte-csf": "^5.1.2",
55
+ "@chromatic-com/storybook": "^5.2.1",
56
+ "@storybook/addon-vitest": "^10.4.1",
57
+ "@storybook/addon-a11y": "^10.4.1",
58
+ "@storybook/addon-docs": "^10.4.1",
59
+ "eslint-plugin-storybook": "^10.4.1",
60
+ "@vitest/coverage-v8": "4.1.7"
61
+ },
62
+ "keywords": [
63
+ "svelte"
64
+ ],
65
+ "scripts": {
66
+ "build": "svelte-package",
67
+ "check": "svelte-check --tsconfig ./tsconfig.json",
68
+ "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
69
+ "lint": "prettier --check . && eslint .",
70
+ "format": "prettier --write .",
71
+ "test": "vitest run --project=unit --project=browser",
72
+ "test:stories": "vitest run --project=storybook",
73
+ "storybook": "storybook dev -p 6006",
74
+ "build-storybook": "storybook build"
75
+ }
76
+ }