packages/core/src/features/viz/lib/plot-series.tsx
This is the source snapshot used to build these API details. View this revision on GitHub.
1 import { Group, resolveSignalValue } from "@pibbl/core";
2 import type { PibblNode } from "@pibbl/core";
3 import type { PlotSeriesProps } from "./plot-types.js";
4 import { pointData } from "./point-data.js";
5 import {
6 useSeriesPosition,
7 seriesAccessor,
8 mapSeriesPosition,
9 } from "./series-position.js";
10 function PlotRow<D>({
11 datum,
12 index,
13 data,
14 render,
15 }: {
16 datum: D;
17 index: number;
18 data: readonly D[];
19 render: PlotSeriesProps<D>["render"];
20 }): PibblNode {
21 return render(datum, index, data);
22 }
23 /**
24 * Places keyed custom Pibbl subtrees at local data coordinates.
25 *
26 * @param props - Data, coordinate accessors, scales, keys, and per-datum renderer. See
27 * {@link PlotSeriesProps} .
28 * @returns Pibbl nodes placing each rendered datum at its mapped coordinates. See {@link PibblNode}.
29 *
30 * @see {@link PlotSeriesProps}
31 * @see {@link PibblNode}
32 */
33 export function PlotSeries<D>({
34 data: input,
35 x: xInput,
36 y: yInput,
37 xScale: xId,
38 yScale: yId,
39 defined,
40 keyBy,
41 render,
42 ...events
43 }: PlotSeriesProps<D>): PibblNode {
44 const xs = useSeriesPosition(xId),
45 ys = useSeriesPosition(yId);
46 const data = pointData(resolveSignalValue(input), "PlotSeries");
47 if (typeof render !== "function")
48 throw new TypeError("PlotSeries: render must be a synchronous function.");
49 const x = seriesAccessor(xInput),
50 y = seriesAccessor(yInput);
51 const keys = new Set<string>();
52 const nodes: PibblNode[] = [];
53 for (let i = 0; i < data.length; i++) {
54 const datum = data[i];
55 if (defined && !defined(datum, i, data)) continue;
56 const xv = x(datum, i, data),
57 yv = y(datum, i, data);
58 const mappedX = mapSeriesPosition(xs, xv),
59 mappedY = mapSeriesPosition(ys, yv);
60 if (mappedX === undefined || mappedY === undefined) continue;
61 const px = mappedX,
62 py = mappedY;
63 const key =
64 keyBy === undefined
65 ? i
66 : typeof keyBy === "function"
67 ? keyBy(datum, i, data)
68 : datum[keyBy];
69 if (typeof key !== "string" && typeof key !== "number")
70 throw new TypeError("PlotSeries: keyBy must return a string or number.");
71 const normalized = String(key);
72 if (keys.has(normalized))
73 throw new Error(`PlotSeries: duplicate key "${normalized}".`);
74 keys.add(normalized);
75 nodes.push(
76 <Group key={normalized} style={{ translateX: px, translateY: py }}>
77 <PlotRow datum={datum} index={i} data={data} render={render} />
78 </Group>,
79 );
80 }
81 return <Group {...events}>{nodes}</Group>;
82 }
83
Documentation version
Section titled “Documentation version”Documentation built with @pibbl/core 0.0.2, revision 2dccb19. ALPHA — NOT FOR PRODUCTION USE.