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
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// insomni-plot — grammar of graphics
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// High-level ggplot2-style API. Built on top of the low-level imperative
|
|
5
|
+
// primitives at "insomni-plot/core" (raw scales, axes, marks, viewport, …).
|
|
6
|
+
|
|
7
|
+
// Chart builder
|
|
8
|
+
export {
|
|
9
|
+
plot,
|
|
10
|
+
type AxesSpec,
|
|
11
|
+
type AxisSpec,
|
|
12
|
+
type AxisTickFormatter,
|
|
13
|
+
type AxisTooltipContentResolver,
|
|
14
|
+
type AxisTooltipInfo,
|
|
15
|
+
type AxisTooltipRow,
|
|
16
|
+
type Chart,
|
|
17
|
+
type LegendMergeChannel,
|
|
18
|
+
type LegendSpec,
|
|
19
|
+
type MountedChart,
|
|
20
|
+
type MountedPlot,
|
|
21
|
+
type MountPlotOptions,
|
|
22
|
+
type PanZoomConfig,
|
|
23
|
+
type PanZoomAxes,
|
|
24
|
+
type ChartPanBounds,
|
|
25
|
+
type ChartPanBoundsOptions,
|
|
26
|
+
type PlotSpec,
|
|
27
|
+
type RenderTarget,
|
|
28
|
+
type Row,
|
|
29
|
+
type ScaleOptionsByChannel,
|
|
30
|
+
type TitleSpec,
|
|
31
|
+
} from "./chart.ts";
|
|
32
|
+
|
|
33
|
+
// Coordinate systems
|
|
34
|
+
export {
|
|
35
|
+
coordCartesian,
|
|
36
|
+
coordPolar,
|
|
37
|
+
coordRadial,
|
|
38
|
+
type Coord,
|
|
39
|
+
type CoordAxesArgs,
|
|
40
|
+
type CoordPanArgs,
|
|
41
|
+
type CoordZoomArgs,
|
|
42
|
+
type CoordPolarOptions,
|
|
43
|
+
type CoordViewportHandle,
|
|
44
|
+
type Point,
|
|
45
|
+
} from "./coord.ts";
|
|
46
|
+
|
|
47
|
+
// Range-preset helper (DOM-aware wrapper around createRangePresets)
|
|
48
|
+
export {
|
|
49
|
+
attachRangePresets,
|
|
50
|
+
type AttachedRangePresets,
|
|
51
|
+
type AttachRangePresetsOptions,
|
|
52
|
+
type AttachRangePresetsPosition,
|
|
53
|
+
type AttachRangePresetsUi,
|
|
54
|
+
} from "./attach-presets.ts";
|
|
55
|
+
|
|
56
|
+
// Brush attach helper (mirrors range-presets / series-readout shape)
|
|
57
|
+
export {
|
|
58
|
+
createAttachedBrush,
|
|
59
|
+
type AttachBrushOptions,
|
|
60
|
+
type AttachedBrush,
|
|
61
|
+
type AttachedBrushInternal,
|
|
62
|
+
} from "./attach-brush.ts";
|
|
63
|
+
|
|
64
|
+
// Series-readout (dygraph-style pinned legend)
|
|
65
|
+
export {
|
|
66
|
+
type AttachedSeriesReadout,
|
|
67
|
+
type AttachSeriesReadoutOptions,
|
|
68
|
+
type SeriesReadoutFormat,
|
|
69
|
+
type SeriesReadoutPosition,
|
|
70
|
+
type SeriesReadoutRow,
|
|
71
|
+
type SeriesReadoutSnapshot,
|
|
72
|
+
type SeriesReadoutUi,
|
|
73
|
+
} from "./interactions/series-readout.ts";
|
|
74
|
+
|
|
75
|
+
// Geoms (factory functions + per-geom option / channel types)
|
|
76
|
+
export {
|
|
77
|
+
aggregate,
|
|
78
|
+
area,
|
|
79
|
+
band,
|
|
80
|
+
bar,
|
|
81
|
+
boxplot,
|
|
82
|
+
connectedScatter,
|
|
83
|
+
histogram,
|
|
84
|
+
interval,
|
|
85
|
+
line,
|
|
86
|
+
point,
|
|
87
|
+
ribbon,
|
|
88
|
+
ridgeline,
|
|
89
|
+
rug,
|
|
90
|
+
rule,
|
|
91
|
+
smooth,
|
|
92
|
+
statRolling,
|
|
93
|
+
text,
|
|
94
|
+
tile,
|
|
95
|
+
violin,
|
|
96
|
+
type AggregateBinBy,
|
|
97
|
+
type AggregateBinSize,
|
|
98
|
+
type AggregateBinView,
|
|
99
|
+
type AggregateBundleResult,
|
|
100
|
+
type AggregateBundleSummary,
|
|
101
|
+
type AggregateBundleSummaryKind,
|
|
102
|
+
type AggregateChannels,
|
|
103
|
+
type AggregateInnerGeom,
|
|
104
|
+
type AggregateOptions,
|
|
105
|
+
type AggregateSummary,
|
|
106
|
+
type AggregateSummaryKind,
|
|
107
|
+
type AreaChannels,
|
|
108
|
+
type AreaOptions,
|
|
109
|
+
type AreaPosition,
|
|
110
|
+
type AutoBinSizeInfo,
|
|
111
|
+
type BandChannels,
|
|
112
|
+
type BandOptions,
|
|
113
|
+
type BarChannels,
|
|
114
|
+
type BarOptions,
|
|
115
|
+
type BarPosition,
|
|
116
|
+
type BoxplotChannels,
|
|
117
|
+
type BoxplotOptions,
|
|
118
|
+
type ChannelSpec,
|
|
119
|
+
type CompileContext,
|
|
120
|
+
type CompiledHitTest,
|
|
121
|
+
type ConnectedScatterChannels,
|
|
122
|
+
type ConnectedScatterOptions,
|
|
123
|
+
type Geom,
|
|
124
|
+
type GeomKind,
|
|
125
|
+
type HistogramChannels,
|
|
126
|
+
type HoveredHit,
|
|
127
|
+
type HistogramMeasure,
|
|
128
|
+
type HistogramOptions,
|
|
129
|
+
type HistogramPosition,
|
|
130
|
+
type IntervalChannels,
|
|
131
|
+
type IntervalOptions,
|
|
132
|
+
type LineChannels,
|
|
133
|
+
type LineOptions,
|
|
134
|
+
type PointChannels,
|
|
135
|
+
type PointOptions,
|
|
136
|
+
type PointsMode,
|
|
137
|
+
type ResolvedChannelMap,
|
|
138
|
+
type RibbonChannels,
|
|
139
|
+
type RibbonOptions,
|
|
140
|
+
type RidgelineChannels,
|
|
141
|
+
type RidgelineFillMode,
|
|
142
|
+
type RidgelineGeom,
|
|
143
|
+
type RidgelineInner,
|
|
144
|
+
type RidgelineOptions,
|
|
145
|
+
type RidgelineScale,
|
|
146
|
+
type RugChannels,
|
|
147
|
+
type RugOptions,
|
|
148
|
+
type RugSide,
|
|
149
|
+
type RuleChannels,
|
|
150
|
+
type RuleOptions,
|
|
151
|
+
type ScaleBundle,
|
|
152
|
+
type SmoothChannels,
|
|
153
|
+
type SmoothLabelOptions,
|
|
154
|
+
type SmoothMethod,
|
|
155
|
+
type SmoothOptions,
|
|
156
|
+
type StatRollingChannels,
|
|
157
|
+
type StatRollingOptions,
|
|
158
|
+
type TextChannels,
|
|
159
|
+
type TextOptions,
|
|
160
|
+
type TileChannels,
|
|
161
|
+
type TileNAOptions,
|
|
162
|
+
type TileOptions,
|
|
163
|
+
type ViolinChannels,
|
|
164
|
+
type ViolinInner,
|
|
165
|
+
type ViolinOptions,
|
|
166
|
+
type ViolinScale,
|
|
167
|
+
} from "./geoms/index.ts";
|
|
168
|
+
|
|
169
|
+
// Aesthetic mapping (user-facing channel typing)
|
|
170
|
+
export type { Accessor, Aes } from "./aes.ts";
|
|
171
|
+
|
|
172
|
+
// Wide → long reshape helpers
|
|
173
|
+
export {
|
|
174
|
+
fromMatrix,
|
|
175
|
+
pivotLonger,
|
|
176
|
+
type FromMatrixOptions,
|
|
177
|
+
type PivotLongerOptions,
|
|
178
|
+
} from "./data/pivot.ts";
|
|
179
|
+
|
|
180
|
+
// Annotations (free-form text/box overlays on the chart)
|
|
181
|
+
export { annotate } from "./annotations.ts";
|
|
182
|
+
export type {
|
|
183
|
+
AnnotationSpec,
|
|
184
|
+
AnnotationX,
|
|
185
|
+
AnnotationY,
|
|
186
|
+
ArrowAnnotationSpec,
|
|
187
|
+
CalloutAnnotationSpec,
|
|
188
|
+
FrameAnchorX,
|
|
189
|
+
FrameAnchorY,
|
|
190
|
+
TextAnnotationSpec,
|
|
191
|
+
} from "./annotations.ts";
|
|
192
|
+
|
|
193
|
+
// Faceting
|
|
194
|
+
export type { FacetScales, FacetSpec, FacetStripStyle } from "./facet.ts";
|
|
195
|
+
|
|
196
|
+
// Scale option types + channel enum
|
|
197
|
+
export type {
|
|
198
|
+
AlphaScaleOptions,
|
|
199
|
+
BorderStyleScaleOptions,
|
|
200
|
+
Channel,
|
|
201
|
+
ColorScaleOptions,
|
|
202
|
+
ColorScaleType,
|
|
203
|
+
OverlayGlyphScaleOptions,
|
|
204
|
+
PositionScaleOptions,
|
|
205
|
+
PositionScaleType,
|
|
206
|
+
ShapeScaleOptions,
|
|
207
|
+
SizeScaleOptions,
|
|
208
|
+
} from "./scales.ts";
|
|
209
|
+
export { DEFAULT_BORDER_STYLE_PALETTE, DEFAULT_OVERLAY_GLYPH_PALETTE } from "./scales.ts";
|
|
210
|
+
|
|
211
|
+
// Categorical-encoding combinators (`palettes.distinguishable`, …)
|
|
212
|
+
export {
|
|
213
|
+
distinguishable,
|
|
214
|
+
palettes,
|
|
215
|
+
type DistinguishableOptions,
|
|
216
|
+
type DistinguishablePalettes,
|
|
217
|
+
type DistinguishableScheme,
|
|
218
|
+
} from "./palettes.ts";
|
|
219
|
+
|
|
220
|
+
// Theme
|
|
221
|
+
export {
|
|
222
|
+
theme,
|
|
223
|
+
themeDefault,
|
|
224
|
+
themeMinimalGrid,
|
|
225
|
+
type Theme,
|
|
226
|
+
type ThemeAccentKey,
|
|
227
|
+
type ThemeAccents,
|
|
228
|
+
type ThemeAxis,
|
|
229
|
+
type ThemeInteractions,
|
|
230
|
+
type ThemeLegend,
|
|
231
|
+
type ThemeMarks,
|
|
232
|
+
type ThemePalettes,
|
|
233
|
+
type ThemeSubtitle,
|
|
234
|
+
type ThemeText,
|
|
235
|
+
type ThemeTitle,
|
|
236
|
+
type ThemeTooltipAccents,
|
|
237
|
+
type Accessibility,
|
|
238
|
+
type AccessibilityMode,
|
|
239
|
+
type TextEffects,
|
|
240
|
+
} from "./theme.ts";
|
|
241
|
+
|
|
242
|
+
export {
|
|
243
|
+
resolveTextColor,
|
|
244
|
+
DEFAULT_ACCESSIBILITY,
|
|
245
|
+
type ContrastMetric,
|
|
246
|
+
type ResolveTextColorOptions,
|
|
247
|
+
} from "./accessibility.ts";
|
|
248
|
+
|
|
249
|
+
export type { BlendSpace } from "insomni";
|
|
250
|
+
|
|
251
|
+
// Axis tick spec — accepted on `AxisSpec.ticks`.
|
|
252
|
+
export type { TickIntervalSpec, TickSpec } from "../axis.ts";
|
|
253
|
+
export type { TimeIntervalUnit } from "../scales.ts";
|
|
254
|
+
|
|
255
|
+
// Color-utility shorthand for chart-level mark options.
|
|
256
|
+
export type { ColorOrAccent } from "./color-utils.ts";
|
|
257
|
+
|
|
258
|
+
// Profiling recorder hook (injectable; defaults to no-op)
|
|
259
|
+
export { setRecorderHook, type RecorderHook } from "./profiling.ts";
|
|
260
|
+
|
|
261
|
+
// Bridge to @phylon/renderer — tip-aligned scales for tree-anchored panels.
|
|
262
|
+
export {
|
|
263
|
+
cladeStripsToAnnotations,
|
|
264
|
+
tipScale,
|
|
265
|
+
type CladeStripAnnotationOptions,
|
|
266
|
+
type CladeStripLike,
|
|
267
|
+
type TipAxisLike,
|
|
268
|
+
type TipScaleOptions,
|
|
269
|
+
} from "./phylo.ts";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Shared disposable guard. Interaction handles all follow the same pattern:
|
|
2
|
+
// methods early-return after disposal, and `dispose()` must be idempotent.
|
|
3
|
+
// Centralizing the flag here removes the per-module `let disposed = false`
|
|
4
|
+
// boilerplate while leaving each module's actual teardown work in place.
|
|
5
|
+
|
|
6
|
+
export interface Disposable {
|
|
7
|
+
readonly isDisposed: boolean;
|
|
8
|
+
dispose(): void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function createDisposable(cleanup: () => void): Disposable {
|
|
12
|
+
let disposed = false;
|
|
13
|
+
return {
|
|
14
|
+
get isDisposed() {
|
|
15
|
+
return disposed;
|
|
16
|
+
},
|
|
17
|
+
dispose() {
|
|
18
|
+
if (disposed) return;
|
|
19
|
+
disposed = true;
|
|
20
|
+
cleanup();
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Centralized z-index constants for plot interaction layers.
|
|
2
|
+
//
|
|
3
|
+
// Layering rules of thumb:
|
|
4
|
+
// - Hit-test clouds (point/region) sit highest so they claim hover ahead
|
|
5
|
+
// of the brush's drag plane and other plain interaction nodes.
|
|
6
|
+
// - Brush handles sit above the brush drag plane; corners get a tiny
|
|
7
|
+
// extra bump so they win over overlapping edge zones at small sizes.
|
|
8
|
+
// - The brush drag plane lives at insomni's USER_DEFAULT_Z so it slots
|
|
9
|
+
// in between user-installed nodes and engine-internal nodes.
|
|
10
|
+
import { USER_DEFAULT_Z } from "insomni";
|
|
11
|
+
|
|
12
|
+
export const Z_BRUSH_DRAG = USER_DEFAULT_Z;
|
|
13
|
+
export const Z_BRUSH_HANDLE_EDGE = USER_DEFAULT_Z + 1;
|
|
14
|
+
export const Z_BRUSH_HANDLE_CORNER = USER_DEFAULT_Z + 2;
|
|
15
|
+
|
|
16
|
+
export const Z_HIT_CLOUD_BASE = 1000;
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
// Integration test: brush + click-selection on the same chart.
|
|
2
|
+
// Verifies the two interactions hold independent state — drag gestures populate
|
|
3
|
+
// `brushed`, press events through the hit-layer populate `selected`, and
|
|
4
|
+
// background-tap clears both. Brush consumes drag-only and selection consumes
|
|
5
|
+
// press-only at the manager level (capability filter), so this test only needs
|
|
6
|
+
// to confirm that the grammar wrappers don't leak their state into each other.
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
DragPointerInfo,
|
|
10
|
+
InteractionManager,
|
|
11
|
+
InteractionNode,
|
|
12
|
+
InteractionNodeSpec,
|
|
13
|
+
PointerInfo,
|
|
14
|
+
} from "insomni";
|
|
15
|
+
import { describe, expect, test } from "vite-plus/test";
|
|
16
|
+
|
|
17
|
+
import type { CompiledHitTest, HoveredHit } from "../geoms/types.ts";
|
|
18
|
+
import { themeDefault } from "../theme.ts";
|
|
19
|
+
import { createGrammarBrush } from "./brush.ts";
|
|
20
|
+
import type { GrammarHitLayer, HitEventContext, HitLayerSubscriber } from "./hit-layer.ts";
|
|
21
|
+
import { createGrammarSelection } from "./selection.ts";
|
|
22
|
+
|
|
23
|
+
interface CapturedNode {
|
|
24
|
+
spec: InteractionNodeSpec;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function fakeManager(): {
|
|
28
|
+
manager: InteractionManager;
|
|
29
|
+
nodes: CapturedNode[];
|
|
30
|
+
fireBackgroundTap: () => void;
|
|
31
|
+
} {
|
|
32
|
+
const nodes: CapturedNode[] = [];
|
|
33
|
+
const bgHandlers = new Set<() => void>();
|
|
34
|
+
const manager = {
|
|
35
|
+
add(spec: InteractionNodeSpec): InteractionNode {
|
|
36
|
+
const captured: CapturedNode = { spec };
|
|
37
|
+
nodes.push(captured);
|
|
38
|
+
return {
|
|
39
|
+
id: Symbol("node"),
|
|
40
|
+
update(patch) {
|
|
41
|
+
captured.spec = { ...captured.spec, ...patch };
|
|
42
|
+
},
|
|
43
|
+
destroy() {},
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
addPointCloud() {
|
|
47
|
+
throw new Error("not used");
|
|
48
|
+
},
|
|
49
|
+
onBackgroundTap(handler: () => void) {
|
|
50
|
+
bgHandlers.add(handler);
|
|
51
|
+
return () => bgHandlers.delete(handler);
|
|
52
|
+
},
|
|
53
|
+
onChange() {
|
|
54
|
+
return () => {};
|
|
55
|
+
},
|
|
56
|
+
destroy() {},
|
|
57
|
+
} as unknown as InteractionManager;
|
|
58
|
+
return {
|
|
59
|
+
manager,
|
|
60
|
+
nodes,
|
|
61
|
+
fireBackgroundTap: () => {
|
|
62
|
+
for (const h of bgHandlers) h();
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function fakeHitLayer(): {
|
|
68
|
+
layer: GrammarHitLayer;
|
|
69
|
+
firePress: <T>(compiled: CompiledHitTest<T>, hitIndex: number, p: PointerInfo) => void;
|
|
70
|
+
} {
|
|
71
|
+
const subscribers: HitLayerSubscriber[] = [];
|
|
72
|
+
const layer: GrammarHitLayer = {
|
|
73
|
+
sync() {},
|
|
74
|
+
subscribe(sub) {
|
|
75
|
+
subscribers.push(sub);
|
|
76
|
+
return () => {
|
|
77
|
+
const i = subscribers.indexOf(sub);
|
|
78
|
+
if (i >= 0) subscribers.splice(i, 1);
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
state() {
|
|
82
|
+
return { active: null };
|
|
83
|
+
},
|
|
84
|
+
subscribeState() {
|
|
85
|
+
return () => {};
|
|
86
|
+
},
|
|
87
|
+
pickAt() {
|
|
88
|
+
return null;
|
|
89
|
+
},
|
|
90
|
+
dispose() {
|
|
91
|
+
subscribers.length = 0;
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
return {
|
|
95
|
+
layer,
|
|
96
|
+
firePress: (compiled, hitIndex, pointer) => {
|
|
97
|
+
const px = compiled.positions[hitIndex * 2]!;
|
|
98
|
+
const py = compiled.positions[hitIndex * 2 + 1]!;
|
|
99
|
+
const hit: HoveredHit = {
|
|
100
|
+
geomKind: compiled.geomKind,
|
|
101
|
+
dataIndex: compiled.dataIndex[hitIndex] ?? hitIndex,
|
|
102
|
+
seriesKey: compiled.seriesKey?.[hitIndex],
|
|
103
|
+
data: compiled.data as readonly unknown[],
|
|
104
|
+
x: px,
|
|
105
|
+
y: py,
|
|
106
|
+
};
|
|
107
|
+
const ctx: HitEventContext = {
|
|
108
|
+
hit,
|
|
109
|
+
compiled: compiled as CompiledHitTest<unknown>,
|
|
110
|
+
hitIndex,
|
|
111
|
+
pointer,
|
|
112
|
+
};
|
|
113
|
+
for (const sub of subscribers) sub.onPress?.(ctx);
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const noMods = { shift: false, ctrl: false, meta: false, alt: false };
|
|
119
|
+
function pointer(x: number, y: number): PointerInfo {
|
|
120
|
+
return {
|
|
121
|
+
pointerId: 1,
|
|
122
|
+
type: "mouse",
|
|
123
|
+
x,
|
|
124
|
+
y,
|
|
125
|
+
localX: x,
|
|
126
|
+
localY: y,
|
|
127
|
+
buttons: 1,
|
|
128
|
+
mods: noMods,
|
|
129
|
+
stopPropagation: () => {},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function dragInfo(x: number, y: number): DragPointerInfo {
|
|
133
|
+
return { ...pointer(x, y), dx: 0, dy: 0 };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
interface Row {
|
|
137
|
+
x: number;
|
|
138
|
+
y: number;
|
|
139
|
+
}
|
|
140
|
+
function hitFor(
|
|
141
|
+
positions: number[],
|
|
142
|
+
indices: number[],
|
|
143
|
+
data: readonly Row[],
|
|
144
|
+
): CompiledHitTest<Row> {
|
|
145
|
+
return {
|
|
146
|
+
geomKind: "point",
|
|
147
|
+
positions: Float32Array.from(positions),
|
|
148
|
+
dataIndex: Int32Array.from(indices),
|
|
149
|
+
pickRadius: 5,
|
|
150
|
+
channels: {},
|
|
151
|
+
data,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const fullBounds = () => ({ x: 0, y: 0, width: 100, height: 100 });
|
|
156
|
+
|
|
157
|
+
function setup() {
|
|
158
|
+
const { manager, nodes, fireBackgroundTap } = fakeManager();
|
|
159
|
+
const { layer: hitLayer, firePress } = fakeHitLayer();
|
|
160
|
+
const inv = { invalidate: () => {}, dirty: false } as never;
|
|
161
|
+
const hud = { pushRect: () => hud };
|
|
162
|
+
|
|
163
|
+
const brushed: HoveredHit[][] = [];
|
|
164
|
+
const selected: HoveredHit[][] = [];
|
|
165
|
+
|
|
166
|
+
const brush = createGrammarBrush(
|
|
167
|
+
{
|
|
168
|
+
manager,
|
|
169
|
+
bounds: fullBounds,
|
|
170
|
+
hudLayer: () => hud as never,
|
|
171
|
+
theme: () => themeDefault,
|
|
172
|
+
invalidator: inv,
|
|
173
|
+
},
|
|
174
|
+
{ onChange: (s) => brushed.push(s) },
|
|
175
|
+
);
|
|
176
|
+
const selection = createGrammarSelection(
|
|
177
|
+
{ manager, hitLayer },
|
|
178
|
+
{ onChange: (s) => selected.push(s) },
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
return { brush, selection, nodes, brushed, selected, fireBackgroundTap, firePress };
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
describe("brush + selection coexistence", () => {
|
|
185
|
+
test("a drag populates brushed but not selected", () => {
|
|
186
|
+
const { brush, selection, nodes, brushed, selected } = setup();
|
|
187
|
+
const data: Row[] = [{ x: 30, y: 40 }];
|
|
188
|
+
const hit = hitFor([30, 40], [0], data);
|
|
189
|
+
brush.sync([hit]);
|
|
190
|
+
selection.sync([hit]);
|
|
191
|
+
|
|
192
|
+
// nodes[0] = brush create-drag node.
|
|
193
|
+
nodes[0]!.spec.onDragStart!(pointer(10, 20));
|
|
194
|
+
nodes[0]!.spec.onDragMove!(dragInfo(60, 70));
|
|
195
|
+
nodes[0]!.spec.onDragEnd!(pointer(60, 70));
|
|
196
|
+
|
|
197
|
+
expect(brush.current().map((h) => h.dataIndex)).toEqual([0]);
|
|
198
|
+
expect(brushed.length).toBeGreaterThan(0);
|
|
199
|
+
expect(selection.current()).toEqual([]);
|
|
200
|
+
expect(selected.length).toBe(0);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test("a press through the hit-layer populates selected but not brushed", () => {
|
|
204
|
+
const { brush, selection, brushed, selected, firePress } = setup();
|
|
205
|
+
const data: Row[] = [{ x: 30, y: 40 }];
|
|
206
|
+
const hit = hitFor([30, 40], [0], data);
|
|
207
|
+
brush.sync([hit]);
|
|
208
|
+
selection.sync([hit]);
|
|
209
|
+
|
|
210
|
+
firePress(hit, 0, pointer(30, 40));
|
|
211
|
+
|
|
212
|
+
expect(selection.current().map((h) => h.dataIndex)).toEqual([0]);
|
|
213
|
+
expect(selected.length).toBe(1);
|
|
214
|
+
expect(brush.current()).toEqual([]);
|
|
215
|
+
expect(brush.rect()).toBeNull();
|
|
216
|
+
expect(brushed.length).toBe(0);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
test("brush and selection can hold state simultaneously without interfering", () => {
|
|
220
|
+
const { brush, selection, nodes, firePress } = setup();
|
|
221
|
+
const data: Row[] = [
|
|
222
|
+
{ x: 20, y: 30 },
|
|
223
|
+
{ x: 60, y: 70 },
|
|
224
|
+
];
|
|
225
|
+
const hit = hitFor([20, 30, 60, 70], [0, 1], data);
|
|
226
|
+
brush.sync([hit]);
|
|
227
|
+
selection.sync([hit]);
|
|
228
|
+
|
|
229
|
+
// Brush drag covering only row 0.
|
|
230
|
+
nodes[0]!.spec.onDragStart!(pointer(0, 0));
|
|
231
|
+
nodes[0]!.spec.onDragMove!(dragInfo(40, 40));
|
|
232
|
+
nodes[0]!.spec.onDragEnd!(pointer(40, 40));
|
|
233
|
+
expect(brush.current().map((h) => h.dataIndex)).toEqual([0]);
|
|
234
|
+
|
|
235
|
+
// Press selecting row 1 — brush state must stay put.
|
|
236
|
+
firePress(hit, 1, pointer(60, 70));
|
|
237
|
+
expect(selection.current().map((h) => h.dataIndex)).toEqual([1]);
|
|
238
|
+
expect(brush.current().map((h) => h.dataIndex)).toEqual([0]);
|
|
239
|
+
expect(brush.rect()).not.toBeNull();
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
test("background tap clears both brush and selection", () => {
|
|
243
|
+
const { brush, selection, nodes, fireBackgroundTap, firePress } = setup();
|
|
244
|
+
const data: Row[] = [{ x: 30, y: 40 }];
|
|
245
|
+
const hit = hitFor([30, 40], [0], data);
|
|
246
|
+
brush.sync([hit]);
|
|
247
|
+
selection.sync([hit]);
|
|
248
|
+
|
|
249
|
+
nodes[0]!.spec.onDragStart!(pointer(10, 20));
|
|
250
|
+
nodes[0]!.spec.onDragMove!(dragInfo(60, 70));
|
|
251
|
+
nodes[0]!.spec.onDragEnd!(pointer(60, 70));
|
|
252
|
+
firePress(hit, 0, pointer(30, 40));
|
|
253
|
+
expect(brush.current()).toHaveLength(1);
|
|
254
|
+
expect(selection.current()).toHaveLength(1);
|
|
255
|
+
|
|
256
|
+
fireBackgroundTap();
|
|
257
|
+
|
|
258
|
+
expect(brush.current()).toEqual([]);
|
|
259
|
+
expect(brush.rect()).toBeNull();
|
|
260
|
+
expect(selection.current()).toEqual([]);
|
|
261
|
+
});
|
|
262
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { type BrushAxis, type BrushRect, type Color, type CrosshairBounds, type InteractionManager, type Invalidator, type Layer } from "insomni";
|
|
2
|
+
import type { CompiledHitTest, HoveredHit } from "../geoms/types.ts";
|
|
3
|
+
import type { Theme } from "../theme.ts";
|
|
4
|
+
export interface GrammarBrushConfig {
|
|
5
|
+
/** Which axes the brush spans. Default `"xy"`. */
|
|
6
|
+
axis?: BrushAxis;
|
|
7
|
+
/** Translucent fill color. Default theme.axis.color × 0.12 alpha. */
|
|
8
|
+
fillColor?: Color;
|
|
9
|
+
/** Outline color. Default theme.axis.color × 0.6 alpha. */
|
|
10
|
+
strokeColor?: Color;
|
|
11
|
+
/** Outline width in CSS px. Default 1. */
|
|
12
|
+
strokeWidth?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Enable edge/corner resize handles on the committed rect. Default `true`.
|
|
15
|
+
* Disable to lock a brush rect to its initial drag.
|
|
16
|
+
*/
|
|
17
|
+
handles?: boolean;
|
|
18
|
+
/** Hit-test extent of each handle in CSS px. Default 8. */
|
|
19
|
+
handleSize?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Enable drag-to-move on the committed rect interior. Default `true`. The
|
|
22
|
+
* rect's size is held constant during the move; off-axis movement is locked
|
|
23
|
+
* for `axis: "x"` / `"y"` brushes. Disable to lock a brush rect in place.
|
|
24
|
+
*/
|
|
25
|
+
translate?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Snap brush rect edges to the nearest hit-test position along the chosen
|
|
28
|
+
* axis. `true` snaps on the brush's active `axis`; pass `"x"` / `"y"` /
|
|
29
|
+
* `"xy"` to override. Default `false`. Useful for axis-locked range brushes
|
|
30
|
+
* over discrete x-ticks. The snap is computed against the live hit-test
|
|
31
|
+
* positions (refreshed on every `sync()`), so it follows the data.
|
|
32
|
+
*/
|
|
33
|
+
snap?: boolean | BrushAxis;
|
|
34
|
+
}
|
|
35
|
+
export interface GrammarBrushOptions extends GrammarBrushConfig {
|
|
36
|
+
/**
|
|
37
|
+
* Fired when the brushed set changes. Receives one `HoveredHit` per data
|
|
38
|
+
* row whose hit-test position falls within the brush rect.
|
|
39
|
+
*/
|
|
40
|
+
onChange?(hits: HoveredHit[]): void;
|
|
41
|
+
}
|
|
42
|
+
export interface GrammarBrushDeps {
|
|
43
|
+
manager: InteractionManager;
|
|
44
|
+
/** Plot-frame bounds in element-local CSS px. The brush only fires inside this rect. */
|
|
45
|
+
bounds: () => CrosshairBounds;
|
|
46
|
+
hudLayer: () => Layer;
|
|
47
|
+
theme: () => Theme;
|
|
48
|
+
invalidator: Invalidator;
|
|
49
|
+
}
|
|
50
|
+
export interface GrammarBrush {
|
|
51
|
+
/** Replace the active hit-test set after each pipeline run. */
|
|
52
|
+
sync<T>(hits: readonly CompiledHitTest<T>[]): void;
|
|
53
|
+
/** Read-only snapshot of the current brushed hits. */
|
|
54
|
+
current(): HoveredHit[];
|
|
55
|
+
/** Current brush rect, or null when idle. */
|
|
56
|
+
rect(): BrushRect | null;
|
|
57
|
+
/** Imperatively clear the brush. */
|
|
58
|
+
clear(): void;
|
|
59
|
+
/** Draw the brush overlay into the hud layer. */
|
|
60
|
+
draw(): void;
|
|
61
|
+
dispose(): void;
|
|
62
|
+
}
|
|
63
|
+
export declare function createGrammarBrush(deps: GrammarBrushDeps, opts?: GrammarBrushOptions): GrammarBrush;
|