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.
Files changed (242) hide show
  1. package/LICENSE.md +674 -0
  2. package/README.md +81 -0
  3. package/dist/core.d.mts +340 -0
  4. package/dist/core.mjs +1047 -0
  5. package/dist/index.d.mts +3426 -0
  6. package/dist/index.mjs +12762 -0
  7. package/dist/interactions-DEFL_F4E.mjs +5395 -0
  8. package/dist/range-presets-CzECsu3V.d.mts +1523 -0
  9. package/package.json +34 -0
  10. package/src/annotations.d.ts +121 -0
  11. package/src/annotations.ts +438 -0
  12. package/src/axis.d.ts +184 -0
  13. package/src/axis.test.ts +131 -0
  14. package/src/axis.ts +765 -0
  15. package/src/colorbar.d.ts +69 -0
  16. package/src/colorbar.ts +294 -0
  17. package/src/colors.d.ts +57 -0
  18. package/src/colors.test.ts +28 -0
  19. package/src/colors.ts +486 -0
  20. package/src/core.ts +299 -0
  21. package/src/format.d.ts +54 -0
  22. package/src/format.ts +138 -0
  23. package/src/grammar/accessibility.d.ts +147 -0
  24. package/src/grammar/accessibility.test.ts +199 -0
  25. package/src/grammar/accessibility.ts +443 -0
  26. package/src/grammar/aes.d.ts +35 -0
  27. package/src/grammar/aes.test.ts +75 -0
  28. package/src/grammar/aes.ts +120 -0
  29. package/src/grammar/annotations.d.ts +86 -0
  30. package/src/grammar/annotations.test.ts +68 -0
  31. package/src/grammar/annotations.ts +336 -0
  32. package/src/grammar/attach-brush.d.ts +44 -0
  33. package/src/grammar/attach-brush.test.ts +214 -0
  34. package/src/grammar/attach-brush.ts +111 -0
  35. package/src/grammar/attach-presets.d.ts +33 -0
  36. package/src/grammar/attach-presets.test.ts +106 -0
  37. package/src/grammar/attach-presets.ts +215 -0
  38. package/src/grammar/chart.d.ts +952 -0
  39. package/src/grammar/chart.test.ts +118 -0
  40. package/src/grammar/chart.ts +1172 -0
  41. package/src/grammar/color-utils.d.ts +29 -0
  42. package/src/grammar/color-utils.test.ts +53 -0
  43. package/src/grammar/color-utils.ts +66 -0
  44. package/src/grammar/constants.d.ts +45 -0
  45. package/src/grammar/constants.ts +61 -0
  46. package/src/grammar/coord.d.ts +183 -0
  47. package/src/grammar/coord.test.ts +355 -0
  48. package/src/grammar/coord.ts +619 -0
  49. package/src/grammar/data/pivot.d.ts +57 -0
  50. package/src/grammar/data/pivot.ts +107 -0
  51. package/src/grammar/emphasis-driver.d.ts +69 -0
  52. package/src/grammar/emphasis-driver.test.ts +199 -0
  53. package/src/grammar/emphasis-driver.ts +205 -0
  54. package/src/grammar/equality.d.ts +3 -0
  55. package/src/grammar/equality.ts +40 -0
  56. package/src/grammar/facet.d.ts +63 -0
  57. package/src/grammar/facet.test.ts +60 -0
  58. package/src/grammar/facet.ts +175 -0
  59. package/src/grammar/geoms/_categorical.d.ts +94 -0
  60. package/src/grammar/geoms/_categorical.ts +0 -0
  61. package/src/grammar/geoms/_distribution.d.ts +52 -0
  62. package/src/grammar/geoms/_distribution.ts +125 -0
  63. package/src/grammar/geoms/_mark.d.ts +69 -0
  64. package/src/grammar/geoms/_mark.ts +136 -0
  65. package/src/grammar/geoms/_shape.d.ts +41 -0
  66. package/src/grammar/geoms/_shape.ts +74 -0
  67. package/src/grammar/geoms/aggregate.d.ts +95 -0
  68. package/src/grammar/geoms/aggregate.test.ts +554 -0
  69. package/src/grammar/geoms/aggregate.ts +840 -0
  70. package/src/grammar/geoms/area.d.ts +32 -0
  71. package/src/grammar/geoms/area.test.ts +165 -0
  72. package/src/grammar/geoms/area.ts +578 -0
  73. package/src/grammar/geoms/band.d.ts +27 -0
  74. package/src/grammar/geoms/band.test.ts +57 -0
  75. package/src/grammar/geoms/band.ts +126 -0
  76. package/src/grammar/geoms/bar.d.ts +56 -0
  77. package/src/grammar/geoms/bar.test.ts +367 -0
  78. package/src/grammar/geoms/bar.ts +1054 -0
  79. package/src/grammar/geoms/boxplot.d.ts +129 -0
  80. package/src/grammar/geoms/boxplot.test.ts +299 -0
  81. package/src/grammar/geoms/boxplot.ts +834 -0
  82. package/src/grammar/geoms/connected-scatter.d.ts +27 -0
  83. package/src/grammar/geoms/connected-scatter.test.ts +157 -0
  84. package/src/grammar/geoms/connected-scatter.ts +63 -0
  85. package/src/grammar/geoms/emphasis.d.ts +76 -0
  86. package/src/grammar/geoms/emphasis.test.ts +135 -0
  87. package/src/grammar/geoms/emphasis.ts +162 -0
  88. package/src/grammar/geoms/histogram.d.ts +75 -0
  89. package/src/grammar/geoms/histogram.test.ts +262 -0
  90. package/src/grammar/geoms/histogram.ts +740 -0
  91. package/src/grammar/geoms/index.d.ts +20 -0
  92. package/src/grammar/geoms/index.ts +77 -0
  93. package/src/grammar/geoms/interval.d.ts +31 -0
  94. package/src/grammar/geoms/interval.test.ts +154 -0
  95. package/src/grammar/geoms/interval.ts +342 -0
  96. package/src/grammar/geoms/line.d.ts +38 -0
  97. package/src/grammar/geoms/line.test.ts +247 -0
  98. package/src/grammar/geoms/line.ts +659 -0
  99. package/src/grammar/geoms/point.d.ts +57 -0
  100. package/src/grammar/geoms/point.test.ts +163 -0
  101. package/src/grammar/geoms/point.ts +545 -0
  102. package/src/grammar/geoms/polar.test.ts +216 -0
  103. package/src/grammar/geoms/ribbon.d.ts +21 -0
  104. package/src/grammar/geoms/ribbon.test.ts +170 -0
  105. package/src/grammar/geoms/ribbon.ts +87 -0
  106. package/src/grammar/geoms/ridgeline.d.ts +89 -0
  107. package/src/grammar/geoms/ridgeline.test.ts +247 -0
  108. package/src/grammar/geoms/ridgeline.ts +1164 -0
  109. package/src/grammar/geoms/rolling.d.ts +43 -0
  110. package/src/grammar/geoms/rolling.test.ts +217 -0
  111. package/src/grammar/geoms/rolling.ts +387 -0
  112. package/src/grammar/geoms/rug.d.ts +28 -0
  113. package/src/grammar/geoms/rug.test.ts +126 -0
  114. package/src/grammar/geoms/rug.ts +214 -0
  115. package/src/grammar/geoms/rule.d.ts +23 -0
  116. package/src/grammar/geoms/rule.test.ts +69 -0
  117. package/src/grammar/geoms/rule.ts +212 -0
  118. package/src/grammar/geoms/smooth.d.ts +54 -0
  119. package/src/grammar/geoms/smooth.test.ts +78 -0
  120. package/src/grammar/geoms/smooth.ts +337 -0
  121. package/src/grammar/geoms/text.d.ts +29 -0
  122. package/src/grammar/geoms/text.test.ts +64 -0
  123. package/src/grammar/geoms/text.ts +234 -0
  124. package/src/grammar/geoms/tile.d.ts +61 -0
  125. package/src/grammar/geoms/tile.test.ts +157 -0
  126. package/src/grammar/geoms/tile.ts +621 -0
  127. package/src/grammar/geoms/types.d.ts +319 -0
  128. package/src/grammar/geoms/types.ts +362 -0
  129. package/src/grammar/geoms/violin.d.ts +85 -0
  130. package/src/grammar/geoms/violin.test.ts +187 -0
  131. package/src/grammar/geoms/violin.ts +672 -0
  132. package/src/grammar/index.d.ts +22 -0
  133. package/src/grammar/index.ts +269 -0
  134. package/src/grammar/interactions/_disposable.d.ts +5 -0
  135. package/src/grammar/interactions/_disposable.ts +23 -0
  136. package/src/grammar/interactions/_z.d.ts +4 -0
  137. package/src/grammar/interactions/_z.ts +16 -0
  138. package/src/grammar/interactions/brush-selection.test.ts +262 -0
  139. package/src/grammar/interactions/brush.d.ts +63 -0
  140. package/src/grammar/interactions/brush.test.ts +483 -0
  141. package/src/grammar/interactions/brush.ts +452 -0
  142. package/src/grammar/interactions/crosshair.d.ts +19 -0
  143. package/src/grammar/interactions/crosshair.test.ts +127 -0
  144. package/src/grammar/interactions/crosshair.ts +76 -0
  145. package/src/grammar/interactions/hit-layer.d.ts +64 -0
  146. package/src/grammar/interactions/hit-layer.ts +246 -0
  147. package/src/grammar/interactions/legend.d.ts +19 -0
  148. package/src/grammar/interactions/legend.ts +101 -0
  149. package/src/grammar/interactions/menu.d.ts +93 -0
  150. package/src/grammar/interactions/menu.test.ts +373 -0
  151. package/src/grammar/interactions/menu.ts +342 -0
  152. package/src/grammar/interactions/selection.d.ts +25 -0
  153. package/src/grammar/interactions/selection.test.ts +289 -0
  154. package/src/grammar/interactions/selection.ts +142 -0
  155. package/src/grammar/interactions/series-readout.d.ts +91 -0
  156. package/src/grammar/interactions/series-readout.test.ts +668 -0
  157. package/src/grammar/interactions/series-readout.ts +422 -0
  158. package/src/grammar/interactions/series-snap.d.ts +70 -0
  159. package/src/grammar/interactions/series-snap.test.ts +214 -0
  160. package/src/grammar/interactions/series-snap.ts +218 -0
  161. package/src/grammar/interactions/tooltip-axis.test.ts +176 -0
  162. package/src/grammar/interactions/tooltip-touch.browser.test.ts +49 -0
  163. package/src/grammar/interactions/tooltip-touch.test.ts +161 -0
  164. package/src/grammar/interactions/tooltip.d.ts +140 -0
  165. package/src/grammar/interactions/tooltip.test.ts +406 -0
  166. package/src/grammar/interactions/tooltip.ts +622 -0
  167. package/src/grammar/interactions/transitions.d.ts +34 -0
  168. package/src/grammar/interactions/transitions.test.ts +172 -0
  169. package/src/grammar/interactions/transitions.ts +160 -0
  170. package/src/grammar/layout.d.ts +68 -0
  171. package/src/grammar/layout.ts +186 -0
  172. package/src/grammar/legend-merge.test.ts +332 -0
  173. package/src/grammar/mount.d.ts +78 -0
  174. package/src/grammar/mount.test.ts +479 -0
  175. package/src/grammar/mount.ts +2112 -0
  176. package/src/grammar/palettes.d.ts +54 -0
  177. package/src/grammar/palettes.test.ts +80 -0
  178. package/src/grammar/palettes.ts +167 -0
  179. package/src/grammar/pan-zoom.test.ts +398 -0
  180. package/src/grammar/phylo.d.ts +65 -0
  181. package/src/grammar/phylo.test.ts +59 -0
  182. package/src/grammar/phylo.ts +112 -0
  183. package/src/grammar/pipeline.auto-ticks.test.ts +40 -0
  184. package/src/grammar/pipeline.d.ts +158 -0
  185. package/src/grammar/pipeline.test.ts +463 -0
  186. package/src/grammar/pipeline.ts +1233 -0
  187. package/src/grammar/profiling.d.ts +8 -0
  188. package/src/grammar/profiling.ts +24 -0
  189. package/src/grammar/scales.d.ts +188 -0
  190. package/src/grammar/scales.test.ts +181 -0
  191. package/src/grammar/scales.ts +800 -0
  192. package/src/grammar/svg.d.ts +3 -0
  193. package/src/grammar/svg.ts +39 -0
  194. package/src/grammar/theme.d.ts +261 -0
  195. package/src/grammar/theme.test.ts +105 -0
  196. package/src/grammar/theme.ts +490 -0
  197. package/src/heatmap/cpu.ts +109 -0
  198. package/src/heatmap/gpu.ts +565 -0
  199. package/src/heatmap/types.ts +177 -0
  200. package/src/heatmap.browser.test.ts +308 -0
  201. package/src/heatmap.test.ts +320 -0
  202. package/src/heatmap.ts +123 -0
  203. package/src/index.d.ts +1 -0
  204. package/src/index.ts +8 -0
  205. package/src/interactions.d.ts +48 -0
  206. package/src/interactions.test.ts +226 -0
  207. package/src/interactions.ts +394 -0
  208. package/src/layout/box.d.ts +48 -0
  209. package/src/layout/box.test.ts +107 -0
  210. package/src/layout/box.ts +143 -0
  211. package/src/legend.d.ts +115 -0
  212. package/src/legend.ts +422 -0
  213. package/src/marks/curve.d.ts +43 -0
  214. package/src/marks/curve.ts +244 -0
  215. package/src/marks/stack.d.ts +53 -0
  216. package/src/marks/stack.ts +184 -0
  217. package/src/marks.d.ts +273 -0
  218. package/src/marks.test.ts +541 -0
  219. package/src/marks.ts +1292 -0
  220. package/src/navigator.test.ts +174 -0
  221. package/src/navigator.ts +393 -0
  222. package/src/range-presets.d.ts +113 -0
  223. package/src/range-presets.test.ts +345 -0
  224. package/src/range-presets.ts +349 -0
  225. package/src/scales.d.ts +98 -0
  226. package/src/scales.test.ts +103 -0
  227. package/src/scales.ts +695 -0
  228. package/src/stats/index.d.ts +200 -0
  229. package/src/stats/index.test.ts +349 -0
  230. package/src/stats/index.ts +740 -0
  231. package/src/stats/regression.d.ts +38 -0
  232. package/src/stats/regression.test.ts +56 -0
  233. package/src/stats/regression.ts +396 -0
  234. package/src/stats/rolling-window.d.ts +55 -0
  235. package/src/stats/rolling-window.test.ts +237 -0
  236. package/src/stats/rolling-window.ts +256 -0
  237. package/src/test-setup.ts +19 -0
  238. package/src/viewport/axis-state.d.ts +72 -0
  239. package/src/viewport/axis-state.ts +476 -0
  240. package/src/viewport.d.ts +170 -0
  241. package/src/viewport.test.ts +363 -0
  242. package/src/viewport.ts +510 -0
