@quantumwake/terminal-ux-dashboard-components 0.1.27 → 0.1.29
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/index.cjs +23 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -5
- package/dist/index.d.ts +25 -5
- package/dist/index.js +23 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -325,12 +325,18 @@ declare function PieView({ records, groupColumn, data: presetData, style }: PieV
|
|
|
325
325
|
|
|
326
326
|
interface LineSerie {
|
|
327
327
|
id: string;
|
|
328
|
+
/** Explicit serie color — STABLE identity coloring: the host assigns a
|
|
329
|
+
* color to the entity, so toggling other series never repaints this
|
|
330
|
+
* one (index-based palette assignment reshuffles on every selection
|
|
331
|
+
* change). Absent ⇒ the fixed-order palette by index. */
|
|
332
|
+
color?: string;
|
|
328
333
|
/** lo/hi (optional, per point) draw a soft envelope band behind the
|
|
329
334
|
* line — the reading for "this line summarizes several": the band is
|
|
330
|
-
* the min–max spread of what it aggregates.
|
|
335
|
+
* the min–max spread of what it aggregates. y may be null for an
|
|
336
|
+
* honest gap (the line breaks instead of bridging). */
|
|
331
337
|
data: {
|
|
332
|
-
x: string;
|
|
333
|
-
y: number;
|
|
338
|
+
x: string | Date | number;
|
|
339
|
+
y: number | null;
|
|
334
340
|
lo?: number;
|
|
335
341
|
hi?: number;
|
|
336
342
|
}[];
|
|
@@ -342,8 +348,22 @@ interface LineViewProps {
|
|
|
342
348
|
/** Pre-shaped Nivo line series bypasses client-side processing. */
|
|
343
349
|
data?: LineSerie[];
|
|
344
350
|
style?: Partial<ChartStyle>;
|
|
345
|
-
|
|
346
|
-
|
|
351
|
+
/** 'point' (default): x values are CATEGORIES, placed at equal spacing
|
|
352
|
+
* in encounter order and ticked by sampling every Nth one — right for
|
|
353
|
+
* labels, wrong for timestamps (a missing bucket collapses, and the
|
|
354
|
+
* ticks land on arbitrary samples). 'time': x values are Dates (or
|
|
355
|
+
* epoch ms / ISO strings) on a continuous scale — gaps stretch, ticks
|
|
356
|
+
* land on ROUND times (d3's time ticks, capped by maxXTicks), and the
|
|
357
|
+
* series need not share buckets. */
|
|
358
|
+
xScale?: 'point' | 'time';
|
|
359
|
+
/** Time axis tick + tooltip formatter. Default: HH:MM:SS, local, 24h. */
|
|
360
|
+
xFormat?: (x: Date) => string;
|
|
361
|
+
/** Time axis: pin the visible domain — a live window keeps a steady
|
|
362
|
+
* width instead of re-fitting to whatever samples exist. Default: fit
|
|
363
|
+
* the data. */
|
|
364
|
+
xDomain?: [Date, Date];
|
|
365
|
+
}
|
|
366
|
+
declare function LineView({ records, xColumn, yColumn, data: presetData, style, xScale, xFormat, xDomain }: LineViewProps): react.JSX.Element;
|
|
347
367
|
|
|
348
368
|
interface SparklineViewProps {
|
|
349
369
|
/** The series, oldest first. */
|
package/dist/index.d.ts
CHANGED
|
@@ -325,12 +325,18 @@ declare function PieView({ records, groupColumn, data: presetData, style }: PieV
|
|
|
325
325
|
|
|
326
326
|
interface LineSerie {
|
|
327
327
|
id: string;
|
|
328
|
+
/** Explicit serie color — STABLE identity coloring: the host assigns a
|
|
329
|
+
* color to the entity, so toggling other series never repaints this
|
|
330
|
+
* one (index-based palette assignment reshuffles on every selection
|
|
331
|
+
* change). Absent ⇒ the fixed-order palette by index. */
|
|
332
|
+
color?: string;
|
|
328
333
|
/** lo/hi (optional, per point) draw a soft envelope band behind the
|
|
329
334
|
* line — the reading for "this line summarizes several": the band is
|
|
330
|
-
* the min–max spread of what it aggregates.
|
|
335
|
+
* the min–max spread of what it aggregates. y may be null for an
|
|
336
|
+
* honest gap (the line breaks instead of bridging). */
|
|
331
337
|
data: {
|
|
332
|
-
x: string;
|
|
333
|
-
y: number;
|
|
338
|
+
x: string | Date | number;
|
|
339
|
+
y: number | null;
|
|
334
340
|
lo?: number;
|
|
335
341
|
hi?: number;
|
|
336
342
|
}[];
|
|
@@ -342,8 +348,22 @@ interface LineViewProps {
|
|
|
342
348
|
/** Pre-shaped Nivo line series bypasses client-side processing. */
|
|
343
349
|
data?: LineSerie[];
|
|
344
350
|
style?: Partial<ChartStyle>;
|
|
345
|
-
|
|
346
|
-
|
|
351
|
+
/** 'point' (default): x values are CATEGORIES, placed at equal spacing
|
|
352
|
+
* in encounter order and ticked by sampling every Nth one — right for
|
|
353
|
+
* labels, wrong for timestamps (a missing bucket collapses, and the
|
|
354
|
+
* ticks land on arbitrary samples). 'time': x values are Dates (or
|
|
355
|
+
* epoch ms / ISO strings) on a continuous scale — gaps stretch, ticks
|
|
356
|
+
* land on ROUND times (d3's time ticks, capped by maxXTicks), and the
|
|
357
|
+
* series need not share buckets. */
|
|
358
|
+
xScale?: 'point' | 'time';
|
|
359
|
+
/** Time axis tick + tooltip formatter. Default: HH:MM:SS, local, 24h. */
|
|
360
|
+
xFormat?: (x: Date) => string;
|
|
361
|
+
/** Time axis: pin the visible domain — a live window keeps a steady
|
|
362
|
+
* width instead of re-fitting to whatever samples exist. Default: fit
|
|
363
|
+
* the data. */
|
|
364
|
+
xDomain?: [Date, Date];
|
|
365
|
+
}
|
|
366
|
+
declare function LineView({ records, xColumn, yColumn, data: presetData, style, xScale, xFormat, xDomain }: LineViewProps): react.JSX.Element;
|
|
347
367
|
|
|
348
368
|
interface SparklineViewProps {
|
|
349
369
|
/** The series, oldest first. */
|
package/dist/index.js
CHANGED
|
@@ -648,7 +648,11 @@ function PieView({ records, groupColumn, data: presetData, style }) {
|
|
|
648
648
|
}
|
|
649
649
|
) });
|
|
650
650
|
}
|
|
651
|
-
|
|
651
|
+
var fmtClock = (d) => d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit", hourCycle: "h23" });
|
|
652
|
+
var toDate = (x) => x instanceof Date ? x : new Date(x);
|
|
653
|
+
function LineView({ records, xColumn, yColumn, data: presetData, style, xScale = "point", xFormat, xDomain }) {
|
|
654
|
+
const timed = xScale === "time";
|
|
655
|
+
const clock = xFormat ?? fmtClock;
|
|
652
656
|
const computed = useMemo(() => {
|
|
653
657
|
if (presetData || !records) return [];
|
|
654
658
|
const sorted = [...records].filter((r) => r[xColumn] != null && r[yColumn] != null).sort((a, b) => {
|
|
@@ -661,18 +665,29 @@ function LineView({ records, xColumn, yColumn, data: presetData, style }) {
|
|
|
661
665
|
data: sorted.map((r) => ({ x: String(r[xColumn]), y: Number(r[yColumn]) || 0 }))
|
|
662
666
|
}];
|
|
663
667
|
}, [records, xColumn, yColumn, presetData]);
|
|
664
|
-
const
|
|
668
|
+
const shaped = presetData || computed;
|
|
669
|
+
const data = useMemo(
|
|
670
|
+
() => timed ? shaped.map((serie) => ({ ...serie, data: serie.data.map((d) => ({ ...d, x: toDate(d.x) })) })) : shaped,
|
|
671
|
+
[shaped, timed]
|
|
672
|
+
);
|
|
665
673
|
const s = withStyleDefaults(style);
|
|
666
674
|
const { frameClass, frameStyle, margin } = chartSizing(style, { top: 20, right: 20, bottom: 60, left: 60 });
|
|
667
675
|
const colorById = new Map(data.map((serie, i) => [
|
|
668
676
|
serie.id,
|
|
669
|
-
s.seriesColors.length || data.length > 1 ? seriesColor(i, s) : "rgba(96, 165, 250, 0.9)"
|
|
677
|
+
serie.color ?? (s.seriesColors.length || data.length > 1 ? seriesColor(i, s) : "rgba(96, 165, 250, 0.9)")
|
|
670
678
|
]));
|
|
671
679
|
const longest = data.reduce((a, b) => b.data.length > a.data.length ? b : a, { id: "", data: [] });
|
|
672
|
-
const tickValues = thinTicks(longest.data.map((d) => d.x), s.maxXTicks);
|
|
680
|
+
const tickValues = timed ? void 0 : thinTicks(longest.data.map((d) => d.x), s.maxXTicks);
|
|
681
|
+
const axisBottom = (() => {
|
|
682
|
+
const base = makeAxis(style, "x", xColumn);
|
|
683
|
+
if (!timed) return { ...base, ...tickValues ? { tickValues } : {} };
|
|
684
|
+
delete base.renderTick;
|
|
685
|
+
return { ...base, tickRotation: s.xTickRotation, format: clock, ...s.maxXTicks > 0 ? { tickValues: s.maxXTicks } : {} };
|
|
686
|
+
})();
|
|
687
|
+
const nivoXScale = timed ? { type: "time", format: "native", precision: "millisecond", useUTC: false, min: xDomain?.[0] ?? "auto", max: xDomain?.[1] ?? "auto" } : { type: "point" };
|
|
673
688
|
let yScale = { type: "linear", min: "auto", max: "auto" };
|
|
674
689
|
if (s.yFromZero) {
|
|
675
|
-
const dataMax = Math.max(0, ...data.flatMap((serie) => serie.data.map((d) => Math.max(d.y, d.hi ?? d.y))));
|
|
690
|
+
const dataMax = Math.max(0, ...data.flatMap((serie) => serie.data.map((d) => Math.max(d.y ?? 0, d.hi ?? d.y ?? 0))));
|
|
676
691
|
yScale = { type: "linear", min: 0, max: niceCeil(dataMax) };
|
|
677
692
|
}
|
|
678
693
|
const bandedIds = new Set(data.filter((serie) => serie.data.some((d) => d.lo != null)).map((serie) => serie.id));
|
|
@@ -700,7 +715,8 @@ function LineView({ records, xColumn, yColumn, data: presetData, style }) {
|
|
|
700
715
|
{
|
|
701
716
|
data,
|
|
702
717
|
margin,
|
|
703
|
-
xScale:
|
|
718
|
+
xScale: nivoXScale,
|
|
719
|
+
xFormat: timed ? (v) => clock(v) : void 0,
|
|
704
720
|
yScale,
|
|
705
721
|
curve: "monotoneX",
|
|
706
722
|
enableArea: s.areaOpacity > 0,
|
|
@@ -711,7 +727,7 @@ function LineView({ records, xColumn, yColumn, data: presetData, style }) {
|
|
|
711
727
|
pointBorderWidth: 2,
|
|
712
728
|
pointBorderColor: { from: "serieColor" },
|
|
713
729
|
enableGridX: false,
|
|
714
|
-
axisBottom
|
|
730
|
+
axisBottom,
|
|
715
731
|
axisLeft: makeAxis(style, "y", yColumn, { numeric: true }),
|
|
716
732
|
useMesh: true,
|
|
717
733
|
layers: ["grid", "markers", "axes", "areas", bandsLayer, linesLayer, "crosshair", "slices", "mesh", "legends"],
|