basalt-ui 1.14.0 → 1.16.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/AGENTS.md +1 -1
- package/CHANGELOG.md +15 -0
- package/README.md +38 -2
- package/agent/rules/basalt-charts.md +279 -108
- package/agent/rules/basalt-mantine.md +4 -2
- package/agent/skills/basalt-charts/SKILL.md +114 -64
- package/agent/skills/basalt-design/SKILL.md +4 -3
- package/agent/templates/CLAUDE-block.md.tpl +9 -6
- package/configs/oxlint-plugin.js +152 -0
- package/configs/oxlint-plugin.test.ts +107 -0
- package/configs/oxlint.json +2 -0
- package/dist/charts/cursor/resolve.d.ts +33 -0
- package/dist/charts/cursor/resolve.d.ts.map +1 -0
- package/dist/charts/cursor/resolve.js +61 -0
- package/dist/charts/cursor/resolve.test.d.ts +2 -0
- package/dist/charts/cursor/resolve.test.d.ts.map +1 -0
- package/dist/charts/cursor/scope.d.ts +17 -0
- package/dist/charts/cursor/scope.d.ts.map +1 -0
- package/dist/charts/cursor/scope.js +20 -0
- package/dist/charts/cursor/store.d.ts +31 -0
- package/dist/charts/cursor/store.d.ts.map +1 -0
- package/dist/charts/cursor/store.js +25 -0
- package/dist/charts/cursor/store.test.d.ts +2 -0
- package/dist/charts/cursor/store.test.d.ts.map +1 -0
- package/dist/charts/hooks/useChartCursor.d.ts +39 -0
- package/dist/charts/hooks/useChartCursor.d.ts.map +1 -0
- package/dist/charts/hooks/useChartCursor.js +104 -0
- package/dist/charts/hooks/useChartSize.d.ts +8 -4
- package/dist/charts/hooks/useChartSize.d.ts.map +1 -1
- package/dist/charts/index.d.ts +16 -13
- package/dist/charts/index.d.ts.map +1 -1
- package/dist/charts/index.js +38 -19
- package/dist/charts/kinds/Bars.d.ts +45 -54
- package/dist/charts/kinds/Bars.d.ts.map +1 -1
- package/dist/charts/kinds/Bars.js +235 -392
- package/dist/charts/kinds/Bars.test.d.ts +2 -0
- package/dist/charts/kinds/Bars.test.d.ts.map +1 -0
- package/dist/charts/kinds/Donut.d.ts +5 -4
- package/dist/charts/kinds/Donut.d.ts.map +1 -1
- package/dist/charts/kinds/Donut.js +17 -14
- package/dist/charts/kinds/DualPanel.d.ts +13 -0
- package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
- package/dist/charts/kinds/DualPanel.js +185 -92
- package/dist/charts/kinds/DualPanel.test.d.ts +2 -0
- package/dist/charts/kinds/DualPanel.test.d.ts.map +1 -0
- package/dist/charts/kinds/Heatmap.d.ts +15 -11
- package/dist/charts/kinds/Heatmap.d.ts.map +1 -1
- package/dist/charts/kinds/Heatmap.js +38 -22
- package/dist/charts/kinds/MultiLine.d.ts +27 -35
- package/dist/charts/kinds/MultiLine.d.ts.map +1 -1
- package/dist/charts/kinds/MultiLine.js +122 -235
- package/dist/charts/kinds/MultiLine.test.d.ts +2 -0
- package/dist/charts/kinds/MultiLine.test.d.ts.map +1 -0
- package/dist/charts/kinds/StackedArea.d.ts +21 -10
- package/dist/charts/kinds/StackedArea.d.ts.map +1 -1
- package/dist/charts/kinds/StackedArea.js +74 -132
- package/dist/charts/kinds/ZonedLine.d.ts +24 -40
- package/dist/charts/kinds/ZonedLine.d.ts.map +1 -1
- package/dist/charts/kinds/ZonedLine.js +104 -184
- package/dist/charts/kinds/ZonedLine.test.d.ts +2 -0
- package/dist/charts/kinds/ZonedLine.test.d.ts.map +1 -0
- package/dist/charts/layout/auto-margin.d.ts +60 -0
- package/dist/charts/layout/auto-margin.d.ts.map +1 -0
- package/dist/charts/layout/auto-margin.js +37 -0
- package/dist/charts/layout/auto-margin.test.d.ts +2 -0
- package/dist/charts/layout/auto-margin.test.d.ts.map +1 -0
- package/dist/charts/primitives/CartesianChart.d.ts +161 -0
- package/dist/charts/primitives/CartesianChart.d.ts.map +1 -0
- package/dist/charts/primitives/CartesianChart.js +359 -0
- package/dist/charts/primitives/CartesianChart.test.d.ts +2 -0
- package/dist/charts/primitives/CartesianChart.test.d.ts.map +1 -0
- package/dist/charts/primitives/ChartFrame.d.ts +16 -5
- package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
- package/dist/charts/primitives/ChartFrame.js +17 -2
- package/dist/charts/primitives/ChartLegend.d.ts +15 -1
- package/dist/charts/primitives/ChartLegend.d.ts.map +1 -1
- package/dist/charts/primitives/ChartLegend.js +25 -3
- package/dist/charts/primitives/ChartLegend.test.d.ts +2 -0
- package/dist/charts/primitives/ChartLegend.test.d.ts.map +1 -0
- package/dist/charts/primitives/ChartTooltip.d.ts +16 -16
- package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
- package/dist/charts/primitives/ChartTooltip.js +45 -19
- package/dist/charts/primitives/HoverOverlay.d.ts +19 -4
- package/dist/charts/primitives/HoverOverlay.d.ts.map +1 -1
- package/dist/charts/primitives/HoverOverlay.js +22 -1
- package/dist/charts/primitives/XZoneRects.d.ts +54 -0
- package/dist/charts/primitives/XZoneRects.d.ts.map +1 -0
- package/dist/charts/primitives/XZoneRects.js +65 -0
- package/dist/charts/primitives/XZoneRects.test.d.ts +2 -0
- package/dist/charts/primitives/XZoneRects.test.d.ts.map +1 -0
- package/dist/charts/series.d.ts +28 -3
- package/dist/charts/series.d.ts.map +1 -1
- package/dist/charts/series.js +5 -2
- package/dist/charts/series.test.d.ts +2 -0
- package/dist/charts/series.test.d.ts.map +1 -0
- package/dist/charts/utils/measure-text.d.ts +25 -0
- package/dist/charts/utils/measure-text.d.ts.map +1 -0
- package/dist/charts/utils/measure-text.js +64 -0
- package/dist/charts/utils/measure-text.test.d.ts +2 -0
- package/dist/charts/utils/measure-text.test.d.ts.map +1 -0
- package/dist/content/fence-block.d.ts.map +1 -1
- package/dist/surfaces.d.ts +1 -1
- package/dist/surfaces.d.ts.map +1 -1
- package/dist/surfaces.js +1 -1
- package/dist/tokens/chart-margin.test.d.ts +2 -0
- package/dist/tokens/chart-margin.test.d.ts.map +1 -0
- package/dist/tokens/index.d.ts +29 -0
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +10 -0
- package/dist/tokens/palette.d.ts +4 -0
- package/dist/tokens/palette.d.ts.map +1 -1
- package/dist/tokens/palette.js +3 -0
- package/llms.txt +3 -3
- package/package.json +1 -1
- package/src/charts/cursor/resolve.test.ts +61 -0
- package/src/charts/cursor/resolve.ts +102 -0
- package/src/charts/cursor/scope.tsx +32 -0
- package/src/charts/cursor/store.test.ts +46 -0
- package/src/charts/cursor/store.ts +53 -0
- package/src/charts/hooks/useChartCursor.ts +163 -0
- package/src/charts/hooks/useChartSize.ts +8 -4
- package/src/charts/index.ts +35 -14
- package/src/charts/kinds/Bars.test.tsx +98 -0
- package/src/charts/kinds/Bars.tsx +350 -467
- package/src/charts/kinds/Donut.tsx +31 -23
- package/src/charts/kinds/DualPanel.test.tsx +131 -0
- package/src/charts/kinds/DualPanel.tsx +301 -135
- package/src/charts/kinds/Heatmap.tsx +72 -47
- package/src/charts/kinds/MultiLine.test.tsx +37 -0
- package/src/charts/kinds/MultiLine.tsx +171 -290
- package/src/charts/kinds/StackedArea.tsx +116 -175
- package/src/charts/kinds/ZonedLine.test.tsx +37 -0
- package/src/charts/kinds/ZonedLine.tsx +149 -255
- package/src/charts/layout/auto-margin.test.ts +42 -0
- package/src/charts/layout/auto-margin.ts +110 -0
- package/src/charts/primitives/CartesianChart.test.tsx +160 -0
- package/src/charts/primitives/CartesianChart.tsx +598 -0
- package/src/charts/primitives/ChartFrame.test.tsx +33 -0
- package/src/charts/primitives/ChartFrame.tsx +40 -4
- package/src/charts/primitives/ChartLegend.test.tsx +78 -0
- package/src/charts/primitives/ChartLegend.tsx +52 -2
- package/src/charts/primitives/ChartTooltip.tsx +67 -37
- package/src/charts/primitives/HoverOverlay.tsx +39 -3
- package/src/charts/primitives/XZoneRects.test.tsx +123 -0
- package/src/charts/primitives/XZoneRects.tsx +132 -0
- package/src/charts/series.test.ts +112 -0
- package/src/charts/series.ts +33 -5
- package/src/charts/utils/measure-text.test.ts +36 -0
- package/src/charts/utils/measure-text.ts +109 -0
- package/src/content/fence-block.tsx +2 -3
- package/src/surfaces.ts +2 -1
- package/src/theme/spacing.test.ts +2 -0
- package/src/tokens/chart-margin.test.ts +39 -0
- package/src/tokens/density.test.ts +1 -0
- package/src/tokens/index.ts +36 -0
- package/src/tokens/palette.ts +3 -0
- package/dist/charts/hooks/useChartTooltip.d.ts +0 -13
- package/dist/charts/hooks/useChartTooltip.d.ts.map +0 -1
- package/dist/charts/hooks/useChartTooltip.js +0 -26
- package/dist/charts/hooks/useHoverSync.d.ts +0 -46
- package/dist/charts/hooks/useHoverSync.d.ts.map +0 -1
- package/dist/charts/hooks/useHoverSync.js +0 -75
- package/dist/charts/hover-context.d.ts +0 -21
- package/dist/charts/hover-context.d.ts.map +0 -1
- package/dist/charts/hover-context.js +0 -12
- package/dist/charts/hover-sync.d.ts +0 -14
- package/dist/charts/hover-sync.d.ts.map +0 -1
- package/dist/charts/hover-sync.js +0 -17
- package/dist/charts/primitives/ResponsiveChart.d.ts +0 -45
- package/dist/charts/primitives/ResponsiveChart.d.ts.map +0 -1
- package/dist/charts/primitives/ResponsiveChart.js +0 -24
- package/src/charts/hooks/useChartTooltip.ts +0 -31
- package/src/charts/hooks/useHoverSync.ts +0 -152
- package/src/charts/hover-context.ts +0 -28
- package/src/charts/hover-sync.tsx +0 -37
- package/src/charts/primitives/ResponsiveChart.tsx +0 -64
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Group } from "@visx/group";
|
|
3
|
-
import { memo, useMemo } from "react";
|
|
3
|
+
import { memo, useMemo, useState } from "react";
|
|
4
4
|
import {
|
|
5
|
-
|
|
5
|
+
ChartTooltipFloat,
|
|
6
6
|
TooltipBody,
|
|
7
7
|
TooltipHeader,
|
|
8
|
-
TooltipRow
|
|
9
|
-
useTooltipStyles
|
|
8
|
+
TooltipRow
|
|
10
9
|
} from "../primitives/ChartTooltip.js";
|
|
11
|
-
import {
|
|
12
|
-
import { useChartTooltip } from "../hooks/useChartTooltip.js";
|
|
10
|
+
import { ChartFrame } from "../primitives/ChartFrame.js";
|
|
13
11
|
import { VX, alpha } from "../../tokens/index.js";
|
|
14
12
|
function firstSeen(data, get) {
|
|
15
13
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -31,10 +29,26 @@ const PAD_TOP = 8;
|
|
|
31
29
|
const LEGEND_H = 8;
|
|
32
30
|
const LEGEND_LABEL_H = 16;
|
|
33
31
|
function HeatmapInner(props) {
|
|
32
|
+
const { chartId, height, aspectRatio, fill, ariaLabel, isPending } = props;
|
|
33
|
+
return /* @__PURE__ */ jsx(
|
|
34
|
+
ChartFrame,
|
|
35
|
+
{
|
|
36
|
+
series: [],
|
|
37
|
+
chartId,
|
|
38
|
+
legend: false,
|
|
39
|
+
...height !== void 0 && { height },
|
|
40
|
+
...aspectRatio !== void 0 && { aspectRatio },
|
|
41
|
+
...fill !== void 0 && { fill },
|
|
42
|
+
...ariaLabel !== void 0 && { ariaLabel },
|
|
43
|
+
...isPending !== void 0 && { isPending },
|
|
44
|
+
children: (plot) => /* @__PURE__ */ jsx(HeatmapPlot, { ...props, plot })
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
function HeatmapPlot(props) {
|
|
34
49
|
const {
|
|
35
50
|
data,
|
|
36
|
-
|
|
37
|
-
height,
|
|
51
|
+
plot,
|
|
38
52
|
chartId,
|
|
39
53
|
getRow,
|
|
40
54
|
getCol,
|
|
@@ -49,11 +63,10 @@ function HeatmapInner(props) {
|
|
|
49
63
|
rowLabel = (r) => r,
|
|
50
64
|
colLabel = (c) => c,
|
|
51
65
|
renderTooltip,
|
|
52
|
-
legend
|
|
53
|
-
isPending
|
|
66
|
+
legend
|
|
54
67
|
} = props;
|
|
55
|
-
const
|
|
56
|
-
const
|
|
68
|
+
const { width, height } = plot;
|
|
69
|
+
const [tip, setTip] = useState(null);
|
|
57
70
|
const rows = useMemo(() => rowsProp ?? firstSeen(data, getRow), [rowsProp, data, getRow]);
|
|
58
71
|
const cols = useMemo(() => colsProp ?? firstSeen(data, getCol), [colsProp, data, getCol]);
|
|
59
72
|
const { lookup, max } = useMemo(() => {
|
|
@@ -66,20 +79,23 @@ function HeatmapInner(props) {
|
|
|
66
79
|
}
|
|
67
80
|
return { lookup: map, max: m };
|
|
68
81
|
}, [data, getRow, getCol, getValue]);
|
|
69
|
-
if (isPending) return /* @__PURE__ */ jsx(ChartPending, { width, height });
|
|
70
82
|
const legendH = legend ? LEGEND_H + LEGEND_LABEL_H : 0;
|
|
71
83
|
const gridW = Math.max(0, width - PAD_LEFT);
|
|
72
84
|
const gridH = Math.max(0, height - PAD_TOP - PAD_BOTTOM - legendH);
|
|
73
85
|
const cellW = cols.length > 0 ? gridW / cols.length : 0;
|
|
74
86
|
const cellH = rows.length > 0 ? gridH / rows.length : 0;
|
|
75
87
|
const legendGradientId = `${chartId}-heat-legend`;
|
|
88
|
+
const show = (row, col, value, event) => {
|
|
89
|
+
setTip({ row, col, value, anchor: { x: event.clientX, y: event.clientY } });
|
|
90
|
+
};
|
|
91
|
+
const hide = () => setTip(null);
|
|
76
92
|
return /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
|
|
77
93
|
/* @__PURE__ */ jsxs("svg", { width, height, children: [
|
|
78
94
|
/* @__PURE__ */ jsx(Group, { left: PAD_LEFT, top: PAD_TOP, children: rows.flatMap(
|
|
79
95
|
(row, ri) => cols.map((col, ci) => {
|
|
80
96
|
const value = lookup.get(cellKey(row, col));
|
|
81
97
|
const has = value !== void 0;
|
|
82
|
-
const
|
|
98
|
+
const cellFill = has ? alpha(color, intensity(value, max)) : alpha(VX.neutral, 0.04);
|
|
83
99
|
return /* @__PURE__ */ jsx(
|
|
84
100
|
"rect",
|
|
85
101
|
{
|
|
@@ -88,9 +104,9 @@ function HeatmapInner(props) {
|
|
|
88
104
|
width: Math.max(0, cellW - cellGap),
|
|
89
105
|
height: Math.max(0, cellH - cellGap),
|
|
90
106
|
rx: cellRadius,
|
|
91
|
-
fill,
|
|
107
|
+
fill: cellFill,
|
|
92
108
|
style: { cursor: has ? "pointer" : "default" },
|
|
93
|
-
onPointerMove: (e) => has && show(
|
|
109
|
+
onPointerMove: (e) => has && show(row, col, value, e),
|
|
94
110
|
onPointerLeave: hide,
|
|
95
111
|
onPointerCancel: hide
|
|
96
112
|
},
|
|
@@ -156,8 +172,8 @@ function HeatmapInner(props) {
|
|
|
156
172
|
)
|
|
157
173
|
] })
|
|
158
174
|
] }),
|
|
159
|
-
|
|
160
|
-
/* @__PURE__ */ jsx(TooltipHeader, { date: rowLabel(tip.
|
|
175
|
+
tip !== null && /* @__PURE__ */ jsxs(ChartTooltipFloat, { anchor: tip.anchor, children: [
|
|
176
|
+
/* @__PURE__ */ jsx(TooltipHeader, { date: rowLabel(tip.row), label: colLabel(tip.col) }),
|
|
161
177
|
/* @__PURE__ */ jsxs(TooltipBody, { children: [
|
|
162
178
|
/* @__PURE__ */ jsx(
|
|
163
179
|
TooltipRow,
|
|
@@ -165,12 +181,12 @@ function HeatmapInner(props) {
|
|
|
165
181
|
color: alpha(color, 0.9),
|
|
166
182
|
shape: "bar",
|
|
167
183
|
label: "Value",
|
|
168
|
-
value: formatValue(tip.
|
|
184
|
+
value: formatValue(tip.value)
|
|
169
185
|
}
|
|
170
186
|
),
|
|
171
|
-
renderTooltip?.(tip
|
|
187
|
+
renderTooltip?.(tip)
|
|
172
188
|
] })
|
|
173
|
-
] })
|
|
189
|
+
] })
|
|
174
190
|
] });
|
|
175
191
|
}
|
|
176
192
|
const Heatmap = memo(HeatmapInner);
|
|
@@ -1,66 +1,58 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CartesianTooltipConfig, AxisConfig } from '../primitives/CartesianChart.js';
|
|
2
|
+
import type { XZoneSpec } from '../primitives/XZoneRects.js';
|
|
2
3
|
import type { ZoneSpec } from '../primitives/ZoneRects.js';
|
|
3
4
|
import type { ChartLegendConfig, ChartSeries } from '../series.js';
|
|
4
5
|
export type MultiLineProps<T> = {
|
|
5
6
|
data: T[];
|
|
6
|
-
/** Fixed height in pixels, forwarded to
|
|
7
|
+
/** Fixed height in pixels, forwarded to `CartesianChart`. Default 240. */
|
|
7
8
|
height?: number;
|
|
8
9
|
chartId: string;
|
|
9
10
|
/** Extracts the x-axis category (date string) from a data point. */
|
|
10
11
|
getX: (d: T) => string;
|
|
11
|
-
/** 1+ line series sharing
|
|
12
|
-
* tooltip rows. */
|
|
12
|
+
/** 1+ line series sharing the y-axis(es) — the single source of truth for color, dash, legend,
|
|
13
|
+
* and tooltip rows. A series opts into the right axis with `axis: 'right'`. */
|
|
13
14
|
series: ChartSeries<T>[];
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
/** When 'auto': padding multiplier applied away from the domain. Default 1.1. The lower bound
|
|
22
|
-
* always pads DOWN from `min(dataMin, yAutoMinCeil)` (never up, which would clip data) — see
|
|
23
|
-
* {@link padAutoLower}. */
|
|
24
|
-
yAutoPad?: number;
|
|
25
|
-
/** Horizontal value-range overlays (target zones), rendered behind the lines on the left scale. */
|
|
15
|
+
/** Left y-axis. Collapses the old `yDomain` / `yAutoMaxFloor` / `yAutoMinCeil` / `yAutoPad` /
|
|
16
|
+
* `numTicksY` / `formatYTick` prop soup into one object. */
|
|
17
|
+
y?: AxisConfig<T>;
|
|
18
|
+
/** Right y-axis. Passing it is what makes the chart dual-axis — the margin widens by
|
|
19
|
+
* measurement, and `axis: 'right'` series read against it. */
|
|
20
|
+
y2?: AxisConfig<T>;
|
|
21
|
+
/** Horizontal value-range overlays (target zones), rendered behind the lines. */
|
|
26
22
|
zones?: ZoneSpec[];
|
|
23
|
+
/** Vertical x-range overlays (time windows), rendered behind the lines. Bounds are `getX`
|
|
24
|
+
* domain keys. */
|
|
25
|
+
xZones?: XZoneSpec[];
|
|
27
26
|
/** Horizontal reference lines. Solid by default; set dashed: true for a dashed line. */
|
|
28
27
|
refLines?: {
|
|
29
28
|
value: number;
|
|
30
29
|
color: string;
|
|
31
30
|
dashed?: boolean;
|
|
32
31
|
}[];
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
/** Tooltip
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
formatYTick?: (v: number) => string;
|
|
39
|
-
/** Label shown at the right of the tooltip header (e.g. status badge). */
|
|
40
|
-
tooltipLabel?: (d: T) => {
|
|
41
|
-
text: string;
|
|
42
|
-
color: string;
|
|
43
|
-
} | null;
|
|
44
|
-
/** Extra tooltip rows rendered after the per-series rows. */
|
|
45
|
-
renderExtraTooltipRows?: (d: T) => ReactNode;
|
|
32
|
+
/** Exact number of x ticks. Default: as many as fit. */
|
|
33
|
+
xTicks?: number;
|
|
34
|
+
/** Tooltip config — `label` for a right-aligned header badge, `extraRows` for rows appended
|
|
35
|
+
* after the derived per-series rows. `false` disables the tooltip entirely. */
|
|
36
|
+
tooltip?: CartesianTooltipConfig<T> | false;
|
|
46
37
|
/** Marker glyph for per-point markers. Default 'circle'. */
|
|
47
38
|
markerShape?: 'circle' | 'star';
|
|
48
|
-
/** Legend config forwarded to `
|
|
39
|
+
/** Legend config forwarded to `CartesianChart`; `false` disables the legend (sparkline escape).
|
|
49
40
|
* Default `{ placement: 'bottom' }`. */
|
|
50
41
|
legend?: ChartLegendConfig | false;
|
|
51
|
-
/** Accessible text alternative, forwarded to `
|
|
42
|
+
/** Accessible text alternative, forwarded to `CartesianChart` as `aria-label` (+ `role="img"`). */
|
|
52
43
|
ariaLabel?: string;
|
|
53
|
-
/** Forwarded to `
|
|
44
|
+
/** Forwarded to `CartesianChart` — see `ChartPending`'s JSDoc for the three-state rationale. */
|
|
54
45
|
isPending?: boolean;
|
|
55
46
|
};
|
|
56
47
|
/**
|
|
57
|
-
* N series sharing one y-
|
|
48
|
+
* N series sharing one or two y-axes, with optional zones/reference lines, per-point markers
|
|
58
49
|
* (PR stars / status dots), a dashed companion line per series, legend-hover dimming, and a
|
|
59
50
|
* shared-cursor tooltip. Generalizes the multi-line argo charts (e1RM trend, relative
|
|
60
51
|
* progression, training load, fitness trends).
|
|
61
52
|
*
|
|
62
|
-
* Composes `
|
|
63
|
-
*
|
|
53
|
+
* Composes `CartesianChart` for measuring, scales, grid, axes, cursor, and tooltip — this kind
|
|
54
|
+
* draws ONLY the marks (lines + per-point markers). `series` is the single array that drives the
|
|
55
|
+
* plotted lines, the legend, and the tooltip rows.
|
|
64
56
|
*
|
|
65
57
|
* X-axis is built from the full `data` array so the calendar is preserved even when a series
|
|
66
58
|
* has nulls; each series line skips null points (creating visual gaps).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiLine.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/MultiLine.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MultiLine.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/MultiLine.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sBAAsB,EAAE,UAAU,EAAe,MAAM,8BAA8B,CAAA;AAEnG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAEvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAG/D,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,IAAI,EAAE,CAAC,EAAE,CAAA;IACT,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,oEAAoE;IACpE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;mFAC+E;IAC/E,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACxB;gEAC4D;IAC5D,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IACjB;kEAC8D;IAC9D,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IAClB,iFAAiF;IACjF,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAA;IAClB;sBACkB;IAClB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAA;IACpB,wFAAwF;IACxF,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;IAC/D,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;mFAC+E;IAC/E,OAAO,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;IAC3C,4DAA4D;IAC5D,WAAW,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAA;IAC/B;4CACwC;IACxC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC,mGAAmG;IACnG,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gGAAgG;IAChG,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AA4BD;;;;;;;;;;;;GAYG;AACH,iBAAS,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,+BAgDlD;AAqHD;;;GAGG;AACH,eAAO,MAAM,SAAS,EAA2B,OAAO,cAAc,CAAA"}
|
|
@@ -1,27 +1,10 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { curveMonotoneX } from "@visx/curve";
|
|
3
|
-
import { GridRows } from "@visx/grid";
|
|
4
|
-
import { Group } from "@visx/group";
|
|
5
|
-
import { scaleLinear, scalePoint } from "@visx/scale";
|
|
6
3
|
import { LinePath } from "@visx/shape";
|
|
7
|
-
import { memo,
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
ChartTooltip,
|
|
11
|
-
TooltipBody,
|
|
12
|
-
TooltipHeader,
|
|
13
|
-
TooltipRow,
|
|
14
|
-
useTooltipStyles
|
|
15
|
-
} from "../primitives/ChartTooltip.js";
|
|
16
|
-
import { ChartFrame, resolveLegend } from "../primitives/ChartFrame.js";
|
|
17
|
-
import { Crosshair, SeriesDot } from "../primitives/Crosshair.js";
|
|
18
|
-
import { HoverOverlay } from "../primitives/HoverOverlay.js";
|
|
19
|
-
import { ZoneRects } from "../primitives/ZoneRects.js";
|
|
20
|
-
import { useHoverSync } from "../hooks/useHoverSync.js";
|
|
21
|
-
import { deriveTooltipRows, LINE_OVERLAY_STROKE_WIDTH } from "../series.js";
|
|
4
|
+
import { memo, useCallback, useMemo } from "react";
|
|
5
|
+
import { CartesianChart } from "../primitives/CartesianChart.js";
|
|
6
|
+
import { LINE_OVERLAY_STROKE_WIDTH } from "../series.js";
|
|
22
7
|
import { VX } from "../../tokens/index.js";
|
|
23
|
-
import { padAutoLower } from "../utils/domain.js";
|
|
24
|
-
import { smartTicks, smartTicksEvery } from "../utils/ticks.js";
|
|
25
8
|
const STAR_R = 6;
|
|
26
9
|
function starPath(cx, cy, r) {
|
|
27
10
|
const inner = r * 0.4;
|
|
@@ -33,241 +16,145 @@ function starPath(cx, cy, r) {
|
|
|
33
16
|
}
|
|
34
17
|
return `M${pts.join("L")}Z`;
|
|
35
18
|
}
|
|
19
|
+
function seriesPoints(series, data) {
|
|
20
|
+
const pts = [];
|
|
21
|
+
for (const d of data) {
|
|
22
|
+
const v = series.getValue(d);
|
|
23
|
+
if (v !== null && v !== void 0 && !Number.isNaN(v)) pts.push({ __d: d, __y: v });
|
|
24
|
+
}
|
|
25
|
+
return pts;
|
|
26
|
+
}
|
|
36
27
|
function MultiLineInner(props) {
|
|
37
|
-
const {
|
|
38
|
-
|
|
28
|
+
const {
|
|
29
|
+
data,
|
|
30
|
+
chartId,
|
|
31
|
+
getX,
|
|
32
|
+
series,
|
|
33
|
+
y,
|
|
34
|
+
y2,
|
|
35
|
+
zones,
|
|
36
|
+
xZones,
|
|
37
|
+
refLines,
|
|
38
|
+
xTicks,
|
|
39
|
+
tooltip,
|
|
40
|
+
markerShape = "circle",
|
|
41
|
+
height,
|
|
42
|
+
legend,
|
|
43
|
+
ariaLabel,
|
|
44
|
+
isPending
|
|
45
|
+
} = props;
|
|
39
46
|
const styledSeries = useMemo(
|
|
40
47
|
() => series.map((s) => ({ ...s, strokeWidth: s.strokeWidth ?? LINE_OVERLAY_STROKE_WIDTH })),
|
|
41
48
|
[series]
|
|
42
49
|
);
|
|
43
50
|
return /* @__PURE__ */ jsx(
|
|
44
|
-
|
|
51
|
+
CartesianChart,
|
|
45
52
|
{
|
|
46
|
-
|
|
53
|
+
data,
|
|
47
54
|
chartId,
|
|
55
|
+
getX,
|
|
56
|
+
series: styledSeries,
|
|
57
|
+
...y !== void 0 && { y },
|
|
58
|
+
...y2 !== void 0 && { y2 },
|
|
59
|
+
...zones !== void 0 && { zones },
|
|
60
|
+
...xZones !== void 0 && { xZones },
|
|
61
|
+
...refLines !== void 0 && { refLines },
|
|
62
|
+
...xTicks !== void 0 && { xTicks },
|
|
63
|
+
...tooltip !== void 0 && { tooltip },
|
|
48
64
|
...height !== void 0 && { height },
|
|
65
|
+
...legend !== void 0 && { legend },
|
|
49
66
|
...ariaLabel !== void 0 && { ariaLabel },
|
|
50
67
|
...isPending !== void 0 && { isPending },
|
|
51
|
-
|
|
52
|
-
highlighted: highlightedKey,
|
|
53
|
-
onHighlight: setHighlightedKey
|
|
54
|
-
}),
|
|
55
|
-
children: (plot) => /* @__PURE__ */ jsx(
|
|
56
|
-
MultiLinePlot,
|
|
57
|
-
{
|
|
58
|
-
...props,
|
|
59
|
-
series: styledSeries,
|
|
60
|
-
plot,
|
|
61
|
-
highlightedKey
|
|
62
|
-
}
|
|
63
|
-
)
|
|
68
|
+
children: (ctx) => /* @__PURE__ */ jsx(MultiLineMarks, { getX, markerShape, ctx })
|
|
64
69
|
}
|
|
65
70
|
);
|
|
66
71
|
}
|
|
67
|
-
function
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
formatValue,
|
|
82
|
-
formatYTick,
|
|
83
|
-
tooltipLabel,
|
|
84
|
-
renderExtraTooltipRows,
|
|
85
|
-
markerShape = "circle",
|
|
86
|
-
plot,
|
|
87
|
-
highlightedKey
|
|
88
|
-
} = props;
|
|
89
|
-
const dimOpacity = (s) => highlightedKey === null || s.key === highlightedKey || s.parent === highlightedKey ? 1 : 0.25;
|
|
90
|
-
const MARGIN = VX.margin;
|
|
91
|
-
const xMax = plot.width - MARGIN.left - MARGIN.right;
|
|
92
|
-
const yMax = plot.height - MARGIN.top - MARGIN.bottom;
|
|
93
|
-
const xScale = useMemo(
|
|
94
|
-
() => scalePoint({
|
|
95
|
-
// Full calendar — axis does not compress across nulls.
|
|
96
|
-
domain: data.map(getX),
|
|
97
|
-
range: [0, xMax],
|
|
98
|
-
padding: 0.3
|
|
99
|
-
}),
|
|
100
|
-
[data, xMax, getX]
|
|
101
|
-
);
|
|
102
|
-
const yScale = useMemo(() => {
|
|
103
|
-
if (yDomain === "auto") {
|
|
104
|
-
let dataMax = -Infinity;
|
|
105
|
-
let dataMin = Infinity;
|
|
106
|
-
for (const d of data) {
|
|
107
|
-
for (const s of series) {
|
|
108
|
-
const v = s.getValue(d);
|
|
109
|
-
if (v === null || v === void 0 || Number.isNaN(v)) continue;
|
|
110
|
-
if (v > dataMax) dataMax = v;
|
|
111
|
-
if (v < dataMin) dataMin = v;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
const safeMax = Number.isFinite(dataMax) ? dataMax : 0;
|
|
115
|
-
const safeMin = Number.isFinite(dataMin) ? dataMin : 0;
|
|
116
|
-
const upper = Math.max(safeMax, yAutoMaxFloor ?? safeMax) * yAutoPad;
|
|
117
|
-
const lower = padAutoLower(Math.min(safeMin, yAutoMinCeil), yAutoPad);
|
|
118
|
-
return scaleLinear({ domain: [lower, upper], range: [yMax, 0], nice: true });
|
|
119
|
-
}
|
|
120
|
-
return scaleLinear({ domain: yDomain, range: [yMax, 0] });
|
|
121
|
-
}, [data, series, yDomain, yMax, yAutoPad, yAutoMaxFloor, yAutoMinCeil]);
|
|
122
|
-
const tooltipStyles = useTooltipStyles();
|
|
123
|
-
const { tip, tooltipRef, syncedPoint, isDirectHover, handleMouse, handleLeave } = useHoverSync(
|
|
124
|
-
{
|
|
125
|
-
data,
|
|
126
|
-
chartId,
|
|
127
|
-
getKey: getX,
|
|
128
|
-
xScale,
|
|
129
|
-
marginLeft: MARGIN.left
|
|
130
|
-
}
|
|
72
|
+
function MultiLineMarks({
|
|
73
|
+
getX,
|
|
74
|
+
markerShape,
|
|
75
|
+
ctx
|
|
76
|
+
}) {
|
|
77
|
+
const { data, visible, xScale, yScale, y2Scale, highlighted } = ctx;
|
|
78
|
+
const pointsBySeries = useMemo(() => {
|
|
79
|
+
const m = /* @__PURE__ */ new Map();
|
|
80
|
+
for (const s of visible) m.set(s.key, seriesPoints(s, data));
|
|
81
|
+
return m;
|
|
82
|
+
}, [visible, data]);
|
|
83
|
+
const dimOpacity = useCallback(
|
|
84
|
+
(s) => highlighted === null || s.key === highlighted || s.parent === highlighted ? 1 : 0.25,
|
|
85
|
+
[highlighted]
|
|
131
86
|
);
|
|
132
|
-
const
|
|
133
|
-
() =>
|
|
134
|
-
[
|
|
87
|
+
const scaleFor = useCallback(
|
|
88
|
+
(s) => s.axis === "right" && y2Scale !== null ? y2Scale : yScale,
|
|
89
|
+
[y2Scale, yScale]
|
|
135
90
|
);
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
91
|
+
const markerNodes = useMemo(
|
|
92
|
+
() => visible.flatMap((s) => {
|
|
93
|
+
const getMarker = s.getMarker;
|
|
94
|
+
if (!getMarker) return [];
|
|
95
|
+
const scale = scaleFor(s);
|
|
96
|
+
const op = dimOpacity(s);
|
|
97
|
+
const markers = [];
|
|
98
|
+
for (const p of pointsBySeries.get(s.key) ?? []) {
|
|
99
|
+
const m = getMarker(p.__d);
|
|
100
|
+
if (m === null) continue;
|
|
101
|
+
const cx = xScale(getX(p.__d)) ?? 0;
|
|
102
|
+
const cy = scale(p.__y);
|
|
103
|
+
const color = m.color ?? s.color;
|
|
104
|
+
const r = m.r ?? (markerShape === "star" ? STAR_R : VX.dotR);
|
|
105
|
+
markers.push(
|
|
106
|
+
markerShape === "star" ? /* @__PURE__ */ jsx(
|
|
107
|
+
"path",
|
|
108
|
+
{
|
|
109
|
+
d: starPath(cx, cy, r),
|
|
110
|
+
fill: color,
|
|
111
|
+
stroke: VX.dotStroke,
|
|
112
|
+
strokeWidth: 1.5,
|
|
113
|
+
fillOpacity: op,
|
|
114
|
+
strokeOpacity: op
|
|
115
|
+
},
|
|
116
|
+
`mk-${s.key}-${getX(p.__d)}`
|
|
117
|
+
) : /* @__PURE__ */ jsx(
|
|
118
|
+
"circle",
|
|
119
|
+
{
|
|
120
|
+
cx,
|
|
121
|
+
cy,
|
|
122
|
+
r,
|
|
123
|
+
fill: color,
|
|
124
|
+
stroke: VX.dotStroke,
|
|
125
|
+
strokeWidth: 2,
|
|
126
|
+
fillOpacity: op,
|
|
127
|
+
strokeOpacity: op
|
|
128
|
+
},
|
|
129
|
+
`mk-${s.key}-${getX(p.__d)}`
|
|
130
|
+
)
|
|
131
|
+
);
|
|
143
132
|
}
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const tooltipLbl = tip ? tooltipLabel?.(tip.data) ?? null : null;
|
|
133
|
+
return markers;
|
|
134
|
+
}),
|
|
135
|
+
[visible, pointsBySeries, xScale, getX, scaleFor, dimOpacity, markerShape]
|
|
136
|
+
);
|
|
149
137
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
138
|
+
visible.map((s) => {
|
|
139
|
+
const valid = pointsBySeries.get(s.key) ?? [];
|
|
140
|
+
if (valid.length === 0) return null;
|
|
141
|
+
const scale = scaleFor(s);
|
|
142
|
+
return /* @__PURE__ */ jsx(
|
|
143
|
+
LinePath,
|
|
155
144
|
{
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
strokeDasharray:
|
|
145
|
+
data: valid,
|
|
146
|
+
x: (p) => xScale(getX(p.__d)) ?? 0,
|
|
147
|
+
y: (p) => scale(p.__y),
|
|
148
|
+
stroke: s.color,
|
|
149
|
+
strokeWidth: s.strokeWidth ?? LINE_OVERLAY_STROKE_WIDTH,
|
|
150
|
+
strokeDasharray: s.dash === "dashed" ? VX.dashArray : void 0,
|
|
151
|
+
strokeOpacity: dimOpacity(s) * (s.strokeOpacity ?? 1),
|
|
152
|
+
curve: curveMonotoneX
|
|
162
153
|
},
|
|
163
|
-
`
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if (valid.length === 0) return null;
|
|
168
|
-
return /* @__PURE__ */ jsx(
|
|
169
|
-
LinePath,
|
|
170
|
-
{
|
|
171
|
-
data: valid,
|
|
172
|
-
x: (p) => xScale(getX(p.__d)) ?? 0,
|
|
173
|
-
y: (p) => yScale(p.__y),
|
|
174
|
-
stroke: s.color,
|
|
175
|
-
strokeWidth: s.strokeWidth ?? VX.lineWidth,
|
|
176
|
-
strokeDasharray: s.dash === "dashed" ? VX.dashArray : void 0,
|
|
177
|
-
strokeOpacity: dimOpacity(s),
|
|
178
|
-
curve: curveMonotoneX
|
|
179
|
-
},
|
|
180
|
-
`line-${s.key}`
|
|
181
|
-
);
|
|
182
|
-
}),
|
|
183
|
-
series.flatMap((s) => {
|
|
184
|
-
const getMarker = s.getMarker;
|
|
185
|
-
if (!getMarker) return [];
|
|
186
|
-
const op = dimOpacity(s);
|
|
187
|
-
const markers = [];
|
|
188
|
-
for (const p of seriesPts.get(s.key) ?? []) {
|
|
189
|
-
const m = getMarker(p.__d);
|
|
190
|
-
if (m === null) continue;
|
|
191
|
-
const cx = xScale(getX(p.__d)) ?? 0;
|
|
192
|
-
const cy = yScale(p.__y);
|
|
193
|
-
const color = m.color ?? s.color;
|
|
194
|
-
const r = m.r ?? (markerShape === "star" ? STAR_R : VX.dotR);
|
|
195
|
-
markers.push(
|
|
196
|
-
markerShape === "star" ? /* @__PURE__ */ jsx(
|
|
197
|
-
"path",
|
|
198
|
-
{
|
|
199
|
-
d: starPath(cx, cy, r),
|
|
200
|
-
fill: color,
|
|
201
|
-
stroke: VX.dotStroke,
|
|
202
|
-
strokeWidth: 1.5,
|
|
203
|
-
fillOpacity: op,
|
|
204
|
-
strokeOpacity: op
|
|
205
|
-
},
|
|
206
|
-
`mk-${s.key}-${getX(p.__d)}`
|
|
207
|
-
) : /* @__PURE__ */ jsx(
|
|
208
|
-
"circle",
|
|
209
|
-
{
|
|
210
|
-
cx,
|
|
211
|
-
cy,
|
|
212
|
-
r,
|
|
213
|
-
fill: color,
|
|
214
|
-
stroke: VX.dotStroke,
|
|
215
|
-
strokeWidth: 2,
|
|
216
|
-
fillOpacity: op,
|
|
217
|
-
strokeOpacity: op
|
|
218
|
-
},
|
|
219
|
-
`mk-${s.key}-${getX(p.__d)}`
|
|
220
|
-
)
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
return markers;
|
|
224
|
-
}),
|
|
225
|
-
syncedPoint && (() => {
|
|
226
|
-
const sx = xScale(getX(syncedPoint)) ?? 0;
|
|
227
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
228
|
-
/* @__PURE__ */ jsx(Crosshair, { x: sx, top: 0, bottom: yMax }),
|
|
229
|
-
series.map((s) => {
|
|
230
|
-
const v = s.getValue(syncedPoint);
|
|
231
|
-
if (v === null || v === void 0 || Number.isNaN(v)) return null;
|
|
232
|
-
return /* @__PURE__ */ jsx(SeriesDot, { cx: sx, cy: yScale(v), color: s.color }, `dot-${s.key}`);
|
|
233
|
-
})
|
|
234
|
-
] });
|
|
235
|
-
})(),
|
|
236
|
-
/* @__PURE__ */ jsx(
|
|
237
|
-
AxisLeftNumeric,
|
|
238
|
-
{
|
|
239
|
-
scale: yScale,
|
|
240
|
-
numTicks: numTicksY,
|
|
241
|
-
...formatYTick !== void 0 && { tickFormat: formatYTick }
|
|
242
|
-
}
|
|
243
|
-
),
|
|
244
|
-
/* @__PURE__ */ jsx(AxisBottomDate, { top: yMax, scale: xScale, tickValues }),
|
|
245
|
-
/* @__PURE__ */ jsx(HoverOverlay, { width: xMax, height: yMax, onMove: handleMouse, onLeave: handleLeave })
|
|
246
|
-
] }) }),
|
|
247
|
-
/* @__PURE__ */ jsx(ChartTooltip, { tip: isDirectHover ? tip : null, tooltipRef, styles: tooltipStyles, children: tip && isDirectHover && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
248
|
-
/* @__PURE__ */ jsx(
|
|
249
|
-
TooltipHeader,
|
|
250
|
-
{
|
|
251
|
-
date: getX(tip.data),
|
|
252
|
-
...tooltipLbl !== null && { label: tooltipLbl.text, labelColor: tooltipLbl.color }
|
|
253
|
-
}
|
|
254
|
-
),
|
|
255
|
-
/* @__PURE__ */ jsxs(TooltipBody, { children: [
|
|
256
|
-
deriveTooltipRows(series, tip.data, formatValue).map((row) => /* @__PURE__ */ jsx(
|
|
257
|
-
TooltipRow,
|
|
258
|
-
{
|
|
259
|
-
color: row.color,
|
|
260
|
-
label: row.label,
|
|
261
|
-
value: row.value,
|
|
262
|
-
shape: row.shape,
|
|
263
|
-
dashed: row.dashed,
|
|
264
|
-
...row.strokeWidth !== void 0 && { strokeWidth: row.strokeWidth }
|
|
265
|
-
},
|
|
266
|
-
row.key
|
|
267
|
-
)),
|
|
268
|
-
renderExtraTooltipRows?.(tip.data)
|
|
269
|
-
] })
|
|
270
|
-
] }) })
|
|
154
|
+
`line-${s.key}`
|
|
155
|
+
);
|
|
156
|
+
}),
|
|
157
|
+
markerNodes
|
|
271
158
|
] });
|
|
272
159
|
}
|
|
273
160
|
const MultiLine = memo(MultiLineInner);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MultiLine.test.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/MultiLine.test.tsx"],"names":[],"mappings":""}
|