@@ -0,0 +1,32 @@
1
+ import { type Color } from "insomni";
2
+ import { type StackOrder } from "../../marks.ts";
3
+ import type { Aes } from "../aes.ts";
4
+ import type { Geom } from "./types.ts";
5
+ export type AreaPosition = "identity" | "stack" | "fill";
6
+ export interface AreaChannels<T> {
7
+ x: Aes<T, number | Date>;
8
+ /**
9
+ * Single column → simple area from y=0 to y. Array of column keys → stacked
10
+ * area, with the implicit `__series` color channel keyed by column name.
11
+ */
12
+ y: Aes<T, number | Date> | readonly (keyof T & string)[];
13
+ color?: Aes<T, unknown>;
14
+ }
15
+ export interface AreaOptions {
16
+ fill?: Color;
17
+ stroke?: Color;
18
+ strokeWidth?: number;
19
+ /** "identity" (default), "stack" (offset zero), or "fill" (offset expand). */
20
+ position?: AreaPosition;
21
+ /** Stack ordering — only meaningful with stacked positions. */
22
+ order?: StackOrder;
23
+ label?: string;
24
+ /**
25
+ * When true, hover hit-tests resolve to the nearest vertex *by x* — the
26
+ * cursor's vertical position doesn't influence which datum (or stacked
27
+ * segment) is picked, so the user can hover anywhere along the area.
28
+ * Default `false` (per-vertex Euclidean pick within `pickRadius`).
29
+ */
30
+ nearestX?: boolean;
31
+ }
32
+ export declare function area<T>(channels: AreaChannels<T>, options?: AreaOptions): Geom<T>;
@@ -0,0 +1,165 @@
1
+ import { createFrame } from "insomni";
2
+ import { describe, expect, test } from "vite-plus/test";
3
+
4
+ import { resolveAes } from "../aes.ts";
5
+ import { buildPositionScale, type ScaleBundle } from "../scales.ts";
6
+ import { themeDefault } from "../theme.ts";
7
+ import { area } from "./area.ts";
8
+ import type { CompileContext } from "./types.ts";
9
+
10
+ interface Row {
11
+ x: number;
12
+ y: number;
13
+ a: number;
14
+ b: number;
15
+ }
16
+
17
+ const data: Row[] = [
18
+ { x: 0, y: 0, a: 1, b: 2 },
19
+ { x: 5, y: 10, a: 2, b: 3 },
20
+ { x: 10, y: 20, a: 3, b: 4 },
21
+ ];
22
+
23
+ function makeCtx(rows: readonly Row[]): CompileContext<Row> {
24
+ const xAes = resolveAes<Row, unknown>("x");
25
+ const yAes = resolveAes<Row, unknown>("y");
26
+ const xScale = buildPositionScale(xAes, rows, [0, 100]);
27
+ const yScale = buildPositionScale(yAes, rows, [200, 0], { domain: [0, 20] });
28
+ const scales: ScaleBundle = { x: xScale, y: yScale };
29
+ return {
30
+ data: rows,
31
+ scales,
32
+ plot: createFrame({ x: 50, y: 30, width: 100, height: 200 }),
33
+ theme: themeDefault,
34
+ atlas: undefined,
35
+ };
36
+ }
37
+
38
+ function fakePolygonLayer(): {
39
+ polygons: Array<{ points: Array<{ x: number; y: number }> }>;
40
+ layer: { pushPolygon: (shape: { points: Array<{ x: number; y: number }> }) => void };
41
+ } {
42
+ const polygons: Array<{ points: Array<{ x: number; y: number }> }> = [];
43
+ return {
44
+ polygons,
45
+ layer: {
46
+ pushPolygon(shape) {
47
+ polygons.push(shape);
48
+ },
49
+ },
50
+ };
51
+ }
52
+
53
+ describe("area geom — compileHitTest", () => {
54
+ test("emits one hit per vertex at top-edge (x, y1) absolute px", () => {
55
+ const geom = area<Row>({ x: "x", y: "y" });
56
+ const hits = geom.compileHitTest!(makeCtx(data))!;
57
+ expect(hits.geomKind).toBe("area");
58
+ expect(hits.dataIndex.length).toBe(3);
59
+ expect(hits.positions[0]).toBeCloseTo(50, 3);
60
+ expect(hits.positions[1]).toBeCloseTo(230, 3);
61
+ expect(hits.positions[5]).toBeCloseTo(30, 3);
62
+ });
63
+
64
+ test("filters non-finite positions", () => {
65
+ const dirty: Row[] = [
66
+ { x: 0, y: 0, a: 0, b: 0 },
67
+ { x: NaN, y: 5, a: 0, b: 0 },
68
+ { x: 10, y: 20, a: 0, b: 0 },
69
+ ];
70
+ const geom = area<Row>({ x: "x", y: "y" });
71
+ const hits = geom.compileHitTest!(makeCtx(dirty))!;
72
+ expect(Array.from(hits.dataIndex)).toEqual([0, 2]);
73
+ });
74
+
75
+ test("emits one hit per stacked-area segment top vertex", () => {
76
+ const geom = area<Row>({ x: "x", y: ["a", "b"] });
77
+ const hits = geom.compileHitTest!(makeCtx(data))!;
78
+ expect(Array.from(hits.dataIndex)).toEqual([0, 0, 1, 1, 2, 2]);
79
+ expect(hits.seriesKey).toEqual(["a", "b", "a", "b", "a", "b"]);
80
+ });
81
+
82
+ test("captures one frame entry per visible stacked-area segment", () => {
83
+ const geom = area<Row>({ x: "x", y: ["a", "b"] });
84
+ const frame = geom.captureFrame!(makeCtx(data))!;
85
+ expect(frame.count).toBe(6);
86
+ expect(frame.r).toBeDefined();
87
+ });
88
+
89
+ test("stacked area compile lerps polygon vertices during activeTransition", () => {
90
+ const fromRows: Row[] = [
91
+ { x: 0, y: 0, a: 2, b: 2 },
92
+ { x: 10, y: 0, a: 2, b: 2 },
93
+ ];
94
+ const toRows: Row[] = [
95
+ { x: 0, y: 0, a: 6, b: 6 },
96
+ { x: 10, y: 0, a: 6, b: 6 },
97
+ ];
98
+ const geom = area<Row>({ x: "x", y: ["a", "b"] });
99
+ const from = geom.captureFrame!(makeCtx(fromRows))!;
100
+ const builders = geom.compile({
101
+ ...makeCtx(toRows),
102
+ activeTransition: {
103
+ t: 0.5,
104
+ from,
105
+ matchIndex: (_key, fallbackIndex) => fallbackIndex,
106
+ },
107
+ });
108
+ const { polygons, layer } = fakePolygonLayer();
109
+ for (const builder of builders) builder.addTo(layer as never);
110
+ expect(polygons).toHaveLength(2);
111
+ expect(polygons[0]!.points[0]!.y).toBeCloseTo(190, 3);
112
+ expect(polygons[1]!.points[0]!.y).toBeCloseTo(150, 3);
113
+ });
114
+
115
+ test("returns null for empty data", () => {
116
+ const geom = area<Row>({ x: "x", y: "y" });
117
+ expect(geom.compileHitTest!(makeCtx([]))).toBeNull();
118
+ });
119
+ });
120
+
121
+ describe("area geom — stacked halos & selection rings", () => {
122
+ function countStrokedCircles(
123
+ builders: ReturnType<ReturnType<typeof area<Row>>["compile"]>,
124
+ ): number {
125
+ let stroked = 0;
126
+ const layer = {
127
+ pushPolygon() {},
128
+ pushCircle(shape: { stroke?: unknown }) {
129
+ if (shape.stroke !== undefined) stroked++;
130
+ },
131
+ };
132
+ for (const builder of builders) builder.addTo(layer as never);
133
+ return stroked;
134
+ }
135
+
136
+ test("hover halo on stacked area draws a stroked circle on the hovered segment top", () => {
137
+ const geom = area<Row>({ x: "x", y: ["a", "b"] });
138
+ const builders = geom.compile({
139
+ ...makeCtx(data),
140
+ hovered: { geomKind: "area", dataIndex: 1, seriesKey: "b", data, x: 0, y: 0 },
141
+ });
142
+ expect(countStrokedCircles(builders)).toBe(1);
143
+ });
144
+
145
+ test("selection rings on stacked area: one ring per selected segment", () => {
146
+ const geom = area<Row>({ x: "x", y: ["a", "b"] });
147
+ const builders = geom.compile({
148
+ ...makeCtx(data),
149
+ selected: [
150
+ { geomKind: "area", dataIndex: 0, seriesKey: "a", data, x: 0, y: 0 },
151
+ { geomKind: "area", dataIndex: 2, seriesKey: "b", data, x: 0, y: 0 },
152
+ ],
153
+ });
154
+ expect(countStrokedCircles(builders)).toBe(2);
155
+ });
156
+
157
+ test("stacked area halo skipped when hovered.seriesKey is missing", () => {
158
+ const geom = area<Row>({ x: "x", y: ["a", "b"] });
159
+ const builders = geom.compile({
160
+ ...makeCtx(data),
161
+ hovered: { geomKind: "area", dataIndex: 0, data, x: 0, y: 0 },
162
+ });
163
+ expect(countStrokedCircles(builders)).toBe(0);
164
+ });
165
+ });