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,215 @@
1
+ // ---------------------------------------------------------------------------
2
+ // attachRangePresets — high-level helper on top of createRangePresets
3
+ // ---------------------------------------------------------------------------
4
+ // Wraps the headless `createRangePresets` controller with an optional DOM
5
+ // chip strip. Lets a consumer go from "I have a MountedPlot and want 1M/3M/…
6
+ // buttons" to a single call site, while still preserving the headless flow
7
+ // for charts that render their own UI (Svelte/React/Solid components,
8
+ // existing toolbars, etc.) — omit the `ui` field and you get the same
9
+ // controller `createRangePresets` would have returned.
10
+
11
+ import type { Color } from "insomni";
12
+ import type { Theme } from "./theme.ts";
13
+ import {
14
+ createRangePresets,
15
+ timePreset,
16
+ type RangePreset,
17
+ type RangePresetDataDomain,
18
+ type RangePresetsController,
19
+ type RangePresetsSubscriber,
20
+ type TimePresetKey,
21
+ } from "../range-presets.ts";
22
+ import type { DataViewport } from "../viewport.ts";
23
+
24
+ // ---------------------------------------------------------------------------
25
+ // Types
26
+ // ---------------------------------------------------------------------------
27
+
28
+ /** Where the chip strip sits inside its mount element. */
29
+ export type AttachRangePresetsPosition = "top-left" | "top-right" | "bottom-left" | "bottom-right";
30
+
31
+ export interface AttachRangePresetsUi {
32
+ /** Element to append the chip strip into (typically the chart's stage). */
33
+ mount: HTMLElement;
34
+ /** Corner placement inside `mount`. Defaults to `"top-left"`. */
35
+ position?: AttachRangePresetsPosition;
36
+ /** Inset (px) from the chosen corner. Defaults to `12`. */
37
+ inset?: number;
38
+ }
39
+
40
+ export interface AttachRangePresetsOptions {
41
+ axis: "x" | "y";
42
+ /**
43
+ * Presets to expose. A `TimePresetKey` string is expanded to `timePreset(key)`;
44
+ * pass a full `RangePreset` for custom presets (label override, linear/log
45
+ * presets, etc.).
46
+ */
47
+ presets: readonly (TimePresetKey | RangePreset)[];
48
+ dataDomain?: RangePresetDataDomain;
49
+ now?: () => number;
50
+ /** Omit to skip DOM construction — returns the same controller, headless. */
51
+ ui?: AttachRangePresetsUi;
52
+ }
53
+
54
+ export interface AttachedRangePresets {
55
+ setActive(key: string | null): void;
56
+ getActive(): string | null;
57
+ subscribe(fn: RangePresetsSubscriber): () => void;
58
+ dispose(): void;
59
+ }
60
+
61
+ // ---------------------------------------------------------------------------
62
+ // Public entry — used by MountedPlot.attachRangePresets and exported directly
63
+ // for tests / advanced consumers that don't go through mount.
64
+ // ---------------------------------------------------------------------------
65
+
66
+ export function attachRangePresets(
67
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
68
+ viewport: DataViewport<any, any>,
69
+ theme: Theme,
70
+ opts: AttachRangePresetsOptions,
71
+ ): AttachedRangePresets {
72
+ const presets = opts.presets.map((p) => (typeof p === "string" ? timePreset(p) : p));
73
+ const controller: RangePresetsController = createRangePresets({
74
+ viewport,
75
+ axis: opts.axis,
76
+ presets,
77
+ dataDomain: opts.dataDomain,
78
+ now: opts.now,
79
+ });
80
+
81
+ const strip = opts.ui ? buildChipStrip(opts.ui, theme, presets, controller) : null;
82
+
83
+ return {
84
+ setActive(key) {
85
+ controller.setActive(key);
86
+ },
87
+ getActive() {
88
+ return controller.getActive();
89
+ },
90
+ subscribe(fn) {
91
+ return controller.subscribe(fn);
92
+ },
93
+ dispose() {
94
+ strip?.dispose();
95
+ controller.dispose();
96
+ },
97
+ };
98
+ }
99
+
100
+ // ---------------------------------------------------------------------------
101
+ // DOM helpers — all in one place so consumers can read the styling pattern
102
+ // when they want to roll their own UI.
103
+ // ---------------------------------------------------------------------------
104
+
105
+ interface ChipStripHandle {
106
+ dispose(): void;
107
+ }
108
+
109
+ const POSITION_STYLES: Record<AttachRangePresetsPosition, (inset: number) => string> = {
110
+ "top-left": (i) => `top:${i}px;left:${i}px`,
111
+ "top-right": (i) => `top:${i}px;right:${i}px`,
112
+ "bottom-left": (i) => `bottom:${i}px;left:${i}px`,
113
+ "bottom-right": (i) => `bottom:${i}px;right:${i}px`,
114
+ };
115
+
116
+ function buildChipStrip(
117
+ ui: AttachRangePresetsUi,
118
+ theme: Theme,
119
+ presets: readonly RangePreset[],
120
+ controller: RangePresetsController,
121
+ ): ChipStripHandle {
122
+ const doc = ui.mount.ownerDocument;
123
+ const inset = ui.inset ?? 12;
124
+ const position = ui.position ?? "top-left";
125
+ const tokens = chipTokens(theme);
126
+
127
+ const strip = doc.createElement("div");
128
+ strip.style.cssText = [
129
+ "position:absolute",
130
+ POSITION_STYLES[position](inset),
131
+ "display:flex",
132
+ "gap:4px",
133
+ "z-index:60",
134
+ "pointer-events:auto",
135
+ ].join(";");
136
+
137
+ const buttons = new Map<string, HTMLButtonElement>();
138
+ const setChipActive = (btn: HTMLButtonElement, active: boolean): void => {
139
+ btn.style.background = active ? tokens.activeBackground : tokens.background;
140
+ btn.style.color = active ? tokens.activeText : tokens.text;
141
+ btn.style.borderColor = active ? tokens.activeBorder : tokens.border;
142
+ };
143
+ for (const preset of presets) {
144
+ const btn = doc.createElement("button");
145
+ btn.type = "button";
146
+ btn.textContent = preset.label;
147
+ btn.dataset.key = preset.key;
148
+ btn.style.cssText = [
149
+ "padding:4px 9px",
150
+ "border-radius:5px",
151
+ "border:1px solid",
152
+ `font:${theme.legend.fontSize - 2}px/1.4 ${cssFontStack(theme.text.fontFamily)}`,
153
+ "cursor:pointer",
154
+ ].join(";");
155
+ btn.addEventListener("click", () => controller.setActive(preset.key));
156
+ setChipActive(btn, false);
157
+ strip.appendChild(btn);
158
+ buttons.set(preset.key, btn);
159
+ }
160
+
161
+ const applyActive = (key: string | null): void => {
162
+ for (const [k, btn] of buttons) setChipActive(btn, k === key);
163
+ };
164
+ applyActive(controller.getActive());
165
+ const unsub = controller.subscribe(applyActive);
166
+
167
+ ui.mount.appendChild(strip);
168
+ return {
169
+ dispose() {
170
+ unsub();
171
+ strip.remove();
172
+ },
173
+ };
174
+ }
175
+
176
+ interface ChipTokens {
177
+ background: string;
178
+ border: string;
179
+ text: string;
180
+ activeBackground: string;
181
+ activeBorder: string;
182
+ activeText: string;
183
+ }
184
+
185
+ function chipTokens(theme: Theme): ChipTokens {
186
+ // Derive chip colors from existing legend/background tokens so the strip
187
+ // tracks dark/light themes without adding a new token section. The active
188
+ // accent picks the first categorical palette slot — same color the legend
189
+ // would use for the first series, which keeps the chip strip visually
190
+ // anchored to the chart's color language.
191
+ const accent = theme.palettes.categorical(0);
192
+ return {
193
+ background: cssColor(withAlphaC(theme.background, 0.85)),
194
+ border: cssColor(withAlphaC(theme.legend.labelColor, 0.18)),
195
+ text: cssColor(withAlphaC(theme.legend.labelColor, 0.7)),
196
+ activeBackground: cssColor(withAlphaC(accent, 0.18)),
197
+ activeBorder: cssColor(withAlphaC(accent, 0.45)),
198
+ activeText: cssColor(theme.legend.labelColor),
199
+ };
200
+ }
201
+
202
+ function cssColor(c: Color): string {
203
+ const r = Math.round(c.r * 255);
204
+ const g = Math.round(c.g * 255);
205
+ const b = Math.round(c.b * 255);
206
+ return `rgba(${r},${g},${b},${c.a})`;
207
+ }
208
+
209
+ function withAlphaC(c: Color, alpha: number): Color {
210
+ return { r: c.r, g: c.g, b: c.b, a: c.a * alpha };
211
+ }
212
+
213
+ function cssFontStack(family: string | undefined): string {
214
+ return family && family.length > 0 ? family : "ui-sans-serif,system-ui,sans-serif";
215
+ }