@fasl-work/caos-app-shell 0.17.0 → 0.19.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/chart.css CHANGED
@@ -22,3 +22,8 @@
22
22
  .caos-chart.fill[data-parity] > .caos-chart-plot { display: flex; align-items: center; justify-content: center; }
23
23
  .caos-chart[data-pick] .u-over { cursor: pointer; }
24
24
  .caos-chart .u-cursor-x, .caos-chart .u-cursor-y { border-color: var(--color-fg-faint) !important; }
25
+ /* The key that solos a series (`solo`, 0.18.0): each entry is a button. At rest it reads as the plain key; the soloed one is
26
+ set off by a border and bold text, in the text colour, never by colour alone. */
27
+ .caos-chart-key-button { display: inline-flex; align-items: center; gap: 0.3rem; min-width: 0; margin: 0; padding: 0.15rem 0.45rem; border: 1px solid transparent; border-radius: 0.4rem; background: none; color: inherit; font: inherit; line-height: inherit; text-align: start; cursor: pointer; }
28
+ .caos-chart-key-button:hover { border-color: var(--color-border); }
29
+ .caos-chart-key-button[aria-pressed="true"] { border-color: var(--color-fg-subtle); color: var(--color-fg); font-weight: 600; }
package/dist/chart.d.ts CHANGED
@@ -1,10 +1,29 @@
1
1
  import * as react from 'react';
2
2
  import uPlot from 'uplot';
3
- import { F as FormatOptions, S as ShellColorToken } from './tokens-BTOzar-U.js';
4
- import { B as BiText } from './text-BlY47nIt.js';
3
+ import { F as FormatOptions, S as ShellColorToken } from './tokens-BvU9bFPw.js';
4
+ export { r as referenceLineName, a as repeatedLabels } from './tokens-BvU9bFPw.js';
5
+ import { B as BiText, L as Lang } from './text-BlY47nIt.js';
5
6
  import 'zustand';
6
7
 
