insomni-plot 0.1.0-alpha.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.
- package/LICENSE.md +674 -0
- package/README.md +81 -0
- package/dist/core.d.mts +340 -0
- package/dist/core.mjs +1047 -0
- package/dist/index.d.mts +3426 -0
- package/dist/index.mjs +12762 -0
- package/dist/interactions-DEFL_F4E.mjs +5395 -0
- package/dist/range-presets-CzECsu3V.d.mts +1523 -0
- package/package.json +34 -0
- package/src/annotations.d.ts +121 -0
- package/src/annotations.ts +438 -0
- package/src/axis.d.ts +184 -0
- package/src/axis.test.ts +131 -0
- package/src/axis.ts +765 -0
- package/src/colorbar.d.ts +69 -0
- package/src/colorbar.ts +294 -0
- package/src/colors.d.ts +57 -0
- package/src/colors.test.ts +28 -0
- package/src/colors.ts +486 -0
- package/src/core.ts +299 -0
- package/src/format.d.ts +54 -0
- package/src/format.ts +138 -0
- package/src/grammar/accessibility.d.ts +147 -0
- package/src/grammar/accessibility.test.ts +199 -0
- package/src/grammar/accessibility.ts +443 -0
- package/src/grammar/aes.d.ts +35 -0
- package/src/grammar/aes.test.ts +75 -0
- package/src/grammar/aes.ts +120 -0
- package/src/grammar/annotations.d.ts +86 -0
- package/src/grammar/annotations.test.ts +68 -0
- package/src/grammar/annotations.ts +336 -0
- package/src/grammar/attach-brush.d.ts +44 -0
- package/src/grammar/attach-brush.test.ts +214 -0
- package/src/grammar/attach-brush.ts +111 -0
- package/src/grammar/attach-presets.d.ts +33 -0
- package/src/grammar/attach-presets.test.ts +106 -0
- package/src/grammar/attach-presets.ts +215 -0
- package/src/grammar/chart.d.ts +952 -0
- package/src/grammar/chart.test.ts +118 -0
- package/src/grammar/chart.ts +1172 -0
- package/src/grammar/color-utils.d.ts +29 -0
- package/src/grammar/color-utils.test.ts +53 -0
- package/src/grammar/color-utils.ts +66 -0
- package/src/grammar/constants.d.ts +45 -0
- package/src/grammar/constants.ts +61 -0
- package/src/grammar/coord.d.ts +183 -0
- package/src/grammar/coord.test.ts +355 -0
- package/src/grammar/coord.ts +619 -0
- package/src/grammar/data/pivot.d.ts +57 -0
- package/src/grammar/data/pivot.ts +107 -0
- package/src/grammar/emphasis-driver.d.ts +69 -0
- package/src/grammar/emphasis-driver.test.ts +199 -0
- package/src/grammar/emphasis-driver.ts +205 -0
- package/src/grammar/equality.d.ts +3 -0
- package/src/grammar/equality.ts +40 -0
- package/src/grammar/facet.d.ts +63 -0
- package/src/grammar/facet.test.ts +60 -0
- package/src/grammar/facet.ts +175 -0
- package/src/grammar/geoms/_categorical.d.ts +94 -0
- package/src/grammar/geoms/_categorical.ts +0 -0
- package/src/grammar/geoms/_distribution.d.ts +52 -0
- package/src/grammar/geoms/_distribution.ts +125 -0
- package/src/grammar/geoms/_mark.d.ts +69 -0
- package/src/grammar/geoms/_mark.ts +136 -0
- package/src/grammar/geoms/_shape.d.ts +41 -0
- package/src/grammar/geoms/_shape.ts +74 -0
- package/src/grammar/geoms/aggregate.d.ts +95 -0
- package/src/grammar/geoms/aggregate.test.ts +554 -0
- package/src/grammar/geoms/aggregate.ts +840 -0
- package/src/grammar/geoms/area.d.ts +32 -0
- package/src/grammar/geoms/area.test.ts +165 -0
- package/src/grammar/geoms/area.ts +578 -0
- package/src/grammar/geoms/band.d.ts +27 -0
- package/src/grammar/geoms/band.test.ts +57 -0
- package/src/grammar/geoms/band.ts +126 -0
- package/src/grammar/geoms/bar.d.ts +56 -0
- package/src/grammar/geoms/bar.test.ts +367 -0
- package/src/grammar/geoms/bar.ts +1054 -0
- package/src/grammar/geoms/boxplot.d.ts +129 -0
- package/src/grammar/geoms/boxplot.test.ts +299 -0
- package/src/grammar/geoms/boxplot.ts +834 -0
- package/src/grammar/geoms/connected-scatter.d.ts +27 -0
- package/src/grammar/geoms/connected-scatter.test.ts +157 -0
- package/src/grammar/geoms/connected-scatter.ts +63 -0
- package/src/grammar/geoms/emphasis.d.ts +76 -0
- package/src/grammar/geoms/emphasis.test.ts +135 -0
- package/src/grammar/geoms/emphasis.ts +162 -0
- package/src/grammar/geoms/histogram.d.ts +75 -0
- package/src/grammar/geoms/histogram.test.ts +262 -0
- package/src/grammar/geoms/histogram.ts +740 -0
- package/src/grammar/geoms/index.d.ts +20 -0
- package/src/grammar/geoms/index.ts +77 -0
- package/src/grammar/geoms/interval.d.ts +31 -0
- package/src/grammar/geoms/interval.test.ts +154 -0
- package/src/grammar/geoms/interval.ts +342 -0
- package/src/grammar/geoms/line.d.ts +38 -0
- package/src/grammar/geoms/line.test.ts +247 -0
- package/src/grammar/geoms/line.ts +659 -0
- package/src/grammar/geoms/point.d.ts +57 -0
- package/src/grammar/geoms/point.test.ts +163 -0
- package/src/grammar/geoms/point.ts +545 -0
- package/src/grammar/geoms/polar.test.ts +216 -0
- package/src/grammar/geoms/ribbon.d.ts +21 -0
- package/src/grammar/geoms/ribbon.test.ts +170 -0
- package/src/grammar/geoms/ribbon.ts +87 -0
- package/src/grammar/geoms/ridgeline.d.ts +89 -0
- package/src/grammar/geoms/ridgeline.test.ts +247 -0
- package/src/grammar/geoms/ridgeline.ts +1164 -0
- package/src/grammar/geoms/rolling.d.ts +43 -0
- package/src/grammar/geoms/rolling.test.ts +217 -0
- package/src/grammar/geoms/rolling.ts +387 -0
- package/src/grammar/geoms/rug.d.ts +28 -0
- package/src/grammar/geoms/rug.test.ts +126 -0
- package/src/grammar/geoms/rug.ts +214 -0
- package/src/grammar/geoms/rule.d.ts +23 -0
- package/src/grammar/geoms/rule.test.ts +69 -0
- package/src/grammar/geoms/rule.ts +212 -0
- package/src/grammar/geoms/smooth.d.ts +54 -0
- package/src/grammar/geoms/smooth.test.ts +78 -0
- package/src/grammar/geoms/smooth.ts +337 -0
- package/src/grammar/geoms/text.d.ts +29 -0
- package/src/grammar/geoms/text.test.ts +64 -0
- package/src/grammar/geoms/text.ts +234 -0
- package/src/grammar/geoms/tile.d.ts +61 -0
- package/src/grammar/geoms/tile.test.ts +157 -0
- package/src/grammar/geoms/tile.ts +621 -0
- package/src/grammar/geoms/types.d.ts +319 -0
- package/src/grammar/geoms/types.ts +362 -0
- package/src/grammar/geoms/violin.d.ts +85 -0
- package/src/grammar/geoms/violin.test.ts +187 -0
- package/src/grammar/geoms/violin.ts +672 -0
- package/src/grammar/index.d.ts +22 -0
- package/src/grammar/index.ts +269 -0
- package/src/grammar/interactions/_disposable.d.ts +5 -0
- package/src/grammar/interactions/_disposable.ts +23 -0
- package/src/grammar/interactions/_z.d.ts +4 -0
- package/src/grammar/interactions/_z.ts +16 -0
- package/src/grammar/interactions/brush-selection.test.ts +262 -0
- package/src/grammar/interactions/brush.d.ts +63 -0
- package/src/grammar/interactions/brush.test.ts +483 -0
- package/src/grammar/interactions/brush.ts +452 -0
- package/src/grammar/interactions/crosshair.d.ts +19 -0
- package/src/grammar/interactions/crosshair.test.ts +127 -0
- package/src/grammar/interactions/crosshair.ts +76 -0
- package/src/grammar/interactions/hit-layer.d.ts +64 -0
- package/src/grammar/interactions/hit-layer.ts +246 -0
- package/src/grammar/interactions/legend.d.ts +19 -0
- package/src/grammar/interactions/legend.ts +101 -0
- package/src/grammar/interactions/menu.d.ts +93 -0
- package/src/grammar/interactions/menu.test.ts +373 -0
- package/src/grammar/interactions/menu.ts +342 -0
- package/src/grammar/interactions/selection.d.ts +25 -0
- package/src/grammar/interactions/selection.test.ts +289 -0
- package/src/grammar/interactions/selection.ts +142 -0
- package/src/grammar/interactions/series-readout.d.ts +91 -0
- package/src/grammar/interactions/series-readout.test.ts +668 -0
- package/src/grammar/interactions/series-readout.ts +422 -0
- package/src/grammar/interactions/series-snap.d.ts +70 -0
- package/src/grammar/interactions/series-snap.test.ts +214 -0
- package/src/grammar/interactions/series-snap.ts +218 -0
- package/src/grammar/interactions/tooltip-axis.test.ts +176 -0
- package/src/grammar/interactions/tooltip-touch.browser.test.ts +49 -0
- package/src/grammar/interactions/tooltip-touch.test.ts +161 -0
- package/src/grammar/interactions/tooltip.d.ts +140 -0
- package/src/grammar/interactions/tooltip.test.ts +406 -0
- package/src/grammar/interactions/tooltip.ts +622 -0
- package/src/grammar/interactions/transitions.d.ts +34 -0
- package/src/grammar/interactions/transitions.test.ts +172 -0
- package/src/grammar/interactions/transitions.ts +160 -0
- package/src/grammar/layout.d.ts +68 -0
- package/src/grammar/layout.ts +186 -0
- package/src/grammar/legend-merge.test.ts +332 -0
- package/src/grammar/mount.d.ts +78 -0
- package/src/grammar/mount.test.ts +479 -0
- package/src/grammar/mount.ts +2112 -0
- package/src/grammar/palettes.d.ts +54 -0
- package/src/grammar/palettes.test.ts +80 -0
- package/src/grammar/palettes.ts +167 -0
- package/src/grammar/pan-zoom.test.ts +398 -0
- package/src/grammar/phylo.d.ts +65 -0
- package/src/grammar/phylo.test.ts +59 -0
- package/src/grammar/phylo.ts +112 -0
- package/src/grammar/pipeline.auto-ticks.test.ts +40 -0
- package/src/grammar/pipeline.d.ts +158 -0
- package/src/grammar/pipeline.test.ts +463 -0
- package/src/grammar/pipeline.ts +1233 -0
- package/src/grammar/profiling.d.ts +8 -0
- package/src/grammar/profiling.ts +24 -0
- package/src/grammar/scales.d.ts +188 -0
- package/src/grammar/scales.test.ts +181 -0
- package/src/grammar/scales.ts +800 -0
- package/src/grammar/svg.d.ts +3 -0
- package/src/grammar/svg.ts +39 -0
- package/src/grammar/theme.d.ts +261 -0
- package/src/grammar/theme.test.ts +105 -0
- package/src/grammar/theme.ts +490 -0
- package/src/heatmap/cpu.ts +109 -0
- package/src/heatmap/gpu.ts +565 -0
- package/src/heatmap/types.ts +177 -0
- package/src/heatmap.browser.test.ts +308 -0
- package/src/heatmap.test.ts +320 -0
- package/src/heatmap.ts +123 -0
- package/src/index.d.ts +1 -0
- package/src/index.ts +8 -0
- package/src/interactions.d.ts +48 -0
- package/src/interactions.test.ts +226 -0
- package/src/interactions.ts +394 -0
- package/src/layout/box.d.ts +48 -0
- package/src/layout/box.test.ts +107 -0
- package/src/layout/box.ts +143 -0
- package/src/legend.d.ts +115 -0
- package/src/legend.ts +422 -0
- package/src/marks/curve.d.ts +43 -0
- package/src/marks/curve.ts +244 -0
- package/src/marks/stack.d.ts +53 -0
- package/src/marks/stack.ts +184 -0
- package/src/marks.d.ts +273 -0
- package/src/marks.test.ts +541 -0
- package/src/marks.ts +1292 -0
- package/src/navigator.test.ts +174 -0
- package/src/navigator.ts +393 -0
- package/src/range-presets.d.ts +113 -0
- package/src/range-presets.test.ts +345 -0
- package/src/range-presets.ts +349 -0
- package/src/scales.d.ts +98 -0
- package/src/scales.test.ts +103 -0
- package/src/scales.ts +695 -0
- package/src/stats/index.d.ts +200 -0
- package/src/stats/index.test.ts +349 -0
- package/src/stats/index.ts +740 -0
- package/src/stats/regression.d.ts +38 -0
- package/src/stats/regression.test.ts +56 -0
- package/src/stats/regression.ts +396 -0
- package/src/stats/rolling-window.d.ts +55 -0
- package/src/stats/rolling-window.test.ts +237 -0
- package/src/stats/rolling-window.ts +256 -0
- package/src/test-setup.ts +19 -0
- package/src/viewport/axis-state.d.ts +72 -0
- package/src/viewport/axis-state.ts +476 -0
- package/src/viewport.d.ts +170 -0
- package/src/viewport.test.ts +363 -0
- package/src/viewport.ts +510 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,3426 @@
|
|
|
1
|
+
import { $t as SwatchSpec, C as KdeBandwidth, D as QuantileMethod, Dn as LineDashStyle, Dr as TimeIntervalUnit, Jn as StackOrder, Nn as PointShapeKind, O as WhiskerRule, Or as TimeScale, Qn as LineCurve, S as HistogramMeasure, Sn as BarOrientation, Tr as NumericRange, U as RollingWindow, V as RollingStatistic, bn as BarBorderStyle, br as ContinuousScale, c as RangePresetsSubscriber, cn as LabelBoxStyle, cr as AxisTickFormatter, dn as ValueLabelAlign, dr as TickSpec, ft as CategoricalPalette, g as BinClosed, i as RangePresetDataDomain, jn as PointBorderStyle, kn as MarkBuilder, l as TimePresetKey, or as AxisOptions, pt as ContinuousPalette, t as RangePreset, tt as DataViewport, ur as TickIntervalSpec, v as BinResult, vr as BandScale, w as KdeKernel, y as BinRule, z as RollingAxis } from "./range-presets-CzECsu3V.mjs";
|
|
2
|
+
import * as _$insomni from "insomni";
|
|
3
|
+
import { BlendSpace, BlendSpace as BlendSpace$1, BrushAxis, BrushRect, Color, Easing, Frame, FrameTiming, GlyphAtlas, InteractionManager, Invalidator, Layer, Padding, Renderer2D } from "insomni";
|
|
4
|
+
import { Signal } from "insomni/reactivity";
|
|
5
|
+
|
|
6
|
+
//#region src/grammar/accessibility.d.ts
|
|
7
|
+
type AccessibilityMode = "auto-color" | "outline" | "shadow" | "none";
|
|
8
|
+
type ContrastMetric = "wcag" | "apca";
|
|
9
|
+
interface Accessibility {
|
|
10
|
+
/**
|
|
11
|
+
* Master switch. When `false`, `resolveTextColor` never alters colors —
|
|
12
|
+
* but if `warn` is also true it logs the failing site once per session so
|
|
13
|
+
* authors can see what would have been fixed.
|
|
14
|
+
*/
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Which contrast metric to enforce.
|
|
18
|
+
*
|
|
19
|
+
* `"apca"` (default) uses APCA Lc — perceptually uniform and
|
|
20
|
+
* polarity-aware, so equalizing produces labels that read with the same
|
|
21
|
+
* weight whether they sit on a dark or a light cell.
|
|
22
|
+
*
|
|
23
|
+
* `"wcag"` uses the WCAG 2.1 ratio formula. Kept for backwards
|
|
24
|
+
* compatibility; equalizing on WCAG ratio looks visually unbalanced
|
|
25
|
+
* across polarities.
|
|
26
|
+
*/
|
|
27
|
+
metric: ContrastMetric;
|
|
28
|
+
/**
|
|
29
|
+
* WCAG-mode target. `"AA"` = 4.5:1 normal / 3:1 large; `"AAA"` = 7:1 / 4.5:1.
|
|
30
|
+
* A raw number sets an absolute minimum ratio (1–21) applied to all text
|
|
31
|
+
* regardless of size. Ignored when `metric === "apca"`.
|
|
32
|
+
*/
|
|
33
|
+
wcagLevel: "AA" | "AAA" | number;
|
|
34
|
+
/**
|
|
35
|
+
* APCA-mode target |Lc|. `"auto"` (default) looks up the recommended
|
|
36
|
+
* minimum from APCA's font/weight table for each site (typical body text
|
|
37
|
+
* lands around Lc 75–90). A raw number applies a single |Lc| floor to
|
|
38
|
+
* every site. Ignored when `metric === "wcag"`.
|
|
39
|
+
*/
|
|
40
|
+
apcaTarget: number | "auto";
|
|
41
|
+
/**
|
|
42
|
+
* How to fix low-contrast text. `auto-color` nudges the color toward an
|
|
43
|
+
* accessible shade preserving hue/saturation. `outline` / `shadow` are
|
|
44
|
+
* reserved API hooks — both currently degrade to `auto-color` since the
|
|
45
|
+
* SDF text pipeline doesn't render text effects yet. `none` leaves text
|
|
46
|
+
* untouched (and warns when `warn` is on).
|
|
47
|
+
*/
|
|
48
|
+
mode: AccessibilityMode;
|
|
49
|
+
/** Whether to console.warn on contrast failures the system isn't fixing. */
|
|
50
|
+
warn: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* When true, every *mark* label (geom-rendered, sitting on a data-driven
|
|
53
|
+
* fill) is normalized to *exactly* the target contrast — not just `>=`.
|
|
54
|
+
* Equalizing prevents cells with high contrast from visually outweighing
|
|
55
|
+
* neighbors. Hue and saturation are preserved; only lightness shifts.
|
|
56
|
+
*
|
|
57
|
+
* Chrome text (titles, axis, legend) skips this — those sit on the
|
|
58
|
+
* panel background and equalizing them just dims legible chrome.
|
|
59
|
+
*/
|
|
60
|
+
equalize: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* How strongly the auto-fixer pulls toward colors already in the theme.
|
|
63
|
+
* `0` keeps the original hue/sat untouched. `1` snaps to the nearest
|
|
64
|
+
* passing theme accent. Intermediate values blend in `blendSpace`,
|
|
65
|
+
* keeping the label feeling "of the same family" as the chart's palette.
|
|
66
|
+
*
|
|
67
|
+
* The pull is only applied when at least one accent independently meets
|
|
68
|
+
* the contrast target — biasing toward an unreadable accent would defeat
|
|
69
|
+
* the fix. When `equalize` is on, the L-channel is re-fit after the blend
|
|
70
|
+
* so the final contrast still lands at the target.
|
|
71
|
+
*/
|
|
72
|
+
themeBias: number;
|
|
73
|
+
/**
|
|
74
|
+
* Optional explicit accent palette for the bias. When unset, the
|
|
75
|
+
* resolver derives accents from the active theme (text/title/legend
|
|
76
|
+
* colors plus a sample of the categorical palette).
|
|
77
|
+
*/
|
|
78
|
+
accents?: readonly Color[];
|
|
79
|
+
/**
|
|
80
|
+
* Color space used for the theme-bias blend. Defaults to `"oklch"` —
|
|
81
|
+
* perceptually uniform with hue preserved along the blend.
|
|
82
|
+
*/
|
|
83
|
+
blendSpace: BlendSpace$1;
|
|
84
|
+
}
|
|
85
|
+
declare const DEFAULT_ACCESSIBILITY: Accessibility;
|
|
86
|
+
/**
|
|
87
|
+
* Stub for SDF text effects. Setting these on the theme today has no visual
|
|
88
|
+
* effect — the renderer will pick them up once outline/shadow are wired into
|
|
89
|
+
* the text pipeline. Kept on the public API so call sites and themes can
|
|
90
|
+
* declare intent now without a follow-up breaking change.
|
|
91
|
+
*/
|
|
92
|
+
interface TextEffects {
|
|
93
|
+
outline?: {
|
|
94
|
+
color: Color;
|
|
95
|
+
width: number;
|
|
96
|
+
};
|
|
97
|
+
shadow?: {
|
|
98
|
+
color: Color;
|
|
99
|
+
blur?: number;
|
|
100
|
+
dx?: number;
|
|
101
|
+
dy?: number;
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
interface ResolveTextColorOptions {
|
|
105
|
+
/** Font size in CSS pixels. */
|
|
106
|
+
fontSizePx: number;
|
|
107
|
+
/** Treat the text as bold (affects WCAG large-text and APCA weight lookup). */
|
|
108
|
+
bold?: boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Short label identifying the draw site (e.g. `"axis-label"`,
|
|
111
|
+
* `"tile-label"`). Used to namespace dedupe keys for warnings.
|
|
112
|
+
*/
|
|
113
|
+
site: string;
|
|
114
|
+
/**
|
|
115
|
+
* Whether this site sits on a *data-driven* background (mark fills,
|
|
116
|
+
* heatmap cells) versus chrome on the panel background. `equalize`
|
|
117
|
+
* normalization applies only to mark sites — chrome text always sits on
|
|
118
|
+
* the same panel background, so equalizing it would just lower legible
|
|
119
|
+
* titles/axis/legend text down toward the contrast floor for no gain.
|
|
120
|
+
* Default `false`.
|
|
121
|
+
*/
|
|
122
|
+
markLabel?: boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Override the engine-computed target. When set, the resolver uses this
|
|
125
|
+
* value instead of the font/level lookup. Used by geoms that need to
|
|
126
|
+
* coordinate a layer-wide equalize floor (e.g. tile pulls every label
|
|
127
|
+
* down to the worst cell's max-achievable contrast so the layer reads
|
|
128
|
+
* uniformly, instead of saturating each label at its own per-cell max).
|
|
129
|
+
*/
|
|
130
|
+
targetOverride?: number;
|
|
131
|
+
/** @internal — APCA polarity, computed inside the resolver. */
|
|
132
|
+
_apcaReverse?: boolean;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Resolve the actual color that should be drawn for a piece of text given
|
|
136
|
+
* the requested foreground, the known background, and the chart's
|
|
137
|
+
* accessibility policy. Pure — does not draw anything.
|
|
138
|
+
*/
|
|
139
|
+
declare function resolveTextColor(fg: Color, bg: Color, theme: Theme, opts: ResolveTextColorOptions): Color;
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/grammar/theme.d.ts
|
|
142
|
+
interface ThemeText {
|
|
143
|
+
color: Color;
|
|
144
|
+
fontFamily: string;
|
|
145
|
+
}
|
|
146
|
+
interface ThemeTitle {
|
|
147
|
+
fontSize: number;
|
|
148
|
+
fontWeight: string;
|
|
149
|
+
color: Color;
|
|
150
|
+
}
|
|
151
|
+
interface ThemeSubtitle {
|
|
152
|
+
fontSize: number;
|
|
153
|
+
color: Color;
|
|
154
|
+
}
|
|
155
|
+
interface ThemeAxis {
|
|
156
|
+
color: Color;
|
|
157
|
+
gridColor: Color;
|
|
158
|
+
labelFontSize: number;
|
|
159
|
+
labelColor: Color;
|
|
160
|
+
titleFontSize: number;
|
|
161
|
+
titleColor: Color;
|
|
162
|
+
}
|
|
163
|
+
interface ThemeLegend {
|
|
164
|
+
fontSize: number;
|
|
165
|
+
labelColor: Color;
|
|
166
|
+
swatchGap: number;
|
|
167
|
+
entryGap: number;
|
|
168
|
+
}
|
|
169
|
+
interface ThemeMarks {
|
|
170
|
+
pointRadius: number;
|
|
171
|
+
pointStroke: Color | undefined;
|
|
172
|
+
pointStrokeWidth: number;
|
|
173
|
+
/**
|
|
174
|
+
* Default stroke width for line-based marks (`line`, `smooth`, `statRolling`,
|
|
175
|
+
* `area` outline, `aggregate` line geom). Geom-level `strokeWidth` options
|
|
176
|
+
* override this token per layer.
|
|
177
|
+
*/
|
|
178
|
+
strokeWidth: number;
|
|
179
|
+
barCornerRadius: number;
|
|
180
|
+
fillAlpha: number;
|
|
181
|
+
/** Font size for value/total labels rendered alongside marks (bar, text). */
|
|
182
|
+
labelFontSize: number;
|
|
183
|
+
/** Default stroke width for `rule()` lines. */
|
|
184
|
+
ruleStrokeWidth: number;
|
|
185
|
+
/** Default label inset for `rule()` annotations. */
|
|
186
|
+
ruleLabelInset: number;
|
|
187
|
+
/** Default font size for inline annotations (rule, band labels). */
|
|
188
|
+
annotationFontSize: number;
|
|
189
|
+
/** Default fill alpha for `ribbon()`. */
|
|
190
|
+
ribbonFillAlpha: number;
|
|
191
|
+
/** Default fill alpha for `band()` highlight regions. */
|
|
192
|
+
bandFillAlpha: number;
|
|
193
|
+
/** Default size-channel pixel range. */
|
|
194
|
+
sizeRange: readonly [number, number];
|
|
195
|
+
/** Default alpha-channel range. */
|
|
196
|
+
alphaRange: readonly [number, number];
|
|
197
|
+
}
|
|
198
|
+
type ThemeDurationKey = "fast" | "base" | "slow";
|
|
199
|
+
type ThemeEasingKey = "standard" | "emphasized" | "decelerate" | "linear";
|
|
200
|
+
interface ThemeDurations {
|
|
201
|
+
fast: number;
|
|
202
|
+
base: number;
|
|
203
|
+
slow: number;
|
|
204
|
+
}
|
|
205
|
+
interface ThemeEasings {
|
|
206
|
+
standard: Easing;
|
|
207
|
+
emphasized: Easing;
|
|
208
|
+
decelerate: Easing;
|
|
209
|
+
linear: Easing;
|
|
210
|
+
}
|
|
211
|
+
interface ThemeMotionChannel {
|
|
212
|
+
duration: ThemeDurationKey;
|
|
213
|
+
easing: ThemeEasingKey;
|
|
214
|
+
}
|
|
215
|
+
interface ThemeMotionTooltip {
|
|
216
|
+
showDelay: number;
|
|
217
|
+
hideDelay: number;
|
|
218
|
+
fadeMs: number;
|
|
219
|
+
/**
|
|
220
|
+
* Hover-intent settle (ms). Rapid enter/leave/switch events are coalesced —
|
|
221
|
+
* the tooltip only commits a show/hide after the cursor holds a target this
|
|
222
|
+
* long. Prevents an overlay re-render per cell while sweeping across a dense
|
|
223
|
+
* mark grid or through gaps. 0 disables (commit immediately).
|
|
224
|
+
*/
|
|
225
|
+
settleDelay: number;
|
|
226
|
+
}
|
|
227
|
+
interface ThemeMotion {
|
|
228
|
+
/** Master switch. False → snap, no scheduled motion. */
|
|
229
|
+
enabled: boolean;
|
|
230
|
+
duration: ThemeDurations;
|
|
231
|
+
easing: ThemeEasings;
|
|
232
|
+
/** Data update / scale change transitions. */
|
|
233
|
+
data: ThemeMotionChannel;
|
|
234
|
+
/** Axis tick / domain transitions. */
|
|
235
|
+
axis: ThemeMotionChannel;
|
|
236
|
+
tooltip: ThemeMotionTooltip;
|
|
237
|
+
}
|
|
238
|
+
interface ThemeInteractionEmphasis {
|
|
239
|
+
/** Master enable. `false` skips both halo and dim. */
|
|
240
|
+
enabled: boolean;
|
|
241
|
+
/** Multiplier on non-active rows' fill alpha. `1` = no dim. */
|
|
242
|
+
dim: number;
|
|
243
|
+
/** Halo stroke width in CSS px. `0` skips the halo. */
|
|
244
|
+
haloStrokeWidth: number;
|
|
245
|
+
/**
|
|
246
|
+
* Halo ring color. When omitted, geoms fall back to a high-contrast
|
|
247
|
+
* foreground (`theme.text.color`) so the focus ring reads against the
|
|
248
|
+
* marks rather than blending in with the datum's own color. Set a `Color`
|
|
249
|
+
* to pin the ring (e.g. a brand accent).
|
|
250
|
+
*/
|
|
251
|
+
haloColor?: Color;
|
|
252
|
+
/**
|
|
253
|
+
* Duration (ms) of the GPU dim animation driven through the core's emphasis
|
|
254
|
+
* uniform (P5-T3). On a hover hit-change over a dim-participating geom the
|
|
255
|
+
* mount ramps the emphasis `t` 0→1 (ease-out cubic) over this window; on
|
|
256
|
+
* hover exit it ramps t→0. Only consumed by `hover` (selection dim stays a
|
|
257
|
+
* compile-time treatment). `<= 0` snaps. Default ~120ms.
|
|
258
|
+
*/
|
|
259
|
+
durationMs?: number;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Semantic row-tint tokens for tooltip rows that use the
|
|
263
|
+
* `accent: "positive" | "negative" | "neutral"` shorthand. `neutral` is
|
|
264
|
+
* intentionally omitted — it means "no override, use the default row text
|
|
265
|
+
* color from the underlying tooltip style." Consumers can also pass a raw
|
|
266
|
+
* `Color` per row to bypass these tokens entirely.
|
|
267
|
+
*/
|
|
268
|
+
interface ThemeTooltipAccents {
|
|
269
|
+
positive: Color;
|
|
270
|
+
negative: Color;
|
|
271
|
+
}
|
|
272
|
+
interface ThemeInteractions {
|
|
273
|
+
/** Visual treatment applied while a row is hovered. */
|
|
274
|
+
hover: ThemeInteractionEmphasis;
|
|
275
|
+
/** Visual treatment applied while rows are selected. */
|
|
276
|
+
selection: ThemeInteractionEmphasis;
|
|
277
|
+
/**
|
|
278
|
+
* Grace window (ms) applied when hover transitions to "nothing" before
|
|
279
|
+
* propagating the null state to dim/halo and crosshair. If a new hit lands
|
|
280
|
+
* within this window, the swap goes directly from prev → next without
|
|
281
|
+
* passing through null — eliminates the un-dim → re-dim flash when the
|
|
282
|
+
* cursor crosses between adjacent or near-adjacent geoms. `0` disables.
|
|
283
|
+
*/
|
|
284
|
+
hoverSwapGraceMs: number;
|
|
285
|
+
/** Semantic row colors for the tooltip `accent` shorthand. */
|
|
286
|
+
tooltipAccents: ThemeTooltipAccents;
|
|
287
|
+
}
|
|
288
|
+
interface ThemePalettes {
|
|
289
|
+
categorical: CategoricalPalette;
|
|
290
|
+
continuous: ContinuousPalette;
|
|
291
|
+
diverging: ContinuousPalette;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Semantic accent palette consumed by chart-level marks that carry meaning
|
|
295
|
+
* (reference regions, threshold rules, callouts, tooltip rows). Geoms that
|
|
296
|
+
* accept an accent key (`fill: "positive"`, `stroke: "warn"`) resolve through
|
|
297
|
+
* this block; literal `Color` values still bypass it.
|
|
298
|
+
*
|
|
299
|
+
* Naming exception to the "name geoms by what they are, not what they do"
|
|
300
|
+
* principle: these tokens exist explicitly to carry semantics. The names
|
|
301
|
+
* follow conventional status vocabulary so any reader can predict the role.
|
|
302
|
+
*
|
|
303
|
+
* `neutral` is intentionally omitted — it means "no override, use the
|
|
304
|
+
* surrounding default" (mark fill, axis label color, …) so consumers can fall
|
|
305
|
+
* back without spelling out a token.
|
|
306
|
+
*
|
|
307
|
+
* Distinct from {@link ThemeTooltipAccents} (under `interactions.tooltipAccents`)
|
|
308
|
+
* which is sized for tooltip-text contrast and may differ in luminance.
|
|
309
|
+
*/
|
|
310
|
+
interface ThemeAccents {
|
|
311
|
+
positive: Color;
|
|
312
|
+
negative: Color;
|
|
313
|
+
warn: Color;
|
|
314
|
+
info: Color;
|
|
315
|
+
}
|
|
316
|
+
type ThemeAccentKey = keyof ThemeAccents;
|
|
317
|
+
interface Theme {
|
|
318
|
+
background: Color;
|
|
319
|
+
text: ThemeText;
|
|
320
|
+
title: ThemeTitle;
|
|
321
|
+
subtitle: ThemeSubtitle;
|
|
322
|
+
axis: ThemeAxis;
|
|
323
|
+
legend: ThemeLegend;
|
|
324
|
+
marks: ThemeMarks;
|
|
325
|
+
palettes: ThemePalettes;
|
|
326
|
+
/** Semantic accent palette for chart-level marks (reference regions, threshold rules, callouts). */
|
|
327
|
+
accents: ThemeAccents;
|
|
328
|
+
/**
|
|
329
|
+
* Text-readability policy. Applied at every draw site where the chart
|
|
330
|
+
* knows the local background color (titles/axis/legend versus the panel
|
|
331
|
+
* background; tile labels versus their cell color).
|
|
332
|
+
*/
|
|
333
|
+
accessibility: Accessibility;
|
|
334
|
+
/**
|
|
335
|
+
* Default text effects (outline / drop shadow). API stub today — the SDF
|
|
336
|
+
* text path doesn't render these yet. See
|
|
337
|
+
* dev_docs/2026-04-30-text-accessibility.md.
|
|
338
|
+
*/
|
|
339
|
+
textEffects?: TextEffects;
|
|
340
|
+
/**
|
|
341
|
+
* Color space used to interpolate continuous palettes (`viridis`, etc.)
|
|
342
|
+
* when sampled by color scales and color bars. `oklch` is the default —
|
|
343
|
+
* perceptually uniform with hue preserved along the gradient. Override
|
|
344
|
+
* per chart (`theme({ paletteBlendSpace: "srgb" })`) or per call (the
|
|
345
|
+
* `blendSpace` option on color-scale and `colorBar` specs).
|
|
346
|
+
*/
|
|
347
|
+
paletteBlendSpace: BlendSpace$1;
|
|
348
|
+
/**
|
|
349
|
+
* Motion tokens — durations, easings, and per-channel defaults consumed by
|
|
350
|
+
* interactions (hover, tooltip), data transitions, and axis updates. See
|
|
351
|
+
* {@link defaultMotion} and {@link applyReducedMotion}.
|
|
352
|
+
*/
|
|
353
|
+
motion: ThemeMotion;
|
|
354
|
+
/**
|
|
355
|
+
* Hover / selection emphasis tokens. Geoms read these to render the active
|
|
356
|
+
* row's halo and optionally dim the rest. See {@link defaultInteractions}.
|
|
357
|
+
*/
|
|
358
|
+
interactions: ThemeInteractions;
|
|
359
|
+
}
|
|
360
|
+
declare const themeDefault: Theme;
|
|
361
|
+
/**
|
|
362
|
+
* Light/minimal theme — white plot background, soft gray gridlines, dark
|
|
363
|
+
* labels. Pairs well with the `category10` palette and is a good default for
|
|
364
|
+
* scatter / smooth charts that should read like a ggplot2 / R reference.
|
|
365
|
+
*/
|
|
366
|
+
declare const themeMinimalGrid: Theme;
|
|
367
|
+
type DeepPartial<T> = { [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K] };
|
|
368
|
+
/**
|
|
369
|
+
* Compose a theme by deep-merging overrides into a base theme. Accepts a
|
|
370
|
+
* shallow override on any nested group (e.g. `{ marks: { strokeWidth: 2 } }`).
|
|
371
|
+
*/
|
|
372
|
+
declare function theme(overrides: DeepPartial<Theme>, base?: Theme): Theme;
|
|
373
|
+
//#endregion
|
|
374
|
+
//#region src/grammar/attach-presets.d.ts
|
|
375
|
+
/** Where the chip strip sits inside its mount element. */
|
|
376
|
+
type AttachRangePresetsPosition = "top-left" | "top-right" | "bottom-left" | "bottom-right";
|
|
377
|
+
interface AttachRangePresetsUi {
|
|
378
|
+
/** Element to append the chip strip into (typically the chart's stage). */
|
|
379
|
+
mount: HTMLElement;
|
|
380
|
+
/** Corner placement inside `mount`. Defaults to `"top-left"`. */
|
|
381
|
+
position?: AttachRangePresetsPosition;
|
|
382
|
+
/** Inset (px) from the chosen corner. Defaults to `12`. */
|
|
383
|
+
inset?: number;
|
|
384
|
+
}
|
|
385
|
+
interface AttachRangePresetsOptions {
|
|
386
|
+
axis: "x" | "y";
|
|
387
|
+
/**
|
|
388
|
+
* Presets to expose. A `TimePresetKey` string is expanded to `timePreset(key)`;
|
|
389
|
+
* pass a full `RangePreset` for custom presets (label override, linear/log
|
|
390
|
+
* presets, etc.).
|
|
391
|
+
*/
|
|
392
|
+
presets: readonly (TimePresetKey | RangePreset)[];
|
|
393
|
+
dataDomain?: RangePresetDataDomain;
|
|
394
|
+
now?: () => number;
|
|
395
|
+
/** Omit to skip DOM construction — returns the same controller, headless. */
|
|
396
|
+
ui?: AttachRangePresetsUi;
|
|
397
|
+
}
|
|
398
|
+
interface AttachedRangePresets {
|
|
399
|
+
setActive(key: string | null): void;
|
|
400
|
+
getActive(): string | null;
|
|
401
|
+
subscribe(fn: RangePresetsSubscriber): () => void;
|
|
402
|
+
dispose(): void;
|
|
403
|
+
}
|
|
404
|
+
declare function attachRangePresets(viewport: DataViewport<any, any>, theme: Theme, opts: AttachRangePresetsOptions): AttachedRangePresets;
|
|
405
|
+
//#endregion
|
|
406
|
+
//#region src/grammar/coord.d.ts
|
|
407
|
+
interface Point {
|
|
408
|
+
x: number;
|
|
409
|
+
y: number;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Inputs to `Coord.renderAxes`. The pipeline owns scale construction and
|
|
413
|
+
* layout; the coord owns axis dispatch (Cartesian → bottom + left; polar →
|
|
414
|
+
* angular ring + radial spokes).
|
|
415
|
+
*/
|
|
416
|
+
interface CoordAxesArgs {
|
|
417
|
+
axisLayer: Layer;
|
|
418
|
+
scales: ScaleBundle;
|
|
419
|
+
/** Inner plot frame — coords project relative to this. */
|
|
420
|
+
plotFrame: _$insomni.Frame;
|
|
421
|
+
/** True when the chart actually has a column on this channel. Skipped axes are not drawn. */
|
|
422
|
+
hasX: boolean;
|
|
423
|
+
hasY: boolean;
|
|
424
|
+
xAxisOptions: AxisOptions<unknown>;
|
|
425
|
+
yAxisOptions: AxisOptions<unknown>;
|
|
426
|
+
atlas: GlyphAtlas | undefined;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Inputs to `Coord.handlePan`. The mount / interactions layer passes a pointer
|
|
430
|
+
* delta in plot-frame pixels plus the active plot frame and a viewport handle
|
|
431
|
+
* the coord can use to mutate scale state. Cartesian delegates the whole
|
|
432
|
+
* thing to `viewport.panBy(dx, dy)`; polar decomposes into tangential
|
|
433
|
+
* (rotate `startAngle`) and radial (translate radius domain via the viewport).
|
|
434
|
+
*/
|
|
435
|
+
interface CoordPanArgs {
|
|
436
|
+
dx: number;
|
|
437
|
+
dy: number;
|
|
438
|
+
/** Plot frame in absolute layer-pixel space (x, y are screen-space origin). */
|
|
439
|
+
plotFrame: _$insomni.Frame;
|
|
440
|
+
/** Viewport handle for scale-domain mutations. */
|
|
441
|
+
viewport: CoordViewportHandle;
|
|
442
|
+
}
|
|
443
|
+
interface CoordZoomArgs {
|
|
444
|
+
/**
|
|
445
|
+
* Multiplicative zoom factor — `> 1` zooms in, `< 1` zooms out. May be a
|
|
446
|
+
* scalar (both axes) or a `{ x?, y? }` per-axis form (matches
|
|
447
|
+
* `viewport.zoomAt` and the masking that `bindDataViewport` performs).
|
|
448
|
+
*/
|
|
449
|
+
factor: number | {
|
|
450
|
+
x?: number;
|
|
451
|
+
y?: number;
|
|
452
|
+
};
|
|
453
|
+
/** Cursor position in absolute layer-pixel space (matches `viewport.zoomAt`). */
|
|
454
|
+
cx: number;
|
|
455
|
+
cy: number;
|
|
456
|
+
plotFrame: _$insomni.Frame;
|
|
457
|
+
viewport: CoordViewportHandle;
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Minimal facade over `DataViewport` so the coord can mutate scale state
|
|
461
|
+
* without depending on the full viewport surface. The two methods polar
|
|
462
|
+
* uses (`panBy`, `zoomAt`) match `DataViewport` semantics 1:1; Cartesian's
|
|
463
|
+
* implementation forwards through them so behavior is byte-identical to the
|
|
464
|
+
* pre-`handlePan` path.
|
|
465
|
+
*/
|
|
466
|
+
interface CoordViewportHandle {
|
|
467
|
+
panBy(dxPx: number, dyPx: number): void;
|
|
468
|
+
zoomAt(anchorSx: number, anchorSy: number, factor: number | {
|
|
469
|
+
x?: number;
|
|
470
|
+
y?: number;
|
|
471
|
+
}): void;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* A coordinate system. Polar / cartesian today; future room for log-polar /
|
|
475
|
+
* geographic projections behind the same interface.
|
|
476
|
+
*/
|
|
477
|
+
interface Coord {
|
|
478
|
+
readonly kind: "cartesian" | "polar";
|
|
479
|
+
/**
|
|
480
|
+
* Bind the coord to a specific plot frame for the upcoming render.
|
|
481
|
+
* Polar's `project` / `segment` / `renderAxes` need the plot-frame
|
|
482
|
+
* dimensions and centre to compute (cx, cy) and the default outerRadius.
|
|
483
|
+
* Called by the pipeline once per panel (faceted) or once per chart
|
|
484
|
+
* (unfaceted) before any `project` / `renderAxes` call. Cartesian no-ops.
|
|
485
|
+
*/
|
|
486
|
+
bindFrame(plotFrame: _$insomni.Frame): void;
|
|
487
|
+
/**
|
|
488
|
+
* Map a single point from plot-frame pixel space (0..plotFrame.width on x,
|
|
489
|
+
* 0..plotFrame.height on y — i.e. the raw output of `xScale.fn` / `yScale.fn`)
|
|
490
|
+
* to layer-pixel space (still relative to the plot frame's origin —
|
|
491
|
+
* `plot.topLeft` offsets are applied later by each geom).
|
|
492
|
+
*
|
|
493
|
+
* Cartesian: identity. Polar: (θ, r) → (cx + r·cosθ, cy + r·sinθ).
|
|
494
|
+
*/
|
|
495
|
+
project(p: Point): Point;
|
|
496
|
+
/**
|
|
497
|
+
* Tessellate a polyline segment between two points in plot-frame pixel
|
|
498
|
+
* space. Returns the projected pixel points (including both endpoints).
|
|
499
|
+
* Cartesian returns `[project(p1), project(p2)]`; polar returns ~N points
|
|
500
|
+
* along the arc.
|
|
501
|
+
*/
|
|
502
|
+
segment(p1: Point, p2: Point): Point[];
|
|
503
|
+
/**
|
|
504
|
+
* Render axes into `args.axisLayer`. Cartesian draws bottom (x) + left (y);
|
|
505
|
+
* polar draws an angular ring (spokes) + radial concentric circles.
|
|
506
|
+
*/
|
|
507
|
+
renderAxes(args: CoordAxesArgs): void;
|
|
508
|
+
/**
|
|
509
|
+
* Inverse of `project`, for hit-testing / tooltips. Cartesian is the
|
|
510
|
+
* identity within the plot frame. Polar inverts (θ, r) and returns `null`
|
|
511
|
+
* when the projected point is outside `[innerRadius, outerRadius]`.
|
|
512
|
+
*/
|
|
513
|
+
unproject(p: Point): Point | null;
|
|
514
|
+
/**
|
|
515
|
+
* Translate a pointer pan delta into scale-domain mutations.
|
|
516
|
+
* Cartesian forwards to `viewport.panBy(dx, dy)` — byte-identical to the
|
|
517
|
+
* pre-coord path. Polar decomposes the delta relative to the plot centre
|
|
518
|
+
* into tangential (rotate `startAngle`) and radial (translate the radius
|
|
519
|
+
* scale via `viewport.panBy(0, radial_dy)`) components.
|
|
520
|
+
*/
|
|
521
|
+
handlePan(args: CoordPanArgs): void;
|
|
522
|
+
/**
|
|
523
|
+
* Translate a zoom factor + anchor into scale-domain mutations.
|
|
524
|
+
* Cartesian forwards to `viewport.zoomAt(cx, cy, factor)`. Polar scales the
|
|
525
|
+
* radius domain around the cursor's data-space radius; angle scale
|
|
526
|
+
* unchanged.
|
|
527
|
+
*/
|
|
528
|
+
handleZoom(args: CoordZoomArgs): void;
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Default coord — identity projection, current axis behavior. Plot's existing
|
|
532
|
+
* pipeline behaves exactly as it did before the `Coord` interface was added
|
|
533
|
+
* when this is in use.
|
|
534
|
+
*/
|
|
535
|
+
declare function coordCartesian(): Coord;
|
|
536
|
+
interface CoordPolarOptions {
|
|
537
|
+
/** Angle (radians) where the angular axis starts. Default `-π/2` (top). */
|
|
538
|
+
startAngle?: number;
|
|
539
|
+
/** Angle where the angular axis ends. Default `startAngle + 2π` (full circle). */
|
|
540
|
+
endAngle?: number;
|
|
541
|
+
/**
|
|
542
|
+
* Convenience for non-full-circle layouts: the gap (in radians) between
|
|
543
|
+
* `startAngle` and `endAngle`. `openAngle: 0` ↔ full circle;
|
|
544
|
+
* `openAngle: π/4` ↔ fan with a 45° gap at the start. Ignored when
|
|
545
|
+
* `endAngle` is provided.
|
|
546
|
+
*/
|
|
547
|
+
openAngle?: number;
|
|
548
|
+
/** `1` (default, CCW) or `-1` (CW). */
|
|
549
|
+
direction?: 1 | -1;
|
|
550
|
+
/** Inner radius in pixels. Default `0`. */
|
|
551
|
+
innerRadius?: number;
|
|
552
|
+
/**
|
|
553
|
+
* Outer radius in pixels. Default `min(plotFrame.width, plotFrame.height) / 2`
|
|
554
|
+
* — resolved lazily on `bindFrame`.
|
|
555
|
+
*/
|
|
556
|
+
outerRadius?: number;
|
|
557
|
+
/** Which channel maps to θ. Default `'y'` (gheatmap/circular-tree convention). */
|
|
558
|
+
angleChannel?: "x" | "y";
|
|
559
|
+
/** Angular tessellation step (radians) for `segment` and circular axes. Default ~1°. */
|
|
560
|
+
quality?: number;
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Polar projection. See {@link CoordPolarOptions}.
|
|
564
|
+
*
|
|
565
|
+
* Each call returns a fresh stateful coord so the same `coordPolar({...})`
|
|
566
|
+
* expression can be reused safely. `bindFrame` mutates the centre and the
|
|
567
|
+
* default `outerRadius`.
|
|
568
|
+
*/
|
|
569
|
+
declare function coordPolar(opts?: CoordPolarOptions): Coord;
|
|
570
|
+
/**
|
|
571
|
+
* Convenience polar coord: full circle, root at centre. Equivalent to
|
|
572
|
+
* `coordPolar({ openAngle: 0, innerRadius: 0 })`.
|
|
573
|
+
*/
|
|
574
|
+
declare function coordRadial(opts?: Omit<CoordPolarOptions, "openAngle" | "innerRadius">): Coord;
|
|
575
|
+
//#endregion
|
|
576
|
+
//#region src/grammar/geoms/emphasis.d.ts
|
|
577
|
+
/**
|
|
578
|
+
* A geom's hover-dim emphasis-key resolver, captured at compile time so the
|
|
579
|
+
* mount can map an active {@link HoveredHit} to the namespaced key it tagged
|
|
580
|
+
* its focused instance(s) with — WITHOUT recompiling. `geomKind` + `data`
|
|
581
|
+
* identity match the resolver to the hit (the same keys that route a hit to its
|
|
582
|
+
* geom, mirroring {@link GeomHoverDecorator}). `resolve` returns the focused
|
|
583
|
+
* key, or `null` when this hit focuses nothing in the geom (the mount then
|
|
584
|
+
* leaves emphasis settled). The geom computes the SAME ordinal it used to tag.
|
|
585
|
+
*/
|
|
586
|
+
interface EmphasisResolver {
|
|
587
|
+
readonly geomKind: GeomKind;
|
|
588
|
+
readonly data: readonly unknown[];
|
|
589
|
+
resolve(hit: HoveredHit): number | null;
|
|
590
|
+
}
|
|
591
|
+
//#endregion
|
|
592
|
+
//#region src/grammar/aes.d.ts
|
|
593
|
+
type ColumnKeys<T, V> = { [K in keyof T]-?: T[K] extends V ? K : never }[keyof T];
|
|
594
|
+
type Accessor<T, V> = (datum: T, index: number) => V;
|
|
595
|
+
type Aes<T, V> = ColumnKeys<T, V> | Accessor<T, V> | V;
|
|
596
|
+
interface ResolvedAes<T, V> {
|
|
597
|
+
readonly kind: "column" | "accessor" | "constant";
|
|
598
|
+
readonly column?: keyof T & string;
|
|
599
|
+
readonly fn: Accessor<T, V>;
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Best-effort guess of a channel's data type. Used to pick a default scale
|
|
603
|
+
* type when no override is supplied. Null / undefined values are skipped
|
|
604
|
+
* (see "Null / undefined policy" above).
|
|
605
|
+
*/
|
|
606
|
+
type ChannelDataType = "number" | "date" | "string" | "boolean" | "unknown";
|
|
607
|
+
//#endregion
|
|
608
|
+
//#region src/grammar/scales.d.ts
|
|
609
|
+
type Channel = "x" | "y" | "color" | "size" | "shape" | "alpha" | "borderStyle" | "overlayGlyph";
|
|
610
|
+
type PositionScaleType = "linear" | "log" | "sqrt" | "time" | "band";
|
|
611
|
+
type ColorScaleType = "categorical" | "continuous" | "diverging";
|
|
612
|
+
interface BasePositionScaleOptions {
|
|
613
|
+
range?: NumericRange;
|
|
614
|
+
nice?: boolean;
|
|
615
|
+
padding?: number;
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* `"nice"` is sugar for the existing `nice: true` flag — set as the domain
|
|
619
|
+
* shortcut so consumers don't need a second toggle when the only reason to
|
|
620
|
+
* touch `domain` was to pad it to round values. The data extent still
|
|
621
|
+
* derives the underlying numbers; `"nice"` just toggles the rounding.
|
|
622
|
+
*/
|
|
623
|
+
type NumericDomainShortcut = "nice";
|
|
624
|
+
interface NumericPositionScaleOptions extends BasePositionScaleOptions {
|
|
625
|
+
type?: "linear" | "log" | "sqrt";
|
|
626
|
+
domain?: readonly [number, number] | NumericDomainShortcut;
|
|
627
|
+
}
|
|
628
|
+
interface TimePositionScaleOptions extends BasePositionScaleOptions {
|
|
629
|
+
type?: "time";
|
|
630
|
+
domain?: readonly [Date, Date];
|
|
631
|
+
}
|
|
632
|
+
interface BandPositionScaleOptions extends BasePositionScaleOptions {
|
|
633
|
+
type?: "band";
|
|
634
|
+
domain?: readonly string[];
|
|
635
|
+
}
|
|
636
|
+
type PositionScaleOptions = NumericPositionScaleOptions | TimePositionScaleOptions | BandPositionScaleOptions;
|
|
637
|
+
interface CategoricalColorScaleOptions<T> {
|
|
638
|
+
type?: "categorical";
|
|
639
|
+
domain?: readonly T[];
|
|
640
|
+
palette?: CategoricalPalette;
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Color-scale domain shortcuts.
|
|
644
|
+
*
|
|
645
|
+
* - `"nice"`: alias for the existing `nice: true` flag on continuous color
|
|
646
|
+
* scales — pad the data extent to round values.
|
|
647
|
+
* - `"quantile"`: bucket the data into N quantile bins (default 5). The
|
|
648
|
+
* returned scale's `type` becomes `"categorical"` with bucket-label
|
|
649
|
+
* domain entries (`"Q1".."QN"`), and the palette is sampled at N evenly
|
|
650
|
+
* spaced stops along the chart's continuous palette so the color
|
|
651
|
+
* gradient reads as ordinal magnitude rather than nominal category.
|
|
652
|
+
*/
|
|
653
|
+
type ColorDomainShortcut = "nice" | "quantile";
|
|
654
|
+
interface ContinuousColorScaleOptions {
|
|
655
|
+
type: "continuous" | "diverging";
|
|
656
|
+
domain?: readonly [number, number] | ColorDomainShortcut;
|
|
657
|
+
palette?: ContinuousPalette;
|
|
658
|
+
/**
|
|
659
|
+
* Extend the inferred domain outward to "nice" round values (e.g. data
|
|
660
|
+
* extent `[-2.8, 1.9]` → `[-3, 2]`). Same algorithm position scales use
|
|
661
|
+
* via `nice: true`. Ignored when `domain` is set explicitly to a tuple.
|
|
662
|
+
* Equivalent to `domain: "nice"` — keep one form per chart for clarity.
|
|
663
|
+
*/
|
|
664
|
+
nice?: boolean;
|
|
665
|
+
/**
|
|
666
|
+
* Number of quantile buckets to use when `domain: "quantile"`. Default 5
|
|
667
|
+
* (quintiles). Ignored otherwise.
|
|
668
|
+
*/
|
|
669
|
+
quantiles?: number;
|
|
670
|
+
/**
|
|
671
|
+
* Override the color space used to interpolate the palette stops.
|
|
672
|
+
* Falls back to `theme.paletteBlendSpace` (default `"oklch"`).
|
|
673
|
+
*/
|
|
674
|
+
blendSpace?: _$insomni.BlendSpace;
|
|
675
|
+
}
|
|
676
|
+
type ColorScaleOptions<T> = CategoricalColorScaleOptions<T> | ContinuousColorScaleOptions;
|
|
677
|
+
interface SizeScaleOptions {
|
|
678
|
+
type?: "linear" | "sqrt";
|
|
679
|
+
domain?: readonly [number, number];
|
|
680
|
+
range?: readonly [number, number];
|
|
681
|
+
}
|
|
682
|
+
interface AlphaScaleOptions {
|
|
683
|
+
domain?: readonly [number, number];
|
|
684
|
+
range?: readonly [number, number];
|
|
685
|
+
}
|
|
686
|
+
interface ShapeScaleOptions {
|
|
687
|
+
/** Explicit category order (default: order of first appearance). */
|
|
688
|
+
domain?: readonly unknown[];
|
|
689
|
+
/** Override the shape palette. Default: `POINT_SHAPE_PALETTE` from `marks`. */
|
|
690
|
+
palette?: readonly PointShapeKind[];
|
|
691
|
+
}
|
|
692
|
+
interface BorderStyleScaleOptions {
|
|
693
|
+
/** Explicit category order (default: order of first appearance). */
|
|
694
|
+
domain?: readonly unknown[];
|
|
695
|
+
/** Override the border-style palette. Default: `DEFAULT_BORDER_STYLE_PALETTE`. */
|
|
696
|
+
palette?: readonly PointBorderStyle[];
|
|
697
|
+
}
|
|
698
|
+
interface OverlayGlyphScaleOptions {
|
|
699
|
+
/** Explicit category order (default: order of first appearance). */
|
|
700
|
+
domain?: readonly unknown[];
|
|
701
|
+
/**
|
|
702
|
+
* Override the overlay palette. Default: a small subset of
|
|
703
|
+
* `POINT_SHAPE_PALETTE` excluding `circle` so the overlay is visually
|
|
704
|
+
* distinct from the typical base shape. Use `null` entries to suppress an
|
|
705
|
+
* overlay for that domain value.
|
|
706
|
+
*/
|
|
707
|
+
palette?: readonly (PointShapeKind | null)[];
|
|
708
|
+
}
|
|
709
|
+
/** A scale callable: any value → number (or color, for color channels). */
|
|
710
|
+
type ScaleFn<In, Out> = (value: In) => Out;
|
|
711
|
+
interface PositionScale {
|
|
712
|
+
readonly kind: "position";
|
|
713
|
+
readonly type: PositionScaleType;
|
|
714
|
+
readonly dataType: ChannelDataType;
|
|
715
|
+
/** Pixel-space transform within the plot frame. */
|
|
716
|
+
readonly fn: ScaleFn<unknown, number>;
|
|
717
|
+
/** Underlying scale for axis builders. */
|
|
718
|
+
readonly axisScale: ContinuousScale | TimeScale | BandScale<string>;
|
|
719
|
+
}
|
|
720
|
+
interface ColorScale {
|
|
721
|
+
readonly kind: "color";
|
|
722
|
+
readonly dataType: ChannelDataType;
|
|
723
|
+
readonly type: ColorScaleType;
|
|
724
|
+
readonly fn: ScaleFn<unknown, Color>;
|
|
725
|
+
readonly domain: readonly unknown[];
|
|
726
|
+
/** Original palette — present for continuous/diverging scales (used by the color-bar legend). */
|
|
727
|
+
readonly palette?: ContinuousPalette | CategoricalPalette;
|
|
728
|
+
}
|
|
729
|
+
interface SizeScale {
|
|
730
|
+
readonly kind: "size";
|
|
731
|
+
readonly fn: ScaleFn<unknown, number>;
|
|
732
|
+
readonly domain: readonly [number, number];
|
|
733
|
+
readonly range: readonly [number, number];
|
|
734
|
+
}
|
|
735
|
+
interface AlphaScale {
|
|
736
|
+
readonly kind: "alpha";
|
|
737
|
+
readonly fn: ScaleFn<unknown, number>;
|
|
738
|
+
readonly domain: readonly [number, number];
|
|
739
|
+
readonly range: readonly [number, number];
|
|
740
|
+
}
|
|
741
|
+
interface ShapeScale {
|
|
742
|
+
readonly kind: "shape";
|
|
743
|
+
readonly fn: ScaleFn<unknown, PointShapeKind>;
|
|
744
|
+
readonly domain: readonly unknown[];
|
|
745
|
+
readonly palette: readonly PointShapeKind[];
|
|
746
|
+
}
|
|
747
|
+
interface BorderStyleScale {
|
|
748
|
+
readonly kind: "borderStyle";
|
|
749
|
+
readonly fn: ScaleFn<unknown, PointBorderStyle>;
|
|
750
|
+
readonly domain: readonly unknown[];
|
|
751
|
+
readonly palette: readonly PointBorderStyle[];
|
|
752
|
+
}
|
|
753
|
+
interface OverlayGlyphScale {
|
|
754
|
+
readonly kind: "overlayGlyph";
|
|
755
|
+
readonly fn: ScaleFn<unknown, PointShapeKind | null>;
|
|
756
|
+
readonly domain: readonly unknown[];
|
|
757
|
+
readonly palette: readonly (PointShapeKind | null)[];
|
|
758
|
+
}
|
|
759
|
+
declare const DEFAULT_BORDER_STYLE_PALETTE: readonly PointBorderStyle[];
|
|
760
|
+
/**
|
|
761
|
+
* Default overlay palette. First slot is `null` so the most-common category
|
|
762
|
+
* gets no overlay — overlays are typically a minority styling for flagged /
|
|
763
|
+
* exceptional rows. The remaining slots are visually distinct glyphs.
|
|
764
|
+
*/
|
|
765
|
+
declare const DEFAULT_OVERLAY_GLYPH_PALETTE: readonly (PointShapeKind | null)[];
|
|
766
|
+
//#endregion
|
|
767
|
+
//#region src/grammar/geoms/types.d.ts
|
|
768
|
+
type GeomKind = "point" | "line" | "area" | "bar" | "text" | "rule" | "band" | "boxplot" | "violin" | "histogram" | "ridgeline" | "rug" | "smooth" | "rolling" | "tile" | "interval";
|
|
769
|
+
/**
|
|
770
|
+
* Channel mappings as declared by the user. Stored at this width on `Geom<T>`
|
|
771
|
+
* so the chart can iterate channels generically. Geom factories accept their
|
|
772
|
+
* narrower per-geom channel types (PointChannels, LineChannels, ...) as the
|
|
773
|
+
* public surface and cast into this for storage.
|
|
774
|
+
*/
|
|
775
|
+
interface ChannelSpec<_T> {
|
|
776
|
+
x?: unknown;
|
|
777
|
+
y?: unknown;
|
|
778
|
+
color?: unknown;
|
|
779
|
+
size?: unknown;
|
|
780
|
+
shape?: unknown;
|
|
781
|
+
alpha?: unknown;
|
|
782
|
+
borderStyle?: unknown;
|
|
783
|
+
overlayGlyph?: unknown;
|
|
784
|
+
}
|
|
785
|
+
/**
|
|
786
|
+
* Per-geom hints for position-scale construction. Geoms that have a
|
|
787
|
+
* conventional baseline (bar, area) request that their value axis include 0
|
|
788
|
+
* — or, for `position: 'fill'`, set an explicit `[0, 1]` domain. Hints are
|
|
789
|
+
* only applied to numeric (linear/log/sqrt) scales; band/time scales ignore
|
|
790
|
+
* them. An explicit `.scale(channel, { domain })` override always wins.
|
|
791
|
+
*/
|
|
792
|
+
interface PositionScaleHint {
|
|
793
|
+
/** Force this exact domain (overrides include flags). */
|
|
794
|
+
domain?: readonly [number, number];
|
|
795
|
+
/** Extend inferred domain to include 0. */
|
|
796
|
+
includeZero?: boolean;
|
|
797
|
+
/** Extend inferred domain to include 1. */
|
|
798
|
+
includeOne?: boolean;
|
|
799
|
+
/**
|
|
800
|
+
* Extend the inferred domain to include this range. Unlike `domain`, this
|
|
801
|
+
* is unioned with the data-derived extent (and with other layers' extends)
|
|
802
|
+
* rather than replacing it. Use for geoms whose visual footprint extends
|
|
803
|
+
* past the raw data — e.g. a KDE-based violin whose smoothed tails reach
|
|
804
|
+
* outside `[dataMin, dataMax]`.
|
|
805
|
+
*/
|
|
806
|
+
extend?: readonly [number, number];
|
|
807
|
+
}
|
|
808
|
+
interface ScaleHints {
|
|
809
|
+
x?: PositionScaleHint;
|
|
810
|
+
y?: PositionScaleHint;
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* Pixel reservations on the plot frame for a geom whose visual extent
|
|
814
|
+
* exceeds its data footprint. The chart shrinks the position-scale range
|
|
815
|
+
* by these amounts so axis ticks track the compressed layout — used by
|
|
816
|
+
* ridgeline rows that rise above their baseline. Reservations from
|
|
817
|
+
* multiple layers are merged by max (the largest demand wins).
|
|
818
|
+
*/
|
|
819
|
+
interface RangeHints {
|
|
820
|
+
top?: number;
|
|
821
|
+
bottom?: number;
|
|
822
|
+
left?: number;
|
|
823
|
+
right?: number;
|
|
824
|
+
}
|
|
825
|
+
interface PrepareRangeContext<T> {
|
|
826
|
+
data: readonly T[];
|
|
827
|
+
plot: Frame;
|
|
828
|
+
scaleOptions: {
|
|
829
|
+
x?: PositionScaleOptions;
|
|
830
|
+
y?: PositionScaleOptions;
|
|
831
|
+
};
|
|
832
|
+
theme: Theme;
|
|
833
|
+
atlas: GlyphAtlas | undefined;
|
|
834
|
+
}
|
|
835
|
+
interface ScaleBundle {
|
|
836
|
+
x: PositionScale;
|
|
837
|
+
y: PositionScale;
|
|
838
|
+
color?: ColorScale;
|
|
839
|
+
size?: SizeScale;
|
|
840
|
+
alpha?: AlphaScale;
|
|
841
|
+
shape?: ShapeScale;
|
|
842
|
+
borderStyle?: BorderStyleScale;
|
|
843
|
+
overlayGlyph?: OverlayGlyphScale;
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* Per-rendered-element channel snapshot used for animated transitions.
|
|
847
|
+
* For simple geoms this usually matches the source datum index; for stacked /
|
|
848
|
+
* grouped geoms it can be one entry per visible segment. NaN marks filtered /
|
|
849
|
+
* hidden entries. Each geom owns the index convention used by its compile path.
|
|
850
|
+
*/
|
|
851
|
+
interface GeomFrame {
|
|
852
|
+
count: number;
|
|
853
|
+
x: Float32Array;
|
|
854
|
+
y: Float32Array;
|
|
855
|
+
rgba: Float32Array;
|
|
856
|
+
a: Float32Array;
|
|
857
|
+
r?: Float32Array;
|
|
858
|
+
ids?: readonly string[];
|
|
859
|
+
}
|
|
860
|
+
/** Injected into CompileContext during an active data/scale transition. */
|
|
861
|
+
interface ActiveTransition {
|
|
862
|
+
/** Progress 0 → 1. */
|
|
863
|
+
t: number;
|
|
864
|
+
/** From-snapshot for this geom. Indexed by datum i. */
|
|
865
|
+
from: GeomFrame;
|
|
866
|
+
/** Resolve a stable match index in `from` for the given key. */
|
|
867
|
+
matchIndex(key: string, fallbackIndex?: number): number | undefined;
|
|
868
|
+
}
|
|
869
|
+
interface CompileContext<T> {
|
|
870
|
+
data: readonly T[];
|
|
871
|
+
scales: ScaleBundle;
|
|
872
|
+
plot: Frame;
|
|
873
|
+
theme: Theme;
|
|
874
|
+
atlas: GlyphAtlas | undefined;
|
|
875
|
+
/**
|
|
876
|
+
* Coordinate system in effect for this chart. Geoms can call
|
|
877
|
+
* `ctx.coord.project(p)` / `ctx.coord.segment(p1, p2)` to remap plot-frame
|
|
878
|
+
* pixel space into layer-pixel space — under `coordCartesian()` (the
|
|
879
|
+
* default) both are the identity, so existing geoms are unaffected. Phase 3
|
|
880
|
+
* adds `coordPolar()` / `coordRadial()` and per-geom polar projection.
|
|
881
|
+
*
|
|
882
|
+
* Optional during Phase 1: only the pipeline supplies it today, and geoms
|
|
883
|
+
* have not been migrated to project through it yet. Treat absence as
|
|
884
|
+
* `coordCartesian()` if you read it in a geom. Will become required when
|
|
885
|
+
* Phase 3 lands and per-geom polar projection ships.
|
|
886
|
+
*/
|
|
887
|
+
coord?: Coord;
|
|
888
|
+
/**
|
|
889
|
+
* Currently hovered hit, or `null` if nothing is hovered. Geoms compare
|
|
890
|
+
* `hovered.data === ctx.data && hovered.geomKind === this.kind` to detect
|
|
891
|
+
* "their" hit and can use `hovered.dataIndex` to render a highlight (halo,
|
|
892
|
+
* elevated alpha/stroke, etc.). Provided by the mount; `undefined` when
|
|
893
|
+
* compiling outside a mount context (e.g. SSR / SVG export).
|
|
894
|
+
*/
|
|
895
|
+
hovered?: HoveredHit | null;
|
|
896
|
+
/**
|
|
897
|
+
* Currently selected hits (multi-select). Empty array = nothing selected;
|
|
898
|
+
* `undefined` = selection is disabled (no visual treatment). Geoms render
|
|
899
|
+
* stroke rings on matching rows and may dim non-selected rows when the
|
|
900
|
+
* array is non-empty.
|
|
901
|
+
*/
|
|
902
|
+
selected?: readonly HoveredHit[];
|
|
903
|
+
/** Set of series keys currently hidden via legend toggle. */
|
|
904
|
+
hidden?: ReadonlySet<string>;
|
|
905
|
+
/** Optional stable key used to match rows across data refreshes for transitions. */
|
|
906
|
+
transitionKey?: (datum: T, index: number) => string;
|
|
907
|
+
/**
|
|
908
|
+
* Active data/scale transition context. Present only during an animated
|
|
909
|
+
* transition; geoms use it to lerp channels from the previous frame toward
|
|
910
|
+
* the current compiled values.
|
|
911
|
+
*/
|
|
912
|
+
activeTransition?: ActiveTransition;
|
|
913
|
+
/**
|
|
914
|
+
* Disjoint emphasis-key band base for this geom (P5-T3). The pipeline assigns
|
|
915
|
+
* `geomEmphasisBase(geomIndex)`; dim-participating geoms tag each mark
|
|
916
|
+
* instance `emphasisKey: emphasisKeyFor(base, ordinal)` so the core's GPU dim
|
|
917
|
+
* uniform can fade non-focused instances WITHOUT a marks recompile. `undefined`
|
|
918
|
+
* outside a mount (SSR / SVG export) → geoms skip tagging (no GPU emphasis).
|
|
919
|
+
* See {@link import("./emphasis.ts")}.
|
|
920
|
+
*/
|
|
921
|
+
emphasisBase?: number;
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* The active hover state surfaced to compile contexts and exposed on
|
|
925
|
+
* `MountedPlot.hovered`. Coordinates are absolute element-CSS pixels
|
|
926
|
+
* (matching `CompiledHitTest.positions`).
|
|
927
|
+
*/
|
|
928
|
+
interface HoveredHit {
|
|
929
|
+
geomKind: GeomKind;
|
|
930
|
+
dataIndex: number;
|
|
931
|
+
/** Optional segment key for multi-series geoms (stacked/dodged bars, stacked areas). */
|
|
932
|
+
seriesKey?: string;
|
|
933
|
+
/**
|
|
934
|
+
* Reference to the data array used to compile the originating geom — used
|
|
935
|
+
* for identity comparison (`hovered.data === ctx.data`) so multi-layer
|
|
936
|
+
* charts can route the hit to the right geom.
|
|
937
|
+
*/
|
|
938
|
+
data: readonly unknown[];
|
|
939
|
+
x: number;
|
|
940
|
+
y: number;
|
|
941
|
+
}
|
|
942
|
+
/**
|
|
943
|
+
* Resolved aesthetics for each channel of a geom — used by interaction layers
|
|
944
|
+
* (tooltips, legends-on-hover) to read the original column name and pull the
|
|
945
|
+
* raw value back out for a given datum.
|
|
946
|
+
*/
|
|
947
|
+
interface ResolvedChannelMap<T> {
|
|
948
|
+
x?: ResolvedAes<T, unknown>;
|
|
949
|
+
y?: ResolvedAes<T, unknown>;
|
|
950
|
+
color?: ResolvedAes<T, unknown>;
|
|
951
|
+
size?: ResolvedAes<T, unknown>;
|
|
952
|
+
shape?: ResolvedAes<T, unknown>;
|
|
953
|
+
alpha?: ResolvedAes<T, unknown>;
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Hit-test points emitted by a geom for hover/click. Coordinates are absolute
|
|
957
|
+
* element-CSS pixels (the chart's plot frame offset is already baked in), so
|
|
958
|
+
* the consumer can hand them to a `space: "ui"` PointCloudNode without
|
|
959
|
+
* adjustment. `dataIndex[i]` maps hit `i` back to the original `data` array
|
|
960
|
+
* (after filtering NaN/null values). `seriesKey[i]` further distinguishes
|
|
961
|
+
* segments that share a source row.
|
|
962
|
+
*/
|
|
963
|
+
interface CompiledHitTest<T> {
|
|
964
|
+
geomKind: GeomKind;
|
|
965
|
+
label?: string;
|
|
966
|
+
positions: Float32Array;
|
|
967
|
+
dataIndex: Int32Array;
|
|
968
|
+
seriesKey?: readonly (string | undefined)[];
|
|
969
|
+
pickRadius: number;
|
|
970
|
+
/**
|
|
971
|
+
* Optional per-hit bounding rect in absolute element-CSS pixels. When
|
|
972
|
+
* present, the hit-layer prefers rect containment over nearest-point
|
|
973
|
+
* picking (`positions` + `pickRadius`), giving "whole shape" hover for
|
|
974
|
+
* shape-based geoms (bar, histogram, ridgeline rows, tile cells, ...).
|
|
975
|
+
* Layout: `[x, y, w, h]` per `dataIndex` entry. `positions` is still
|
|
976
|
+
* required as a fallback (used to anchor tooltips, brushes, etc.).
|
|
977
|
+
*/
|
|
978
|
+
rects?: Float32Array;
|
|
979
|
+
/**
|
|
980
|
+
* Distance metric for nearest-point queries. Default `"xy"` (Euclidean).
|
|
981
|
+
* `"x"` makes the picker resolve nearest-by-x only — used by `line()` /
|
|
982
|
+
* `area()` when `nearestX: true` so the user can hover anywhere along the
|
|
983
|
+
* curve and the active vertex follows the cursor's x.
|
|
984
|
+
*/
|
|
985
|
+
pickAxis?: "x" | "y" | "xy";
|
|
986
|
+
channels: ResolvedChannelMap<T>;
|
|
987
|
+
data: readonly T[];
|
|
988
|
+
}
|
|
989
|
+
/**
|
|
990
|
+
* A geom's hover-focus decoration, captured at compile time so the mount can
|
|
991
|
+
* draw it on hover **without recompiling the pipeline**. The mount calls
|
|
992
|
+
* {@link decorate} into the live overlay layer (which composites above the baked
|
|
993
|
+
* marks), so local focus treatment — a contrast halo, bringing the hovered
|
|
994
|
+
* element to the front — costs only a cheap overlay repaint rather than a full
|
|
995
|
+
* marks recompute. The complementary *global* dim-others treatment (fading every
|
|
996
|
+
* other element) rides the core's GPU emphasis uniform (see {@link
|
|
997
|
+
* EmphasisResolver}), so a geom can provide both: the decorator draws the focus
|
|
998
|
+
* halo (left at emphasis key 0 = exempt, full-strength) while the uniform dims
|
|
999
|
+
* the rest. Geoms with no local focus shape simply omit this.
|
|
1000
|
+
*
|
|
1001
|
+
* `geomKind` + `data` identity let the mount match the decorator to the active
|
|
1002
|
+
* `HoveredHit` (the same keys used to route a hit to its geom).
|
|
1003
|
+
*/
|
|
1004
|
+
interface GeomHoverDecorator {
|
|
1005
|
+
readonly geomKind: GeomKind;
|
|
1006
|
+
readonly data: readonly unknown[];
|
|
1007
|
+
/** Draw the focus decoration for `hit` into `layer` (the overlay layer). */
|
|
1008
|
+
decorate(hit: HoveredHit, layer: Layer): void;
|
|
1009
|
+
}
|
|
1010
|
+
interface Geom<T> {
|
|
1011
|
+
readonly kind: GeomKind;
|
|
1012
|
+
readonly channels: ChannelSpec<T>;
|
|
1013
|
+
/** Used by the auto-legend to label the layer. Falls back to channel name. */
|
|
1014
|
+
readonly label?: string;
|
|
1015
|
+
/** Optional position-scale hints (e.g. anchor value axis at 0 for bars). */
|
|
1016
|
+
readonly scaleHints?: ScaleHints;
|
|
1017
|
+
/**
|
|
1018
|
+
* When true, the geom renders into the hud layer (above marks, no clip rect)
|
|
1019
|
+
* instead of the marks layer. Used by geoms whose visual extent intentionally
|
|
1020
|
+
* exceeds the plot frame — e.g. phylo tip labels — and that should not be
|
|
1021
|
+
* clipped at the frame edge.
|
|
1022
|
+
*/
|
|
1023
|
+
readonly overlay?: boolean;
|
|
1024
|
+
/**
|
|
1025
|
+
* Optional data-derived scale hints. Called once before scales are built,
|
|
1026
|
+
* so geoms whose visual extent depends on the data (e.g. KDE-smoothed
|
|
1027
|
+
* violins) can extend the position-scale domain accordingly. Returned
|
|
1028
|
+
* hints are merged with `scaleHints` and any hints contributed by other
|
|
1029
|
+
* layers. An explicit `.scale(channel, { domain })` override always wins.
|
|
1030
|
+
*/
|
|
1031
|
+
prepareDomain?(data: readonly T[]): ScaleHints | undefined;
|
|
1032
|
+
/**
|
|
1033
|
+
* Optional layout-time hook that runs after layout but before scale
|
|
1034
|
+
* construction. Geoms whose visual extent exceeds their data footprint
|
|
1035
|
+
* — e.g. a ridgeline ridge that rises above its baseline by `overlap ×
|
|
1036
|
+
* cellSize` — use this to reserve pixel margins on the plot frame, so
|
|
1037
|
+
* the position scale (and its axis ticks) shrink to fit.
|
|
1038
|
+
*/
|
|
1039
|
+
prepareRange?(ctx: PrepareRangeContext<T>): RangeHints | undefined;
|
|
1040
|
+
/**
|
|
1041
|
+
* Optional override for the auto-legend's per-series swatch. Geoms that
|
|
1042
|
+
* draw filled regions (bar/area/tile) or strokes (line) supply their own;
|
|
1043
|
+
* the pipeline falls back to a point swatch when omitted.
|
|
1044
|
+
*/
|
|
1045
|
+
legendSwatch?(color: Color, theme: Theme): SwatchSpec;
|
|
1046
|
+
compile(ctx: CompileContext<T>): readonly MarkBuilder[];
|
|
1047
|
+
/**
|
|
1048
|
+
* Optional hit-test contribution for interactions. Implemented per geom that
|
|
1049
|
+
* wants to support hover/click selection (`point` in v1; bar/line/area in
|
|
1050
|
+
* later phases). Return `null` to opt out for a particular compile pass
|
|
1051
|
+
* (e.g. when the geom has no points after filtering).
|
|
1052
|
+
*/
|
|
1053
|
+
compileHitTest?(ctx: CompileContext<T>): CompiledHitTest<T> | null;
|
|
1054
|
+
/**
|
|
1055
|
+
* Optional hover-focus decorator. Implemented by geoms whose focus treatment
|
|
1056
|
+
* is *local* (point: contrast halo + bring-to-front) so it can ride the
|
|
1057
|
+
* mount's cheap overlay path instead of a marks recompute. Called once per
|
|
1058
|
+
* full compile with the same `ctx`; returns `null` to opt out (e.g. empty
|
|
1059
|
+
* data). See {@link GeomHoverDecorator}.
|
|
1060
|
+
*/
|
|
1061
|
+
hoverDecoration?(ctx: CompileContext<T>): GeomHoverDecorator | null;
|
|
1062
|
+
/**
|
|
1063
|
+
* Emphasis-key resolver for geoms whose hover treatment is *global* (dim the
|
|
1064
|
+
* others via the core's GPU emphasis uniform: bar/line/violin/...). Captured
|
|
1065
|
+
* once per full compile with the same `ctx` (so it sees the same `emphasisBase`
|
|
1066
|
+
* + scales the tagging used); the mount maps an active {@link HoveredHit} to the
|
|
1067
|
+
* namespaced key the geom tagged its focused instance(s) with — without
|
|
1068
|
+
* recompiling. Returns `null` to opt out (e.g. empty data, or `emphasisBase`
|
|
1069
|
+
* absent). Mutually complementary with {@link hoverDecoration} (local focus).
|
|
1070
|
+
* See {@link import("./emphasis.ts").EmphasisResolver}.
|
|
1071
|
+
*/
|
|
1072
|
+
emphasisResolution?(ctx: CompileContext<T>): EmphasisResolver | null;
|
|
1073
|
+
/**
|
|
1074
|
+
* Capture a per-datum channel snapshot for use as a transition "from" frame.
|
|
1075
|
+
* Called after `compile` on each stable (non-animating) frame. Returns `null`
|
|
1076
|
+
* if the geom has no meaningful frame to capture (e.g. empty data).
|
|
1077
|
+
*/
|
|
1078
|
+
captureFrame?(ctx: CompileContext<T>): GeomFrame | null;
|
|
1079
|
+
}
|
|
1080
|
+
//#endregion
|
|
1081
|
+
//#region src/grammar/interactions/series-readout.d.ts
|
|
1082
|
+
interface SeriesReadoutRow {
|
|
1083
|
+
/** Series name (color-channel value) or layer label. */
|
|
1084
|
+
label: string;
|
|
1085
|
+
/** Formatted display value (raw y at the snapped x). */
|
|
1086
|
+
value: string;
|
|
1087
|
+
/** Series swatch color, when the layer has a color channel. */
|
|
1088
|
+
color?: Color;
|
|
1089
|
+
/** True for the row whose snapped position is closest to the cursor. */
|
|
1090
|
+
active: boolean;
|
|
1091
|
+
}
|
|
1092
|
+
interface SeriesReadoutSnapshot {
|
|
1093
|
+
/** Formatted snapped x (from the closest layer). */
|
|
1094
|
+
x: string;
|
|
1095
|
+
/** Raw snapped x value (column-typed). Useful for custom formatting. */
|
|
1096
|
+
xValue: unknown;
|
|
1097
|
+
/** One row per series across all layers, in original layer + series order. */
|
|
1098
|
+
rows: readonly SeriesReadoutRow[];
|
|
1099
|
+
}
|
|
1100
|
+
type SeriesReadoutFormat = {
|
|
1101
|
+
/** Format the snapped x for the panel title. Default: `defaultFormat`. */x?: (value: unknown) => string; /** Format each per-series y value. Default: `defaultFormat`. */
|
|
1102
|
+
y?: (value: unknown) => string;
|
|
1103
|
+
};
|
|
1104
|
+
type SeriesReadoutPosition = "top-left" | "top-right" | "bottom-left" | "bottom-right";
|
|
1105
|
+
interface SeriesReadoutUi {
|
|
1106
|
+
/** Element to append the panel into (typically the chart's stage). */
|
|
1107
|
+
mount: HTMLElement;
|
|
1108
|
+
/** Corner inside `mount`. Default `"top-right"`. */
|
|
1109
|
+
position?: SeriesReadoutPosition;
|
|
1110
|
+
/** Inset (px) from the chosen corner. Default `12`. */
|
|
1111
|
+
inset?: number;
|
|
1112
|
+
}
|
|
1113
|
+
interface AttachSeriesReadoutOptions {
|
|
1114
|
+
/** DOM mount info. Omit to run headless and observe via `subscribe`. */
|
|
1115
|
+
ui?: SeriesReadoutUi;
|
|
1116
|
+
/**
|
|
1117
|
+
* How to pick a hit per series.
|
|
1118
|
+
* - `"nearest-x"` (default): the hit with smallest |x − cursorX|. Best for
|
|
1119
|
+
* time-series readouts; one row per series at the cursor's x.
|
|
1120
|
+
* - `"hover"`: only show rows while the cursor is over a real hit (the
|
|
1121
|
+
* tooltip-style behavior, but extended to every series in the chart).
|
|
1122
|
+
*/
|
|
1123
|
+
snap?: "nearest-x" | "hover";
|
|
1124
|
+
/** Per-channel formatters. */
|
|
1125
|
+
format?: SeriesReadoutFormat;
|
|
1126
|
+
/** Hide when the cursor leaves the plot frame. Default `true`. */
|
|
1127
|
+
hideOnLeave?: boolean;
|
|
1128
|
+
/** Notified whenever the snapshot changes (incl. with `ui` attached). */
|
|
1129
|
+
onChange?(snapshot: SeriesReadoutSnapshot | null): void;
|
|
1130
|
+
}
|
|
1131
|
+
interface AttachedSeriesReadout {
|
|
1132
|
+
peek(): SeriesReadoutSnapshot | null;
|
|
1133
|
+
subscribe(fn: (snapshot: SeriesReadoutSnapshot | null) => void): () => void;
|
|
1134
|
+
dispose(): void;
|
|
1135
|
+
}
|
|
1136
|
+
//#endregion
|
|
1137
|
+
//#region src/grammar/interactions/brush.d.ts
|
|
1138
|
+
interface GrammarBrushConfig {
|
|
1139
|
+
/** Which axes the brush spans. Default `"xy"`. */
|
|
1140
|
+
axis?: BrushAxis;
|
|
1141
|
+
/** Translucent fill color. Default theme.axis.color × 0.12 alpha. */
|
|
1142
|
+
fillColor?: Color;
|
|
1143
|
+
/** Outline color. Default theme.axis.color × 0.6 alpha. */
|
|
1144
|
+
strokeColor?: Color;
|
|
1145
|
+
/** Outline width in CSS px. Default 1. */
|
|
1146
|
+
strokeWidth?: number;
|
|
1147
|
+
/**
|
|
1148
|
+
* Enable edge/corner resize handles on the committed rect. Default `true`.
|
|
1149
|
+
* Disable to lock a brush rect to its initial drag.
|
|
1150
|
+
*/
|
|
1151
|
+
handles?: boolean;
|
|
1152
|
+
/** Hit-test extent of each handle in CSS px. Default 8. */
|
|
1153
|
+
handleSize?: number;
|
|
1154
|
+
/**
|
|
1155
|
+
* Enable drag-to-move on the committed rect interior. Default `true`. The
|
|
1156
|
+
* rect's size is held constant during the move; off-axis movement is locked
|
|
1157
|
+
* for `axis: "x"` / `"y"` brushes. Disable to lock a brush rect in place.
|
|
1158
|
+
*/
|
|
1159
|
+
translate?: boolean;
|
|
1160
|
+
/**
|
|
1161
|
+
* Snap brush rect edges to the nearest hit-test position along the chosen
|
|
1162
|
+
* axis. `true` snaps on the brush's active `axis`; pass `"x"` / `"y"` /
|
|
1163
|
+
* `"xy"` to override. Default `false`. Useful for axis-locked range brushes
|
|
1164
|
+
* over discrete x-ticks. The snap is computed against the live hit-test
|
|
1165
|
+
* positions (refreshed on every `sync()`), so it follows the data.
|
|
1166
|
+
*/
|
|
1167
|
+
snap?: boolean | BrushAxis;
|
|
1168
|
+
}
|
|
1169
|
+
interface GrammarBrush {
|
|
1170
|
+
/** Replace the active hit-test set after each pipeline run. */
|
|
1171
|
+
sync<T>(hits: readonly CompiledHitTest<T>[]): void;
|
|
1172
|
+
/** Read-only snapshot of the current brushed hits. */
|
|
1173
|
+
current(): HoveredHit[];
|
|
1174
|
+
/** Current brush rect, or null when idle. */
|
|
1175
|
+
rect(): BrushRect | null;
|
|
1176
|
+
/** Imperatively clear the brush. */
|
|
1177
|
+
clear(): void;
|
|
1178
|
+
/** Draw the brush overlay into the hud layer. */
|
|
1179
|
+
draw(): void;
|
|
1180
|
+
dispose(): void;
|
|
1181
|
+
}
|
|
1182
|
+
//#endregion
|
|
1183
|
+
//#region src/grammar/attach-brush.d.ts
|
|
1184
|
+
interface AttachBrushOptions extends GrammarBrushConfig {
|
|
1185
|
+
/**
|
|
1186
|
+
* Fires whenever the brushed set changes — including the empty `[]` after
|
|
1187
|
+
* `clear()` / background tap. Receives one `HoveredHit` per data row whose
|
|
1188
|
+
* hit-test position falls within the brush rect.
|
|
1189
|
+
*/
|
|
1190
|
+
onSelect?(hits: readonly HoveredHit[]): void;
|
|
1191
|
+
}
|
|
1192
|
+
interface AttachedBrush {
|
|
1193
|
+
/** Read-only snapshot of the current brushed hits. */
|
|
1194
|
+
peek(): readonly HoveredHit[];
|
|
1195
|
+
/** Current brush rect in element-local CSS px, or `null` while idle. */
|
|
1196
|
+
rect(): BrushRect | null;
|
|
1197
|
+
/** Subscribe to changes. Fires immediately with the current set. */
|
|
1198
|
+
subscribe(fn: (hits: readonly HoveredHit[]) => void): () => void;
|
|
1199
|
+
/** Imperatively clear the brush. */
|
|
1200
|
+
clear(): void;
|
|
1201
|
+
/** Tear down the brush + interaction nodes. */
|
|
1202
|
+
dispose(): void;
|
|
1203
|
+
}
|
|
1204
|
+
interface AttachBrushDeps {
|
|
1205
|
+
manager: InteractionManager;
|
|
1206
|
+
/** Plot-frame bounds in element-local CSS px. */
|
|
1207
|
+
bounds: () => Frame;
|
|
1208
|
+
hudLayer: () => Layer;
|
|
1209
|
+
theme: () => Theme;
|
|
1210
|
+
invalidator: Invalidator;
|
|
1211
|
+
}
|
|
1212
|
+
/**
|
|
1213
|
+
* Internal handle exposed to the mount so it can drive `sync` + `draw` from
|
|
1214
|
+
* its rAF loop and dispose alongside teardown. Public consumers receive the
|
|
1215
|
+
* narrower `AttachedBrush` view returned by `MountedPlot.attachBrush`.
|
|
1216
|
+
*/
|
|
1217
|
+
interface AttachedBrushInternal extends AttachedBrush {
|
|
1218
|
+
syncHits<T>(hits: readonly CompiledHitTest<T>[]): void;
|
|
1219
|
+
draw(): void;
|
|
1220
|
+
/** Underlying grammar brush — exposed for tests; not part of the public API. */
|
|
1221
|
+
readonly brush: GrammarBrush;
|
|
1222
|
+
}
|
|
1223
|
+
declare function createAttachedBrush(deps: AttachBrushDeps, opts: AttachBrushOptions): AttachedBrushInternal;
|
|
1224
|
+
//#endregion
|
|
1225
|
+
//#region src/grammar/annotations.d.ts
|
|
1226
|
+
type FrameAnchorX = "left" | "center" | "right";
|
|
1227
|
+
type FrameAnchorY = "top" | "middle" | "bottom";
|
|
1228
|
+
/** Coordinate value accepted by annotation factories — data value or frame anchor. */
|
|
1229
|
+
type AnnotationX = FrameAnchorX | number | Date | string;
|
|
1230
|
+
type AnnotationY = FrameAnchorY | number | Date | string;
|
|
1231
|
+
interface TextAnnotationSpec {
|
|
1232
|
+
kind?: "text";
|
|
1233
|
+
text: string;
|
|
1234
|
+
/**
|
|
1235
|
+
* Horizontal position. A `FrameAnchorX` resolves to the plot frame edges;
|
|
1236
|
+
* a number/Date is run through the active x scale.
|
|
1237
|
+
*/
|
|
1238
|
+
x: AnnotationX;
|
|
1239
|
+
/** Vertical position. See `x` — but resolves against the y scale. */
|
|
1240
|
+
y: AnnotationY;
|
|
1241
|
+
/** Pixel offset added after position resolution. */
|
|
1242
|
+
offsetX?: number;
|
|
1243
|
+
offsetY?: number;
|
|
1244
|
+
align?: ValueLabelAlign;
|
|
1245
|
+
color?: Color;
|
|
1246
|
+
fontSize?: number;
|
|
1247
|
+
fontStyle?: string;
|
|
1248
|
+
box?: LabelBoxStyle;
|
|
1249
|
+
}
|
|
1250
|
+
interface ArrowAnnotationSpec {
|
|
1251
|
+
kind: "arrow";
|
|
1252
|
+
/** Tail of the arrow — `[x, y]` in data or frame-anchor coordinates. */
|
|
1253
|
+
from: readonly [AnnotationX, AnnotationY];
|
|
1254
|
+
/** Head of the arrow. Direction is `from → to`. */
|
|
1255
|
+
to: readonly [AnnotationX, AnnotationY];
|
|
1256
|
+
/** Optional label rendered near the arrowhead. */
|
|
1257
|
+
label?: string;
|
|
1258
|
+
/**
|
|
1259
|
+
* Pixel offset for the label relative to the arrowhead. Default
|
|
1260
|
+
* `[6, -6]` — to-the-right-and-above the head.
|
|
1261
|
+
*/
|
|
1262
|
+
labelOffset?: readonly [number, number];
|
|
1263
|
+
labelAlign?: ValueLabelAlign;
|
|
1264
|
+
labelBox?: LabelBoxStyle;
|
|
1265
|
+
/** Stroke color for the shaft and head fill. Defaults to `theme.text.color`. */
|
|
1266
|
+
color?: Color;
|
|
1267
|
+
/** Shaft thickness in CSS pixels. Default `1.5`. */
|
|
1268
|
+
strokeWidth?: number;
|
|
1269
|
+
/**
|
|
1270
|
+
* Arrowhead size in CSS pixels — total length from base to tip. Default
|
|
1271
|
+
* `9`; the head is `headSize × 0.5` wide at the base.
|
|
1272
|
+
*/
|
|
1273
|
+
headSize?: number;
|
|
1274
|
+
fontSize?: number;
|
|
1275
|
+
fontStyle?: string;
|
|
1276
|
+
}
|
|
1277
|
+
interface CalloutAnnotationSpec {
|
|
1278
|
+
kind: "callout";
|
|
1279
|
+
/** Data point the callout is anchored to. */
|
|
1280
|
+
at: readonly [AnnotationX, AnnotationY];
|
|
1281
|
+
/** Label text rendered at the offset position. */
|
|
1282
|
+
label: string;
|
|
1283
|
+
/**
|
|
1284
|
+
* Pixel offset from the anchor to the label position. The leader line
|
|
1285
|
+
* runs between them. Default `[40, -20]`.
|
|
1286
|
+
*/
|
|
1287
|
+
offset?: readonly [number, number];
|
|
1288
|
+
/** Leader stroke color. Defaults to `theme.text.color` (faded by `leaderAlpha`). */
|
|
1289
|
+
color?: Color;
|
|
1290
|
+
/** Multiplier on the leader's stroke alpha. Default `0.6`. */
|
|
1291
|
+
leaderAlpha?: number;
|
|
1292
|
+
/** Leader thickness in CSS pixels. Default `1`. */
|
|
1293
|
+
strokeWidth?: number;
|
|
1294
|
+
/** Label text color. Defaults to `theme.text.color`. */
|
|
1295
|
+
labelColor?: Color;
|
|
1296
|
+
align?: ValueLabelAlign;
|
|
1297
|
+
box?: LabelBoxStyle;
|
|
1298
|
+
fontSize?: number;
|
|
1299
|
+
fontStyle?: string;
|
|
1300
|
+
}
|
|
1301
|
+
type AnnotationSpec = TextAnnotationSpec | ArrowAnnotationSpec | CalloutAnnotationSpec;
|
|
1302
|
+
declare const annotate: {
|
|
1303
|
+
readonly arrow: (spec: Omit<ArrowAnnotationSpec, "kind">) => ArrowAnnotationSpec;
|
|
1304
|
+
readonly callout: (spec: Omit<CalloutAnnotationSpec, "kind">) => CalloutAnnotationSpec;
|
|
1305
|
+
readonly text: (spec: Omit<TextAnnotationSpec, "kind">) => TextAnnotationSpec;
|
|
1306
|
+
};
|
|
1307
|
+
//#endregion
|
|
1308
|
+
//#region src/grammar/facet.d.ts
|
|
1309
|
+
type FacetScales = "fixed" | "free";
|
|
1310
|
+
interface FacetStripStyle {
|
|
1311
|
+
height?: number;
|
|
1312
|
+
fontSize?: number;
|
|
1313
|
+
color?: Color;
|
|
1314
|
+
background?: Color;
|
|
1315
|
+
}
|
|
1316
|
+
interface FacetSpec<T> {
|
|
1317
|
+
/** Accessor / column name producing the facet key per datum. */
|
|
1318
|
+
by: Aes<T, unknown>;
|
|
1319
|
+
/** Number of columns. Default: ceil(sqrt(n)). */
|
|
1320
|
+
ncol?: number;
|
|
1321
|
+
/** Number of rows. Default: ceil(n / ncol). */
|
|
1322
|
+
nrow?: number;
|
|
1323
|
+
/**
|
|
1324
|
+
* Scale handling across panels.
|
|
1325
|
+
* - `"fixed"` (default) — every panel shares the same x/y/color/… scales.
|
|
1326
|
+
* - `"free"` — each panel computes its own scales from its data.
|
|
1327
|
+
*/
|
|
1328
|
+
scales?: FacetScales;
|
|
1329
|
+
/** Spacing between panels in pixels. Default `12`. */
|
|
1330
|
+
gap?: number;
|
|
1331
|
+
/** Strip header style. */
|
|
1332
|
+
strip?: FacetStripStyle;
|
|
1333
|
+
/** Optional formatter for the strip label. */
|
|
1334
|
+
format?: (key: unknown) => string;
|
|
1335
|
+
}
|
|
1336
|
+
//#endregion
|
|
1337
|
+
//#region src/grammar/geoms/point.d.ts
|
|
1338
|
+
interface PointChannels<T> {
|
|
1339
|
+
x: Aes<T, number | Date>;
|
|
1340
|
+
y: Aes<T, number | Date>;
|
|
1341
|
+
color?: Aes<T, unknown>;
|
|
1342
|
+
size?: Aes<T, number>;
|
|
1343
|
+
/**
|
|
1344
|
+
* Categorical shape mapping. Values are looked up in the active shape scale
|
|
1345
|
+
* — by default a built-in palette (`POINT_SHAPE_PALETTE`). Pass a literal
|
|
1346
|
+
* `PointShapeKind` accessor and `.scale("shape", { palette: [...] })` to
|
|
1347
|
+
* customize. When the value is already a `PointShapeKind`, it's used as-is.
|
|
1348
|
+
*/
|
|
1349
|
+
shape?: Aes<T, unknown>;
|
|
1350
|
+
alpha?: Aes<T, number>;
|
|
1351
|
+
/**
|
|
1352
|
+
* Per-datum border treatment. The accessor may return either a resolved
|
|
1353
|
+
* {@link PointBorderStyle} (used as-is) or any other categorical value that
|
|
1354
|
+
* gets routed through the active `borderStyle` scale (default palette:
|
|
1355
|
+
* `solid`, `open`, `dashed`, `dotted`). Configure a custom mapping with
|
|
1356
|
+
* `.scale("borderStyle", { palette: [...] })`.
|
|
1357
|
+
*/
|
|
1358
|
+
borderStyle?: Aes<T, unknown>;
|
|
1359
|
+
/**
|
|
1360
|
+
* Optional secondary glyph overlaid on the base shape at the same anchor.
|
|
1361
|
+
* Accepts either a resolved {@link PointShapeKind}/`null`, or a categorical
|
|
1362
|
+
* value routed through the `overlayGlyph` scale (default palette starts
|
|
1363
|
+
* with `null` so the most-common category gets no overlay). Configure with
|
|
1364
|
+
* `.scale("overlayGlyph", { palette: [...] })`.
|
|
1365
|
+
*/
|
|
1366
|
+
overlayGlyph?: Aes<T, unknown>;
|
|
1367
|
+
/** Overlay radius as a fraction of base radius. Default `0.6`. */
|
|
1368
|
+
overlayScale?: Aes<T, number>;
|
|
1369
|
+
}
|
|
1370
|
+
interface PointOptions {
|
|
1371
|
+
/** Constant fill if color channel is absent. */
|
|
1372
|
+
fill?: Color;
|
|
1373
|
+
/** Constant point radius if size channel is absent. */
|
|
1374
|
+
radius?: number;
|
|
1375
|
+
/** Override theme stroke. */
|
|
1376
|
+
stroke?: Color | null;
|
|
1377
|
+
/** Override theme stroke width. */
|
|
1378
|
+
strokeWidth?: number;
|
|
1379
|
+
/** Constant shape if shape channel is absent. */
|
|
1380
|
+
shape?: PointShapeKind;
|
|
1381
|
+
/** Constant border style if border-style channel is absent. */
|
|
1382
|
+
borderStyle?: PointBorderStyle;
|
|
1383
|
+
/** Constant overlay glyph if overlay-glyph channel is absent. */
|
|
1384
|
+
overlayGlyph?: PointShapeKind | null;
|
|
1385
|
+
/** Constant overlay scale if overlay-scale channel is absent. */
|
|
1386
|
+
overlayScale?: number;
|
|
1387
|
+
/** Display label for legend (defaults to color column name). */
|
|
1388
|
+
label?: string;
|
|
1389
|
+
}
|
|
1390
|
+
declare function point<T>(channels: PointChannels<T>, options?: PointOptions): Geom<T>;
|
|
1391
|
+
//#endregion
|
|
1392
|
+
//#region src/grammar/geoms/line.d.ts
|
|
1393
|
+
interface LineChannels<T> {
|
|
1394
|
+
x: Aes<T, number | Date>;
|
|
1395
|
+
y: Aes<T, number | Date>;
|
|
1396
|
+
/** Categorical color channel splits the line into one stroke per category. */
|
|
1397
|
+
color?: Aes<T, unknown>;
|
|
1398
|
+
/**
|
|
1399
|
+
* Optional ordering aesthetic. When present, rows are connected in ascending
|
|
1400
|
+
* order (globally, or within each color-grouped series).
|
|
1401
|
+
*/
|
|
1402
|
+
order?: Aes<T, number | Date>;
|
|
1403
|
+
}
|
|
1404
|
+
interface LineOptions {
|
|
1405
|
+
stroke?: Color;
|
|
1406
|
+
strokeWidth?: number;
|
|
1407
|
+
curve?: LineCurve;
|
|
1408
|
+
curveSamples?: number;
|
|
1409
|
+
dashPattern?: readonly number[];
|
|
1410
|
+
/**
|
|
1411
|
+
* Categorical dash treatment. `dashPattern` takes precedence when both
|
|
1412
|
+
* are supplied. See {@link LineDashStyle}.
|
|
1413
|
+
*/
|
|
1414
|
+
dashStyle?: LineDashStyle;
|
|
1415
|
+
label?: string;
|
|
1416
|
+
/**
|
|
1417
|
+
* When true, hover hit-tests resolve to the nearest vertex *by x* — the
|
|
1418
|
+
* cursor's vertical position doesn't influence which datum is picked, so
|
|
1419
|
+
* the user can hover anywhere along the line. Default `false` (per-vertex
|
|
1420
|
+
* Euclidean pick within `pickRadius`). For multi-line charts this means
|
|
1421
|
+
* the cursor's x picks one vertex per series; the topmost series wins
|
|
1422
|
+
* via PointCloud zIndex order.
|
|
1423
|
+
*/
|
|
1424
|
+
nearestX?: boolean;
|
|
1425
|
+
}
|
|
1426
|
+
declare function line<T>(channels: LineChannels<T>, options?: LineOptions): Geom<T>;
|
|
1427
|
+
//#endregion
|
|
1428
|
+
//#region src/grammar/geoms/connected-scatter.d.ts
|
|
1429
|
+
interface ConnectedScatterChannels<T> {
|
|
1430
|
+
x: Aes<T, number | Date>;
|
|
1431
|
+
y: Aes<T, number | Date>;
|
|
1432
|
+
color?: Aes<T, unknown>;
|
|
1433
|
+
order: Aes<T, number | Date>;
|
|
1434
|
+
size?: Aes<T, number>;
|
|
1435
|
+
shape?: Aes<T, unknown>;
|
|
1436
|
+
alpha?: Aes<T, number>;
|
|
1437
|
+
}
|
|
1438
|
+
interface ConnectedScatterOptions {
|
|
1439
|
+
/** Line-layer options. */
|
|
1440
|
+
line?: LineOptions;
|
|
1441
|
+
/** Point-layer options. Pass `false` to render only the connecting path. */
|
|
1442
|
+
point?: PointOptions | false;
|
|
1443
|
+
}
|
|
1444
|
+
/**
|
|
1445
|
+
* Grammar helper for the common "connected scatterplot" recipe:
|
|
1446
|
+
* a path ordered by a third variable, optionally topped with points.
|
|
1447
|
+
*
|
|
1448
|
+
* Returns plain geoms so callers still compose with `.layer(text(...))`,
|
|
1449
|
+
* `.annotate(...)`, facets, transitions, and the normal interaction stack.
|
|
1450
|
+
*/
|
|
1451
|
+
declare function connectedScatter<T>(channels: ConnectedScatterChannels<T>, options?: ConnectedScatterOptions): readonly Geom<T>[];
|
|
1452
|
+
//#endregion
|
|
1453
|
+
//#region src/grammar/geoms/area.d.ts
|
|
1454
|
+
type AreaPosition = "identity" | "stack" | "fill";
|
|
1455
|
+
interface AreaChannels<T> {
|
|
1456
|
+
x: Aes<T, number | Date>;
|
|
1457
|
+
/**
|
|
1458
|
+
* Single column → simple area from y=0 to y. Array of column keys → stacked
|
|
1459
|
+
* area, with the implicit `__series` color channel keyed by column name.
|
|
1460
|
+
*/
|
|
1461
|
+
y: Aes<T, number | Date> | readonly (keyof T & string)[];
|
|
1462
|
+
color?: Aes<T, unknown>;
|
|
1463
|
+
}
|
|
1464
|
+
interface AreaOptions {
|
|
1465
|
+
fill?: Color;
|
|
1466
|
+
stroke?: Color;
|
|
1467
|
+
strokeWidth?: number;
|
|
1468
|
+
/** "identity" (default), "stack" (offset zero), or "fill" (offset expand). */
|
|
1469
|
+
position?: AreaPosition;
|
|
1470
|
+
/** Stack ordering — only meaningful with stacked positions. */
|
|
1471
|
+
order?: StackOrder;
|
|
1472
|
+
label?: string;
|
|
1473
|
+
/**
|
|
1474
|
+
* When true, hover hit-tests resolve to the nearest vertex *by x* — the
|
|
1475
|
+
* cursor's vertical position doesn't influence which datum (or stacked
|
|
1476
|
+
* segment) is picked, so the user can hover anywhere along the area.
|
|
1477
|
+
* Default `false` (per-vertex Euclidean pick within `pickRadius`).
|
|
1478
|
+
*/
|
|
1479
|
+
nearestX?: boolean;
|
|
1480
|
+
}
|
|
1481
|
+
declare function area<T>(channels: AreaChannels<T>, options?: AreaOptions): Geom<T>;
|
|
1482
|
+
//#endregion
|
|
1483
|
+
//#region src/grammar/geoms/bar.d.ts
|
|
1484
|
+
type BarPosition = "identity" | "stack" | "dodge" | "fill";
|
|
1485
|
+
interface BarChannels<T> {
|
|
1486
|
+
x: Aes<T, string | number | Date>;
|
|
1487
|
+
/**
|
|
1488
|
+
* Single column → simple bars (one per category). Array of column keys →
|
|
1489
|
+
* multi-series bars (stacked / dodged / 100% stacked).
|
|
1490
|
+
*
|
|
1491
|
+
* For horizontal layouts (`orientation: "x"`) the single-column form carries
|
|
1492
|
+
* the band category, so a string is accepted; the value axis then lives on
|
|
1493
|
+
* `x`.
|
|
1494
|
+
*/
|
|
1495
|
+
y: Aes<T, string | number | Date> | readonly (keyof T & string)[];
|
|
1496
|
+
color?: Aes<T, unknown>;
|
|
1497
|
+
}
|
|
1498
|
+
interface BarOptions<T = unknown> {
|
|
1499
|
+
orientation?: BarOrientation;
|
|
1500
|
+
fill?: Color;
|
|
1501
|
+
stroke?: Color;
|
|
1502
|
+
strokeWidth?: number;
|
|
1503
|
+
cornerRadius?: number;
|
|
1504
|
+
/**
|
|
1505
|
+
* Border treatment shared across every bar (or segment, for stacked/dodged
|
|
1506
|
+
* layouts). See {@link BarBorderStyle}.
|
|
1507
|
+
*/
|
|
1508
|
+
borderStyle?: BarBorderStyle;
|
|
1509
|
+
/**
|
|
1510
|
+
* Multi-series layout. Only meaningful when `y` (or `x`) is an array of keys.
|
|
1511
|
+
* - `"stack"` (default for arrays) — segments stacked from 0
|
|
1512
|
+
* - `"dodge"` — bars side-by-side within each category
|
|
1513
|
+
* - `"fill"` — stacked, normalized to [0, 1]
|
|
1514
|
+
* - `"identity"` — each datum drawn at its raw value
|
|
1515
|
+
*/
|
|
1516
|
+
position?: BarPosition;
|
|
1517
|
+
order?: StackOrder;
|
|
1518
|
+
label?: string;
|
|
1519
|
+
/** Inner-band padding for `position: 'dodge'`. Default 0.05. */
|
|
1520
|
+
groupPadding?: number;
|
|
1521
|
+
/** If set, render a label above each bar with the per-category total. */
|
|
1522
|
+
showTotals?: (total: number, datum: T, datumIndex: number) => string;
|
|
1523
|
+
/**
|
|
1524
|
+
* If set, render a label per-bar (or per-segment for stacked / fill) with
|
|
1525
|
+
* the segment's value. For `fill`, the supplied `value` is normalized
|
|
1526
|
+
* `[0, 1]`; for other positions it's the raw segment value. `key` is the
|
|
1527
|
+
* column name for multi-series bars, `undefined` for simple bars.
|
|
1528
|
+
*/
|
|
1529
|
+
showValues?: (value: number, datum: T, datumIndex: number, key?: string) => string;
|
|
1530
|
+
/** Override label color. */
|
|
1531
|
+
labelColor?: Color;
|
|
1532
|
+
/** Override label font size. */
|
|
1533
|
+
labelFontSize?: number;
|
|
1534
|
+
}
|
|
1535
|
+
declare function bar<T>(channels: BarChannels<T>, options?: BarOptions<T>): Geom<T>;
|
|
1536
|
+
//#endregion
|
|
1537
|
+
//#region src/grammar/geoms/histogram.d.ts
|
|
1538
|
+
type HistogramPosition = "identity" | "stack" | "dodge" | "fill";
|
|
1539
|
+
interface HistogramChannels<T> {
|
|
1540
|
+
/** Numeric variable to bin. Provide one of `x` (vertical bars) or `y`. */
|
|
1541
|
+
x?: Aes<T, number>;
|
|
1542
|
+
/** Numeric variable to bin. Provide one of `x` (vertical bars) or `y`. */
|
|
1543
|
+
y?: Aes<T, number>;
|
|
1544
|
+
/** Optional categorical group key — splits the sample into per-group bins. */
|
|
1545
|
+
color?: Aes<T, unknown>;
|
|
1546
|
+
}
|
|
1547
|
+
interface HistogramOptions {
|
|
1548
|
+
/** Explicit bin count. Loses to `binwidth` and `breaks`. */
|
|
1549
|
+
bins?: number;
|
|
1550
|
+
/** Explicit bin width in data units. Beats `bins` and `rule`. */
|
|
1551
|
+
binwidth?: number;
|
|
1552
|
+
/** Fully explicit edge array. Beats every other bin selector. */
|
|
1553
|
+
breaks?: readonly number[];
|
|
1554
|
+
/**
|
|
1555
|
+
* Auto-bin rule when none of `bins`, `binwidth`, `breaks` is set.
|
|
1556
|
+
*
|
|
1557
|
+
* - `"sturges"` (default) — R / ggplot default; works for ~normal data.
|
|
1558
|
+
* - `"rice"` — slightly more bins.
|
|
1559
|
+
* - `"scott"` — uses σ; good for normal-ish data.
|
|
1560
|
+
* - `"fd"` — Freedman–Diaconis; robust to outliers.
|
|
1561
|
+
*/
|
|
1562
|
+
rule?: BinRule;
|
|
1563
|
+
/** Clip / extend the value-axis range used when computing edges. */
|
|
1564
|
+
domain?: readonly [number, number];
|
|
1565
|
+
/** Round outer edges + step to nice numbers. Default `true`. */
|
|
1566
|
+
nice?: boolean;
|
|
1567
|
+
/** Edge convention. Default `"left"` (`[x0, x1)` plus closed last bin). */
|
|
1568
|
+
closed?: BinClosed;
|
|
1569
|
+
/**
|
|
1570
|
+
* Y measure. Default `"count"`.
|
|
1571
|
+
*
|
|
1572
|
+
* - `"count"` / `"frequency"` — raw bin count.
|
|
1573
|
+
* - `"density"` — `count / (n · width)`. Integrates to 1 across bins.
|
|
1574
|
+
* - `"proportion"` — `count / n`. Sums to 1 across bins (per group).
|
|
1575
|
+
*/
|
|
1576
|
+
y?: HistogramMeasure;
|
|
1577
|
+
/**
|
|
1578
|
+
* Multi-group layout. Default `"stack"` when `color` channel is present,
|
|
1579
|
+
* else `"identity"`.
|
|
1580
|
+
*
|
|
1581
|
+
* - `"identity"` — bars share a baseline of 0; useful with reduced
|
|
1582
|
+
* `fillAlpha` for an overlay effect.
|
|
1583
|
+
* - `"stack"` — per-bin counts stacked.
|
|
1584
|
+
* - `"dodge"` — sub-divide bin width across groups, side by side.
|
|
1585
|
+
* - `"fill"` — stack normalized to `[0, 1]` per bin.
|
|
1586
|
+
*/
|
|
1587
|
+
position?: HistogramPosition;
|
|
1588
|
+
/** Render bars below the baseline (negate the count axis). Default `false`. */
|
|
1589
|
+
mirror?: boolean;
|
|
1590
|
+
/** Override theme `fillAlpha`. Lower this for `position: "identity"` overlays. */
|
|
1591
|
+
fillAlpha?: number;
|
|
1592
|
+
fill?: Color;
|
|
1593
|
+
stroke?: Color;
|
|
1594
|
+
strokeWidth?: number;
|
|
1595
|
+
cornerRadius?: number;
|
|
1596
|
+
/** Pixel gap between adjacent bars. Default `0` (continuous wall). */
|
|
1597
|
+
gap?: number;
|
|
1598
|
+
/** Inner-band padding for `position: "dodge"` (fraction of bin width). Default `0.05`. */
|
|
1599
|
+
groupPadding?: number;
|
|
1600
|
+
/** Optional per-bar label (uses bin midpoint + value). */
|
|
1601
|
+
showCounts?: (value: number, bin: BinResult, key?: string) => string;
|
|
1602
|
+
labelColor?: Color;
|
|
1603
|
+
labelFontSize?: number;
|
|
1604
|
+
/** Used by the auto-legend. */
|
|
1605
|
+
label?: string;
|
|
1606
|
+
}
|
|
1607
|
+
declare function histogram<T>(channels: HistogramChannels<T>, options?: HistogramOptions): Geom<T>;
|
|
1608
|
+
//#endregion
|
|
1609
|
+
//#region src/grammar/geoms/rug.d.ts
|
|
1610
|
+
interface RugChannels<T> {
|
|
1611
|
+
x?: Aes<T, number | Date>;
|
|
1612
|
+
y?: Aes<T, number | Date>;
|
|
1613
|
+
/** Categorical color split for the ticks. */
|
|
1614
|
+
color?: Aes<T, unknown>;
|
|
1615
|
+
}
|
|
1616
|
+
type RugSide = "x" | "y" | "both";
|
|
1617
|
+
interface RugOptions {
|
|
1618
|
+
/**
|
|
1619
|
+
* Which edges receive ticks. Defaults to whichever channels are wired —
|
|
1620
|
+
* with both `x` and `y`, both edges; otherwise just the matching edge.
|
|
1621
|
+
* Use `"both"` to force both edges (mirrors x onto bottom, y onto left).
|
|
1622
|
+
*/
|
|
1623
|
+
side?: RugSide;
|
|
1624
|
+
/** Tick length in pixels. Default `6`. */
|
|
1625
|
+
length?: number;
|
|
1626
|
+
/** Tick stroke width. Default `1`. */
|
|
1627
|
+
strokeWidth?: number;
|
|
1628
|
+
/** Override stroke color (defaults to theme.axis.color). */
|
|
1629
|
+
stroke?: Color;
|
|
1630
|
+
/** Multiplier on the resolved stroke alpha. Default `0.6`. */
|
|
1631
|
+
opacity?: number;
|
|
1632
|
+
label?: string;
|
|
1633
|
+
}
|
|
1634
|
+
declare function rug<T>(channels: RugChannels<T>, options?: RugOptions): Geom<T>;
|
|
1635
|
+
//#endregion
|
|
1636
|
+
//#region src/grammar/color-utils.d.ts
|
|
1637
|
+
/**
|
|
1638
|
+
* Accent-key shorthand used by chart-level marks (`band`, `rule`, `interval`,
|
|
1639
|
+
* `ribbon`). Literal {@link Color} values bypass theme resolution; accent
|
|
1640
|
+
* keys resolve through `theme.accents`.
|
|
1641
|
+
*/
|
|
1642
|
+
type ColorOrAccent = Color | ThemeAccentKey;
|
|
1643
|
+
//#endregion
|
|
1644
|
+
//#region src/grammar/geoms/rule.d.ts
|
|
1645
|
+
interface RuleChannels<T> {
|
|
1646
|
+
x?: Aes<T, number | Date>;
|
|
1647
|
+
y?: Aes<T, number | Date>;
|
|
1648
|
+
}
|
|
1649
|
+
interface RuleOptions {
|
|
1650
|
+
/**
|
|
1651
|
+
* Stroke color. Accepts a literal {@link Color} or a theme accent key
|
|
1652
|
+
* (`"positive" | "negative" | "warn" | "info"`); accent keys resolve through
|
|
1653
|
+
* `theme.accents`.
|
|
1654
|
+
*/
|
|
1655
|
+
stroke?: ColorOrAccent;
|
|
1656
|
+
strokeWidth?: number;
|
|
1657
|
+
dashPattern?: readonly number[];
|
|
1658
|
+
/** Optional inline rule label (only meaningful for non-data rules). */
|
|
1659
|
+
label?: string;
|
|
1660
|
+
labelColor?: Color;
|
|
1661
|
+
labelInset?: number;
|
|
1662
|
+
}
|
|
1663
|
+
declare function rule<T>(channels: RuleChannels<T>, options?: RuleOptions): Geom<T>;
|
|
1664
|
+
//#endregion
|
|
1665
|
+
//#region src/grammar/geoms/smooth.d.ts
|
|
1666
|
+
type SmoothMethod = "lm" | "poly" | "loess";
|
|
1667
|
+
interface SmoothChannels<T> {
|
|
1668
|
+
x: Aes<T, number | Date>;
|
|
1669
|
+
y: Aes<T, number>;
|
|
1670
|
+
/** Categorical color channel — fits one curve per group. */
|
|
1671
|
+
color?: Aes<T, unknown>;
|
|
1672
|
+
}
|
|
1673
|
+
interface SmoothLabelOptions {
|
|
1674
|
+
/** Pixel offset from the right end of the fit. */
|
|
1675
|
+
offsetX?: number;
|
|
1676
|
+
offsetY?: number;
|
|
1677
|
+
/** Custom label color. Defaults to the curve color. */
|
|
1678
|
+
color?: Color;
|
|
1679
|
+
fontSize?: number;
|
|
1680
|
+
/** Optional rounded-rect background. */
|
|
1681
|
+
box?: LabelBoxStyle;
|
|
1682
|
+
}
|
|
1683
|
+
interface SmoothOptions {
|
|
1684
|
+
/** Fit method. Default `"lm"`. */
|
|
1685
|
+
method?: SmoothMethod;
|
|
1686
|
+
/** Degree for `"poly"` (default `2`) or `"loess"` local polynomial (default `1`). */
|
|
1687
|
+
degree?: number;
|
|
1688
|
+
/** Span for `"loess"` (fraction of data per neighborhood). Default `0.5`. */
|
|
1689
|
+
span?: number;
|
|
1690
|
+
/**
|
|
1691
|
+
* Confidence ribbon. `true` (default) → 95%, `false` → no ribbon, `number`
|
|
1692
|
+
* → that confidence level (e.g. `0.99`).
|
|
1693
|
+
*/
|
|
1694
|
+
ci?: boolean | number;
|
|
1695
|
+
/** Number of x samples for the curve & ribbon. Default `64`. */
|
|
1696
|
+
samples?: number;
|
|
1697
|
+
stroke?: Color;
|
|
1698
|
+
strokeWidth?: number;
|
|
1699
|
+
/** Override the ribbon fill. Defaults to the stroke color at low alpha. */
|
|
1700
|
+
ribbonFill?: Color;
|
|
1701
|
+
ribbonOpacity?: number;
|
|
1702
|
+
/**
|
|
1703
|
+
* Per-group inline label at the right end of each fitted curve. Only emitted
|
|
1704
|
+
* when the `color` channel is present. `true` uses the group key as the
|
|
1705
|
+
* label string.
|
|
1706
|
+
*/
|
|
1707
|
+
label?: boolean | SmoothLabelOptions;
|
|
1708
|
+
/**
|
|
1709
|
+
* When true, hit-tests resolve to the nearest sample by x. Hover anywhere
|
|
1710
|
+
* along the curve and the closest source row in the matching group is
|
|
1711
|
+
* picked. Default `false` (Euclidean within `pickRadius`).
|
|
1712
|
+
*/
|
|
1713
|
+
nearestX?: boolean;
|
|
1714
|
+
}
|
|
1715
|
+
declare function smooth<T>(channels: SmoothChannels<T>, options?: SmoothOptions): Geom<T>;
|
|
1716
|
+
//#endregion
|
|
1717
|
+
//#region src/grammar/geoms/rolling.d.ts
|
|
1718
|
+
interface StatRollingChannels<T> {
|
|
1719
|
+
x: Aes<T, number | Date>;
|
|
1720
|
+
y: Aes<T, number>;
|
|
1721
|
+
/** Categorical color channel — runs one rolling fit per group. */
|
|
1722
|
+
color?: Aes<T, unknown>;
|
|
1723
|
+
}
|
|
1724
|
+
interface StatRollingOptions<T> {
|
|
1725
|
+
/** Sliding window. See `RollingWindow` — bare number = count, object for explicit unit. */
|
|
1726
|
+
window: RollingWindow;
|
|
1727
|
+
/** Default `"mean"`. */
|
|
1728
|
+
statistic?: RollingStatistic<T>;
|
|
1729
|
+
/** Default `"x"`. */
|
|
1730
|
+
axis?: RollingAxis;
|
|
1731
|
+
/** Rows failing the filter are dropped from every window and the output series. */
|
|
1732
|
+
filter?: (datum: T, index: number) => boolean;
|
|
1733
|
+
/** Line curve. Default `"linear"` — pre-smoothed data rarely needs another smoother. */
|
|
1734
|
+
curve?: LineCurve;
|
|
1735
|
+
/** Override the per-group stroke color. When `color` is set, defaults to the color scale. */
|
|
1736
|
+
stroke?: Color;
|
|
1737
|
+
strokeWidth?: number;
|
|
1738
|
+
dashStyle?: LineDashStyle;
|
|
1739
|
+
/**
|
|
1740
|
+
* When true (default), hovering anywhere along the curve resolves to the
|
|
1741
|
+
* nearest rolling point by x — the cursor reads off "the smoothed value
|
|
1742
|
+
* here." Set false for Euclidean nearest within a small pickRadius.
|
|
1743
|
+
*
|
|
1744
|
+
* Hits always carry the synthetic {@link RollingPoint} (`{ x, y, count,
|
|
1745
|
+
* sourceIndex }`) as `info.datum`, not the underlying source row — so a
|
|
1746
|
+
* tooltip resolver can describe the *line's* value at the cursor (e.g.
|
|
1747
|
+
* "14-day mean: 88.4 kg") rather than misattributing a source row's tooltip
|
|
1748
|
+
* to a position on the smoothed curve. Branch on `info.mark === label` to
|
|
1749
|
+
* format the rolling tooltip distinctly from sibling point/line layers.
|
|
1750
|
+
*/
|
|
1751
|
+
nearestX?: boolean;
|
|
1752
|
+
/** Used by the auto-legend and tooltip discrimination. Default `"rolling"`. */
|
|
1753
|
+
label?: string;
|
|
1754
|
+
}
|
|
1755
|
+
declare function statRolling<T>(channels: StatRollingChannels<T>, options: StatRollingOptions<T>): Geom<T>;
|
|
1756
|
+
//#endregion
|
|
1757
|
+
//#region src/grammar/geoms/ribbon.d.ts
|
|
1758
|
+
interface RibbonChannels<T> {
|
|
1759
|
+
x: Aes<T, number | Date>;
|
|
1760
|
+
y0: Aes<T, number | Date>;
|
|
1761
|
+
y1: Aes<T, number | Date>;
|
|
1762
|
+
}
|
|
1763
|
+
interface RibbonOptions {
|
|
1764
|
+
/**
|
|
1765
|
+
* Fill color. Accepts a literal {@link Color} or a theme accent key
|
|
1766
|
+
* (`"positive" | "negative" | "warn" | "info"`); accent keys resolve through
|
|
1767
|
+
* `theme.accents`.
|
|
1768
|
+
*/
|
|
1769
|
+
fill?: ColorOrAccent;
|
|
1770
|
+
stroke?: ColorOrAccent;
|
|
1771
|
+
strokeWidth?: number;
|
|
1772
|
+
fillAlpha?: number;
|
|
1773
|
+
label?: string;
|
|
1774
|
+
}
|
|
1775
|
+
declare function ribbon<T>(channels: RibbonChannels<T>, options?: RibbonOptions): Geom<T>;
|
|
1776
|
+
//#endregion
|
|
1777
|
+
//#region src/grammar/geoms/interval.d.ts
|
|
1778
|
+
interface IntervalChannels<T> {
|
|
1779
|
+
/** Anchor for vertical intervals (required when `yMin`/`yMax` are bound). */
|
|
1780
|
+
x?: Aes<T, number | Date>;
|
|
1781
|
+
/** Anchor for horizontal intervals (required when `xMin`/`xMax` are bound). */
|
|
1782
|
+
y?: Aes<T, number | Date>;
|
|
1783
|
+
yMin?: Aes<T, number | Date>;
|
|
1784
|
+
yMax?: Aes<T, number | Date>;
|
|
1785
|
+
xMin?: Aes<T, number | Date>;
|
|
1786
|
+
xMax?: Aes<T, number | Date>;
|
|
1787
|
+
/** Optional categorical color channel — routed through the chart's color scale. */
|
|
1788
|
+
color?: Aes<T, unknown>;
|
|
1789
|
+
}
|
|
1790
|
+
interface IntervalOptions {
|
|
1791
|
+
/**
|
|
1792
|
+
* Stroke color. Accepts a literal {@link Color} or a theme accent key
|
|
1793
|
+
* (`"positive" | "negative" | "warn" | "info"`); accent keys resolve through
|
|
1794
|
+
* `theme.accents`.
|
|
1795
|
+
*/
|
|
1796
|
+
stroke?: ColorOrAccent;
|
|
1797
|
+
strokeWidth?: number;
|
|
1798
|
+
/** Render perpendicular caps at each end. Default `true`. */
|
|
1799
|
+
caps?: boolean;
|
|
1800
|
+
/** Cap length in pixels (total, across both sides of the spine). Default `6`. */
|
|
1801
|
+
capWidth?: number;
|
|
1802
|
+
/** Display label for legend. */
|
|
1803
|
+
label?: string;
|
|
1804
|
+
}
|
|
1805
|
+
declare function interval<T>(channels: IntervalChannels<T>, options?: IntervalOptions): Geom<T>;
|
|
1806
|
+
//#endregion
|
|
1807
|
+
//#region src/grammar/geoms/band.d.ts
|
|
1808
|
+
interface BandChannels {
|
|
1809
|
+
x?: readonly [number | Date, number | Date];
|
|
1810
|
+
y?: readonly [number | Date, number | Date];
|
|
1811
|
+
}
|
|
1812
|
+
interface BandOptions {
|
|
1813
|
+
/**
|
|
1814
|
+
* Fill color. Accepts a literal {@link Color} or a theme accent key
|
|
1815
|
+
* (`"positive" | "negative" | "warn" | "info"`); accent keys resolve through
|
|
1816
|
+
* `theme.accents` and have `theme.marks.bandFillAlpha` applied unless
|
|
1817
|
+
* {@link BandOptions.alpha} is set.
|
|
1818
|
+
*/
|
|
1819
|
+
fill?: ColorOrAccent;
|
|
1820
|
+
stroke?: ColorOrAccent;
|
|
1821
|
+
strokeWidth?: number;
|
|
1822
|
+
/**
|
|
1823
|
+
* Override the fill alpha. Defaults to `theme.marks.bandFillAlpha` when
|
|
1824
|
+
* `fill` is omitted or is an accent key; defaults to no override (use the
|
|
1825
|
+
* color's own alpha) when `fill` is a literal {@link Color}.
|
|
1826
|
+
*/
|
|
1827
|
+
alpha?: number;
|
|
1828
|
+
label?: string;
|
|
1829
|
+
labelColor?: Color;
|
|
1830
|
+
}
|
|
1831
|
+
declare function band<T>(channels: BandChannels, options?: BandOptions): Geom<T>;
|
|
1832
|
+
//#endregion
|
|
1833
|
+
//#region src/grammar/geoms/text.d.ts
|
|
1834
|
+
type TextCollisionMode = "none" | "hide" | "stagger";
|
|
1835
|
+
interface TextChannels<T> {
|
|
1836
|
+
x: Aes<T, number | Date | string>;
|
|
1837
|
+
y: Aes<T, number | Date | string>;
|
|
1838
|
+
text: Aes<T, string>;
|
|
1839
|
+
}
|
|
1840
|
+
interface TextOptions {
|
|
1841
|
+
fontSize?: number;
|
|
1842
|
+
color?: Color;
|
|
1843
|
+
align?: ValueLabelAlign;
|
|
1844
|
+
offsetX?: number;
|
|
1845
|
+
offsetY?: number;
|
|
1846
|
+
/** Optional rounded-rect background. Requires the chart's glyph atlas. */
|
|
1847
|
+
box?: LabelBoxStyle;
|
|
1848
|
+
label?: string;
|
|
1849
|
+
/**
|
|
1850
|
+
* Post-layout collision handling. Default `"none"`. `"hide"` drops
|
|
1851
|
+
* overlapping labels via a greedy first-fit pass; `"stagger"` adds an
|
|
1852
|
+
* alternating y offset so adjacent labels sit on two rows.
|
|
1853
|
+
*/
|
|
1854
|
+
collisionMode?: TextCollisionMode;
|
|
1855
|
+
/** Pixel padding around each label's measured rect when checking overlap. Default `2`. */
|
|
1856
|
+
collisionPadding?: number;
|
|
1857
|
+
}
|
|
1858
|
+
declare function text<T>(channels: TextChannels<T>, options?: TextOptions): Geom<T>;
|
|
1859
|
+
//#endregion
|
|
1860
|
+
//#region src/grammar/geoms/boxplot.d.ts
|
|
1861
|
+
type PointsMode = "auto" | "always" | "none";
|
|
1862
|
+
interface BoxplotChannels<T> {
|
|
1863
|
+
/** Categorical band axis. */
|
|
1864
|
+
x: Aes<T, string | number | Date>;
|
|
1865
|
+
/**
|
|
1866
|
+
* Numeric value axis (the distribution to summarize) when vertical. For
|
|
1867
|
+
* horizontal layouts (`orientation: "x"`) this carries the band category, so
|
|
1868
|
+
* a string is accepted; the value axis then lives on `x`.
|
|
1869
|
+
*/
|
|
1870
|
+
y: Aes<T, string | number | Date>;
|
|
1871
|
+
/**
|
|
1872
|
+
* Optional grouping key. When supplied (and distinct from `x`) the layer
|
|
1873
|
+
* dodges side-by-side by this channel within each band.
|
|
1874
|
+
*/
|
|
1875
|
+
color?: Aes<T, unknown>;
|
|
1876
|
+
}
|
|
1877
|
+
/**
|
|
1878
|
+
* Mean-overlay configuration. `true` → default red dot; `false` (default) →
|
|
1879
|
+
* no overlay; object → fully customised.
|
|
1880
|
+
*/
|
|
1881
|
+
interface MeanMarkerOptions {
|
|
1882
|
+
shape?: PointShapeKind;
|
|
1883
|
+
/** Radius in pixels. Default `3.5`. */
|
|
1884
|
+
radius?: number;
|
|
1885
|
+
fill?: Color;
|
|
1886
|
+
stroke?: Color;
|
|
1887
|
+
strokeWidth?: number;
|
|
1888
|
+
}
|
|
1889
|
+
interface BoxplotOptions {
|
|
1890
|
+
/** Auto-detected from scale types when omitted (band axis = category axis). */
|
|
1891
|
+
orientation?: "x" | "y";
|
|
1892
|
+
/**
|
|
1893
|
+
* Box width as a fraction of the bandwidth (or grouped inner bandwidth, when
|
|
1894
|
+
* dodging). Default `0.6`.
|
|
1895
|
+
*/
|
|
1896
|
+
width?: number;
|
|
1897
|
+
/**
|
|
1898
|
+
* Scale box widths by `√(n / nMax)` so groups with more samples render
|
|
1899
|
+
* wider — matches ggplot's `varwidth = TRUE`. Default `false`.
|
|
1900
|
+
*/
|
|
1901
|
+
varwidth?: boolean;
|
|
1902
|
+
/** Whisker rule. Default `1.5` (Tukey). Pass `"minmax"` for no outliers. */
|
|
1903
|
+
whisker?: WhiskerRule;
|
|
1904
|
+
/** Quantile interpolation method. Default `"type-7"` (R default). */
|
|
1905
|
+
quantile?: QuantileMethod;
|
|
1906
|
+
/**
|
|
1907
|
+
* Render notches around the median at `± 1.58 · IQR / √n` (McGill 1978's
|
|
1908
|
+
* 95% CI). Useful as an informal significance test: non-overlapping
|
|
1909
|
+
* notches between groups suggest medians differ. Default `false`.
|
|
1910
|
+
*/
|
|
1911
|
+
notched?: boolean;
|
|
1912
|
+
/**
|
|
1913
|
+
* Notch indent as a fraction of the box width (how far the sides pull in
|
|
1914
|
+
* at the median). Default `0.5`.
|
|
1915
|
+
*/
|
|
1916
|
+
notchWidth?: number;
|
|
1917
|
+
/**
|
|
1918
|
+
* When to overlay raw jittered points.
|
|
1919
|
+
*
|
|
1920
|
+
* - `"auto"` (default) — only when `n < pointsThreshold` for the group.
|
|
1921
|
+
* Rationale: small samples are easy to mislead with a box; show the dots.
|
|
1922
|
+
* - `"always"` — always overlay.
|
|
1923
|
+
* - `"none"` — never overlay (still draws outliers unless `outliers: false`).
|
|
1924
|
+
*/
|
|
1925
|
+
points?: PointsMode;
|
|
1926
|
+
/** Threshold for `points: "auto"`. Default `10`. */
|
|
1927
|
+
pointsThreshold?: number;
|
|
1928
|
+
/** Jitter spread, fraction of the per-box width. Default `0.5`. */
|
|
1929
|
+
pointJitter?: number;
|
|
1930
|
+
/** Radius of overlay & outlier points. Default `2.5`. */
|
|
1931
|
+
pointRadius?: number;
|
|
1932
|
+
/** Override fill for jittered overlay points. Default `alphaize(stroke, 0.5)`. */
|
|
1933
|
+
pointFill?: Color;
|
|
1934
|
+
/** Override fill for outlier points. Default = stroke. */
|
|
1935
|
+
outlierFill?: Color;
|
|
1936
|
+
/** Outlier point radius. Default = `pointRadius`. */
|
|
1937
|
+
outlierRadius?: number;
|
|
1938
|
+
/** Seed for deterministic jitter. Default `1`. */
|
|
1939
|
+
jitterSeed?: number;
|
|
1940
|
+
/** Render outlier dots beyond the whiskers. Default `true`. */
|
|
1941
|
+
outliers?: boolean;
|
|
1942
|
+
/** Constant fill when no `color` channel. Default theme palette[0]. */
|
|
1943
|
+
fill?: Color;
|
|
1944
|
+
/**
|
|
1945
|
+
* Override the theme's fill alpha (use `0` for outline-only boxes, e.g.
|
|
1946
|
+
* to match ggplot's bottom-middle "no-fill" look). When unset the layer
|
|
1947
|
+
* uses `theme.marks.fillAlpha`.
|
|
1948
|
+
*/
|
|
1949
|
+
fillAlpha?: number;
|
|
1950
|
+
/** Box stroke color. Default theme text color (light line on dark fill). */
|
|
1951
|
+
stroke?: Color;
|
|
1952
|
+
/** Box stroke width. Default `1`. */
|
|
1953
|
+
strokeWidth?: number;
|
|
1954
|
+
/** Median line color. Defaults to `stroke`. */
|
|
1955
|
+
medianStroke?: Color;
|
|
1956
|
+
/** Median line stroke width. Default `2`. */
|
|
1957
|
+
medianStrokeWidth?: number;
|
|
1958
|
+
/** Whisker line stroke width. Default = `strokeWidth`. */
|
|
1959
|
+
whiskerStrokeWidth?: number;
|
|
1960
|
+
/** Whisker cap width as a fraction of box width. Default `0.5`. */
|
|
1961
|
+
capWidth?: number;
|
|
1962
|
+
/**
|
|
1963
|
+
* Mean overlay. `true` for the default red dot; `false` (default) to omit;
|
|
1964
|
+
* pass an object to customize shape, radius, fill, stroke. The mean is
|
|
1965
|
+
* **not** part of the box geometry — it's an annotation on top.
|
|
1966
|
+
*/
|
|
1967
|
+
mean?: boolean | MeanMarkerOptions;
|
|
1968
|
+
/** Inner-band padding for grouped (color-split) layout. Default `0.05`. */
|
|
1969
|
+
groupPadding?: number;
|
|
1970
|
+
/**
|
|
1971
|
+
* Render an `n=<count>` label per band-axis category, just outside the
|
|
1972
|
+
* plot frame. Counts are summed across dodge groups. Default `false`.
|
|
1973
|
+
*/
|
|
1974
|
+
showCounts?: boolean;
|
|
1975
|
+
/** Pixel offset of count labels from plot frame. Default `28` (vertical) / `32` (horizontal). */
|
|
1976
|
+
countsOffset?: number;
|
|
1977
|
+
countsFontSize?: number;
|
|
1978
|
+
countsColor?: Color;
|
|
1979
|
+
/** Display label for legend. */
|
|
1980
|
+
label?: string;
|
|
1981
|
+
}
|
|
1982
|
+
declare function boxplot<T>(channels: BoxplotChannels<T>, options?: BoxplotOptions): Geom<T>;
|
|
1983
|
+
//#endregion
|
|
1984
|
+
//#region src/grammar/geoms/_distribution.d.ts
|
|
1985
|
+
/** How per-row width relates to density across groups. */
|
|
1986
|
+
type DensityScale = "width" | "area" | "count";
|
|
1987
|
+
//#endregion
|
|
1988
|
+
//#region src/grammar/geoms/violin.d.ts
|
|
1989
|
+
interface ViolinChannels<T> {
|
|
1990
|
+
x: Aes<T, string | number | Date>;
|
|
1991
|
+
/**
|
|
1992
|
+
* Numeric value axis when vertical. For horizontal layouts
|
|
1993
|
+
* (`orientation: "x"`) this carries the band category, so a string is
|
|
1994
|
+
* accepted; the value axis then lives on `x`.
|
|
1995
|
+
*/
|
|
1996
|
+
y: Aes<T, string | number | Date>;
|
|
1997
|
+
color?: Aes<T, unknown>;
|
|
1998
|
+
}
|
|
1999
|
+
type ViolinScale = DensityScale;
|
|
2000
|
+
type ViolinInner = "box" | "quartile" | "stick" | "none";
|
|
2001
|
+
interface ViolinOptions {
|
|
2002
|
+
orientation?: "x" | "y";
|
|
2003
|
+
/** Violin width as a fraction of the bandwidth (or grouped inner bandwidth). Default `0.9`. */
|
|
2004
|
+
width?: number;
|
|
2005
|
+
/** KDE bandwidth — number, `"silverman"` (default), or `"scott"`. */
|
|
2006
|
+
bandwidth?: KdeBandwidth;
|
|
2007
|
+
/** KDE evaluation grid size. Default `64`. */
|
|
2008
|
+
gridSize?: number;
|
|
2009
|
+
/** KDE kernel. Default `"gaussian"`. */
|
|
2010
|
+
kernel?: KdeKernel;
|
|
2011
|
+
/** Clip KDE to data range (true, default) or pad outward by ~3 bandwidths. */
|
|
2012
|
+
trim?: boolean;
|
|
2013
|
+
/**
|
|
2014
|
+
* Width-normalization mode.
|
|
2015
|
+
*
|
|
2016
|
+
* - `"width"` (default) — each violin uses its full allotted width; shapes
|
|
2017
|
+
* are easy to compare but **areas are misleading**.
|
|
2018
|
+
* - `"area"` — density scaled relative to the global max so areas are
|
|
2019
|
+
* comparable across groups (groups with low n look skinny).
|
|
2020
|
+
* - `"count"` — area scales with sample size (bigger n → wider violin).
|
|
2021
|
+
*/
|
|
2022
|
+
scale?: ViolinScale;
|
|
2023
|
+
/**
|
|
2024
|
+
* Inner annotation drawn on top of the violin.
|
|
2025
|
+
*
|
|
2026
|
+
* - `"none"` (default) — bare KDE polygon, like ggplot's `geom_violin`.
|
|
2027
|
+
* - `"box"` — slim box plot with median, IQR, whiskers.
|
|
2028
|
+
* - `"quartile"` — three horizontal/vertical lines at Q1, median, Q3.
|
|
2029
|
+
* - `"stick"` — single line at the median only.
|
|
2030
|
+
*/
|
|
2031
|
+
inner?: ViolinInner;
|
|
2032
|
+
/** When to overlay raw jittered points. See `BoxplotOptions["points"]`. */
|
|
2033
|
+
points?: PointsMode;
|
|
2034
|
+
pointsThreshold?: number;
|
|
2035
|
+
pointJitter?: number;
|
|
2036
|
+
pointRadius?: number;
|
|
2037
|
+
jitterSeed?: number;
|
|
2038
|
+
/** Box stats: whisker rule when `inner: "box"`. Default `1.5`. */
|
|
2039
|
+
whisker?: WhiskerRule;
|
|
2040
|
+
/** Box stats: quantile method. Default `"type-7"`. */
|
|
2041
|
+
quantile?: QuantileMethod;
|
|
2042
|
+
fill?: Color;
|
|
2043
|
+
stroke?: Color;
|
|
2044
|
+
strokeWidth?: number;
|
|
2045
|
+
/** Color of inner annotation marks. Defaults to `stroke` (or theme text). */
|
|
2046
|
+
innerStroke?: Color;
|
|
2047
|
+
/** Stroke width for the embedded mini-box body. Default `1`. */
|
|
2048
|
+
innerStrokeWidth?: number;
|
|
2049
|
+
/** Inner-band padding for grouped (color-split) layout. Default `0.05`. */
|
|
2050
|
+
groupPadding?: number;
|
|
2051
|
+
/**
|
|
2052
|
+
* Render an `n=<count>` label per group, aligned with the band axis just
|
|
2053
|
+
* outside the plot frame. Useful when the categorical labels alone hide
|
|
2054
|
+
* sample-size differences.
|
|
2055
|
+
*/
|
|
2056
|
+
showCounts?: boolean;
|
|
2057
|
+
/**
|
|
2058
|
+
* Pixel offset of the count labels from the plot frame edge along the
|
|
2059
|
+
* band-axis perpendicular. Increase to clear longer tick labels. Default
|
|
2060
|
+
* `28` (vertical) / `32` (horizontal).
|
|
2061
|
+
*/
|
|
2062
|
+
countsOffset?: number;
|
|
2063
|
+
countsFontSize?: number;
|
|
2064
|
+
countsColor?: Color;
|
|
2065
|
+
label?: string;
|
|
2066
|
+
}
|
|
2067
|
+
declare function violin<T>(channels: ViolinChannels<T>, options?: ViolinOptions): Geom<T>;
|
|
2068
|
+
//#endregion
|
|
2069
|
+
//#region src/grammar/geoms/ridgeline.d.ts
|
|
2070
|
+
type RidgelineGeom = "kde" | "histogram";
|
|
2071
|
+
type RidgelineScale = DensityScale;
|
|
2072
|
+
type RidgelineInner = "none" | "median" | "quartile" | "mean";
|
|
2073
|
+
type RidgelineFillMode = "solid" | "gradient";
|
|
2074
|
+
interface RidgelineChannels<T> {
|
|
2075
|
+
/** Numeric value being distributed. Provide one of x or y; the other is the row category. */
|
|
2076
|
+
x: Aes<T, string | number>;
|
|
2077
|
+
y: Aes<T, string | number>;
|
|
2078
|
+
/** Optional categorical group key. Drives palette fill (chart color scale). */
|
|
2079
|
+
color?: Aes<T, unknown>;
|
|
2080
|
+
}
|
|
2081
|
+
interface RidgelineOptions {
|
|
2082
|
+
/** Auto-detected from scale types when omitted. The default reproduces the common "rows on y, values on x" layout. */
|
|
2083
|
+
orientation?: "x" | "y";
|
|
2084
|
+
/** Density estimator. Default `"kde"`. */
|
|
2085
|
+
geom?: RidgelineGeom;
|
|
2086
|
+
/**
|
|
2087
|
+
* How tall a ridge can be relative to its band-cell spacing. `1` = no
|
|
2088
|
+
* overlap (each ridge stays inside its row); `>1` allows overlap into
|
|
2089
|
+
* neighbours. Default `2.5`.
|
|
2090
|
+
*/
|
|
2091
|
+
overlap?: number;
|
|
2092
|
+
/**
|
|
2093
|
+
* Across-group height normalization (same semantics as `violin`'s `scale`).
|
|
2094
|
+
*
|
|
2095
|
+
* - `"width"` (default) — each row uses its full allotted height.
|
|
2096
|
+
* - `"area"` — heights normalized by the global max density.
|
|
2097
|
+
* - `"count"` — heights scaled by sample size on top of `"area"`.
|
|
2098
|
+
*/
|
|
2099
|
+
scale?: RidgelineScale;
|
|
2100
|
+
bandwidth?: KdeBandwidth;
|
|
2101
|
+
gridSize?: number;
|
|
2102
|
+
kernel?: KdeKernel;
|
|
2103
|
+
trim?: boolean;
|
|
2104
|
+
bins?: number;
|
|
2105
|
+
binwidth?: number;
|
|
2106
|
+
breaks?: readonly number[];
|
|
2107
|
+
rule?: BinRule;
|
|
2108
|
+
measure?: HistogramMeasure;
|
|
2109
|
+
closed?: BinClosed;
|
|
2110
|
+
/**
|
|
2111
|
+
* Solid fill (default) uses the chart color scale per category, or the
|
|
2112
|
+
* theme's categorical palette if no `color` channel is mapped. Gradient
|
|
2113
|
+
* fill ignores the category and applies a value-axis-mapped color ramp,
|
|
2114
|
+
* reproducing the "Lincoln NE temperatures" look.
|
|
2115
|
+
*/
|
|
2116
|
+
fillMode?: RidgelineFillMode;
|
|
2117
|
+
/**
|
|
2118
|
+
* Color ramp for `fillMode: "gradient"`. Receives `t ∈ [0, 1]` mapped from
|
|
2119
|
+
* the value-axis range. Default = `theme.palettes.continuous`.
|
|
2120
|
+
*/
|
|
2121
|
+
gradient?: (t01: number) => Color;
|
|
2122
|
+
/** Per-row inner annotation. Default `"none"`. */
|
|
2123
|
+
inner?: RidgelineInner;
|
|
2124
|
+
innerStroke?: Color;
|
|
2125
|
+
innerStrokeWidth?: number;
|
|
2126
|
+
/** Radius of the median/mean dot when `inner` includes a point. Default `3`. */
|
|
2127
|
+
innerDotRadius?: number;
|
|
2128
|
+
/** Draw a thin rule along each row's baseline. Default `true`. */
|
|
2129
|
+
baseline?: boolean;
|
|
2130
|
+
baselineStroke?: Color;
|
|
2131
|
+
baselineWidth?: number;
|
|
2132
|
+
/** `n=<count>` per row, anchored inline at the row baseline by default. */
|
|
2133
|
+
showCounts?: boolean;
|
|
2134
|
+
countsAnchor?: "outside" | "inline";
|
|
2135
|
+
/** Pixel offset for the counts label. Default 4 (inline) / 28 (outside, vertical) / 32 (outside, horizontal). */
|
|
2136
|
+
countsOffset?: number;
|
|
2137
|
+
countsFontSize?: number;
|
|
2138
|
+
countsColor?: Color;
|
|
2139
|
+
/** Solid fill for the silhouette. Default theme palette[0] (overridden by chart color scale when `color` is set). */
|
|
2140
|
+
fill?: Color;
|
|
2141
|
+
fillAlpha?: number;
|
|
2142
|
+
/** Silhouette outline. Default theme text color. */
|
|
2143
|
+
stroke?: Color;
|
|
2144
|
+
strokeWidth?: number;
|
|
2145
|
+
/** Inner-band padding when dodging via `color`. Default `0.05`. */
|
|
2146
|
+
groupPadding?: number;
|
|
2147
|
+
whisker?: WhiskerRule;
|
|
2148
|
+
quantile?: QuantileMethod;
|
|
2149
|
+
label?: string;
|
|
2150
|
+
}
|
|
2151
|
+
declare function ridgeline<T>(channels: RidgelineChannels<T>, options?: RidgelineOptions): Geom<T>;
|
|
2152
|
+
//#endregion
|
|
2153
|
+
//#region src/grammar/geoms/tile.d.ts
|
|
2154
|
+
interface TileChannels<T> {
|
|
2155
|
+
x: Aes<T, string | number | Date>;
|
|
2156
|
+
y: Aes<T, string | number | Date>;
|
|
2157
|
+
/**
|
|
2158
|
+
* Continuous fill — typically a numeric column. Drives the chart's color
|
|
2159
|
+
* scale (legend renders as a continuous color bar). For a per-cell constant
|
|
2160
|
+
* color, pass `options.fill` instead and omit this channel.
|
|
2161
|
+
*/
|
|
2162
|
+
fill?: Aes<T, unknown>;
|
|
2163
|
+
}
|
|
2164
|
+
interface TileNAOptions {
|
|
2165
|
+
/** Fill for missing/non-finite values. When unset, NA cells are skipped. */
|
|
2166
|
+
fill?: Color;
|
|
2167
|
+
}
|
|
2168
|
+
interface TileOptions<T = unknown> {
|
|
2169
|
+
/**
|
|
2170
|
+
* Constant cell color when no `fill` channel is mapped. Ignored when
|
|
2171
|
+
* `channels.fill` is present (in which case the color scale supplies the
|
|
2172
|
+
* fill).
|
|
2173
|
+
*/
|
|
2174
|
+
fill?: Color;
|
|
2175
|
+
/** Horizontal/vertical inset between cells. Default `0`. */
|
|
2176
|
+
padding?: number;
|
|
2177
|
+
/** Per-axis padding override (multi-key form). Wins over `padding`. */
|
|
2178
|
+
paddingX?: number;
|
|
2179
|
+
paddingY?: number;
|
|
2180
|
+
/** Optional border outline per cell. */
|
|
2181
|
+
stroke?: Color;
|
|
2182
|
+
strokeWidth?: number;
|
|
2183
|
+
cornerRadius?: number;
|
|
2184
|
+
/**
|
|
2185
|
+
* Per-cell text label. Receives the (numeric) fill value when the `fill`
|
|
2186
|
+
* channel is mapped; receives `NaN` otherwise (in which case you'll
|
|
2187
|
+
* typically derive the label from the datum directly).
|
|
2188
|
+
*/
|
|
2189
|
+
showValues?: (value: number, datum: T, index: number) => string;
|
|
2190
|
+
labelColor?: Color;
|
|
2191
|
+
labelFontSize?: number;
|
|
2192
|
+
/**
|
|
2193
|
+
* Skip per-cell labels when the projected cell is below this pixel size on
|
|
2194
|
+
* either axis. Labels at small cell sizes are unreadable smudges and the
|
|
2195
|
+
* shaping cost dominates frame time at high cell counts. Default: unset
|
|
2196
|
+
* (every cell labeled). A value around `1.5 * labelFontSize` is a sensible
|
|
2197
|
+
* floor for legibility.
|
|
2198
|
+
*/
|
|
2199
|
+
minLabelCellPx?: number;
|
|
2200
|
+
/**
|
|
2201
|
+
* For numeric/time x or y axes only — the implicit cell width/height in
|
|
2202
|
+
* domain units. When omitted, the cell extent is inferred from the
|
|
2203
|
+
* smallest gap between sorted unique values in the data.
|
|
2204
|
+
*/
|
|
2205
|
+
cellWidth?: number;
|
|
2206
|
+
cellHeight?: number;
|
|
2207
|
+
/** Missing-value handling. */
|
|
2208
|
+
na?: TileNAOptions;
|
|
2209
|
+
label?: string;
|
|
2210
|
+
}
|
|
2211
|
+
declare function tile<T>(channels: TileChannels<T>, options?: TileOptions<T>): Geom<T>;
|
|
2212
|
+
//#endregion
|
|
2213
|
+
//#region src/grammar/geoms/aggregate.d.ts
|
|
2214
|
+
type AggregateBinBy = "x" | "y";
|
|
2215
|
+
type AggregateBinSize = number | "auto" | ((info: AutoBinSizeInfo) => number);
|
|
2216
|
+
interface AutoBinSizeInfo {
|
|
2217
|
+
/** Pixel span of the binned axis (positive). */
|
|
2218
|
+
pixelSpan: number;
|
|
2219
|
+
/** Domain span of the binned axis in axis units (positive). For time scales, ms. */
|
|
2220
|
+
domainSpan: number;
|
|
2221
|
+
/** `pixelSpan / domainSpan` — pixels per domain unit on the binned axis. */
|
|
2222
|
+
pixelsPerUnit: number;
|
|
2223
|
+
}
|
|
2224
|
+
type AggregateSummaryKind = "mean" | "median" | "count" | "sum" | "first" | "last";
|
|
2225
|
+
interface AggregateBinView<T> {
|
|
2226
|
+
/** Values from the *non-binned* axis, in input order within this bin. */
|
|
2227
|
+
values: readonly number[];
|
|
2228
|
+
/** Source items inside this bin, in input order. */
|
|
2229
|
+
items: readonly T[];
|
|
2230
|
+
/** Count after filter. */
|
|
2231
|
+
count: number;
|
|
2232
|
+
/** Bin's lower edge on the binned axis (inclusive). */
|
|
2233
|
+
lo: number;
|
|
2234
|
+
/** Bin's upper edge on the binned axis (exclusive, except the final bin). */
|
|
2235
|
+
hi: number;
|
|
2236
|
+
}
|
|
2237
|
+
type AggregateSummary<T> = AggregateSummaryKind | ((bin: AggregateBinView<T>) => number);
|
|
2238
|
+
/** Result of a bundle summary — one center + a [lo, hi] range per bin. */
|
|
2239
|
+
interface AggregateBundleResult {
|
|
2240
|
+
center: number;
|
|
2241
|
+
lo: number;
|
|
2242
|
+
hi: number;
|
|
2243
|
+
}
|
|
2244
|
+
type AggregateBundleSummaryKind = "mean+ci" | "median+iqr";
|
|
2245
|
+
/**
|
|
2246
|
+
* Bundle summaries emit `{ center, lo, hi }` per bin and pair with the
|
|
2247
|
+
* `interval` or `ribbon` inner geom. Built-in kinds plus a quantile triple
|
|
2248
|
+
* `{ quantiles: [loQ, centerQ, hiQ] }` (e.g. `[0.1, 0.5, 0.9]` for an 80%
|
|
2249
|
+
* range) or a custom function returning the bundle directly.
|
|
2250
|
+
*/
|
|
2251
|
+
type AggregateBundleSummary<T> = AggregateBundleSummaryKind | {
|
|
2252
|
+
quantiles: readonly [number, number, number];
|
|
2253
|
+
} | ((bin: AggregateBinView<T>) => AggregateBundleResult);
|
|
2254
|
+
interface AggregateChannels<T> {
|
|
2255
|
+
x: Aes<T, number | Date>;
|
|
2256
|
+
y: Aes<T, number | Date>;
|
|
2257
|
+
}
|
|
2258
|
+
type AggregateInnerGeom = "point" | "line" | "bar" | "interval" | "ribbon";
|
|
2259
|
+
interface AggregateOptions<T> {
|
|
2260
|
+
/** Axis to slide along. Default `"x"`. */
|
|
2261
|
+
binBy?: AggregateBinBy;
|
|
2262
|
+
/** Bin width in domain units; `"auto"` targets `~autoTargetPx` px. Default `"auto"`. */
|
|
2263
|
+
binSize?: AggregateBinSize;
|
|
2264
|
+
/**
|
|
2265
|
+
* Reduction applied per bin. Scalar kinds (`"mean"`, `"median"`, …) pair
|
|
2266
|
+
* with `geom: "point" | "line" | "bar"`. Bundle kinds (`"mean+ci"`,
|
|
2267
|
+
* `"median+iqr"`, `{ quantiles }`, function-returning-`{center, lo, hi}`)
|
|
2268
|
+
* pair with `geom: "interval" | "ribbon"`. Default `"mean"`.
|
|
2269
|
+
*/
|
|
2270
|
+
summary?: AggregateSummary<T> | AggregateBundleSummary<T>;
|
|
2271
|
+
/** Row predicate. Rejected rows are excluded from both binning and the
|
|
2272
|
+
* raw-fallback path. */
|
|
2273
|
+
filter?: (datum: T, index: number) => boolean;
|
|
2274
|
+
/** When `avg-points-per-bin < dissolveAt`, render raw geom instead.
|
|
2275
|
+
* Default `1.2`. */
|
|
2276
|
+
dissolveAt?: number;
|
|
2277
|
+
/** Inner mark kind. Default `"point"`. */
|
|
2278
|
+
geom?: AggregateInnerGeom;
|
|
2279
|
+
/** Fill / stroke applied to every emitted mark. */
|
|
2280
|
+
fill?: Color;
|
|
2281
|
+
stroke?: Color;
|
|
2282
|
+
strokeWidth?: number;
|
|
2283
|
+
/** Point-specific. */
|
|
2284
|
+
radius?: number;
|
|
2285
|
+
shape?: PointShapeKind;
|
|
2286
|
+
/** Line-specific. */
|
|
2287
|
+
curve?: LineCurve;
|
|
2288
|
+
/** Target pixels per bin for `"auto"` sizing. Default `7`. */
|
|
2289
|
+
autoTargetPx?: number;
|
|
2290
|
+
/** Display label for legend / hit-test (forwarded to inner mark). */
|
|
2291
|
+
label?: string;
|
|
2292
|
+
/**
|
|
2293
|
+
* Confidence level for the `"mean+ci"` bundle summary. Default `0.95`.
|
|
2294
|
+
* Ignored for other summaries.
|
|
2295
|
+
*/
|
|
2296
|
+
ciLevel?: number;
|
|
2297
|
+
/** Interval-specific: render perpendicular caps. Default `true`. */
|
|
2298
|
+
caps?: boolean;
|
|
2299
|
+
/** Interval-specific: cap length in pixels. Default `6`. */
|
|
2300
|
+
capWidth?: number;
|
|
2301
|
+
/** Ribbon-specific: fill alpha override (otherwise theme.marks.ribbonFillAlpha). */
|
|
2302
|
+
fillAlpha?: number;
|
|
2303
|
+
}
|
|
2304
|
+
declare function aggregate<T>(channels: AggregateChannels<T>, options?: AggregateOptions<T>): Geom<T>;
|
|
2305
|
+
//#endregion
|
|
2306
|
+
//#region src/grammar/chart.d.ts
|
|
2307
|
+
type Row = Record<string, unknown>;
|
|
2308
|
+
interface PlotSpec<T> {
|
|
2309
|
+
data: readonly T[] | Signal<readonly T[]>;
|
|
2310
|
+
width?: number;
|
|
2311
|
+
height?: number;
|
|
2312
|
+
background?: Color;
|
|
2313
|
+
padding?: Padding;
|
|
2314
|
+
/**
|
|
2315
|
+
* Inner padding inside the plot frame, in pixels. Adds slack between the
|
|
2316
|
+
* axis lines and the data — as if the view were zoomed out a bit. Accepts a
|
|
2317
|
+
* single number applied to all sides, or per-side overrides. Different from
|
|
2318
|
+
* `padding`, which is the *outer* canvas inset before axes/legend/title.
|
|
2319
|
+
*/
|
|
2320
|
+
framePadding?: number | {
|
|
2321
|
+
top?: number;
|
|
2322
|
+
right?: number;
|
|
2323
|
+
bottom?: number;
|
|
2324
|
+
left?: number;
|
|
2325
|
+
};
|
|
2326
|
+
device?: GPUDevice;
|
|
2327
|
+
/** Initial theme; can be replaced via `.theme(...)`. */
|
|
2328
|
+
theme?: Theme;
|
|
2329
|
+
}
|
|
2330
|
+
interface AxisSpec {
|
|
2331
|
+
title?: string | {
|
|
2332
|
+
text: string;
|
|
2333
|
+
maxWidth?: number;
|
|
2334
|
+
};
|
|
2335
|
+
format?: AxisTickFormatter;
|
|
2336
|
+
/**
|
|
2337
|
+
* How many ticks to render:
|
|
2338
|
+
* - `number` — target count (default 5).
|
|
2339
|
+
* - `"auto"` — pick the count from the axis's pixel span (~80px/tick
|
|
2340
|
+
* horizontal, ~50px/tick vertical). Useful for time-series so dense
|
|
2341
|
+
* per-day ticks decay to weeks / months / quarters as the view widens.
|
|
2342
|
+
* - `{ interval, step? }` — explicit time interval (time scales only).
|
|
2343
|
+
* `interval: "quarter"` is sugar for `month, step: 3`.
|
|
2344
|
+
*/
|
|
2345
|
+
ticks?: TickSpec;
|
|
2346
|
+
gridLines?: boolean;
|
|
2347
|
+
/** Draw the axis line itself (the spine along the plot frame). Default `true`. */
|
|
2348
|
+
axisLine?: boolean;
|
|
2349
|
+
label?: {
|
|
2350
|
+
maxWidth?: number;
|
|
2351
|
+
};
|
|
2352
|
+
/**
|
|
2353
|
+
* Auto-decimate tick labels until they no longer visually overlap.
|
|
2354
|
+
* `"auto"` measures the formatted labels and inflates the effective
|
|
2355
|
+
* `labelStep` accordingly. Useful for dense band axes (≥15 categories)
|
|
2356
|
+
* and time axes whose density shifts under zoom. Default off — opt in
|
|
2357
|
+
* per axis.
|
|
2358
|
+
*/
|
|
2359
|
+
labelCollision?: "auto";
|
|
2360
|
+
}
|
|
2361
|
+
interface AxesSpec {
|
|
2362
|
+
x?: AxisSpec;
|
|
2363
|
+
y?: AxisSpec;
|
|
2364
|
+
}
|
|
2365
|
+
/**
|
|
2366
|
+
* Chart title / subtitle. Each accepts a string or `{ text, maxWidth }` —
|
|
2367
|
+
* the object form clips with an ellipsis when the rendered text exceeds the
|
|
2368
|
+
* given pixel width.
|
|
2369
|
+
*/
|
|
2370
|
+
interface TitleSpec {
|
|
2371
|
+
title?: string | {
|
|
2372
|
+
text: string;
|
|
2373
|
+
maxWidth?: number;
|
|
2374
|
+
};
|
|
2375
|
+
subtitle?: string | {
|
|
2376
|
+
text: string;
|
|
2377
|
+
maxWidth?: number;
|
|
2378
|
+
};
|
|
2379
|
+
}
|
|
2380
|
+
/**
|
|
2381
|
+
* Float-over-plot position. `x` and `y` are normalized to the plot frame
|
|
2382
|
+
* (`0..1`); `justify` controls which corner of the legend's bbox lands on
|
|
2383
|
+
* that point. Inspired by ggplot2's `legend.position = c(x, y)`.
|
|
2384
|
+
*/
|
|
2385
|
+
interface LegendInsidePosition {
|
|
2386
|
+
inside: {
|
|
2387
|
+
x: number;
|
|
2388
|
+
y: number;
|
|
2389
|
+
};
|
|
2390
|
+
/** Default `"start"` — top-left of legend lands on the point. */
|
|
2391
|
+
justify?: {
|
|
2392
|
+
x?: "start" | "center" | "end";
|
|
2393
|
+
y?: "start" | "center" | "end";
|
|
2394
|
+
};
|
|
2395
|
+
}
|
|
2396
|
+
type LegendPosition = "top" | "right" | "bottom" | "left" | LegendInsidePosition;
|
|
2397
|
+
/**
|
|
2398
|
+
* Channels eligible for being merged into a single legend entry. When merged,
|
|
2399
|
+
* each domain value's swatch shows the resolved value from every listed scale
|
|
2400
|
+
* — e.g. `merge: ["color", "shape"]` produces one row per category whose
|
|
2401
|
+
* swatch is colored by the color scale AND shaped by the shape scale.
|
|
2402
|
+
*
|
|
2403
|
+
* `size` participation is supported only when another categorical channel is
|
|
2404
|
+
* also in the merge list (the entries are still iterated over the categorical
|
|
2405
|
+
* domain; size is sampled from its numeric range at evenly-spaced positions).
|
|
2406
|
+
*/
|
|
2407
|
+
type LegendMergeChannel = "color" | "shape" | "size" | "borderStyle" | "overlayGlyph";
|
|
2408
|
+
interface LegendSpec {
|
|
2409
|
+
/** Disable the auto-legend. */
|
|
2410
|
+
show?: boolean;
|
|
2411
|
+
/**
|
|
2412
|
+
* Where the legend sits. Outer slots: `"top" | "right" | "bottom" | "left"`.
|
|
2413
|
+
* For an over-plot legend, pass `{ inside: { x, y } }` with `x`/`y` in `0..1`
|
|
2414
|
+
* (plot-frame coords). Default depends on legend type — `"right"` for
|
|
2415
|
+
* continuous color bars, `"top"` for categorical swatches.
|
|
2416
|
+
*/
|
|
2417
|
+
position?: LegendPosition;
|
|
2418
|
+
/** Optional title rendered above the legend entries / color bar. */
|
|
2419
|
+
title?: string;
|
|
2420
|
+
/** Override color-bar long-axis pixel length. Default 160. */
|
|
2421
|
+
length?: number;
|
|
2422
|
+
/** Override color-bar thickness. Default 12. */
|
|
2423
|
+
thickness?: number;
|
|
2424
|
+
/** Continuous legend — major tick count target. Default `5`. */
|
|
2425
|
+
ticks?: number;
|
|
2426
|
+
/** Continuous legend — explicit major tick values (override `ticks`). */
|
|
2427
|
+
tickValues?: readonly number[];
|
|
2428
|
+
/**
|
|
2429
|
+
* Continuous legend — minor (unlabeled) tick marks. Number subdivides each
|
|
2430
|
+
* major interval (`2` = one minor halfway); array places ticks explicitly.
|
|
2431
|
+
*/
|
|
2432
|
+
minorTicks?: number | readonly number[];
|
|
2433
|
+
/**
|
|
2434
|
+
* Continuous legend — render a tick label every `N`th major tick.
|
|
2435
|
+
* Default `1`. Combine with `minorTicks` for "lines every 0.5, labels
|
|
2436
|
+
* every 1.0" style guides.
|
|
2437
|
+
*/
|
|
2438
|
+
labelStep?: number;
|
|
2439
|
+
/** Continuous legend — tick label formatter. */
|
|
2440
|
+
format?: (value: number) => string;
|
|
2441
|
+
/**
|
|
2442
|
+
* Continuous legend — override the color space used to interpolate the
|
|
2443
|
+
* palette stops for the bar's gradient. Falls back to the chart's color
|
|
2444
|
+
* scale (which itself defaults to `theme.paletteBlendSpace = "oklch"`).
|
|
2445
|
+
*/
|
|
2446
|
+
blendSpace?: _$insomni.BlendSpace;
|
|
2447
|
+
/**
|
|
2448
|
+
* Merge the listed aesthetic channels into a single combined legend. When
|
|
2449
|
+
* provided, every listed channel must encode the same field (the consumer
|
|
2450
|
+
* is asserting this) and the merged legend iterates the primary scale's
|
|
2451
|
+
* domain (priority: color → shape → borderStyle → overlayGlyph). Each
|
|
2452
|
+
* entry's swatch combines the resolved values across every listed scale.
|
|
2453
|
+
*
|
|
2454
|
+
* Channels that are listed but have no active scale on the chart are
|
|
2455
|
+
* silently skipped — they contribute nothing to the swatch. Omitting this
|
|
2456
|
+
* option leaves the default behavior unchanged (color-only legend).
|
|
2457
|
+
*/
|
|
2458
|
+
merge?: readonly LegendMergeChannel[];
|
|
2459
|
+
}
|
|
2460
|
+
type ScaleOptionsByChannel<C extends Channel> = C extends "x" | "y" ? PositionScaleOptions : C extends "color" ? ColorScaleOptions<unknown> : C extends "size" ? SizeScaleOptions : C extends "alpha" ? AlphaScaleOptions : C extends "shape" ? ShapeScaleOptions : never;
|
|
2461
|
+
interface TransitionsConfig {
|
|
2462
|
+
/** Duration in milliseconds. Default: theme.motion.data duration (240ms). */
|
|
2463
|
+
duration?: number;
|
|
2464
|
+
/** Stable key for matching rows across data refreshes. Required for enter animations. */
|
|
2465
|
+
key?: (datum: unknown, index: number) => string | number;
|
|
2466
|
+
}
|
|
2467
|
+
/** Handle exposed on MountedPlot to request manual transitions. */
|
|
2468
|
+
interface TransitionsHandle {
|
|
2469
|
+
/** Trigger a transition on the next draw (e.g. after a scale domain change). */
|
|
2470
|
+
requestTransition(): void;
|
|
2471
|
+
}
|
|
2472
|
+
interface MountPlotOptions<T> {
|
|
2473
|
+
/**
|
|
2474
|
+
* GPU device. Required when the mount has to create a `Renderer2D` or
|
|
2475
|
+
* `GlyphAtlas` (i.e. when you don't pass them yourself). Either source
|
|
2476
|
+
* works — `plot({ device })` or `mount(canvas, { device })`.
|
|
2477
|
+
*/
|
|
2478
|
+
device?: GPUDevice;
|
|
2479
|
+
/**
|
|
2480
|
+
* Builder closure called on every `invalidate()`. Use this when chart
|
|
2481
|
+
* settings live in module-scope state (controls, signals, etc.) and you
|
|
2482
|
+
* want the chart to be re-derived on each draw. The closure should return
|
|
2483
|
+
* a fresh `Chart<T>` (typically by calling the same `plot().layer()...`
|
|
2484
|
+
* chain that produced this chart).
|
|
2485
|
+
*
|
|
2486
|
+
* If omitted, the mount renders the chart you mounted on, statically.
|
|
2487
|
+
* Either way, `handle.update(newChart | newBuilder)` swaps it.
|
|
2488
|
+
*/
|
|
2489
|
+
build?: () => Chart<T>;
|
|
2490
|
+
/**
|
|
2491
|
+
* Use an externally owned renderer. The mount won't call `setBackground`,
|
|
2492
|
+
* `resize`, `setDpr`, or `destroy()` on it — those become the caller's
|
|
2493
|
+
* responsibility. Useful for sharing a single renderer across multiple
|
|
2494
|
+
* charts or compositing a chart over a world-space scene.
|
|
2495
|
+
*/
|
|
2496
|
+
renderer?: Renderer2D;
|
|
2497
|
+
/**
|
|
2498
|
+
* External layers (axis under, marks middle, hud over). Mount won't clear
|
|
2499
|
+
* them outside the pipeline. The optional `overlay` layer sits on top of the
|
|
2500
|
+
* hud and carries the cursor-driven overlays (tooltip / crosshair / brush /
|
|
2501
|
+
* menu); omit it and the mount creates its own.
|
|
2502
|
+
*/
|
|
2503
|
+
layers?: {
|
|
2504
|
+
axis: Layer;
|
|
2505
|
+
marks: Layer;
|
|
2506
|
+
hud: Layer;
|
|
2507
|
+
overlay?: Layer;
|
|
2508
|
+
};
|
|
2509
|
+
/**
|
|
2510
|
+
* Extra layers rendered alongside the chart's own layers. Called each draw
|
|
2511
|
+
* to read the current list, so callers can lazy-create or swap layers
|
|
2512
|
+
* without re-mounting. Layers returned here are NOT cleared by the chart
|
|
2513
|
+
* pipeline — they persist across draws until the caller clears them
|
|
2514
|
+
* themselves. Use this for retained, world-anchored content (large label
|
|
2515
|
+
* sets that ride the camera, scatter overlays driven by a separate camera
|
|
2516
|
+
* viewport, etc.) where per-frame re-emission would dominate CPU cost.
|
|
2517
|
+
*
|
|
2518
|
+
* Two slots:
|
|
2519
|
+
* - `belowMarks`: rendered after axes, before chart marks. Behind data.
|
|
2520
|
+
* - `aboveMarks`: rendered after chart marks, before the HUD. Above
|
|
2521
|
+
* data but below tooltips / brushes / interactive overlays.
|
|
2522
|
+
*/
|
|
2523
|
+
extraLayers?: () => {
|
|
2524
|
+
belowMarks?: readonly Layer[];
|
|
2525
|
+
aboveMarks?: readonly Layer[];
|
|
2526
|
+
};
|
|
2527
|
+
/** Fixed width (CSS px). When set with `height`, disables auto-resize by default. */
|
|
2528
|
+
width?: number;
|
|
2529
|
+
/** Fixed height (CSS px). When set with `width`, disables auto-resize by default. */
|
|
2530
|
+
height?: number;
|
|
2531
|
+
/** Override DPR. Default: `window.devicePixelRatio`. */
|
|
2532
|
+
dpr?: number;
|
|
2533
|
+
/** Track canvas size via `ResizeObserver`. Default: `true` unless `width` and `height` are both set. */
|
|
2534
|
+
autoResize?: boolean;
|
|
2535
|
+
/** Run an internal `requestAnimationFrame` loop. Default `true`. Set false to call `update()` from your own loop. */
|
|
2536
|
+
autoFrame?: boolean;
|
|
2537
|
+
/** Pause draws while `document.hidden`. Default `true`. */
|
|
2538
|
+
pauseOnHidden?: boolean;
|
|
2539
|
+
/** Background override. Falls back to `chart.background` then `theme.background`. */
|
|
2540
|
+
background?: Color;
|
|
2541
|
+
/** Per-frame CPU/GPU timing callback. Forwarded to the underlying `Renderer2D`. */
|
|
2542
|
+
onFrameTiming?: (t: FrameTiming) => void;
|
|
2543
|
+
/** Enable detailed GPU pipeline-level profiling. Forwarded to the underlying `Renderer2D`. */
|
|
2544
|
+
enablePipelineProfiling?: boolean;
|
|
2545
|
+
/**
|
|
2546
|
+
* Default interactions wired into the chart. Pass `false` to disable all of
|
|
2547
|
+
* them. Pass `true` (or omit) to enable the defaults: a hover tooltip on
|
|
2548
|
+
* geoms that support hit-testing (`point` / `bar` / `line` / `area`) plus a
|
|
2549
|
+
* snapping crosshair on continuous x-scale charts. Pass an object to enable
|
|
2550
|
+
* a subset and tune options.
|
|
2551
|
+
*/
|
|
2552
|
+
interactions?: boolean | InteractionsConfig;
|
|
2553
|
+
/**
|
|
2554
|
+
* Animated transitions when data or chart config changes. On by default
|
|
2555
|
+
* (inherits `theme.motion.data` duration and easing). Pass `false` to disable.
|
|
2556
|
+
*/
|
|
2557
|
+
transitions?: boolean | TransitionsConfig;
|
|
2558
|
+
/**
|
|
2559
|
+
* Wire up pan/zoom on the chart's x/y scales. Off by default. Pass `true`
|
|
2560
|
+
* to enable with default zoom limits, or an object to override.
|
|
2561
|
+
*
|
|
2562
|
+
* Behavior when enabled:
|
|
2563
|
+
* - The mount creates a `DataViewport` seeded from the chart's x/y scale
|
|
2564
|
+
* domain options (the values you passed to `.scale("x", { domain })`).
|
|
2565
|
+
* - Pointer events on the canvas pan/zoom the viewport.
|
|
2566
|
+
* - The viewport's visible domains are written back into the chart's x/y
|
|
2567
|
+
* scale options on every draw, so axes/ticks update automatically.
|
|
2568
|
+
* - The viewport is exposed on `MountedPlot.viewport` for read-only
|
|
2569
|
+
* introspection (e.g. a `build:` closure that re-bins data into the
|
|
2570
|
+
* visible domain).
|
|
2571
|
+
*
|
|
2572
|
+
* Requires both x and y scales to be continuous (linear / log / sqrt /
|
|
2573
|
+
* time). Throws if either scale is missing a numeric/date domain.
|
|
2574
|
+
*/
|
|
2575
|
+
panZoom?: boolean | PanZoomConfig;
|
|
2576
|
+
/**
|
|
2577
|
+
* Clip marks to the inner plot panel rect. Default `true`. When on, the
|
|
2578
|
+
* mount sets `marksLayer.setClipRect(plotFrame)` after each pipeline run
|
|
2579
|
+
* so geom rects/lines/etc. don't bleed into axis / legend / title slots.
|
|
2580
|
+
*/
|
|
2581
|
+
clipMarks?: boolean;
|
|
2582
|
+
/**
|
|
2583
|
+
* Damage-tracked partial redraw. On by default — set `false` to opt out,
|
|
2584
|
+
* which renders byte-identically to the classic full-frame path.
|
|
2585
|
+
*
|
|
2586
|
+
* When on (and the mount owns its renderer), the renderer is given a
|
|
2587
|
+
* persistent backbuffer and the static marks are baked to a texture, so
|
|
2588
|
+
* cursor-driven overlays (tooltip / crosshair / brush / menu) repaint only
|
|
2589
|
+
* their own damage rect instead of clearing + re-compiling the whole chart
|
|
2590
|
+
* on every pointer move. View-changing events (data, pan/zoom, resize,
|
|
2591
|
+
* selection, legend toggle, transitions) still run a full frame and re-bake.
|
|
2592
|
+
*
|
|
2593
|
+
* Silently ignored when an external `renderer` or `layers` is supplied (the
|
|
2594
|
+
* mount can't reconfigure pieces it doesn't own); only an *explicit*
|
|
2595
|
+
* `partialRedraw: true` in that situation logs a one-time warning.
|
|
2596
|
+
*/
|
|
2597
|
+
partialRedraw?: boolean;
|
|
2598
|
+
}
|
|
2599
|
+
/**
|
|
2600
|
+
* Per-axis pan / zoom enable. Either axis can be silenced independently.
|
|
2601
|
+
* Sugar: `true` ≡ `"xy"`, `false` ≡ `"none"`.
|
|
2602
|
+
*/
|
|
2603
|
+
type PanZoomAxes = "x" | "y" | "xy" | "none";
|
|
2604
|
+
/**
|
|
2605
|
+
* Pan-bound margins, expressed as fractions of the visible span. A bare
|
|
2606
|
+
* number applies to both axes. See `DataPanBoundsOptions` for the full
|
|
2607
|
+
* `{ overshoot, drift }` shape inherited from the viewport.
|
|
2608
|
+
*/
|
|
2609
|
+
type ChartPanBounds = ChartPanBoundsOptions | false;
|
|
2610
|
+
interface ChartPanBoundsOptions {
|
|
2611
|
+
/** Pan-past-content allowance when zoomed in (content > viewport). */
|
|
2612
|
+
overshoot?: number | {
|
|
2613
|
+
x?: number;
|
|
2614
|
+
y?: number;
|
|
2615
|
+
};
|
|
2616
|
+
/** Drift allowance when zoomed out (content ≤ viewport). */
|
|
2617
|
+
drift?: number | {
|
|
2618
|
+
x?: number;
|
|
2619
|
+
y?: number;
|
|
2620
|
+
};
|
|
2621
|
+
}
|
|
2622
|
+
interface PanZoomConfig {
|
|
2623
|
+
/**
|
|
2624
|
+
* Minimum zoom factor relative to the chart's base domain. `1` means the
|
|
2625
|
+
* user cannot zoom *out* past the data extent — a sensible chart default.
|
|
2626
|
+
* Smaller values (e.g. `0.1`) allow zooming out into empty space.
|
|
2627
|
+
*
|
|
2628
|
+
* Default `1` (zoom-out clamped to the data extent).
|
|
2629
|
+
*/
|
|
2630
|
+
minZoom?: number;
|
|
2631
|
+
/**
|
|
2632
|
+
* Maximum zoom factor relative to the chart's base domain. `100` lets the
|
|
2633
|
+
* user zoom in to 1% of the data range — usually a sane floor before axis
|
|
2634
|
+
* ticks and labels collapse.
|
|
2635
|
+
*
|
|
2636
|
+
* Default `100`.
|
|
2637
|
+
*/
|
|
2638
|
+
maxZoom?: number;
|
|
2639
|
+
/**
|
|
2640
|
+
* Pan-bound the visible domain to the chart's base (data) domain. When
|
|
2641
|
+
* zoomed in, panning stops at content edges plus an `overshoot` margin;
|
|
2642
|
+
* when zoomed out far enough that content fits in view, the viewport can
|
|
2643
|
+
* still drift by `drift × visibleSpan`.
|
|
2644
|
+
*
|
|
2645
|
+
* Default `{ overshoot: 0.1 }` (the user can rubber-band 10% past the
|
|
2646
|
+
* data edges but can't drag the chart fully off-screen). Pass `false`
|
|
2647
|
+
* to opt out entirely.
|
|
2648
|
+
*/
|
|
2649
|
+
panBounds?: ChartPanBounds;
|
|
2650
|
+
/**
|
|
2651
|
+
* Lock pan to a subset of axes. Default `"xy"` (both axes pan).
|
|
2652
|
+
*/
|
|
2653
|
+
pan?: PanZoomAxes;
|
|
2654
|
+
/**
|
|
2655
|
+
* Lock zoom to a subset of axes. Default `"xy"` (both axes zoom).
|
|
2656
|
+
*/
|
|
2657
|
+
zoom?: PanZoomAxes;
|
|
2658
|
+
/**
|
|
2659
|
+
* When set, the Y scale's domain is recomputed every frame from whatever
|
|
2660
|
+
* data is currently visible along X (financial-chart "auto-Y" behavior).
|
|
2661
|
+
* Implies `pan: "x"` and `zoom: "x"` — Y becomes read-only.
|
|
2662
|
+
*
|
|
2663
|
+
* `true` uses the default 5% padding around the visible Y extent; pass
|
|
2664
|
+
* `{ padding }` to override (0..0.5).
|
|
2665
|
+
*
|
|
2666
|
+
* The Y scale must still declare an explicit `domain` (used as a fallback
|
|
2667
|
+
* when no data is visible in the current X window).
|
|
2668
|
+
*/
|
|
2669
|
+
yFit?: boolean | {
|
|
2670
|
+
padding?: number;
|
|
2671
|
+
};
|
|
2672
|
+
}
|
|
2673
|
+
interface InteractionsConfig {
|
|
2674
|
+
tooltip?: boolean | TooltipConfig;
|
|
2675
|
+
/**
|
|
2676
|
+
* Hover crosshair (guide line). Default: enabled on charts whose x-scale
|
|
2677
|
+
* is continuous (`linear` / `log` / `sqrt` / `time`); auto-disabled on
|
|
2678
|
+
* band x-scales. Pass `false` to disable, `true` for defaults, or an
|
|
2679
|
+
* object to tune. Snaps to the same hit positions the tooltip uses.
|
|
2680
|
+
*/
|
|
2681
|
+
crosshair?: boolean | CrosshairConfig;
|
|
2682
|
+
/**
|
|
2683
|
+
* Click-to-select. Off by default — selection has app-level semantics so
|
|
2684
|
+
* the chart shouldn't claim it silently. Pass `true` to enable defaults
|
|
2685
|
+
* (plain click replaces, shift toggles, meta/ctrl removes, click-empty
|
|
2686
|
+
* clears) or an object to tune. The active selection is exposed on
|
|
2687
|
+
* `MountedPlot.selected` and surfaces to geoms via `CompileContext.selected`
|
|
2688
|
+
* — selected rows get a stroke ring and unselected rows dim while a
|
|
2689
|
+
* selection is active.
|
|
2690
|
+
*/
|
|
2691
|
+
selection?: boolean | SelectionConfig;
|
|
2692
|
+
/**
|
|
2693
|
+
* Drag-to-rect brush. Off by default — like click-selection, brush semantics
|
|
2694
|
+
* are app-specific. Pass `true` to enable defaults (xy rect, dismiss on
|
|
2695
|
+
* background tap) or an object to tune. The active brushed rows are exposed
|
|
2696
|
+
* on `MountedPlot.brushed`. Brush populates a separate signal from
|
|
2697
|
+
* click-selection so the two coexist with different semantics (range query
|
|
2698
|
+
* vs. discrete pick).
|
|
2699
|
+
*/
|
|
2700
|
+
brush?: boolean | BrushConfig;
|
|
2701
|
+
/**
|
|
2702
|
+
* Legend interactivity. Default: enabled when `interactions` is on.
|
|
2703
|
+
* Enables click-to-toggle visibility of categorical series.
|
|
2704
|
+
*/
|
|
2705
|
+
legend?: boolean | LegendInteractionConfig;
|
|
2706
|
+
/**
|
|
2707
|
+
* Context-menu trigger. Off by default — requires an `onTrigger` handler so
|
|
2708
|
+
* the host app can render its own menu UI. Fires for right-click, touch
|
|
2709
|
+
* long-press (≥500ms), and the keyboard ContextMenu / Shift+F10 keys. The
|
|
2710
|
+
* library only emits the event; menu rendering / positioning stays the
|
|
2711
|
+
* consumer's responsibility.
|
|
2712
|
+
*/
|
|
2713
|
+
contextMenu?: ContextMenuConfig;
|
|
2714
|
+
}
|
|
2715
|
+
interface ContextMenuConfig {
|
|
2716
|
+
/**
|
|
2717
|
+
* Resolution policy for the trigger point. Default `"nearest-point"`.
|
|
2718
|
+
*
|
|
2719
|
+
* - `"nearest-point"`: snap to the nearest mark within its `pickRadius`
|
|
2720
|
+
* (skips region-based geoms like bars). When no mark is within range, the
|
|
2721
|
+
* trigger is **suppressed entirely** — matches the behavior of the hover
|
|
2722
|
+
* tooltip / crosshair (no popup unless something would be highlighted).
|
|
2723
|
+
* - `"any-mark"`: include region-based geoms (bars, histograms, tiles).
|
|
2724
|
+
* Same suppression behavior as `"nearest-point"` when no mark is hit.
|
|
2725
|
+
* - `"background"`: never resolve — `hit`/`datum`/`mark` are always null,
|
|
2726
|
+
* and the trigger always fires. Useful for "add a point here" menus.
|
|
2727
|
+
*/
|
|
2728
|
+
hitMode?: "nearest-point" | "any-mark" | "background";
|
|
2729
|
+
/** Touch long-press hold duration (ms). Default `500`. */
|
|
2730
|
+
holdMs?: number;
|
|
2731
|
+
/** Max pointer movement during long-press hold (CSS px). Default `5`. */
|
|
2732
|
+
slopPx?: number;
|
|
2733
|
+
/**
|
|
2734
|
+
* Menu items. Static array or a per-trigger resolver. When provided, the
|
|
2735
|
+
* library renders a GPU-drawn menu inside the canvas (no DOM, no host
|
|
2736
|
+
* popover required) and routes clicks through `onAction`. When omitted the
|
|
2737
|
+
* library only emits `onTrigger` and rendering is the consumer's problem.
|
|
2738
|
+
*/
|
|
2739
|
+
items?: readonly ContextMenuItem[] | ((info: ContextMenuTriggerPayload) => readonly ContextMenuItem[]);
|
|
2740
|
+
/** Called when an item in the rendered menu is clicked. */
|
|
2741
|
+
onAction?(itemId: string, info: ContextMenuTriggerPayload): void;
|
|
2742
|
+
/** Placement of the rendered menu relative to the trigger point. */
|
|
2743
|
+
placement?: _$insomni.MenuPlacement;
|
|
2744
|
+
/** Style overrides for the rendered menu. */
|
|
2745
|
+
style?: _$insomni.MenuStyle;
|
|
2746
|
+
/**
|
|
2747
|
+
* Low-level trigger callback. Fires even when `items` is set, so consumers
|
|
2748
|
+
* can hook telemetry / aria-live announcements alongside the rendered menu.
|
|
2749
|
+
* Required only when `items` is omitted (otherwise the library has no idea
|
|
2750
|
+
* what menu to show).
|
|
2751
|
+
*/
|
|
2752
|
+
onTrigger?(info: ContextMenuTriggerPayload): void;
|
|
2753
|
+
}
|
|
2754
|
+
interface ContextMenuItem {
|
|
2755
|
+
/** Stable id passed to `onAction`. Ignored for separators. */
|
|
2756
|
+
id: string;
|
|
2757
|
+
/** Display label. Ignored for separators. */
|
|
2758
|
+
label: string;
|
|
2759
|
+
/** Renders as a thin separator line; non-interactive. */
|
|
2760
|
+
separator?: boolean;
|
|
2761
|
+
/** Greyed out; ignored by hover/click. */
|
|
2762
|
+
disabled?: boolean;
|
|
2763
|
+
/** Tinted with the menu's `dangerColor` (destructive actions). */
|
|
2764
|
+
danger?: boolean;
|
|
2765
|
+
/** Optional swatch dot at the start of the row. */
|
|
2766
|
+
swatch?: Color;
|
|
2767
|
+
/** Optional right-aligned shortcut hint (e.g. "⌘D"). */
|
|
2768
|
+
kbd?: string;
|
|
2769
|
+
}
|
|
2770
|
+
interface ContextMenuTriggerPayload {
|
|
2771
|
+
/**
|
|
2772
|
+
* Resolved hit at the trigger point, or `null` for a background trigger /
|
|
2773
|
+
* `hitMode: "background"`.
|
|
2774
|
+
*/
|
|
2775
|
+
hit: HoveredHit | null;
|
|
2776
|
+
/** Convenience: the data row at `hit.dataIndex`, or `null` for background. */
|
|
2777
|
+
datum: unknown | null;
|
|
2778
|
+
/** Convenience: the geom kind that produced the hit. */
|
|
2779
|
+
mark: HoveredHit["geomKind"] | null;
|
|
2780
|
+
/** Element-local CSS px where the menu should anchor. */
|
|
2781
|
+
screenX: number;
|
|
2782
|
+
screenY: number;
|
|
2783
|
+
source: "mouse" | "touch" | "pen" | "keyboard";
|
|
2784
|
+
mods: _$insomni.Mods;
|
|
2785
|
+
originalEvent: Event | null;
|
|
2786
|
+
}
|
|
2787
|
+
interface LegendInteractionConfig {
|
|
2788
|
+
/** Default `0.2` — alpha for hidden series labels/swatches. */
|
|
2789
|
+
dimAlpha?: number;
|
|
2790
|
+
}
|
|
2791
|
+
/**
|
|
2792
|
+
* Semantic accents for `TooltipShorthandRow.accent`. `positive` / `negative`
|
|
2793
|
+
* resolve through `theme.interactions.tooltipAccents`. `neutral` is a
|
|
2794
|
+
* no-op marker — the row uses the default text color. Passing a raw `Color`
|
|
2795
|
+
* bypasses theme tokens entirely.
|
|
2796
|
+
*/
|
|
2797
|
+
type TooltipAccent = "positive" | "negative" | "neutral" | Color;
|
|
2798
|
+
interface TooltipShorthandRow {
|
|
2799
|
+
label?: string;
|
|
2800
|
+
/**
|
|
2801
|
+
* Row value. Numbers / Dates / null / undefined are formatted through the
|
|
2802
|
+
* library's default formatter; strings are emitted verbatim.
|
|
2803
|
+
*/
|
|
2804
|
+
value: string | number | Date | boolean | null | undefined;
|
|
2805
|
+
/** Optional swatch dot to the left of the row. */
|
|
2806
|
+
swatch?: Color;
|
|
2807
|
+
/**
|
|
2808
|
+
* Semantic accent applied to the row's text color (positive/negative tint
|
|
2809
|
+
* for diffs, deltas, status changes). `neutral` is a no-op.
|
|
2810
|
+
*/
|
|
2811
|
+
accent?: TooltipAccent;
|
|
2812
|
+
}
|
|
2813
|
+
/**
|
|
2814
|
+
* Shorthand object form of `TooltipContent`. The grammar normalizes this into
|
|
2815
|
+
* the canvas-tooltip's full `TooltipContent` shape, applying default
|
|
2816
|
+
* formatting to non-string values and resolving accents through the theme.
|
|
2817
|
+
*/
|
|
2818
|
+
interface TooltipContentShorthand {
|
|
2819
|
+
title?: string;
|
|
2820
|
+
rows: readonly TooltipShorthandRow[];
|
|
2821
|
+
}
|
|
2822
|
+
interface TooltipContentInfo<T = unknown> {
|
|
2823
|
+
/** The hovered datum (the row from the geom's data array). */
|
|
2824
|
+
datum: T;
|
|
2825
|
+
/** Index into the data array. */
|
|
2826
|
+
dataIndex: number;
|
|
2827
|
+
/** Geom kind (e.g. `"point"`, `"bar"`, `"line"`). */
|
|
2828
|
+
mark: string;
|
|
2829
|
+
/** Series key when the geom emits multiple segments per row (stacks, dodges). */
|
|
2830
|
+
seriesKey?: string;
|
|
2831
|
+
/**
|
|
2832
|
+
* Resolved aesthetic accessors for the geom. Useful for advanced resolvers
|
|
2833
|
+
* that need to read a channel's raw value or column name — most consumers
|
|
2834
|
+
* can ignore this and just read fields off `datum`.
|
|
2835
|
+
*/
|
|
2836
|
+
channels: Readonly<Record<string, unknown>>;
|
|
2837
|
+
}
|
|
2838
|
+
/**
|
|
2839
|
+
* Override the auto-built tooltip content. Receives the hovered datum and
|
|
2840
|
+
* returns either the canvas-tooltip's full `TooltipContent` (with
|
|
2841
|
+
* `swatch`/`color`/`fontSize` per row), the shorthand `{ title, rows }` form
|
|
2842
|
+
* with optional `accent` tokens, or a plain string (single-row body), or
|
|
2843
|
+
* `null` to fall back to the default channel-driven content.
|
|
2844
|
+
*/
|
|
2845
|
+
type TooltipContentResolver<T = unknown> = (info: TooltipContentInfo<T>) => TooltipContentResult | null | undefined;
|
|
2846
|
+
type TooltipContentResult = TooltipContentShorthand | string;
|
|
2847
|
+
/** One auto-built series row in axis-mode tooltips (mirrors SeriesReadoutRow). */
|
|
2848
|
+
interface AxisTooltipRow {
|
|
2849
|
+
/** Series label (color-channel value, seriesKey, or layer label). */
|
|
2850
|
+
label: string;
|
|
2851
|
+
/** Formatted value at the snapped column. */
|
|
2852
|
+
value: string;
|
|
2853
|
+
/** Raw value at the snapped column (pre-format) for custom transforms. */
|
|
2854
|
+
rawValue: unknown;
|
|
2855
|
+
/** Series swatch color, when resolvable. */
|
|
2856
|
+
color?: Color;
|
|
2857
|
+
/** True for the row whose snapped position is closest to the cursor. */
|
|
2858
|
+
active: boolean;
|
|
2859
|
+
/** seriesKey when the row came from a stacked / dodged segment. */
|
|
2860
|
+
seriesKey?: string;
|
|
2861
|
+
}
|
|
2862
|
+
/** Info handed to the axis-mode tooltip content hook. */
|
|
2863
|
+
interface AxisTooltipInfo {
|
|
2864
|
+
/** Raw snapped column value (the X for `axis:"x"`, the Y for `axis:"y"`). */
|
|
2865
|
+
columnValue: unknown;
|
|
2866
|
+
/** Formatted column value (`axisTitleFormat` / `defaultFormat`). */
|
|
2867
|
+
columnLabel: string;
|
|
2868
|
+
/** Which screen axis we snapped on. */
|
|
2869
|
+
axis: "x" | "y";
|
|
2870
|
+
/** Auto-built series rows (one per series at the snapped column). */
|
|
2871
|
+
rows: readonly AxisTooltipRow[];
|
|
2872
|
+
/**
|
|
2873
|
+
* The snapped datum(s) — one entry per hit-testable layer that produced a
|
|
2874
|
+
* group at this column, in layer order. Each carries the source datum, its
|
|
2875
|
+
* data index, and the layer's mark label, so a consumer can read any field
|
|
2876
|
+
* off a wide row (incl. fields belonging to ribbon/band/text layers that
|
|
2877
|
+
* have no hit tests of their own). For wide rows, `data[0].datum` already
|
|
2878
|
+
* holds every column.
|
|
2879
|
+
*/
|
|
2880
|
+
data: readonly {
|
|
2881
|
+
datum: unknown;
|
|
2882
|
+
dataIndex: number;
|
|
2883
|
+
mark: string;
|
|
2884
|
+
}[];
|
|
2885
|
+
}
|
|
2886
|
+
/**
|
|
2887
|
+
* Axis-mode tooltip content hook. Return a `{ title?, rows }` shorthand (the
|
|
2888
|
+
* same shape the item resolver returns) to REPLACE the auto rows, or
|
|
2889
|
+
* `null` / `undefined` to keep them verbatim. `accent` / `swatch` per row
|
|
2890
|
+
* resolve through the theme exactly like the item path.
|
|
2891
|
+
*/
|
|
2892
|
+
type AxisTooltipContentResolver = (info: AxisTooltipInfo) => TooltipContentShorthand | null | undefined;
|
|
2893
|
+
interface TooltipConfig {
|
|
2894
|
+
showDelay?: number;
|
|
2895
|
+
hideDelay?: number;
|
|
2896
|
+
fadeMs?: number;
|
|
2897
|
+
placement?: "top" | "bottom" | "left" | "right" | "auto";
|
|
2898
|
+
/**
|
|
2899
|
+
* Override the default channel-driven tooltip body. Receives the hovered
|
|
2900
|
+
* datum and returns either:
|
|
2901
|
+
* - a plain string (single-row body, no label)
|
|
2902
|
+
* - a `{ title?, rows: [{label?, value, accent?, swatch?}] }` shorthand —
|
|
2903
|
+
* `accent: "positive" | "negative" | "neutral" | Color` tints the row
|
|
2904
|
+
* text via `theme.interactions.tooltipAccents`
|
|
2905
|
+
* - `null` / `undefined` to fall back to the auto-built content
|
|
2906
|
+
*
|
|
2907
|
+
* The library renders the canvas tooltip primitive — there's no HTML/CSS
|
|
2908
|
+
* surface to style; row colors come from the theme.
|
|
2909
|
+
*
|
|
2910
|
+
* Ignored in `trigger:"axis"` mode (use `axisContent`).
|
|
2911
|
+
*/
|
|
2912
|
+
content?: TooltipContentResolver;
|
|
2913
|
+
/**
|
|
2914
|
+
* Tooltip trigger model. Default `"item"` (today's behavior — one box per
|
|
2915
|
+
* hovered mark, fully backward compatible). `"axis"` turns the tooltip into
|
|
2916
|
+
* a floating, cursor-following unified readout: it snaps to the nearest data
|
|
2917
|
+
* column across ALL hit-testable layers and lists one row per series in a
|
|
2918
|
+
* single box.
|
|
2919
|
+
*/
|
|
2920
|
+
trigger?: "item" | "axis";
|
|
2921
|
+
/**
|
|
2922
|
+
* Which screen axis to snap on in `trigger:"axis"` mode. `"x"` (default) =
|
|
2923
|
+
* nearest-X (vertical time-series — pick the column under the cursor's x).
|
|
2924
|
+
* `"y"` = nearest-Y (horizontal charts — pick the row under the cursor's y).
|
|
2925
|
+
* Ignored when `trigger:"item"`.
|
|
2926
|
+
*/
|
|
2927
|
+
axis?: "x" | "y";
|
|
2928
|
+
/**
|
|
2929
|
+
* Axis-mode content hook. Receives the snapped column plus the auto-built
|
|
2930
|
+
* series rows AND the snapped datum(s), so a consumer can append rows that
|
|
2931
|
+
* are NOT y-series (a wind-direction arrow, a day/night flag, a UV risk
|
|
2932
|
+
* band) or transform the auto rows. Return value REPLACES the auto rows when
|
|
2933
|
+
* non-null; return null/undefined to keep the auto-built rows verbatim.
|
|
2934
|
+
* Ignored unless `trigger:"axis"`.
|
|
2935
|
+
*/
|
|
2936
|
+
axisContent?: AxisTooltipContentResolver;
|
|
2937
|
+
/** Format the snapped column value used as the tooltip title in axis mode. */
|
|
2938
|
+
axisTitleFormat?: (value: unknown) => string;
|
|
2939
|
+
/** Format each auto-built series row's value in axis mode. */
|
|
2940
|
+
axisValueFormat?: (value: unknown) => string;
|
|
2941
|
+
}
|
|
2942
|
+
interface CrosshairConfig {
|
|
2943
|
+
/** Which guide line(s) to draw. Default `"x"` (vertical line tracking cursor). */
|
|
2944
|
+
axis?: "x" | "y" | "xy";
|
|
2945
|
+
/** Stroke color. Default theme.colors.muted at 0.6 alpha. */
|
|
2946
|
+
color?: Color;
|
|
2947
|
+
/** Stroke width in CSS px. Default 1. */
|
|
2948
|
+
width?: number;
|
|
2949
|
+
/**
|
|
2950
|
+
* Track the raw pointer position even between data points (no snap). Useful
|
|
2951
|
+
* for sparse line/area charts where the snapped-to-hit default leaves big
|
|
2952
|
+
* gaps. Snapping still wins when the cursor is over a hit; outside hits the
|
|
2953
|
+
* crosshair follows the cursor within the plot frame. Default `false`.
|
|
2954
|
+
*/
|
|
2955
|
+
followPointer?: boolean;
|
|
2956
|
+
}
|
|
2957
|
+
interface BrushConfig {
|
|
2958
|
+
/** Which axes the brush spans. Default `"xy"`. */
|
|
2959
|
+
axis?: "x" | "y" | "xy";
|
|
2960
|
+
/** Translucent fill. Default theme axis color × 0.12 alpha. */
|
|
2961
|
+
fillColor?: Color;
|
|
2962
|
+
/** Outline color. Default theme axis color × 0.6 alpha. */
|
|
2963
|
+
strokeColor?: Color;
|
|
2964
|
+
/** Outline width in CSS px. Default 1. */
|
|
2965
|
+
strokeWidth?: number;
|
|
2966
|
+
/** Enable edge/corner resize handles. Default `true`. */
|
|
2967
|
+
handles?: boolean;
|
|
2968
|
+
/** Enable drag-the-rect-interior translate. Default `true`. */
|
|
2969
|
+
translate?: boolean;
|
|
2970
|
+
/**
|
|
2971
|
+
* Snap brush rect edges to nearest hit-test position. `true` snaps on the
|
|
2972
|
+
* brush's `axis`; pass `"x"` / `"y"` / `"xy"` to override. Default `false`.
|
|
2973
|
+
*/
|
|
2974
|
+
snap?: boolean | "x" | "y" | "xy";
|
|
2975
|
+
}
|
|
2976
|
+
/**
|
|
2977
|
+
* Read-only view of a `Signal<HoveredHit[]>` exposed on `MountedPlot.brushed`.
|
|
2978
|
+
* Empty array when nothing is brushed; remains an empty array (never `null`)
|
|
2979
|
+
* when brush is disabled. Independent of `selected` — click + brush coexist
|
|
2980
|
+
* with different semantics.
|
|
2981
|
+
*/
|
|
2982
|
+
interface BrushedSignal {
|
|
2983
|
+
get(): readonly HoveredHit[];
|
|
2984
|
+
peek(): readonly HoveredHit[];
|
|
2985
|
+
subscribe(fn: (v: readonly HoveredHit[]) => void): () => void;
|
|
2986
|
+
/** Imperatively clear the active brush. */
|
|
2987
|
+
clear(): void;
|
|
2988
|
+
}
|
|
2989
|
+
interface SelectionConfig {
|
|
2990
|
+
/**
|
|
2991
|
+
* Alpha applied to non-selected marks while a selection is active. Default
|
|
2992
|
+
* `0.3`. Set `1` to disable dimming (selected rows still get a stroke ring).
|
|
2993
|
+
*/
|
|
2994
|
+
dimAlpha?: number;
|
|
2995
|
+
/** Stroke ring color override; defaults to theme.axis.color. */
|
|
2996
|
+
ringColor?: Color;
|
|
2997
|
+
/** Stroke ring width in CSS px. Default 2. */
|
|
2998
|
+
ringWidth?: number;
|
|
2999
|
+
}
|
|
3000
|
+
/**
|
|
3001
|
+
* Read-only view of a `Signal<HoveredHit[]>` exposed on `MountedPlot`. The
|
|
3002
|
+
* array is empty when nothing is selected; `null` is never produced (use
|
|
3003
|
+
* `length === 0` to detect the empty case).
|
|
3004
|
+
*/
|
|
3005
|
+
interface SelectedSignal {
|
|
3006
|
+
get(): readonly HoveredHit[];
|
|
3007
|
+
peek(): readonly HoveredHit[];
|
|
3008
|
+
subscribe(fn: (v: readonly HoveredHit[]) => void): () => void;
|
|
3009
|
+
/** Imperatively clear the active selection. */
|
|
3010
|
+
clear(): void;
|
|
3011
|
+
}
|
|
3012
|
+
/**
|
|
3013
|
+
* Read-only view of a `Signal<ReadonlySet<string>>` exposed on `MountedPlot.hidden`.
|
|
3014
|
+
* Empty set when all series are visible.
|
|
3015
|
+
*/
|
|
3016
|
+
interface HiddenSignal {
|
|
3017
|
+
get(): ReadonlySet<string>;
|
|
3018
|
+
peek(): ReadonlySet<string>;
|
|
3019
|
+
subscribe(fn: (v: ReadonlySet<string>) => void): () => void;
|
|
3020
|
+
/** Clear the hidden set (show all). */
|
|
3021
|
+
clear(): void;
|
|
3022
|
+
}
|
|
3023
|
+
/**
|
|
3024
|
+
* Read-only view of a `Signal<HoveredHit | null>` exposed on `MountedPlot`.
|
|
3025
|
+
* Drops `set`/`update` so callers can subscribe + peek without writing.
|
|
3026
|
+
*/
|
|
3027
|
+
interface HoveredSignal {
|
|
3028
|
+
get(): HoveredHit | null;
|
|
3029
|
+
peek(): HoveredHit | null;
|
|
3030
|
+
subscribe(fn: (v: HoveredHit | null) => void): () => void;
|
|
3031
|
+
}
|
|
3032
|
+
interface MountedPlot<T> {
|
|
3033
|
+
/** Schedule a redraw on the next animation frame. */
|
|
3034
|
+
invalidate(): void;
|
|
3035
|
+
/**
|
|
3036
|
+
* Replace the active chart spec or builder.
|
|
3037
|
+
* - Pass a `Chart<T>` to swap to a static spec.
|
|
3038
|
+
* - Pass `() => Chart<T>` to swap the rebuild closure.
|
|
3039
|
+
* - Pass nothing to force a rebuild via the existing builder.
|
|
3040
|
+
*
|
|
3041
|
+
* When `autoFrame: false`, also draws synchronously.
|
|
3042
|
+
*/
|
|
3043
|
+
update(source?: Chart<T> | (() => Chart<T>)): void;
|
|
3044
|
+
/** Replace the data array (drops any reactive data signal subscription). */
|
|
3045
|
+
setData(data: readonly T[]): void;
|
|
3046
|
+
/**
|
|
3047
|
+
* Manual resize. If `autoResize` is on you usually don't need this.
|
|
3048
|
+
* Pass no args to re-read the canvas's current bounding rect.
|
|
3049
|
+
*/
|
|
3050
|
+
resize(w?: number, h?: number): void;
|
|
3051
|
+
/** Override the background color. Pass `null` to revert to the chart/theme default. */
|
|
3052
|
+
setBackground(color: Color | null): void;
|
|
3053
|
+
/** Static SVG export from the current spec + data. */
|
|
3054
|
+
toSVG(opts?: {
|
|
3055
|
+
width?: number;
|
|
3056
|
+
height?: number;
|
|
3057
|
+
atlas?: GlyphAtlas;
|
|
3058
|
+
}): SVGSVGElement;
|
|
3059
|
+
/** Tear down: cancels the rAF loop, ResizeObserver, signal subs; destroys what we created. */
|
|
3060
|
+
destroy(): void;
|
|
3061
|
+
readonly renderer: Renderer2D;
|
|
3062
|
+
readonly axisLayer: Layer;
|
|
3063
|
+
readonly marksLayer: Layer;
|
|
3064
|
+
readonly hudLayer: Layer;
|
|
3065
|
+
/** Cursor-overlay layer (tooltip / crosshair / brush / menu), above the hud. */
|
|
3066
|
+
readonly overlayLayer: Layer;
|
|
3067
|
+
readonly invalidator: Invalidator;
|
|
3068
|
+
/**
|
|
3069
|
+
* Read-only signal carrying the currently hovered hit (geom kind, dataIndex,
|
|
3070
|
+
* data array reference, snapped position) or `null` when nothing is
|
|
3071
|
+
* hovered. Updated synchronously from pointer events. Geoms also receive
|
|
3072
|
+
* the same value via `CompileContext.hovered` during compile.
|
|
3073
|
+
*/
|
|
3074
|
+
readonly hovered: HoveredSignal;
|
|
3075
|
+
/**
|
|
3076
|
+
* Read-only signal carrying the currently selected rows (one `HoveredHit`
|
|
3077
|
+
* per selected datum). Empty array when nothing is selected; remains an
|
|
3078
|
+
* empty array (never `null`) when selection is disabled. Geoms receive
|
|
3079
|
+
* the same payload via `CompileContext.selected` during compile.
|
|
3080
|
+
*/
|
|
3081
|
+
readonly selected: SelectedSignal;
|
|
3082
|
+
/**
|
|
3083
|
+
* Read-only signal carrying the rows currently inside the brush rect.
|
|
3084
|
+
* Empty array when nothing is brushed (or when brush is disabled).
|
|
3085
|
+
* Independent of `selected`.
|
|
3086
|
+
*/
|
|
3087
|
+
readonly brushed: BrushedSignal;
|
|
3088
|
+
/**
|
|
3089
|
+
* Read-only signal carrying the set of series keys currently hidden via
|
|
3090
|
+
* legend toggle. Empty set when all series are visible; remains an empty
|
|
3091
|
+
* set (never `null`) when legend interaction is disabled.
|
|
3092
|
+
*/
|
|
3093
|
+
readonly hidden: HiddenSignal;
|
|
3094
|
+
/**
|
|
3095
|
+
* Handle for programmatic transition control. Always present even when
|
|
3096
|
+
* transitions are disabled (calls become no-ops in that case).
|
|
3097
|
+
*/
|
|
3098
|
+
readonly transitions: TransitionsHandle;
|
|
3099
|
+
/** CSS-pixel width currently rendered. */
|
|
3100
|
+
readonly width: number;
|
|
3101
|
+
/** CSS-pixel height currently rendered. */
|
|
3102
|
+
readonly height: number;
|
|
3103
|
+
/** Active device-pixel ratio. */
|
|
3104
|
+
readonly dpr: number;
|
|
3105
|
+
/** Combined shape count across the three internal layers. */
|
|
3106
|
+
readonly shapeCount: number;
|
|
3107
|
+
/** Combined triangle count across the three internal layers. */
|
|
3108
|
+
readonly triangleCount: number;
|
|
3109
|
+
/** True when `invalidate()` has been called and a draw hasn't happened yet. */
|
|
3110
|
+
readonly needsFrame: boolean;
|
|
3111
|
+
/**
|
|
3112
|
+
* Inner plot panel rect (absolute element-CSS px) — the area enclosed by
|
|
3113
|
+
* the axes, where geom marks draw. Updated each frame from the pipeline.
|
|
3114
|
+
* For faceted charts this is the union of all panel frames. Returns a
|
|
3115
|
+
* zero-rect before the first draw.
|
|
3116
|
+
*/
|
|
3117
|
+
readonly plotFrame: Frame;
|
|
3118
|
+
/**
|
|
3119
|
+
* The chart's pan/zoom viewport, present only when `panZoom` was enabled
|
|
3120
|
+
* on mount. Lets the caller subscribe to view changes, read the visible
|
|
3121
|
+
* domain (e.g. for re-binning data), or call `.reset()`. The mount keeps
|
|
3122
|
+
* its frame in sync with `plotFrame` automatically.
|
|
3123
|
+
*/
|
|
3124
|
+
readonly viewport: DataViewport<number, number> | null;
|
|
3125
|
+
/**
|
|
3126
|
+
* Wire a `createRangePresets` controller against this chart's viewport and
|
|
3127
|
+
* optionally render a chip strip into a host element. Throws if `panZoom`
|
|
3128
|
+
* was not enabled at mount time (no `viewport` to drive).
|
|
3129
|
+
*
|
|
3130
|
+
* The headless flow is preserved — omit `opts.ui` and you get the same
|
|
3131
|
+
* controller (`setActive` / `getActive` / `subscribe`) without any DOM
|
|
3132
|
+
* construction. Strings in `presets` are expanded to `timePreset(key)`.
|
|
3133
|
+
*/
|
|
3134
|
+
attachRangePresets(opts: AttachRangePresetsOptions): AttachedRangePresets;
|
|
3135
|
+
/**
|
|
3136
|
+
* Attach a dygraph-style pinned legend — a side panel that updates with each
|
|
3137
|
+
* series' value at the cursor's snapped x. Reuses the chart's compiled
|
|
3138
|
+
* hit-tests (no separate spatial index) so the snap stays aligned with what
|
|
3139
|
+
* the tooltip would have shown.
|
|
3140
|
+
*
|
|
3141
|
+
* Headless: omit `opts.ui` and observe via `subscribe()` to render your own
|
|
3142
|
+
* UI. With `opts.ui` set, a minimal absolute-positioned panel is appended
|
|
3143
|
+
* into the mount element and disposed alongside this readout.
|
|
3144
|
+
*/
|
|
3145
|
+
attachSeriesReadout(opts: AttachSeriesReadoutOptions): AttachedSeriesReadout;
|
|
3146
|
+
/**
|
|
3147
|
+
* Wire a drag-to-rect brush onto the chart imperatively. Mirrors the
|
|
3148
|
+
* declarative `interactions: { brush: ... }` config path — the same
|
|
3149
|
+
* `MountedPlot.brushed` signal observes the brushed set — but lets a
|
|
3150
|
+
* consumer attach (and later dispose) a brush after mount without
|
|
3151
|
+
* rebuilding the chart spec.
|
|
3152
|
+
*
|
|
3153
|
+
* Throws if a brush is already configured on this mount, either via
|
|
3154
|
+
* `interactions.brush` or a prior `attachBrush` call that hasn't been
|
|
3155
|
+
* disposed. The two surfaces are mutually exclusive: the brush rect is a
|
|
3156
|
+
* singleton.
|
|
3157
|
+
*/
|
|
3158
|
+
attachBrush(opts: AttachBrushOptions): AttachedBrush;
|
|
3159
|
+
/**
|
|
3160
|
+
* Convert an event-relative canvas coordinate (e.g. `event.offsetX/Y`, or
|
|
3161
|
+
* `clientX - rect.left`) into the chart's data space, routing through the
|
|
3162
|
+
* active coord's `unproject` (identity for Cartesian, polar inverse for
|
|
3163
|
+
* `coordPolar` / `coordRadial`).
|
|
3164
|
+
*
|
|
3165
|
+
* Returns `null` when:
|
|
3166
|
+
* - the point falls outside the active plot frame, or
|
|
3167
|
+
* - `coord.unproject` returns null (e.g. polar point outside the radius
|
|
3168
|
+
* band), or
|
|
3169
|
+
* - the pipeline has not produced scales yet (no draw has happened), or
|
|
3170
|
+
* - either position scale lacks an `invert` (band scales).
|
|
3171
|
+
*
|
|
3172
|
+
* `dataX` / `dataY` are the result of `xScale.axisScale.invert(plotFrameX)`
|
|
3173
|
+
* and `yScale.axisScale.invert(plotFrameY)` respectively. `plotFrameX/Y` are
|
|
3174
|
+
* relative to the plot frame's top-left.
|
|
3175
|
+
*
|
|
3176
|
+
* This is the screen → data primitive consumers use to drive picking on top
|
|
3177
|
+
* of their own spatial index. The mount doesn't know what's in the chart —
|
|
3178
|
+
* downstream layers (phylo's `hitTestPhylo`, custom geoms, etc.) take it
|
|
3179
|
+
* from here.
|
|
3180
|
+
*/
|
|
3181
|
+
pickAt(canvasX: number, canvasY: number): {
|
|
3182
|
+
plotFrameX: number;
|
|
3183
|
+
plotFrameY: number;
|
|
3184
|
+
dataX: number;
|
|
3185
|
+
dataY: number;
|
|
3186
|
+
frame: Frame;
|
|
3187
|
+
} | null;
|
|
3188
|
+
}
|
|
3189
|
+
/** @deprecated kept for back-compat; use `MountedPlot<T>`. */
|
|
3190
|
+
type MountedChart<T = Row> = MountedPlot<T>;
|
|
3191
|
+
interface RenderTarget {
|
|
3192
|
+
axisLayer: Layer;
|
|
3193
|
+
marksLayer: Layer;
|
|
3194
|
+
hudLayer: Layer;
|
|
3195
|
+
width?: number;
|
|
3196
|
+
height?: number;
|
|
3197
|
+
}
|
|
3198
|
+
interface Chart<T> {
|
|
3199
|
+
layer(geom: Geom<T>): Chart<T>;
|
|
3200
|
+
layers(geoms: readonly Geom<T>[]): Chart<T>;
|
|
3201
|
+
/**
|
|
3202
|
+
* Configure a scale. `domain` is always optional — when omitted it is
|
|
3203
|
+
* inferred from the data, and when `panZoom` is enabled on `.mount()` the
|
|
3204
|
+
* pipeline overrides the x/y position-scale domain each frame from the
|
|
3205
|
+
* viewport's visible window. Consumers should NOT re-thread the viewport's
|
|
3206
|
+
* visible domain back through `.scale()` from a `build:` closure; it's
|
|
3207
|
+
* redundant and forces a rebuild on every dirty draw.
|
|
3208
|
+
*/
|
|
3209
|
+
scale<C extends Channel>(channel: C, options: ScaleOptionsByChannel<C>): Chart<T>;
|
|
3210
|
+
axes(spec: AxesSpec): Chart<T>;
|
|
3211
|
+
title(spec: TitleSpec | string): Chart<T>;
|
|
3212
|
+
legend(spec: LegendSpec | false): Chart<T>;
|
|
3213
|
+
/** Add a free-form text/box annotation. Multiple calls accumulate. */
|
|
3214
|
+
annotate(spec: AnnotationSpec): Chart<T>;
|
|
3215
|
+
/** Split data into a grid of panels by `spec.by`. Replaces any prior facet. */
|
|
3216
|
+
facet(spec: FacetSpec<T>): Chart<T>;
|
|
3217
|
+
/**
|
|
3218
|
+
* Set the coordinate system. Defaults to `coordCartesian()`. Polar / radial
|
|
3219
|
+
* coords land in Phase 3 of the phylo-on-plot rewrite.
|
|
3220
|
+
*/
|
|
3221
|
+
coord(coord: Coord): Chart<T>;
|
|
3222
|
+
theme(theme: Theme): Chart<T>;
|
|
3223
|
+
/**
|
|
3224
|
+
* Bind this chart to a canvas. The mount owns the renderer, atlas, three
|
|
3225
|
+
* layers, rAF loop, ResizeObserver and visibility-pause unless you pass
|
|
3226
|
+
* your own pieces in `opts`. See `MountPlotOptions` for every escape hatch.
|
|
3227
|
+
*/
|
|
3228
|
+
mount(canvas: HTMLCanvasElement, opts?: MountPlotOptions<T>): MountedPlot<T>;
|
|
3229
|
+
/**
|
|
3230
|
+
* Compile + emit into externally owned layers. Use when the host already
|
|
3231
|
+
* owns a `Renderer2D` (and wants its own per-frame timing). For simpler
|
|
3232
|
+
* cases, prefer `mount(canvas)`.
|
|
3233
|
+
*/
|
|
3234
|
+
render(target: RenderTarget): void;
|
|
3235
|
+
/** Static SVG export. Caller mounts the returned element where they want. */
|
|
3236
|
+
toSVG(options?: {
|
|
3237
|
+
width?: number;
|
|
3238
|
+
height?: number;
|
|
3239
|
+
atlas?: GlyphAtlas;
|
|
3240
|
+
}): SVGSVGElement;
|
|
3241
|
+
}
|
|
3242
|
+
declare function plot<T>(spec: PlotSpec<T>): Chart<T>;
|
|
3243
|
+
//#endregion
|
|
3244
|
+
//#region src/grammar/data/pivot.d.ts
|
|
3245
|
+
interface FromMatrixOptions {
|
|
3246
|
+
/** Y labels (rows). Top to bottom. Length must equal `values.length`. */
|
|
3247
|
+
rows: readonly string[];
|
|
3248
|
+
/** X labels (cols). Left to right. Length must equal `values[0].length`. */
|
|
3249
|
+
cols: readonly string[];
|
|
3250
|
+
/** Output key for the row label. Default `"row"`. */
|
|
3251
|
+
rowKey?: string;
|
|
3252
|
+
/** Output key for the col label. Default `"col"`. */
|
|
3253
|
+
colKey?: string;
|
|
3254
|
+
/** Output key for the cell value. Default `"value"`. */
|
|
3255
|
+
valueKey?: string;
|
|
3256
|
+
}
|
|
3257
|
+
/**
|
|
3258
|
+
* Convert a 2D `values[row][col]` matrix into long-format rows that the
|
|
3259
|
+
* `tile()` geom consumes directly. Cells with `NaN` / `null` / `undefined`
|
|
3260
|
+
* are kept (so consumers can opt into NA cell rendering); cells whose
|
|
3261
|
+
* coordinates are out of range are skipped.
|
|
3262
|
+
*
|
|
3263
|
+
* Example:
|
|
3264
|
+
* ```ts
|
|
3265
|
+
* const long = fromMatrix(temperatures, {
|
|
3266
|
+
* rows: ["00:00", "06:00", "12:00", "18:00"],
|
|
3267
|
+
* cols: ["Mon", "Tue", "Wed", "Thu", "Fri"],
|
|
3268
|
+
* });
|
|
3269
|
+
* tile({ x: "col", y: "row", fill: "value" })
|
|
3270
|
+
* ```
|
|
3271
|
+
*/
|
|
3272
|
+
declare function fromMatrix(values: readonly (readonly number[])[], opts: FromMatrixOptions): {
|
|
3273
|
+
row: string;
|
|
3274
|
+
col: string;
|
|
3275
|
+
value: number;
|
|
3276
|
+
}[];
|
|
3277
|
+
interface PivotLongerOptions<T> {
|
|
3278
|
+
/** Output column name for the original key. Default `"name"`. */
|
|
3279
|
+
nameKey?: string;
|
|
3280
|
+
/** Output column name for the value. Default `"value"`. */
|
|
3281
|
+
valueKey?: string;
|
|
3282
|
+
/** Optional id columns kept verbatim alongside the long pair. */
|
|
3283
|
+
idColumns?: readonly (keyof T & string)[];
|
|
3284
|
+
}
|
|
3285
|
+
/**
|
|
3286
|
+
* Pivot a wide row to a sequence of long rows — one per `keys` entry.
|
|
3287
|
+
* `idColumns` are copied through to every output row so a per-row identifier
|
|
3288
|
+
* (e.g. car name in the mtcars example) is preserved.
|
|
3289
|
+
*
|
|
3290
|
+
* Example:
|
|
3291
|
+
* ```ts
|
|
3292
|
+
* const long = pivotLonger(mtcars, ["mpg", "cyl", "disp", "hp"], {
|
|
3293
|
+
* idColumns: ["model"],
|
|
3294
|
+
* });
|
|
3295
|
+
* // → [{ model, name: "mpg", value }, { model, name: "cyl", value }, ...]
|
|
3296
|
+
* ```
|
|
3297
|
+
*/
|
|
3298
|
+
declare function pivotLonger<T extends Record<string, unknown>>(rows: readonly T[], keys: readonly (keyof T & string)[], options?: PivotLongerOptions<T>): Record<string, unknown>[];
|
|
3299
|
+
//#endregion
|
|
3300
|
+
//#region src/grammar/palettes.d.ts
|
|
3301
|
+
/** Built-in categorical palette identifiers supported by `distinguishable`. */
|
|
3302
|
+
type DistinguishableScheme = "category10" | "tableau10" | "set1" | "set2" | "set3" | "dark2" | "paired" | "pastel";
|
|
3303
|
+
interface DistinguishableOptions {
|
|
3304
|
+
/** Per-channel cardinality. Each count must be ≥ 1. */
|
|
3305
|
+
for: {
|
|
3306
|
+
color: number;
|
|
3307
|
+
shape: number;
|
|
3308
|
+
};
|
|
3309
|
+
/**
|
|
3310
|
+
* Categorical palette to source the color palette from. Default
|
|
3311
|
+
* `"category10"`. Pass a `CategoricalPalette` directly for a custom set.
|
|
3312
|
+
*/
|
|
3313
|
+
scheme?: DistinguishableScheme | CategoricalPalette;
|
|
3314
|
+
/**
|
|
3315
|
+
* Override the shape pool. Default: `POINT_SHAPE_PALETTE` from `marks`,
|
|
3316
|
+
* which is already ordered for silhouette distinctness.
|
|
3317
|
+
*/
|
|
3318
|
+
shapes?: readonly PointShapeKind[];
|
|
3319
|
+
}
|
|
3320
|
+
interface DistinguishablePalettes {
|
|
3321
|
+
/**
|
|
3322
|
+
* A categorical palette sliced to exactly `for.color` colors from the
|
|
3323
|
+
* requested scheme. Plug into `scale("color", { palette })`.
|
|
3324
|
+
*/
|
|
3325
|
+
color: CategoricalPalette;
|
|
3326
|
+
/**
|
|
3327
|
+
* Shape palette sliced to exactly `for.shape` entries. Plug into
|
|
3328
|
+
* `scale("shape", { palette })`.
|
|
3329
|
+
*/
|
|
3330
|
+
shape: readonly PointShapeKind[];
|
|
3331
|
+
}
|
|
3332
|
+
/**
|
|
3333
|
+
* Build a matched `{ color, shape }` pair sized for the two channels'
|
|
3334
|
+
* cardinalities. Sugar over manual `palette.colors.slice(0, N)` +
|
|
3335
|
+
* `POINT_SHAPE_PALETTE.slice(0, M)` — the goal is one declaration site for
|
|
3336
|
+
* the visual contract of a multi-encoding chart.
|
|
3337
|
+
*
|
|
3338
|
+
* Counts that exceed the source pool wrap modulo length, matching the
|
|
3339
|
+
* default `CategoricalPalette` / scale wrap semantics so the helper never
|
|
3340
|
+
* silently drops categories. (The visual distinction degrades past the pool
|
|
3341
|
+
* size — that's an authoring problem, not a library one — but the runtime
|
|
3342
|
+
* stays consistent with the rest of the scale system.)
|
|
3343
|
+
*/
|
|
3344
|
+
declare function distinguishable(options: DistinguishableOptions): DistinguishablePalettes;
|
|
3345
|
+
/**
|
|
3346
|
+
* `palettes` namespace — currently the home of `distinguishable`. Future
|
|
3347
|
+
* combinators (legend-paired schemes, perceptual-uniform slicing, …) live
|
|
3348
|
+
* here so the surface stays small and predictable.
|
|
3349
|
+
*/
|
|
3350
|
+
declare const palettes: {
|
|
3351
|
+
readonly distinguishable: typeof distinguishable;
|
|
3352
|
+
};
|
|
3353
|
+
//#endregion
|
|
3354
|
+
//#region src/grammar/profiling.d.ts
|
|
3355
|
+
interface RecorderHook {
|
|
3356
|
+
recordCpu(name: string, durationMs: number): void;
|
|
3357
|
+
recordGpu(name: string, startNs: number, endNs: number): void;
|
|
3358
|
+
}
|
|
3359
|
+
/** Inject a recorder (e.g. devtools' `recordCpu`/`recordGpu`). Pass `null` to reset to no-op. */
|
|
3360
|
+
declare function setRecorderHook(rec: RecorderHook | null): void;
|
|
3361
|
+
//#endregion
|
|
3362
|
+
//#region src/grammar/phylo.d.ts
|
|
3363
|
+
/**
|
|
3364
|
+
* Subset of `@phylon/renderer`'s `TipAxis` consumed by the bridge. Any object
|
|
3365
|
+
* with this shape (typically the `tipAxis` field on a `RectLayout`) works.
|
|
3366
|
+
*/
|
|
3367
|
+
interface TipAxisLike {
|
|
3368
|
+
/** Number of tips. */
|
|
3369
|
+
count: number;
|
|
3370
|
+
/** Tip node ids in display order (top→bottom for rectilinear). */
|
|
3371
|
+
order: ArrayLike<number>;
|
|
3372
|
+
/** Tip node id → label, or `null` if the tip is unnamed. */
|
|
3373
|
+
name(tipId: number): string | null;
|
|
3374
|
+
}
|
|
3375
|
+
interface TipScaleOptions {
|
|
3376
|
+
/**
|
|
3377
|
+
* Band padding in [0, 1). Default `0` — heatmaps and tile-style geoms want
|
|
3378
|
+
* tight rows. Bump to e.g. `0.1` for visible gaps between bars.
|
|
3379
|
+
*/
|
|
3380
|
+
padding?: number;
|
|
3381
|
+
/**
|
|
3382
|
+
* Replacement label for unnamed tips. Receives the tip's node id and its
|
|
3383
|
+
* row index. Default: `(id) => "tip_" + id`.
|
|
3384
|
+
*/
|
|
3385
|
+
unnamed?: (tipId: number, row: number) => string;
|
|
3386
|
+
}
|
|
3387
|
+
/**
|
|
3388
|
+
* Build a y-channel `PositionScaleOptions` from a phylo `TipAxis`. The
|
|
3389
|
+
* resulting scale is a band scale whose domain is the tip names in tree
|
|
3390
|
+
* display order (top→bottom). Geoms whose `y` aesthetic resolves to a tip
|
|
3391
|
+
* name will land on the matching tree row.
|
|
3392
|
+
*
|
|
3393
|
+
* Tip labels in the data must match `axis.name(tipId)`. Use `joinByTip`
|
|
3394
|
+
* (phylo) to align metadata rows to tip names ahead of time.
|
|
3395
|
+
*/
|
|
3396
|
+
declare function tipScale(axis: TipAxisLike, opts?: TipScaleOptions): BandPositionScaleOptions;
|
|
3397
|
+
/**
|
|
3398
|
+
* Structural shape of a phylo `CladeStrip` — neutral data describing a clade
|
|
3399
|
+
* range plus a label. Mirrors `@phylon/renderer`'s exported `CladeStrip` so the
|
|
3400
|
+
* plot package doesn't have to depend on phylo to consume them.
|
|
3401
|
+
*/
|
|
3402
|
+
interface CladeStripLike {
|
|
3403
|
+
label: string;
|
|
3404
|
+
tipCenter: string;
|
|
3405
|
+
color?: Color;
|
|
3406
|
+
offsetX?: number;
|
|
3407
|
+
}
|
|
3408
|
+
interface CladeStripAnnotationOptions {
|
|
3409
|
+
/**
|
|
3410
|
+
* Pixel offset added to every strip's annotation. Default `8` — pushes the
|
|
3411
|
+
* label clear of the chart's right edge / tip labels. Per-strip
|
|
3412
|
+
* `offsetX` is added on top of this.
|
|
3413
|
+
*/
|
|
3414
|
+
offsetX?: number;
|
|
3415
|
+
fontSize?: number;
|
|
3416
|
+
fontStyle?: string;
|
|
3417
|
+
}
|
|
3418
|
+
/**
|
|
3419
|
+
* Convert phylo `CladeStrip[]` into plot `AnnotationSpec[]`. Labels anchor at
|
|
3420
|
+
* the chart's right frame edge, vertically aligned to the clade's y-center
|
|
3421
|
+
* (resolved by the y-channel's `tipScale`). v1 emits text-only annotations;
|
|
3422
|
+
* brackets are a follow-up that needs a non-text annotation kind.
|
|
3423
|
+
*/
|
|
3424
|
+
declare function cladeStripsToAnnotations(strips: readonly CladeStripLike[], opts?: CladeStripAnnotationOptions): TextAnnotationSpec[];
|
|
3425
|
+
//#endregion
|
|
3426
|
+
export { type Accessibility, type AccessibilityMode, type Accessor, type Aes, type AggregateBinBy, type AggregateBinSize, type AggregateBinView, type AggregateBundleResult, type AggregateBundleSummary, type AggregateBundleSummaryKind, type AggregateChannels, type AggregateInnerGeom, type AggregateOptions, type AggregateSummary, type AggregateSummaryKind, type AlphaScaleOptions, type AnnotationSpec, type AnnotationX, type AnnotationY, type AreaChannels, type AreaOptions, type AreaPosition, type ArrowAnnotationSpec, type AttachBrushOptions, type AttachRangePresetsOptions, type AttachRangePresetsPosition, type AttachRangePresetsUi, type AttachSeriesReadoutOptions, type AttachedBrush, type AttachedBrushInternal, type AttachedRangePresets, type AttachedSeriesReadout, type AutoBinSizeInfo, type AxesSpec, type AxisSpec, type AxisTickFormatter, type AxisTooltipContentResolver, type AxisTooltipInfo, type AxisTooltipRow, type BandChannels, type BandOptions, type BarChannels, type BarOptions, type BarPosition, type BlendSpace, type BorderStyleScaleOptions, type BoxplotChannels, type BoxplotOptions, type CalloutAnnotationSpec, type Channel, type ChannelSpec, type Chart, type ChartPanBounds, type ChartPanBoundsOptions, type CladeStripAnnotationOptions, type CladeStripLike, type ColorOrAccent, type ColorScaleOptions, type ColorScaleType, type CompileContext, type CompiledHitTest, type ConnectedScatterChannels, type ConnectedScatterOptions, type ContrastMetric, type Coord, type CoordAxesArgs, type CoordPanArgs, type CoordPolarOptions, type CoordViewportHandle, type CoordZoomArgs, DEFAULT_ACCESSIBILITY, DEFAULT_BORDER_STYLE_PALETTE, DEFAULT_OVERLAY_GLYPH_PALETTE, type DistinguishableOptions, type DistinguishablePalettes, type DistinguishableScheme, type FacetScales, type FacetSpec, type FacetStripStyle, type FrameAnchorX, type FrameAnchorY, type FromMatrixOptions, type Geom, type GeomKind, type HistogramChannels, type HistogramMeasure, type HistogramOptions, type HistogramPosition, type HoveredHit, type IntervalChannels, type IntervalOptions, type LegendMergeChannel, type LegendSpec, type LineChannels, type LineOptions, type MountPlotOptions, type MountedChart, type MountedPlot, type OverlayGlyphScaleOptions, type PanZoomAxes, type PanZoomConfig, type PivotLongerOptions, type PlotSpec, type Point, type PointChannels, type PointOptions, type PointsMode, type PositionScaleOptions, type PositionScaleType, type RecorderHook, type RenderTarget, type ResolveTextColorOptions, type ResolvedChannelMap, type RibbonChannels, type RibbonOptions, type RidgelineChannels, type RidgelineFillMode, type RidgelineGeom, type RidgelineInner, type RidgelineOptions, type RidgelineScale, type Row, type RugChannels, type RugOptions, type RugSide, type RuleChannels, type RuleOptions, type ScaleBundle, type ScaleOptionsByChannel, type SeriesReadoutFormat, type SeriesReadoutPosition, type SeriesReadoutRow, type SeriesReadoutSnapshot, type SeriesReadoutUi, type ShapeScaleOptions, type SizeScaleOptions, type SmoothChannels, type SmoothLabelOptions, type SmoothMethod, type SmoothOptions, type StatRollingChannels, type StatRollingOptions, type TextAnnotationSpec, type TextChannels, type TextEffects, type TextOptions, type Theme, type ThemeAccentKey, type ThemeAccents, type ThemeAxis, type ThemeInteractions, type ThemeLegend, type ThemeMarks, type ThemePalettes, type ThemeSubtitle, type ThemeText, type ThemeTitle, type ThemeTooltipAccents, type TickIntervalSpec, type TickSpec, type TileChannels, type TileNAOptions, type TileOptions, type TimeIntervalUnit, type TipAxisLike, type TipScaleOptions, type TitleSpec, type ViolinChannels, type ViolinInner, type ViolinOptions, type ViolinScale, aggregate, annotate, area, attachRangePresets, band, bar, boxplot, cladeStripsToAnnotations, connectedScatter, coordCartesian, coordPolar, coordRadial, createAttachedBrush, distinguishable, fromMatrix, histogram, interval, line, palettes, pivotLonger, plot, point, resolveTextColor, ribbon, ridgeline, rug, rule, setRecorderHook, smooth, statRolling, text, theme, themeDefault, themeMinimalGrid, tile, tipScale, violin };
|