Skip to content

packages/core/src/features/viz/lib/plot-series.tsx

Read as Markdown

This is the source snapshot used to build these API details. View this revision on GitHub.

Back to reference

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 built with @pibbl/core 0.0.2, revision 272a94a. ALPHA — NOT FOR PRODUCTION USE.