8
+ /**
9
+ * The pure rules of the interactions every shell chart carries (Tier A of the interactive-visualization rubric, shell 0.19.0):
10
+ * zoom and pan of a range, the keys of the keyboard model, the window of categories a bar chart shows, the text a screen
11
+ * reader gets, and the thinning of a long table. Nothing here touches the DOM, so each rule is tested in node.
12
+ */
13
+
14
+ /** A placed mark label, in device pixels: the box its text occupies (`y1` is the baseline). */
15
+ interface LabelBox {
16
+ x0: number;
17
+ y0: number;
18
+ x1: number;
19
+ y1: number;
20
+ }
21
+
7
22
  interface ChartSeries {
23
+ /** What identifies the series to the solo key (0.18.0): the solo follows the series with this id when the list of series
24
+ * changes (one dropped, one added, a label changed), not its position. Without an id the English label is the key. Unique
25
+ * within the chart; with two series of one key the first is taken. */
26
+ id?: string;
8
27
  label: BiText;
9
28
  /** One value per x; `null` leaves a gap. */
10
29
  values: (number | null)[];
@@ -20,6 +39,14 @@ interface ChartSeries {
20
39
  * value. It is drawn over the plot on its own x, outside the curve's data, so it takes no part in the cursor, the
21
40
  * pick or the readout, and the axes take its extent in. */
22
41
  x?: number[];
42
+ /** A dot at each value of a `line` series (CAOS_Fragmenta drew them under 40 values: `dots={x.length < 40}`). Off by
43
+ * default; no dot is drawn at a `null`. */
44
+ dots?: boolean;
45
+ }
46
+ /** A named x tick: the x value it sits at and the text the axis reads there (and the readout, for an x on it). */
47
+ interface ChartTick {
48
+ value: number;
49
+ label: BiText;
23
50
  }
24
51
  /** What a reference line may be dragged over: the range it stays inside, and the step it snaps to (a hundredth of the
25
52
  * range when not given; on a log axis the step is a factor). */
@@ -46,6 +73,17 @@ interface UPlotChartProps {
46
73
  values: number[];
47
74
  time?: boolean;
48
75
  log?: boolean;
76
+ /** Named ticks (0.18.0): the axis ticks exactly at these values, no other, each labelled with its text in the page
77
+ * language (a categorical axis: protocols, blast ids). The readout names an x that sits on one by its label. A tick
78
+ * outside the range is not drawn; an empty list leaves uPlot its own ticks. A value listed twice keeps its first label.
79
+ * Labels must be different from each other, adjacent or not (the gate fails any repeated label, G6). An x is on a tick
80
+ * when it is within 1e-9 of the x span of it. Ignored on a time axis. */
81
+ ticks?: ChartTick[];
82
+ /** The x scale spans at least this range (0.18.0), as `y.range` fixes the y scale: widen it past the data so an end tick's
83
+ * label is not cut by the plot edge. The data and the overlays still widen it further. On a log axis a range that reaches 0
84
+ * or below is ignored (the overlays still widen the scale); on a parity chart it is ignored, the chart's own shared range
85
+ * rules. */
86
+ range?: [number, number];
49
87
  };
50
88
  y: ChartAxis & {
51
89
  log?: boolean;
@@ -58,10 +96,10 @@ interface UPlotChartProps {
58
96
  label: BiText;
59
97
  }[];
60
98
  /** Horizontal reference lines at y values, labelled at their right end (a null model's constant prediction, a
61
- * target, a limit). */
99
+ * target, a limit). A line without a `label` is drawn with no label box and nothing reserved for one (a zero line). */
62
100
  yMarks?: {
63
101
  y: number;
64
- label: BiText;
102
+ label?: BiText;
65
103
  tone?: YMarkTone;
66
104
  drag?: YMarkDrag;
67
105
  }[];
@@ -88,7 +126,49 @@ interface UPlotChartProps {
88
126
  readout?: (index: number) => string;
89
127
  /** The readout at rest; by default "Hover the chart to read the values". */
90
128
  hint?: BiText;
129
+ /** The key solos a series (0.18.0): each entry is a button (`aria-pressed`, Tab, click, Enter or Space) that dims every
130
+ * other series (alpha 0.12, 1 px) and leaves the chosen one as drawn; pressing it again releases it, pressing another
131
+ * moves the solo. The chart is redrawn, not rebuilt. A chart of one series shows the key too. Off by default. */
132
+ solo?: boolean;
133
+ /** The chart's accessible name and the name of its data table (0.19.0); by default the y axis by the x axis. */
134
+ title?: BiText;
135
+ /** Zoom and pan the y axis too (0.19.0): the wheel, the pinch, the brush and the keys then work on both axes (a parity plot
136
+ * always does, its two axes share one range). Off by default: x zooms and y follows the visible data. */
137
+ zoomY?: boolean;
138
+ /** Turn zoom, pan and the brush off (0.19.0), with the reason, in both languages when the page is bilingual (a chart whose
139
+ * range is the finding). It names a reason of at least 12 characters, or the gate fails it; the gate lists every chart that
140
+ * sets it. The keyboard crosshair, the readout, the data table and the summary cannot be turned off. */
141
+ zoomOff?: BiText;
91
142
  }
143
+ /** The alpha a series takes when another one is soloed (0.18.0; what CAOS_Fragmenta's key did). */
144
+ declare const SOLO_DIM_ALPHA = 0.12;
145
+ /** How a series is drawn while `solo` (the index in `series` of the soloed one, or null) is held: as given, or dimmed to
146
+ * `SOLO_DIM_ALPHA` and 1 px when another is soloed. Dimmed, never hidden, so the reader keeps the context. */
147
+ declare function soloStyle(solo: number | null, i: number, width: number): {
148
+ alpha: number;
149
+ width: number;
150
+ };
151
+ /** The values a named x axis ticks at inside [min, max]: ascending, each once; on a log axis only the ones above 0. A value
152
+ * that is not a number is dropped. */
153
+ declare function tickSplits(ticks: readonly ChartTick[], min: number, max: number, log?: boolean): number[];
154
+ /** The label of the named tick at an x, in the page language; null when no tick sits there. An x is on a tick when it is
155
+ * within 1e-9 of `span` (the x span, as `tickSplits` takes the range) of its value, so 0.1 + 0.2 is on a tick at 0.3; without
156
+ * a span only an equal x is. A value listed twice keeps its first label. */
157
+ declare function tickLabelAt(ticks: readonly ChartTick[] | undefined, x: number, lang: Lang, span?: number): string | null;
158
+ /** How many of the labels of named ticks repeat another's, adjacent or not (the gate's check of numeric ticks counts only
159
+ * neighbours, and on a categorical axis order means nothing), and which ones; an empty label is no label. */
160
+ declare function namedRepeats(labels: readonly string[]): {
161
+ n: number;
162
+ names: string[];
163
+ };
164
+ /** What a series is known by to the solo key: its id, else its English label. */
165
+ declare function soloKey(s: ChartSeries): string;
166
+ /** The x scale of a chart whose x range is fixed, or whose overlays reach past the curve: the data's extent widened by the
167
+ * given range and by the overlays' x; null when none is given (uPlot's own range), and on a log axis when the data would reach 0.
168
+ * One x alone gets a unit either side, a decade on a log axis. `xs` is sorted ascending. */
169
+ declare function xScaleRange(xs: readonly number[], ext: {
170
+ x: [number, number];
171
+ } | null, range: readonly [number, number] | undefined, log: boolean): [number, number] | null;
92
172
  /** The colour and dash of a series: its own, or the rotation's; when the rotation comes round (a seventh series
93
173
  * repeats the first colour) the repeat is dashed, so two series never look the same (CAOS_Fragmenta drew this for
94
174
  * itself until 0.9.0). */
@@ -149,14 +229,22 @@ declare function overlayExtent(series: readonly ChartSeries[], positiveX?: boole
149
229
  x: [number, number];
150
230
  y: [number, number];
151
231
  } | null;
152
- /** How many tick labels repeat the label before them (empty labels apart); the gate fails a chart with any (G6). */
153
- declare function repeatedLabels(labels: readonly (string | null | undefined)[]): number;
232
+ /** A placed mark label, in device pixels: its box (`y1` is the baseline), the kind of mark, the text drawn and the whole text it stands for. */
233
+ interface MarkBox extends LabelBox {
234
+ kind: 'x' | 'y';
235
+ text: string;
236
+ full: string;
237
+ }
154
238
  /**
155
239
  * The vertical marks of a chart and their labels. Every label is drawn with an explicit alignment (uPlot leaves the
156
240
  * context right-aligned after its last axis, so a label meant to start at its line ended there and ran off the plot
157
241
  * near the left edge, CAOS_Fragmenta 2026-10-06), on the side of its line where it fits inside the plot, on the next
158
- * row down when it would overlap the label before it, with a halo in the surface colour so a curve under it does not
242
+ * row down when it would overlap a label before it, with a halo in the surface colour so a curve under it does not
159
243
  * cross its letters. A mark outside the x range is not drawn.
244
+ *
245
+ * Since 0.19.0 the labels of x marks and of y marks share one set of boxes (`boxes`, to which `drawYMarks` adds its own first): no x
246
+ * label lies over a y label or another x label. A label for which no row inside the plot has room is cut with an ellipsis, and one
247
+ * that fits nowhere is not written; the whole texts of those are returned, and every label placed is added to `boxes`.
160
248
  */
161
249
  declare function drawMarks(u: uPlot, marks: {
162
250
  x: number;
@@ -165,22 +253,24 @@ declare function drawMarks(u: uPlot, marks: {
165
253
  color: string;
166
254
  halo: string;
167
255
  family: string;
168
- }): void;
256
+ }, boxes?: MarkBox[]): string[];
169
257
  /**
170
258
  * The horizontal reference lines of a chart and their labels: a dashed line across the plot, its label at the right
171
259
  * end above the line (below it when the line runs along the top), inside the plot, haloed; a label that would overlap
172
- * the one placed before it moves left of it. A line outside the y range is not drawn. A mark's `color` (the tone's) draws
260
+ * the one placed before it moves left of it, then to the other side of its line or a row further, and is cut with an ellipsis when no place
261
+ * clears (`placeYLabel`; `boxes`, when given, collects what is placed, for `drawMarks` to avoid). Returns the whole texts of the labels it cut
262
+ * or could not write. A line outside the y range is not drawn; a line without a label is drawn alone. A mark's `color` (the tone's) draws
173
263
  * its line and its label; without one `style.color` does.
174
264
  */
175
265
  declare function drawYMarks(u: uPlot, marks: {
176
266
  y: number;
177
- label: string;
267
+ label?: string;
178
268
  color?: string;
179
269
  }[], style: {
180
270
  color: string;
181
271
  halo: string;
182
272
  family: string;
183
- }): void;
273
+ }, boxes?: MarkBox[]): string[];
184
274
  /**
185
275
  * The index of the point nearest (left, top) in the plane, over every series, or null when no point has a value.
186
276
  * `xs` and every column of `ys` are positions in the same pixels as (left, top); a null position is no point.
@@ -195,8 +285,10 @@ declare function nearestPoint(xs: readonly number[], ys: readonly (readonly (num
195
285
  * uPlot's legend, which a sized host clips (known shell defect 3). A chart of two or more series keys every series
196
286
  * under the plot, always (its colour, a dashed or a dotted swatch, its label): at rest the readout names none of them
197
287
  * (known shell defect 17). An axis with fixed decimals ticks only where its labels differ (`tickSteps`). The host
198
- * declares `data-series`, `data-axis-titles`, `data-ticks-cut`, `data-ticks-repeat` and `data-drawn` for the gate.
288
+ * declares `data-series`, `data-axis-titles`, `data-ticks-cut`, `data-ticks-repeat` and `data-drawn` for the gate. Since
289
+ * 0.18.0: named x ticks (`x.ticks`, declared in `data-x-tick-labels`), an x range (`x.range`), a key that solos a series
290
+ * (`solo`, declared in `data-solo`), dots on a line (`ChartSeries.dots`) and reference lines without a label.
199
291
  */
