@fusion.dev/helix-plot 0.218.0 → 0.220.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.
@@ -45,13 +45,16 @@ export interface PlotColors {
45
45
  * and its numbers and names are drawn, which the chart's `no-box` turns off.
46
46
  * `contours` and `drops` are whether a surface's contour lines and a
47
47
  * scatter's lines down to the floor are drawn, as its `contours` and
48
- * `drop-lines` ask.
48
+ * `drop-lines` ask. `muted` is whether the marks are drawn in the neutral
49
+ * ink, all but the ones a cell gives a tone, as a bar chart's
50
+ * `emphasis="muted"` asks; `emphasis` then reads `solid`.
49
51
  */
50
52
  look: {
51
53
  box: boolean;
52
54
  contours: boolean;
53
55
  drops: boolean;
54
56
  emphasis: 'outlined' | 'solid' | 'subtle';
57
+ muted: boolean;
55
58
  through: number;
56
59
  };
57
60
  /** The page a faded fill moves toward: `background`. */
@@ -43,6 +43,7 @@ export const plotColorsFrom = (chart, groups, extra = {}) => {
43
43
  contours: chart.hasAttribute('contours'),
44
44
  drops: chart.hasAttribute('drop-lines'),
45
45
  emphasis: emphasis === 'outlined' || emphasis === 'subtle' ? emphasis : 'solid',
46
+ muted: emphasis === 'muted',
46
47
  through: material === 'glass' ? 0.62 * scale : material === 'frosted' ? 0.88 * scale : 1,
47
48
  };
48
49
  const colors = [];
@@ -3,9 +3,16 @@ import { type Axes, type PlotConnection, type PlotDriver } from '../connect-plot
3
3
  export interface BarCell {
4
4
  across: number;
5
5
  column: number;
6
+ /** Its series, which colors it. */
6
7
  depth: number;
8
+ /** Where its block starts: zero, or under `stacked` the blocks below it. */
9
+ from: number;
7
10
  label: string;
11
+ /** The row of the grid in depth it stands in: its series, or the one row of a stacked chart. */
12
+ lane: number;
8
13
  row: number;
14
+ /** The tone its cell names, which colors its own bar. */
15
+ tone?: string | undefined;
9
16
  value?: number | undefined;
10
17
  }
11
18
  /**
@@ -18,8 +25,12 @@ export interface BarField {
18
25
  axes: Axes;
19
26
  categories: readonly string[];
20
27
  cells: readonly BarCell[];
28
+ /** How many rows of bars stand in depth: one a series, or one in all when stacked. */
29
+ lanes: number;
21
30
  readings: number;
22
31
  series: readonly string[];
32
+ /** Whether a category's series stand in one column, each on the ones before it. */
33
+ stacked: boolean;
23
34
  }
24
35
  /** A renderer for a Spatial Bar Chart: `focus` and `onPress` take a bar's index in `field.cells`. */
25
36
  export type SpatialBarChartDriver = PlotDriver<BarField>;
@@ -33,7 +44,8 @@ export type SpatialBarChartConnection = PlotConnection;
33
44
  * one of your own. The connection draws the chart's bars in the driver, each
34
45
  * series in a series color, marks the bar the keys rest on, turns the view
35
46
  * for Shift with an arrow, and puts a bar pressed in the drawing on the
36
- * chart's reading. Once the driver has drawn, the chart hides its own SVG
37
- * drawing; `disconnect()` shows it again.
47
+ * chart's reading. A bar whose cell names a tone takes the page's
48
+ * `--spatial-bar-chart-tone-*` color. Once the driver has drawn, the chart
49
+ * hides its own SVG drawing; `disconnect()` shows it again.
38
50
  */
39
51
  export declare const connectSpatialBarChart: (frame: HTMLElement, driver: SpatialBarChartDriver) => SpatialBarChartConnection;
@@ -1,5 +1,9 @@
1
1
  import { connectPlot, } from '../connect-plot/connect-plot.js';
