@fusion.dev/helix-plot 0.0.0-dev

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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +147 -0
  3. package/dist/connect-plot/connect-plot.d.ts +125 -0
  4. package/dist/connect-plot/connect-plot.d.ts.map +1 -0
  5. package/dist/connect-plot/connect-plot.js +130 -0
  6. package/dist/connect-plot/connect-plot.js.map +1 -0
  7. package/dist/connect-spatial-heatmap/connect-spatial-heatmap.d.ts +43 -0
  8. package/dist/connect-spatial-heatmap/connect-spatial-heatmap.d.ts.map +1 -0
  9. package/dist/connect-spatial-heatmap/connect-spatial-heatmap.js +15 -0
  10. package/dist/connect-spatial-heatmap/connect-spatial-heatmap.js.map +1 -0
  11. package/dist/connect-spatial-scatter-chart/connect-spatial-scatter-chart.d.ts +34 -0
  12. package/dist/connect-spatial-scatter-chart/connect-spatial-scatter-chart.d.ts.map +1 -0
  13. package/dist/connect-spatial-scatter-chart/connect-spatial-scatter-chart.js +7 -0
  14. package/dist/connect-spatial-scatter-chart/connect-spatial-scatter-chart.js.map +1 -0
  15. package/dist/connect-spatial-surface-chart/connect-spatial-surface-chart.d.ts +39 -0
  16. package/dist/connect-spatial-surface-chart/connect-spatial-surface-chart.d.ts.map +1 -0
  17. package/dist/connect-spatial-surface-chart/connect-spatial-surface-chart.js +7 -0
  18. package/dist/connect-spatial-surface-chart/connect-spatial-surface-chart.js.map +1 -0
  19. package/dist/index.d.ts +5 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +5 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/three/heatmap-driver.d.ts +36 -0
  24. package/dist/three/heatmap-driver.d.ts.map +1 -0
  25. package/dist/three/heatmap-driver.js +120 -0
  26. package/dist/three/heatmap-driver.js.map +1 -0
  27. package/dist/three/index.d.ts +4 -0
  28. package/dist/three/index.d.ts.map +1 -0
  29. package/dist/three/index.js +4 -0
  30. package/dist/three/index.js.map +1 -0
  31. package/dist/three/scatter-driver.d.ts +38 -0
  32. package/dist/three/scatter-driver.d.ts.map +1 -0
  33. package/dist/three/scatter-driver.js +85 -0
  34. package/dist/three/scatter-driver.js.map +1 -0
  35. package/dist/three/stage.d.ts +66 -0
  36. package/dist/three/stage.d.ts.map +1 -0
  37. package/dist/three/stage.js +446 -0
  38. package/dist/three/stage.js.map +1 -0
  39. package/dist/three/surface-driver.d.ts +39 -0
  40. package/dist/three/surface-driver.d.ts.map +1 -0
  41. package/dist/three/surface-driver.js +150 -0
  42. package/dist/three/surface-driver.js.map +1 -0
  43. package/package.json +68 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Fusion Development Group
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,147 @@
1
+ # @fusion.dev/helix-plot
2
+
3
+ Connects the Helix `Spatial Heatmap`, `Spatial Scatter Chart` and
4
+ `Spatial Surface Chart` to three.js, which draws them in three dimensions,
5
+ lit, in a view you can drag round and zoom, colored from your tokens. Each
6
+ also draws itself in SVG, which this package replaces where it is connected.
7
+
8
+ ```sh
9
+ bun add @fusion.dev/helix @fusion.dev/helix-plot three
10
+ ```
11
+
12
+ Put the chart beside its table, with an element inside it for the renderer to
13
+ draw in:
14
+
15
+ ```html
16
+ <table id="customers">…</table>
17
+
18
+ <helix-spatial-scatter-chart for="customers" group-by="Segment" label="Customers">
19
+ <div></div>
20
+ </helix-spatial-scatter-chart>
21
+ ```
22
+
23
+ Connect the two:
24
+
25
+ ```js
26
+ import '@fusion.dev/helix/spatial-scatter-chart'
27
+ import { connectSpatialScatterChart } from '@fusion.dev/helix-plot'
28
+ import { threeScatterDriver } from '@fusion.dev/helix-plot/three'
29
+
30
+ const chart = document.querySelector('helix-spatial-scatter-chart')
31
+ const connection = connectSpatialScatterChart(chart, threeScatterDriver(chart.querySelector('div')))
32
+ ```
33
+
34
+ ## What a scatter does
35
+
36
+ - **The chart reads its table.** The first three numeric columns are across,
37
+ up, and in depth, and `group-by` names a column of text that colors each
38
+ point by its group, from the theme's series colors.
39
+ - **The points stand in a box** with a grid on its floor and two of its walls
40
+ at the ticks, and each axis named along its edges.
41
+ - **Dragging turns the box, and the wheel and a pinch bring it nearer.** Shift
42
+ with an arrow on the chart turns it a step of 15 degrees. It never turns by
43
+ itself.
44
+ - **A point the mouse rests on, or one tapped or pressed, is the chart's
45
+ reading**, as one reached by the keys is. It is ringed in the drawing, and
46
+ the chart shows its row in the tooltip every Helix chart shows, pointed at
47
+ the ring and following it as the view turns.
48
+ - **It draws only while something moves**, and asks the browser for no frames
49
+ at rest or while its box is out of view.
50
+ - **Every three.js drawing Helix makes on a page shares six WebGL contexts**,
51
+ the graph's and the plot's alike. Past six, one far off screen gives its
52
+ context back and takes it again as it comes near.
53
+ - **Until the renderer has drawn, the chart draws the points in 3D itself**,
54
+ in SVG, from about where the renderer's camera starts, and it draws them
55
+ again after `connection.disconnect()`.
56
+
57
+ | `threeScatterDriver` option | Default | What else it takes |
58
+ |---|---|---|
59
+ | `density` | screen × 1.5, 2 to 3; on a touch screen, the screen's own, at most 2 | How many pixels the drawing has for each of the page's |
60
+ | `pointSize` | `9` | How large a point is drawn, in CSS pixels, at any distance |
61
+
62
+ ## A surface
63
+
64
+ `Spatial Surface Chart` connects the same way, with its own connector and driver:
65
+
66
+ ```html
67
+ <table id="load">…</table>
68
+
69
+ <helix-spatial-surface-chart for="load" label="Load over a week">
70
+ <div></div>
71
+ </helix-spatial-surface-chart>
72
+ ```
73
+
74
+ ```js
75
+ import '@fusion.dev/helix/spatial-surface-chart'
76
+ import { connectSpatialSurfaceChart } from '@fusion.dev/helix-plot'
77
+ import { threeSurfaceDriver } from '@fusion.dev/helix-plot/three'
78
+
79
+ const chart = document.querySelector('helix-spatial-surface-chart')
80
+ const connection = connectSpatialSurfaceChart(chart, threeSurfaceDriver(chart.querySelector('div')))
81
+ ```
82
+
83
+ - **The chart reads its table as a grid.** Each row is one reading: the first
84
+ numeric column is across, the second is in depth, and the third is the
85
+ height. A place on the grid with no reading leaves a hole in the surface.
86
+ - **The surface is shaded along a ramp**, from `--spatial-surface-chart-low` to
87
+ `--spatial-surface-chart-high`, which default to a quiet tint of the theme's
88
+ `primary-active` and to `primary-active` itself. It is lit from above and
89
+ ruled along the grid.
90
+ - **A place the mouse rests on, or one tapped or pressed, is the chart's
91
+ reading**, ringed and shown in the chart's tooltip as the scatter's is. The
92
+ left and right arrows move across, and the down and up arrows in depth.
93
+ - The box, the turning, the frames, and the shared contexts are the scatter's.
94
+ - **Until the renderer has drawn, the chart draws the surface in 3D itself**,
95
+ in SVG, as the scatter draws its points.
96
+
97
+ | `threeSurfaceDriver` option | Default | What else it takes |
98
+ |---|---|---|
99
+ | `density` | screen × 1.5, 2 to 3; on a touch screen, the screen's own, at most 2 | How many pixels the drawing has for each of the page's |
100
+
101
+ ## A heatmap
102
+
103
+ `Spatial Heatmap` takes the renderer's box in its `renderer` slot, since its
104
+ table sits inside it:
105
+
106
+ ```html
107
+ <helix-spatial-heatmap for="commits" rows="7">
108
+ <table id="commits">…</table>
109
+ <div slot="renderer"></div>
110
+ </helix-spatial-heatmap>
111
+ ```
112
+
113
+ ```js
114
+ import '@fusion.dev/helix/spatial-heatmap'
115
+ import { connectSpatialHeatmap } from '@fusion.dev/helix-plot'
116
+ import { threeHeatmapDriver } from '@fusion.dev/helix-plot/three'
117
+
118
+ const chart = document.querySelector('helix-spatial-heatmap')
119
+ const box = chart.querySelector('[slot="renderer"]')
120
+ const connection = connectSpatialHeatmap(chart, threeHeatmapDriver(box))
121
+ ```
122
+
123
+ - **Each reading is a prism on a slab**, as tall as the chart's own drawing
124
+ stands it and in its tone from the `--heatmap-tone-*` tokens, lit from
125
+ above, with each edge set a little apart from its face.
126
+ - **The view starts at the isometric angle** the chart's own drawing is seen
127
+ from, fitted to the relief, so nothing jumps when the renderer takes over.
128
+ - **The chart's own drawing stays under the renderer's, unseen**, where a
129
+ screen reader and the keys still reach it, `selection-mode` included.
130
+ - **Shift with an arrow turns the view**, except under
131
+ `selection-mode="multiple"`, where it selects a range as it always has.
132
+ - **The `start` and `end` labels stand at the two ends of the front edge**
133
+ where the renderer draws them, as they do in the chart's own drawing, and
134
+ follow them as the view turns.
135
+
136
+ | `threeHeatmapDriver` option | Default | What else it takes |
137
+ |---|---|---|
138
+ | `density` | screen × 1.5, 2 to 3; on a touch screen, the screen's own, at most 2 | How many pixels the drawing has for each of the page's |
139
+
140
+ ## What it exports
141
+
142
+ | Import | What |
143
+ |---|---|
144
+ | `@fusion.dev/helix-plot` | `connectSpatialHeatmap(chart, driver)`, `connectSpatialScatterChart(chart, driver)`, `connectSpatialSurfaceChart(chart, driver)`, `plotColorsFrom(chart, groups, extra)`, and the types `Axes`, `Axis`, `Field`, `HeatmapCell`, `Place`, `PlotColors`, `PlotConnection`, `PlotDriver`, `Point`, `PointerKind`, `SpatialHeatmapConnection`, `SpatialHeatmapDriver`, `SpatialHeatmapField`, `SpatialScatterChartConnection`, `SpatialScatterChartDriver`, `SpatialSurfaceChartConnection`, `SpatialSurfaceChartDriver`, `SurfaceCell` and `SurfaceField` |
145
+ | `@fusion.dev/helix-plot/three` | `threeHeatmapDriver(box, options)`, `threeScatterDriver(box, options)` and `threeSurfaceDriver(box, options)`, and the types `ThreeHeatmapDriverOptions`, `ThreeScatterDriverOptions` and `ThreeSurfaceDriverOptions` |
146
+
147
+ **three.js is an optional peer**, so a page brings the version it has. `@fusion.dev/helix-plot` itself never imports it: only `@fusion.dev/helix-plot/three` does, so a page with a driver of its own needs no three.js.
@@ -0,0 +1,125 @@
1
+ /** One axis of a plot: its column's name, its range, and the ticks on it. */
2
+ export interface Axis {
3
+ name: string;
4
+ range: readonly [number, number];
5
+ ticks: readonly number[];
6
+ }
7
+ /** A plot's three axes: across, up, and in depth. */
8
+ export interface Axes {
9
+ readonly x: Axis;
10
+ readonly y: Axis;
11
+ readonly z: Axis;
12
+ }
13
+ /** The colors a plot is drawn in, each `rgb()`, read from the page's tokens where the chart is. */
14
+ export interface PlotColors {
15
+ /**
16
+ * Any further colors the chart names, by the name it gave them: a spatial
17
+ * heatmap's tones, its empty tiles, and its base.
18
+ */
19
+ extra: Record<string, string>;
20
+ /** The box's edges and grid lines: `border`. */
21
+ grid: string;
22
+ /** What the drawing is laid on: `surface-sunken`. */
23
+ ground: string;
24
+ /** One color for each group, in the order of the groups: `--chart-series-1` and on. */
25
+ groups: string[];
26
+ /** The names and the ring on what the keys rest on: `foreground`. */
27
+ ink: string;
28
+ /** The ticks' numbers: `foreground-muted`. */
29
+ quiet: string;
30
+ /**
31
+ * The ramp a height is shaded along, from `--spatial-surface-chart-low` to
32
+ * `--spatial-surface-chart-high`: a quiet tint of `primary-active` up to it whole.
33
+ */
34
+ ramp: {
35
+ high: string;
36
+ low: string;
37
+ };
38
+ }
39
+ /** What moved a reading in the drawing. */
40
+ export type PointerKind = 'mouse' | 'pen' | 'touch';
41
+ /** Where a reading is drawn, as fractions of the box the drawing fills, from its top left. */
42
+ export interface Place {
43
+ x: number;
44
+ y: number;
45
+ }
46
+ /**
47
+ * What a renderer has to answer for a 3D chart to drive it, and nothing that
48
+ * is the same for every renderer: that is the connector's.
49
+ */
50
+ export interface PlotDriver<F> {
51
+ /** Draws the chart's field and the axes, replacing whatever was drawn. */
52
+ draw(field: F, colors: PlotColors, font: string): void;
53
+ /** Marks the reading at `index` as the one the keys rest on, or none with `-1`. */
54
+ focus(index: number): void;
55
+ /**
56
+ * Calls `hover` with the index of the reading a mouse or a pen rests on in
57
+ * the drawing, and with `-1` when it rests on none. Returns what stops
58
+ * listening.
59
+ */
60
+ onHover?(hover: (index: number, kind: PointerKind) => void): () => void;
61
+ /**
62
+ * Calls `place` with where the reading `focus` marked is drawn, whenever a
63
+ * frame moves it, and with `undefined` while none is marked or it is out of
64
+ * view. The chart points its tooltip there. Returns what stops listening.
65
+ */
66
+ onPlace?(place: (at: Place | undefined) => void): () => void;
67
+ /**
68
+ * Calls `corners` with where the drawing's named corners are drawn, the
69
+ * two ends of a spatial heatmap's front edge, whenever a frame moves them,
70
+ * and with `undefined` while they are out of view. The chart stands its
71
+ * first and last labels there. Returns what stops listening.
72
+ */
73
+ onCorners?(corners: (at: {
74
+ end: Place;
75
+ start: Place;
76
+ } | undefined) => void): () => void;
77
+ /**
78
+ * Calls `press` with a reading's index when the reader presses it in the
79
+ * drawing, and with `-1` when they press where none is. Returns what stops
80
+ * listening.
81
+ */
82
+ onPress?(press: (index: number, kind: PointerKind) => void): () => void;
83
+ /** Turns the view by steps across and up, over a short animation or at once. */
84
+ turnBy(across: number, up: number, animate: boolean): void;
85
+ /** Removes whatever the driver added to the page, and frees its renderer. */
86
+ stop?(): void;
87
+ }
88
+ /** A connection, which is ended rather than left to leak. */
89
+ export interface PlotConnection {
90
+ /** Stops answering the chart, frees the renderer, and shows the chart's flat drawing again. */
91
+ disconnect(): void;
92
+ /**
93
+ * Reads the page's colors again. The connection hears a theme that changes
94
+ * by a class, a mode, or the reader's preference on its own; call this
95
+ * after replacing a stylesheet, which no attribute shows.
96
+ */
97
+ restyle(): void;
98
+ }
99
+ /**
100
+ * The page's colors where the chart is, or `null` while they cannot be read.
101
+ *
102
+ * **Settled by the browser and read back as `rgb()`**, since a token is
103
+ * `light-dark()` over a ramp, which only the browser can settle for the
104
+ * chart's scheme, and what it settles to may be `oklch()`, which three.js
105
+ * cannot read. Read inside the chart, so a chart in a dark region of a light
106
+ * page is drawn dark, and from the names the chart's own sheet gives the
107
+ * series, so a page that colors its groups colors them here too.
108
+ */
109
+ export declare const plotColorsFrom: (chart: Element, groups: number, extra?: Record<string, string>) => PlotColors | null;
110
+ /**
111
+ * Connects a 3D chart to a driver: draws the chart's field, colors it from
112
+ * the page's tokens, marks the chart's reading, turns the view for Shift
113
+ * with an arrow, puts a reading hovered or pressed in the drawing on the
114
+ * chart, and tells the chart where its reading is drawn, for its tooltip.
115
+ * `groupsOf` says how many group colors the field needs, and `name` is the
116
+ * connector a misuse is reported by.
117
+ */
118
+ export declare const connectPlot: <F extends object>(frame: HTMLElement, driver: PlotDriver<F>, options: {
119
+ /** Further colors to read, by name, as CSS colors that may name the page's tokens. */
120
+ extraOf?: (field: F) => Record<string, string>;
121
+ groupsOf: (field: F) => number;
122
+ name: string;
123
+ readings: (field: F) => number;
124
+ }) => PlotConnection;
125
+ //# sourceMappingURL=connect-plot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-plot.d.ts","sourceRoot":"","sources":["../../src/connect-plot/connect-plot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,130 @@
1
+ import { HelixPlotChangeEvent, HelixPlotTurnEvent, reportRuntime, rgbOf, watchTheme, } from '@fusion.dev/helix-core';
2
+ const SERIES = 24;
3
+ const still = () => typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;
4
+ export const plotColorsFrom = (chart, groups, extra = {}) => {
5
+ if (typeof document === 'undefined') {
6
+ return null;
7
+ }
8
+ const probe = document.createElement('span');
9
+ probe.style.display = 'none';
10
+ probe.setAttribute('aria-hidden', 'true');
11
+ (chart.shadowRoot ?? chart).append(probe);
12
+ try {
13
+ const read = (value) => {
14
+ probe.style.color = '';
15
+ probe.style.color = value;
16
+ const color = getComputedStyle(probe).color;
17
+ return color === '' ? null : rgbOf(color);
18
+ };
19
+ const token = (name) => {
20
+ probe.style.color = '';
21
+ probe.style.color = `var(--helix-color-${name}, transparent)`;
22
+ const color = getComputedStyle(probe).color.replace(/\s/g, '');
23
+ return color === '' || color === 'transparent' || color === 'rgba(0,0,0,0)'
24
+ ? null
25
+ : read(`var(--helix-color-${name})`);
26
+ };
27
+ const [grid, ground, ink, quiet] = [
28
+ 'border',
29
+ 'surface-sunken',
30
+ 'foreground',
31
+ 'foreground-muted',
32
+ ].map(token);
33
+ if (!grid || !ground || !ink || !quiet) {
34
+ return null;
35
+ }
36
+ const colors = [];
37
+ for (let at = 0; at < Math.max(groups, 1); at++) {
38
+ colors.push(read(`var(--chart-series-${(at % SERIES) + 1}, var(--helix-color-primary))`) ?? ink);
39
+ }
40
+ const high = read('var(--spatial-surface-chart-high, var(--helix-color-primary-active))') ?? ink;
41
+ const low = read('var(--spatial-surface-chart-low, color-mix(in oklab, var(--helix-color-primary-active) 15%, var(--helix-color-surface-sunken)))') ?? ground;
42
+ const named = {};
43
+ for (const [name, value] of Object.entries(extra)) {
44
+ named[name] = read(value) ?? ink;
45
+ }
46
+ return { extra: named, grid, ground, groups: colors, ink, quiet, ramp: { high, low } };
47
+ }
48
+ finally {
49
+ probe.remove();
50
+ }
51
+ };
52
+ export const connectPlot = (frame, driver, options) => {
53
+ const chart = frame;
54
+ if (!('field' in frame) || typeof chart.requestActive !== 'function') {
55
+ reportRuntime({
56
+ detail: frame,
57
+ kind: 'not-a-plot',
58
+ message: `${options.name}: the element given is not the 3D chart it connects, so nothing will be drawn.`,
59
+ tag: frame.localName,
60
+ });
61
+ }
62
+ let connected = true;
63
+ const draw = () => {
64
+ const field = chart.field;
65
+ if (!connected || !field) {
66
+ return;
67
+ }
68
+ const colors = plotColorsFrom(frame, options.groupsOf(field), options.extraOf?.(field));
69
+ if (!colors || options.readings(field) === 0) {
70
+ chart.rendererDrawn?.(false);
71
+ return;
72
+ }
73
+ const font = getComputedStyle(frame)
74
+ .fontFamily.split(',')[0]
75
+ ?.trim()
76
+ .replace(/^["']|["']$/g, '') ?? '';
77
+ driver.draw(field, colors, font || 'sans-serif');
78
+ driver.focus(chart.active ?? -1);
79
+ chart.rendererDrawn?.(true);
80
+ };
81
+ const handleChange = (event) => {
82
+ const { kind } = event.detail;
83
+ if (kind === 'data') {
84
+ draw();
85
+ }
86
+ else {
87
+ driver.focus(chart.active ?? -1);
88
+ }
89
+ };
90
+ const handleTurn = (event) => {
91
+ const { across, up } = event.detail;
92
+ driver.turnBy(across, up, !still());
93
+ };
94
+ frame.addEventListener(HelixPlotChangeEvent.eventName, handleChange);
95
+ frame.addEventListener(HelixPlotTurnEvent.eventName, handleTurn);
96
+ const stopPress = driver.onPress?.((index, kind) => {
97
+ chart.requestActive?.(index, kind);
98
+ });
99
+ const stopHover = driver.onHover?.((index, kind) => {
100
+ chart.requestActive?.(index, kind);
101
+ });
102
+ const stopPlace = driver.onPlace?.((at) => {
103
+ chart.placeReading?.(at);
104
+ });
105
+ const stopCorners = driver.onCorners?.((at) => {
106
+ chart.placeCorners?.(at);
107
+ });
108
+ const stopTheme = watchTheme(frame, () => {
109
+ draw();
110
+ });
111
+ void Promise.resolve(chart.updateComplete).then(draw);
112
+ return {
113
+ disconnect: () => {
114
+ connected = false;
115
+ frame.removeEventListener(HelixPlotChangeEvent.eventName, handleChange);
116
+ frame.removeEventListener(HelixPlotTurnEvent.eventName, handleTurn);
117
+ stopPress?.();
118
+ stopHover?.();
119
+ stopPlace?.();
120
+ stopCorners?.();
121
+ chart.placeReading?.(undefined);
122
+ chart.placeCorners?.(undefined);
123
+ stopTheme();
124
+ driver.stop?.();
125
+ chart.rendererDrawn?.(false);
126
+ },
127
+ restyle: draw,
128
+ };
129
+ };
130
+ //# sourceMappingURL=connect-plot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-plot.js","sourceRoot":"","sources":["../../src/connect-plot/connect-plot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { type PlotConnection, type PlotDriver } from '../connect-plot/connect-plot.js';
2
+ /** One reading of a spatial heatmap, where it stands on the grid and how tall. */
3
+ export interface HeatmapCell {
4
+ /** Which column it stands in, from the oldest drawn. */
5
+ column: number;
6
+ /** How tall it stands, in cells, from zero. */
7
+ height: number;
8
+ /** The row's own label, which names it. */
9
+ label: string;
10
+ /** Which row of its column it stands in. */
11
+ row: number;
12
+ /** The tone it is painted in, as the chart names it, or none for a day with nothing in it. */
13
+ tone?: string | undefined;
14
+ }
15
+ /**
16
+ * What a spatial heatmap publishes for a renderer to draw: every reading it
17
+ * draws, down each column and then across, as its own drawing paints them,
18
+ * and how many columns and rows the grid has.
19
+ */
20
+ export interface SpatialHeatmapField {
21
+ cells: readonly HeatmapCell[];
22
+ columns: number;
23
+ rows: number;
24
+ }
25
+ /** A renderer for a spatial heatmap: `focus` and `onPress` take a reading's place in `field.cells`. */
26
+ export type SpatialHeatmapDriver = PlotDriver<SpatialHeatmapField>;
27
+ /** A connection between a spatial heatmap and its renderer. */
28
+ export type SpatialHeatmapConnection = PlotConnection;
29
+ /**
30
+ * Connects a spatial heatmap to whatever draws it in three dimensions.
31
+ *
32
+ * The chart is `helix-spatial-heatmap` or `helix-headless-spatial-heatmap`,
33
+ * with the renderer's box in its `renderer` slot, and the driver is
34
+ * `threeHeatmapDriver` from `@fusion.dev/helix-plot/three`, or one of your
35
+ * own. The connection draws the chart's readings as prisms in the driver,
36
+ * each in its tone from the page's `--heatmap-tone-*` tokens, marks the
37
+ * reading the chart rests on, turns the view for Shift with an arrow, and
38
+ * puts a reading hovered or pressed in the drawing on the chart. Once the
39
+ * driver has drawn, the chart's own SVG drawing gives way to it;
40
+ * `disconnect()` shows it again.
41
+ */
42
+ export declare const connectSpatialHeatmap: (frame: HTMLElement, driver: SpatialHeatmapDriver) => SpatialHeatmapConnection;
43
+ //# sourceMappingURL=connect-spatial-heatmap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-spatial-heatmap.d.ts","sourceRoot":"","sources":["../../src/connect-spatial-heatmap/connect-spatial-heatmap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,iCAAiC,CAAA;AAEnG,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAA;IACd,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAA;IACd,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAA;IACb,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAA;IACX,8FAA8F;IAC9F,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAA;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb;AAED,uGAAuG;AACvG,MAAM,MAAM,oBAAoB,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAA;AAElE,+DAA+D;AAC/D,MAAM,MAAM,wBAAwB,GAAG,cAAc,CAAA;AAErD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB,UACzB,WAAW,UACV,oBAAoB,KAC3B,wBAiBC,CAAA"}
@@ -0,0 +1,15 @@
1
+ import { connectPlot } from '../connect-plot/connect-plot.js';
2
+ export const connectSpatialHeatmap = (frame, driver) => connectPlot(frame, driver, {
3
+ extraOf: (field) => ({
4
+ base: 'color-mix(in oklab, var(--helix-color-surface-sunken), var(--helix-color-border) 45%)',
5
+ tile: 'color-mix(in oklab, var(--helix-color-surface-sunken), var(--helix-color-surface) 60%)',
6
+ ...Object.fromEntries([...new Set(field.cells.flatMap((cell) => (cell.tone ? [cell.tone] : [])))].map((tone) => [
7
+ `tone-${tone}`,
8
+ `var(--heatmap-tone-${tone})`,
9
+ ])),
10
+ }),
11
+ groupsOf: () => 0,
12
+ name: 'connectSpatialHeatmap',
13
+ readings: (field) => field.cells.length,
14
+ });
15
+ //# sourceMappingURL=connect-spatial-heatmap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-spatial-heatmap.js","sourceRoot":"","sources":["../../src/connect-spatial-heatmap/connect-spatial-heatmap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAwC,MAAM,iCAAiC,CAAA;AA8CnG,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,KAAkB,EAClB,MAA4B,EACF,EAAE,CAC5B,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE;IAGzB,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACnB,IAAI,EAAE,uFAAuF;QAC7F,IAAI,EAAE,wFAAwF;QAC9F,GAAG,MAAM,CAAC,WAAW,CACnB,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACxF,QAAQ,IAAI,EAAE;YACd,sBAAsB,IAAI,GAAG;SAC9B,CAAC,CACH;KACF,CAAC;IACF,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;IACjB,IAAI,EAAE,uBAAuB;IAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM;CACxC,CAAC,CAAA"}
@@ -0,0 +1,34 @@
1
+ import { type Axes, type PlotConnection, type PlotDriver } from '../connect-plot/connect-plot.js';
2
+ /** One point of the plot: its row's label, its group, and its three numbers. */
3
+ export interface Point {
4
+ group: string;
5
+ groupIndex: number;
6
+ label: string;
7
+ row: number;
8
+ x: number;
9
+ y: number;
10
+ z: number;
11
+ }
12
+ /** What a Spatial Scatter Chart publishes for a renderer to draw: its points, its axes, and its groups. */
13
+ export interface Field {
14
+ axes: Axes;
15
+ groups: readonly string[];
16
+ points: readonly Point[];
17
+ }
18
+ /** A renderer for a Spatial Scatter Chart: `focus` and `onPress` take a point's place in `field.points`. */
19
+ export type SpatialScatterChartDriver = PlotDriver<Field>;
20
+ /** A connection between a Spatial Scatter Chart and its renderer. */
21
+ export type SpatialScatterChartConnection = PlotConnection;
22
+ /**
23
+ * Connects a Spatial Scatter Chart to whatever draws it in three dimensions.
24
+ *
25
+ * The chart is `helix-spatial-scatter-chart` or `helix-headless-spatial-scatter-chart`, and the
26
+ * driver is `threeScatterDriver` from `@fusion.dev/helix-plot/three`, or one
27
+ * of your own. The connection draws the chart's points and axes in the
28
+ * driver, colors each group from the page's series tokens, marks the point
29
+ * the keys rest on, turns the view for Shift with an arrow, and puts a point
30
+ * pressed in the drawing on the chart's reading. Once the driver has drawn,
31
+ * the chart hides its own SVG drawing; `disconnect()` shows it again.
32
+ */
33
+ export declare const connectSpatialScatterChart: (frame: HTMLElement, driver: SpatialScatterChartDriver) => SpatialScatterChartConnection;
34
+ //# sourceMappingURL=connect-spatial-scatter-chart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-spatial-scatter-chart.d.ts","sourceRoot":"","sources":["../../src/connect-spatial-scatter-chart/connect-spatial-scatter-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,IAAI,EAET,KAAK,cAAc,EACnB,KAAK,UAAU,EAChB,MAAM,iCAAiC,CAAA;AAExC,gFAAgF;AAChF,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV;AAED,2GAA2G;AAC3G,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,IAAI,CAAA;IACV,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IACzB,MAAM,EAAE,SAAS,KAAK,EAAE,CAAA;CACzB;AAED,4GAA4G;AAC5G,MAAM,MAAM,yBAAyB,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;AAEzD,qEAAqE;AACrE,MAAM,MAAM,6BAA6B,GAAG,cAAc,CAAA;AAE1D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,0BAA0B,UAC9B,WAAW,UACV,yBAAyB,KAChC,6BAKC,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { connectPlot, } from '../connect-plot/connect-plot.js';
2
+ export const connectSpatialScatterChart = (frame, driver) => connectPlot(frame, driver, {
3
+ groupsOf: (field) => field.groups.length,
4
+ name: 'connectSpatialScatterChart',
5
+ readings: (field) => field.points.length,
6
+ });
7
+ //# sourceMappingURL=connect-spatial-scatter-chart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-spatial-scatter-chart.js","sourceRoot":"","sources":["../../src/connect-spatial-scatter-chart/connect-spatial-scatter-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,GAGZ,MAAM,iCAAiC,CAAA;AAqCxC,MAAM,CAAC,MAAM,0BAA0B,GAAG,CACxC,KAAkB,EAClB,MAAiC,EACF,EAAE,CACjC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE;IACzB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;IACxC,IAAI,EAAE,4BAA4B;IAClC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;CACzC,CAAC,CAAA"}
@@ -0,0 +1,39 @@
1
+ import { type Axes, type PlotConnection, type PlotDriver } from '../connect-plot/connect-plot.js';
2
+ /** One place on a surface's grid, and its reading, where the table has one. */
3
+ export interface SurfaceCell {
4
+ label?: string | undefined;
5
+ row?: number | undefined;
6
+ value?: number | undefined;
7
+ x: number;
8
+ z: number;
9
+ }
10
+ /**
11
+ * What a Spatial Surface Chart publishes for a renderer to draw: every place on
12
+ * its grid, across first, so the place `across` along and `depth` back is
13
+ * `cells[across * depths.length + depth]`, and its axes.
14
+ */
15
+ export interface SurfaceField {
16
+ acrosses: readonly number[];
17
+ axes: Axes;
18
+ cells: readonly SurfaceCell[];
19
+ depths: readonly number[];
20
+ readings: number;
21
+ }
22
+ /** A renderer for a Spatial Surface Chart: `focus` and `onPress` take a place's index in `field.cells`. */
23
+ export type SpatialSurfaceChartDriver = PlotDriver<SurfaceField>;
24
+ /** A connection between a Spatial Surface Chart and its renderer. */
25
+ export type SpatialSurfaceChartConnection = PlotConnection;
26
+ /**
27
+ * Connects a Spatial Surface Chart to whatever draws it in three dimensions.
28
+ *
29
+ * The chart is `helix-spatial-surface-chart` or `helix-headless-spatial-surface-chart`, and the
30
+ * driver is `threeSurfaceDriver` from `@fusion.dev/helix-plot/three`, or one
31
+ * of your own. The connection draws the chart's grid as a surface in the
32
+ * driver, shaded along the ramp `--spatial-surface-chart-low` to `--spatial-surface-chart-high`,
33
+ * marks the place the keys rest on, turns the view for Shift with an arrow,
34
+ * and puts a place pressed in the drawing on the chart's reading. Once the
35
+ * driver has drawn, the chart hides its own SVG drawing; `disconnect()`
36
+ * shows it again.
37
+ */
38
+ export declare const connectSpatialSurfaceChart: (frame: HTMLElement, driver: SpatialSurfaceChartDriver) => SpatialSurfaceChartConnection;
39
+ //# sourceMappingURL=connect-spatial-surface-chart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-spatial-surface-chart.d.ts","sourceRoot":"","sources":["../../src/connect-spatial-surface-chart/connect-spatial-surface-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,IAAI,EAET,KAAK,cAAc,EACnB,KAAK,UAAU,EAChB,MAAM,iCAAiC,CAAA;AAExC,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,IAAI,EAAE,IAAI,CAAA;IACV,KAAK,EAAE,SAAS,WAAW,EAAE,CAAA;IAC7B,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IACzB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,2GAA2G;AAC3G,MAAM,MAAM,yBAAyB,GAAG,UAAU,CAAC,YAAY,CAAC,CAAA;AAEhE,qEAAqE;AACrE,MAAM,MAAM,6BAA6B,GAAG,cAAc,CAAA;AAE1D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,0BAA0B,UAC9B,WAAW,UACV,yBAAyB,KAChC,6BAKC,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { connectPlot, } from '../connect-plot/connect-plot.js';
2
+ export const connectSpatialSurfaceChart = (frame, driver) => connectPlot(frame, driver, {
3
+ groupsOf: () => 0,
4
+ name: 'connectSpatialSurfaceChart',
5
+ readings: (field) => field.readings,
6
+ });
7
+ //# sourceMappingURL=connect-spatial-surface-chart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-spatial-surface-chart.js","sourceRoot":"","sources":["../../src/connect-spatial-surface-chart/connect-spatial-surface-chart.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,GAGZ,MAAM,iCAAiC,CAAA;AA0CxC,MAAM,CAAC,MAAM,0BAA0B,GAAG,CACxC,KAAkB,EAClB,MAAiC,EACF,EAAE,CACjC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE;IACzB,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;IACjB,IAAI,EAAE,4BAA4B;IAClC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ;CACpC,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ export { type Axes, type Axis, type Place, type PlotColors, type PlotConnection, type PlotDriver, type PointerKind, plotColorsFrom, } from './connect-plot/connect-plot.js';
2
+ export { connectSpatialHeatmap, type HeatmapCell, type SpatialHeatmapConnection, type SpatialHeatmapDriver, type SpatialHeatmapField, } from './connect-spatial-heatmap/connect-spatial-heatmap.js';
3
+ export { connectSpatialScatterChart, type Field, type Point, type SpatialScatterChartConnection, type SpatialScatterChartDriver, } from './connect-spatial-scatter-chart/connect-spatial-scatter-chart.js';
4
+ export { connectSpatialSurfaceChart, type SpatialSurfaceChartConnection, type SpatialSurfaceChartDriver, type SurfaceCell, type SurfaceField, } from './connect-spatial-surface-chart/connect-spatial-surface-chart.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,IAAI,EACT,KAAK,IAAI,EACT,KAAK,KAAK,EACV,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,cAAc,GACf,MAAM,gCAAgC,CAAA;AACvC,OAAO,EACL,qBAAqB,EACrB,KAAK,WAAW,EAChB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,sDAAsD,CAAA;AAC7D,OAAO,EACL,0BAA0B,EAC1B,KAAK,KAAK,EACV,KAAK,KAAK,EACV,KAAK,6BAA6B,EAClC,KAAK,yBAAyB,GAC/B,MAAM,kEAAkE,CAAA;AACzE,OAAO,EACL,0BAA0B,EAC1B,KAAK,6BAA6B,EAClC,KAAK,yBAAyB,EAC9B,KAAK,WAAW,EAChB,KAAK,YAAY,GAClB,MAAM,kEAAkE,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { plotColorsFrom, } from './connect-plot/connect-plot.js';
2
+ export { connectSpatialHeatmap, } from './connect-spatial-heatmap/connect-spatial-heatmap.js';
3
+ export { connectSpatialScatterChart, } from './connect-spatial-scatter-chart/connect-spatial-scatter-chart.js';
4
+ export { connectSpatialSurfaceChart, } from './connect-spatial-surface-chart/connect-spatial-surface-chart.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,cAAc,GACf,MAAM,gCAAgC,CAAA;AACvC,OAAO,EACL,qBAAqB,GAKtB,MAAM,sDAAsD,CAAA;AAC7D,OAAO,EACL,0BAA0B,GAK3B,MAAM,kEAAkE,CAAA;AACzE,OAAO,EACL,0BAA0B,GAK3B,MAAM,kEAAkE,CAAA"}