@fasl-work/caos-app-shell 0.9.1 → 0.9.2
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/dist/chart.d.ts +12 -1
- package/dist/chart.js +33 -4
- package/package.json +1 -1
package/dist/chart.d.ts
CHANGED
|
@@ -68,6 +68,17 @@ declare function parityRange(...arrays: readonly (readonly (number | null)[])[])
|
|
|
68
68
|
* by significant digits has no fixed resolution, and `data-ticks-repeat` reports what it does.
|
|
69
69
|
*/
|
|
70
70
|
declare function tickSteps(fmt: FormatOptions | undefined): number[] | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* uPlot ticks a log axis at 1 to 9 times every power of ten, from a precision table that ends near 1e-22: a log axis
|
|
73
|
+
* that reaches below it throws "Invalid array length" after stalling the page, and the chart is never drawn (known
|
|
74
|
+
* shell defect 31, p-values of 1e-124 in CAOS_Contraste, 2026-10-07). Below this floor the axis ticks at powers of ten
|
|
75
|
+
* only (`logDecades`), each one labelled.
|
|
76
|
+
*/
|
|
77
|
+
declare const LOG_TABLE_FLOOR = 1e-22;
|
|
78
|
+
/** The powers of ten within [min, max], thinned to at most `most` (every k-th decade, the top one kept). */
|
|
79
|
+
declare function logDecades(min: number, max: number, most?: number): number[];
|
|
80
|
+
/** The smallest positive value among columns of values and the lower end of a fixed range; Infinity if none. */
|
|
81
|
+
declare function smallestPositive(columns: readonly (readonly (number | null)[])[], range?: readonly [number, number] | null): number;
|
|
71
82
|
/** How many tick labels repeat the label before them (empty labels apart); the gate fails a chart with any (G6). */
|
|
72
83
|
declare function repeatedLabels(labels: readonly (string | null | undefined)[]): number;
|
|
73
84
|
/**
|
|
@@ -98,4 +109,4 @@ declare function drawMarks(u: uPlot, marks: {
|
|
|
98
109
|
*/
|
|
99
110
|
declare function UPlotChart({ x, y, series, marks, height, onCursor, onPick, parity }: UPlotChartProps): react.JSX.Element;
|
|
100
111
|
|
|
101
|
-
export { type ChartAxis, type ChartSeries, UPlotChart, type UPlotChartProps, drawMarks, parityRange, repeatedLabels, seriesStyle, sortOrder, tickSteps };
|
|
112
|
+
export { type ChartAxis, type ChartSeries, LOG_TABLE_FLOOR, UPlotChart, type UPlotChartProps, drawMarks, logDecades, parityRange, repeatedLabels, seriesStyle, smallestPositive, sortOrder, tickSteps };
|
package/dist/chart.js
CHANGED
|
@@ -37,6 +37,26 @@ function tickSteps(fmt) {
|
|
|
37
37
|
const res = 10 ** -fmt.decimals / (fmt.percent ? 100 : 1);
|
|
38
38
|
return STEPS.filter((s) => s >= res * (1 - 1e-9) && Math.abs(s / res - Math.round(s / res)) < 1e-6);
|
|
39
39
|
}
|
|
40
|
+
var LOG_TABLE_FLOOR = 1e-22;
|
|
41
|
+
function logDecades(min, max, most = 8) {
|
|
42
|
+
if (!(min > 0) || !(max > 0) || !Number.isFinite(min) || !Number.isFinite(max) || max < min) return [];
|
|
43
|
+
const a = Math.ceil(Math.log10(min) - 1e-9);
|
|
44
|
+
const b = Math.floor(Math.log10(max) + 1e-9);
|
|
45
|
+
if (b < a) return [];
|
|
46
|
+
const step = Math.max(1, Math.ceil((b - a + 1) / most));
|
|
47
|
+
const out = [];
|
|
48
|
+
for (let k = b; k >= a; k -= step) out.unshift(Number(`1e${k}`));
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
function smallestPositive(columns, range) {
|
|
52
|
+
let lo = range && range[0] > 0 ? range[0] : Infinity;
|
|
53
|
+
for (const c of columns) for (const v of c) if (v !== null && Number.isFinite(v) && v > 0 && v < lo) lo = v;
|
|
54
|
+
return lo;
|
|
55
|
+
}
|
|
56
|
+
var DECADE_AXIS = {
|
|
57
|
+
splits: (_u, _i, min, max) => logDecades(min, max),
|
|
58
|
+
filter: (_u, splits) => splits
|
|
59
|
+
};
|
|
40
60
|
function repeatedLabels(labels) {
|
|
41
61
|
let n = 0;
|
|
42
62
|
for (let i = 1; i < labels.length; i++) if (labels[i] && labels[i] === labels[i - 1]) n++;
|
|
@@ -110,16 +130,23 @@ function UPlotChart({ x, y, series, marks, height = 280, onCursor, onPick, parit
|
|
|
110
130
|
const xs = useMemo(() => order ? order.map((i) => x.values[i]) : x.values, [order, x.values]);
|
|
111
131
|
const ys = useMemo(() => series.map((s) => order ? order.map((i) => s.values[i] ?? null) : s.values), [order, series]);
|
|
112
132
|
const range = useMemo(() => parity ? parityRange(xs, ...ys) : null, [parity, xs, ys]);
|
|
133
|
+
const tiny = useMemo(
|
|
134
|
+
() => ({
|
|
135
|
+
x: Boolean(x.log) && smallestPositive([xs], range) < LOG_TABLE_FLOOR,
|
|
136
|
+
y: Boolean(y.log) && smallestPositive(ys, range ?? y.range) < LOG_TABLE_FLOOR
|
|
137
|
+
}),
|
|
138
|
+
[x.log, y.log, xs, ys, range, y.range]
|
|
139
|
+
);
|
|
113
140
|
const xLabel = pick(x.label, lang);
|
|
114
141
|
const yLabel = pick(y.label, lang);
|
|
115
142
|
const xUnit = x.unit ? pick(x.unit, lang) : "";
|
|
116
143
|
const yUnit = y.unit ? pick(y.unit, lang) : "";
|
|
117
144
|
const structure = JSON.stringify({
|
|
118
145
|
s: series.map((s, i) => [pick(s.label, lang), seriesStyle(s, i), s.width ?? 2, s.mode ?? "line"]),
|
|
119
|
-
x: [xLabel, xUnit, Boolean(x.time), Boolean(x.log), x.format ?? null],
|
|
146
|
+
x: [xLabel, xUnit, Boolean(x.time), Boolean(x.log), x.format ?? null, tiny.x],
|
|
120
147
|
p: range,
|
|
121
148
|
pick: Boolean(onPick),
|
|
122
|
-
y: [yLabel, yUnit, Boolean(y.log), y.range ?? null, y.format ?? null],
|
|
149
|
+
y: [yLabel, yUnit, Boolean(y.log), y.range ?? null, y.format ?? null, tiny.y],
|
|
123
150
|
m: (marks ?? []).map((m) => [m.x, pick(m.label, lang)]),
|
|
124
151
|
theme,
|
|
125
152
|
lang,
|
|
@@ -168,7 +195,8 @@ function UPlotChart({ x, y, series, marks, height = 280, onCursor, onPick, parit
|
|
|
168
195
|
label: xUnit ? `${xLabel} (${xUnit})` : xLabel,
|
|
169
196
|
labelFont: font,
|
|
170
197
|
values: x.time ? void 0 : tick(x.format, "x"),
|
|
171
|
-
...xSteps ? { incrs: xSteps } : {}
|
|
198
|
+
...xSteps ? { incrs: xSteps } : {},
|
|
199
|
+
...tiny.x ? DECADE_AXIS : {}
|
|
172
200
|
},
|
|
173
201
|
{
|
|
174
202
|
stroke: fg,
|
|
@@ -179,6 +207,7 @@ function UPlotChart({ x, y, series, marks, height = 280, onCursor, onPick, parit
|
|
|
179
207
|
labelFont: font,
|
|
180
208
|
values: tick(y.format, "y"),
|
|
181
209
|
...ySteps ? { incrs: ySteps } : {},
|
|
210
|
+
...tiny.y ? DECADE_AXIS : {},
|
|
182
211
|
// Sized to the longest tick label. uPlot draws in device pixels with a font scaled by its pixel ratio, so the
|
|
183
212
|
// label is measured in that font and divided back (measuring the unscaled font and dividing by the ratio
|
|
184
213
|
// made the axis too narrow on every high-density screen; the gate runs at ratio 1 and never saw it).
|
|
@@ -282,4 +311,4 @@ function UPlotChart({ x, y, series, marks, height = 280, onCursor, onPick, parit
|
|
|
282
311
|
);
|
|
283
312
|
}
|
|
284
313
|
|
|
285
|
-
export { UPlotChart, drawMarks, parityRange, repeatedLabels, seriesStyle, sortOrder, tickSteps };
|
|
314
|
+
export { LOG_TABLE_FLOOR, UPlotChart, drawMarks, logDecades, parityRange, repeatedLabels, seriesStyle, smallestPositive, sortOrder, tickSteps };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fasl-work/caos-app-shell",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "Shared web-app shell, workbench primitives, content primitives, design system and measured gate for the CAOS / Faena public apps (ADR-0016, ADR-0017, ADR-0071).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Felipe Santibáñez-Leal",
|