2
2
  export const connectSpatialBarChart = (frame, driver) => connectPlot(frame, driver, {
3
+ extraOf: (field) => Object.fromEntries([...new Set(field.cells.flatMap((cell) => (cell.tone ? [cell.tone] : [])))].map((tone) => [
4
+ `tone-${tone}`,
5
+ `var(--spatial-bar-chart-tone-${tone}, var(--helix-color-primary))`,
6
+ ])),
3
7
  groupsOf: (field) => field.series.length,
4
8
  name: 'connectSpatialBarChart',
5
9
  readings: (field) => field.readings,
@@ -21,9 +21,12 @@ export interface ThreeBarDriverOptions {
21
21
  * connectSpatialBarChart(chart, threeBarDriver(chart.querySelector('div')))
22
22
  * ```
23
23
  *
24
- * **Each bar is a block from zero to its value**, on a grid of categories
25
- * across and series in depth, in a box with a grid on its floor and two of
26
- * its walls, lit from above. Each series takes a series color from the theme.
24
+ * **Each bar is a block from zero to its value**, or under `stacked` from
25
+ * the blocks below it, on a grid of categories across and series in depth, in a box with a grid on its floor and two of
26
+ * its walls, lit from above. Each series takes a series color from the theme,
27
+ * and a bar whose cell names a tone takes that tone's. Under the chart's
28
+ * `emphasis="muted"`, every other bar is the neutral ink. The chart's own
29
+ * drawing alone draws a row, the glow, a toned bar's value, and the growth.
27
30
  *
28
31
  * **Dragging turns the box, and the wheel and a pinch bring it nearer.**
29
32
  * Shift with an arrow on the chart turns it a step. It never turns by itself.
@@ -42,31 +42,36 @@ export const threeBarDriver = (container, options = {}) => {
42
42
  draw: (next, colors, font) => {
43
43
  field = next;
44
44
  const [ex, ey, ez] = next.axes.extent ?? [1, 1, 1];
45
- const spacing = Math.min((2 * HALF * ex) / Math.max(next.categories.length, 1), (2 * HALF * ez) / Math.max(next.series.length, 1));
45
+ const spacing = Math.min((2 * HALF * ex) / Math.max(next.categories.length, 1), (2 * HALF * ez) / Math.max(next.lanes, 1));
46
46
  const width = spacing * FOOTPRINT;
47
- const zero = inBox(next.axes.y, 0) * ey;
48
47
  const page = new Color(colors.page);
49
- const { emphasis, through } = colors.look;
48
+ const { emphasis, muted, through } = colors.look;
50
49
  const solids = [];
51
50
  const lines = [];
52
51
  drawnCells = [];
53
52
  tops = new Map();
54
53
  next.cells.forEach((cell, index) => {
55
- if (cell.value === undefined) {
54
+ if (cell.value === undefined || (next.stacked && cell.value === 0)) {
56
55
  return;
57
56
  }
58
- const tone = new Color(colors.groups[cell.depth % colors.groups.length] ?? colors.ink);
57
+ const toned = cell.tone ? colors.extra[`tone-${cell.tone}`] : undefined;
58
+ const tone = toned
59
+ ? new Color(toned)
60
+ : muted
61
+ ? new Color(colors.ground).lerp(new Color(colors.ink), 0.3)
62
+ : new Color(colors.groups[cell.depth % colors.groups.length] ?? colors.ink);
59
63
  const color = emphasis === 'outlined' ? tone.clone().lerp(page, 0.4) : tone;
60
- const top = inBox(next.axes.y, cell.value) * ey;
61
- const tall = Math.max(Math.abs(top - zero), 1e-3);
64
+ const start = inBox(next.axes.y, cell.from) * ey;
65
+ const top = inBox(next.axes.y, cell.from + cell.value) * ey;
66
+ const tall = Math.max(Math.abs(top - start), 1e-3);
62
67
  const x = inBox(next.axes.x, cell.across) * ex;
63
- const z = inBox(next.axes.z, cell.depth) * ez;
68
+ const z = inBox(next.axes.z, cell.lane) * ez;
64
69
  const box = new BoxGeometry(width, tall, width);
65
- box.translate(x, Math.min(top, zero) + tall / 2, z);
70
+ box.translate(x, Math.min(top, start) + tall / 2, z);
66
71
  solids.push(painted(box, color));
67
72
  lines.push(painted(new EdgesGeometry(box), emphasis === 'solid' ? edgeOf(color) : tone));
68
73
  drawnCells.push(index);
69
- tops.set(index, new Vector3(x, Math.max(top, zero), z));
74
+ tops.set(index, new Vector3(x, Math.max(top, start), z));
70
75
  });
71
76
  lookThrough(barMaterial, (emphasis === 'subtle' ? 0.2 : 1) * through);
72
77
  lookThrough(edgeMaterial, through);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fusion.dev/helix-plot",
3
3
  "description": "Connects the Helix spatial charts to three.js, which draws them in three dimensions: Spatial Bar Chart, Spatial Heatmap, Spatial Ribbon Chart, Spatial Scatter Chart, Spatial Surface Chart, and Spatial Treemap.",
4
- "version": "0.218.0",
4
+ "version": "0.220.0",
5
5
  "license": "MIT",
6
6
  "author": "Ross Sheppard <ross.sheppard@fusion.dev>",
7
7
  "repository": {
@@ -36,11 +36,11 @@
36
36
  },
37
37
  "bugs": "https://github.com/project-fusion/fusion/issues",
38
38
  "dependencies": {
39
- "@fusion.dev/helix-core": "0.218.0"
39
+ "@fusion.dev/helix-core": "0.220.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@fusion.dev/helix-headless": "0.218.0",
43
- "@fusion.dev/helix-testing": "0.218.0",
42
+ "@fusion.dev/helix-headless": "0.220.0",
43
+ "@fusion.dev/helix-testing": "0.220.0",
44
44
  "@types/bun": "^1.4.3",
45
45
  "@types/three": "^0.186.0",
46
46
  "three": "^0.186.1"