200
- declare function UPlotChart({ x, y, series, marks, yMarks, onYMarkChange, height, onCursor, onPick, parity, readout, hint }: UPlotChartProps): react.JSX.Element;
292
+ declare function UPlotChart({ x, y, series, marks, yMarks, onYMarkChange, height, onCursor, onPick, parity, readout, hint, solo, title, zoomY, zoomOff }: UPlotChartProps): react.JSX.Element;
201
293
 
202
- export { type ChartAxis, type ChartSeries, LOG_TABLE_FLOOR, UPlotChart, type UPlotChartProps, YMARK_TONE_TOKENS, type YMarkDrag, type YMarkTone, clampMark, decadeOnly, drawMarks, drawYMarks, logDecades, nearestPoint, nudgeMark, overlayExtent, parityBox, parityRange, rangeWithLevels, repeatedLabels, seriesStyle, smallestPositive, sortOrder, tickSteps };
294
+ export { type ChartAxis, type ChartSeries, type ChartTick, LOG_TABLE_FLOOR, SOLO_DIM_ALPHA, UPlotChart, type UPlotChartProps, YMARK_TONE_TOKENS, type YMarkDrag, type YMarkTone, clampMark, decadeOnly, drawMarks, drawYMarks, logDecades, namedRepeats, nearestPoint, nudgeMark, overlayExtent, parityBox, parityRange, rangeWithLevels, seriesStyle, smallestPositive, soloKey, soloStyle, sortOrder, tickLabelAt, tickSplits, tickSteps, xScaleRange };