basalt-ui 1.14.0 → 1.15.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.
Files changed (162) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +8 -0
  3. package/README.md +38 -2
  4. package/agent/rules/basalt-charts.md +260 -108
  5. package/agent/rules/basalt-mantine.md +4 -2
  6. package/agent/skills/basalt-charts/SKILL.md +114 -64
  7. package/agent/skills/basalt-design/SKILL.md +4 -3
  8. package/configs/oxlint-plugin.js +152 -0
  9. package/configs/oxlint-plugin.test.ts +107 -0
  10. package/configs/oxlint.json +2 -0
  11. package/dist/charts/cursor/resolve.d.ts +33 -0
  12. package/dist/charts/cursor/resolve.d.ts.map +1 -0
  13. package/dist/charts/cursor/resolve.js +61 -0
  14. package/dist/charts/cursor/resolve.test.d.ts +2 -0
  15. package/dist/charts/cursor/resolve.test.d.ts.map +1 -0
  16. package/dist/charts/cursor/scope.d.ts +17 -0
  17. package/dist/charts/cursor/scope.d.ts.map +1 -0
  18. package/dist/charts/cursor/scope.js +20 -0
  19. package/dist/charts/cursor/store.d.ts +31 -0
  20. package/dist/charts/cursor/store.d.ts.map +1 -0
  21. package/dist/charts/cursor/store.js +25 -0
  22. package/dist/charts/cursor/store.test.d.ts +2 -0
  23. package/dist/charts/cursor/store.test.d.ts.map +1 -0
  24. package/dist/charts/hooks/useChartCursor.d.ts +39 -0
  25. package/dist/charts/hooks/useChartCursor.d.ts.map +1 -0
  26. package/dist/charts/hooks/useChartCursor.js +104 -0
  27. package/dist/charts/hooks/useChartSize.d.ts +8 -4
  28. package/dist/charts/hooks/useChartSize.d.ts.map +1 -1
  29. package/dist/charts/index.d.ts +16 -13
  30. package/dist/charts/index.d.ts.map +1 -1
  31. package/dist/charts/index.js +38 -19
  32. package/dist/charts/kinds/Bars.d.ts +25 -47
  33. package/dist/charts/kinds/Bars.d.ts.map +1 -1
  34. package/dist/charts/kinds/Bars.js +230 -390
  35. package/dist/charts/kinds/Donut.d.ts +5 -4
  36. package/dist/charts/kinds/Donut.d.ts.map +1 -1
  37. package/dist/charts/kinds/Donut.js +17 -14
  38. package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
  39. package/dist/charts/kinds/DualPanel.js +136 -90
  40. package/dist/charts/kinds/Heatmap.d.ts +15 -11
  41. package/dist/charts/kinds/Heatmap.d.ts.map +1 -1
  42. package/dist/charts/kinds/Heatmap.js +38 -22
  43. package/dist/charts/kinds/MultiLine.d.ts +27 -35
  44. package/dist/charts/kinds/MultiLine.d.ts.map +1 -1
  45. package/dist/charts/kinds/MultiLine.js +114 -237
  46. package/dist/charts/kinds/StackedArea.d.ts +21 -10
  47. package/dist/charts/kinds/StackedArea.d.ts.map +1 -1
  48. package/dist/charts/kinds/StackedArea.js +74 -132
  49. package/dist/charts/kinds/ZonedLine.d.ts +24 -40
  50. package/dist/charts/kinds/ZonedLine.d.ts.map +1 -1
  51. package/dist/charts/kinds/ZonedLine.js +103 -184
  52. package/dist/charts/layout/auto-margin.d.ts +60 -0
  53. package/dist/charts/layout/auto-margin.d.ts.map +1 -0
  54. package/dist/charts/layout/auto-margin.js +37 -0
  55. package/dist/charts/layout/auto-margin.test.d.ts +2 -0
  56. package/dist/charts/layout/auto-margin.test.d.ts.map +1 -0
  57. package/dist/charts/primitives/CartesianChart.d.ts +143 -0
  58. package/dist/charts/primitives/CartesianChart.d.ts.map +1 -0
  59. package/dist/charts/primitives/CartesianChart.js +349 -0
  60. package/dist/charts/primitives/CartesianChart.test.d.ts +2 -0
  61. package/dist/charts/primitives/CartesianChart.test.d.ts.map +1 -0
  62. package/dist/charts/primitives/ChartFrame.d.ts +16 -5
  63. package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
  64. package/dist/charts/primitives/ChartFrame.js +17 -2
  65. package/dist/charts/primitives/ChartLegend.d.ts +12 -1
  66. package/dist/charts/primitives/ChartLegend.d.ts.map +1 -1
  67. package/dist/charts/primitives/ChartLegend.js +21 -3
  68. package/dist/charts/primitives/ChartLegend.test.d.ts +2 -0
  69. package/dist/charts/primitives/ChartLegend.test.d.ts.map +1 -0
  70. package/dist/charts/primitives/ChartTooltip.d.ts +16 -16
  71. package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
  72. package/dist/charts/primitives/ChartTooltip.js +45 -19
  73. package/dist/charts/primitives/HoverOverlay.d.ts +19 -4
  74. package/dist/charts/primitives/HoverOverlay.d.ts.map +1 -1
  75. package/dist/charts/primitives/HoverOverlay.js +22 -1
  76. package/dist/charts/primitives/XZoneRects.d.ts +40 -0
  77. package/dist/charts/primitives/XZoneRects.d.ts.map +1 -0
  78. package/dist/charts/primitives/XZoneRects.js +28 -0
  79. package/dist/charts/primitives/XZoneRects.test.d.ts +2 -0
  80. package/dist/charts/primitives/XZoneRects.test.d.ts.map +1 -0
  81. package/dist/charts/series.d.ts +16 -1
  82. package/dist/charts/series.d.ts.map +1 -1
  83. package/dist/charts/series.js +3 -1
  84. package/dist/charts/series.test.d.ts +2 -0
  85. package/dist/charts/series.test.d.ts.map +1 -0
  86. package/dist/charts/utils/measure-text.d.ts +25 -0
  87. package/dist/charts/utils/measure-text.d.ts.map +1 -0
  88. package/dist/charts/utils/measure-text.js +64 -0
  89. package/dist/charts/utils/measure-text.test.d.ts +2 -0
  90. package/dist/charts/utils/measure-text.test.d.ts.map +1 -0
  91. package/dist/content/fence-block.d.ts.map +1 -1
  92. package/dist/surfaces.d.ts +1 -1
  93. package/dist/surfaces.d.ts.map +1 -1
  94. package/dist/surfaces.js +1 -1
  95. package/dist/tokens/chart-margin.test.d.ts +2 -0
  96. package/dist/tokens/chart-margin.test.d.ts.map +1 -0
  97. package/dist/tokens/index.d.ts +29 -0
  98. package/dist/tokens/index.d.ts.map +1 -1
  99. package/dist/tokens/index.js +10 -0
  100. package/dist/tokens/palette.d.ts +4 -0
  101. package/dist/tokens/palette.d.ts.map +1 -1
  102. package/dist/tokens/palette.js +3 -0
  103. package/llms.txt +3 -3
  104. package/package.json +1 -1
  105. package/src/charts/cursor/resolve.test.ts +61 -0
  106. package/src/charts/cursor/resolve.ts +102 -0
  107. package/src/charts/cursor/scope.tsx +32 -0
  108. package/src/charts/cursor/store.test.ts +46 -0
  109. package/src/charts/cursor/store.ts +53 -0
  110. package/src/charts/hooks/useChartCursor.ts +163 -0
  111. package/src/charts/hooks/useChartSize.ts +8 -4
  112. package/src/charts/index.ts +34 -14
  113. package/src/charts/kinds/Bars.tsx +327 -460
  114. package/src/charts/kinds/Donut.tsx +31 -23
  115. package/src/charts/kinds/DualPanel.tsx +228 -134
  116. package/src/charts/kinds/Heatmap.tsx +72 -47
  117. package/src/charts/kinds/MultiLine.tsx +158 -294
  118. package/src/charts/kinds/StackedArea.tsx +116 -175
  119. package/src/charts/kinds/ZonedLine.tsx +148 -255
  120. package/src/charts/layout/auto-margin.test.ts +42 -0
  121. package/src/charts/layout/auto-margin.ts +110 -0
  122. package/src/charts/primitives/CartesianChart.test.ts +99 -0
  123. package/src/charts/primitives/CartesianChart.tsx +566 -0
  124. package/src/charts/primitives/ChartFrame.test.tsx +33 -0
  125. package/src/charts/primitives/ChartFrame.tsx +40 -4
  126. package/src/charts/primitives/ChartLegend.test.tsx +48 -0
  127. package/src/charts/primitives/ChartLegend.tsx +45 -2
  128. package/src/charts/primitives/ChartTooltip.tsx +67 -37
  129. package/src/charts/primitives/HoverOverlay.tsx +39 -3
  130. package/src/charts/primitives/XZoneRects.test.tsx +63 -0
  131. package/src/charts/primitives/XZoneRects.tsx +67 -0
  132. package/src/charts/series.test.ts +61 -0
  133. package/src/charts/series.ts +18 -1
  134. package/src/charts/utils/measure-text.test.ts +36 -0
  135. package/src/charts/utils/measure-text.ts +109 -0
  136. package/src/content/fence-block.tsx +2 -3
  137. package/src/surfaces.ts +2 -1
  138. package/src/theme/spacing.test.ts +2 -0
  139. package/src/tokens/chart-margin.test.ts +39 -0
  140. package/src/tokens/density.test.ts +1 -0
  141. package/src/tokens/index.ts +36 -0
  142. package/src/tokens/palette.ts +3 -0
  143. package/dist/charts/hooks/useChartTooltip.d.ts +0 -13
  144. package/dist/charts/hooks/useChartTooltip.d.ts.map +0 -1
  145. package/dist/charts/hooks/useChartTooltip.js +0 -26
  146. package/dist/charts/hooks/useHoverSync.d.ts +0 -46
  147. package/dist/charts/hooks/useHoverSync.d.ts.map +0 -1
  148. package/dist/charts/hooks/useHoverSync.js +0 -75
  149. package/dist/charts/hover-context.d.ts +0 -21
  150. package/dist/charts/hover-context.d.ts.map +0 -1
  151. package/dist/charts/hover-context.js +0 -12
  152. package/dist/charts/hover-sync.d.ts +0 -14
  153. package/dist/charts/hover-sync.d.ts.map +0 -1
  154. package/dist/charts/hover-sync.js +0 -17
  155. package/dist/charts/primitives/ResponsiveChart.d.ts +0 -45
  156. package/dist/charts/primitives/ResponsiveChart.d.ts.map +0 -1
  157. package/dist/charts/primitives/ResponsiveChart.js +0 -24
  158. package/src/charts/hooks/useChartTooltip.ts +0 -31
  159. package/src/charts/hooks/useHoverSync.ts +0 -152
  160. package/src/charts/hover-context.ts +0 -28
  161. package/src/charts/hover-sync.tsx +0 -37
  162. package/src/charts/primitives/ResponsiveChart.tsx +0 -64
@@ -1,150 +1,92 @@
1
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
1
+ import { jsx } 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 { AreaStack } from "@visx/shape";
7
- import { memo, useMemo, useState } from "react";
8
- import { AxisBottomDate, AxisLeftNumeric } from "../primitives/Axes.js";
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 { useHoverSync } from "../hooks/useHoverSync.js";
20
- import { deriveTooltipRows } from "../series.js";
21
- import { VX } from "../../tokens/index.js";
22
- import { smartTicks, smartTicksEvery } from "../utils/ticks.js";
4
+ import { memo, useCallback, useMemo } from "react";
5
+ import { CartesianChart } from "../primitives/CartesianChart.js";
23
6
  function StackedAreaInner(props) {
24
- const { series, chartId, height, legend, ariaLabel, isPending } = props;
25
- const [highlightedKey, setHighlightedKey] = useState(null);
7
+ const { data, chartId, getX, series, y, xTicks, height, legend, ariaLabel, isPending } = props;
8
+ const yConfig = useMemo(() => {
9
+ const base = y ?? {};
10
+ if (base.domain !== void 0 && base.domain !== "auto") return base;
11
+ const pad = base.autoPad ?? 1.1;
12
+ return {
13
+ ...base,
14
+ // Sums the VISIBLE bands only, so toggling one off in the legend shrinks the axis instead
15
+ // of leaving a permanent empty gap above the stack.
16
+ domain: (rows, visible) => {
17
+ let maxTotal = 0;
18
+ for (const d of rows) {
19
+ let total = 0;
20
+ for (const s of visible) total += s.getValue(d) ?? 0;
21
+ if (total > maxTotal) maxTotal = total;
22
+ }
23
+ return [0, Math.max(maxTotal, base.autoMaxFloor ?? maxTotal) * pad];
24
+ }
25
+ };
26
+ }, [y]);
27
+ const stackedCursorValue = useCallback(
28
+ (d, s, visible) => {
29
+ let total = 0;
30
+ for (let i = visible.length - 1; i >= 0; i--) {
31
+ const band = visible[i];
32
+ total += band.getValue(d) ?? 0;
33
+ if (band.key === s.key) return total;
34
+ }
35
+ return null;
36
+ },
37
+ []
38
+ );
39
+ const reversedSeries = useMemo(() => series.toReversed(), [series]);
26
40
  return /* @__PURE__ */ jsx(
27
- ChartFrame,
41
+ CartesianChart,
28
42
  {
29
- series,
43
+ data,
30
44
  chartId,
45
+ getX,
46
+ series: reversedSeries,
47
+ y: yConfig,
48
+ cursorValue: stackedCursorValue,
49
+ ...xTicks !== void 0 && { xTicks },
31
50
  ...height !== void 0 && { height },
51
+ ...legend !== void 0 && { legend },
32
52
  ...ariaLabel !== void 0 && { ariaLabel },
33
53
  ...isPending !== void 0 && { isPending },
34
- legend: resolveLegend(legend, {
35
- highlighted: highlightedKey,
36
- onHighlight: setHighlightedKey
37
- }),
38
- children: (plot) => /* @__PURE__ */ jsx(StackedAreaPlot, { ...props, plot, highlightedKey })
54
+ children: (ctx) => /* @__PURE__ */ jsx(StackedAreaMarks, { getX, ctx })
39
55
  }
40
56
  );
41
57
  }
42
- function StackedAreaPlot(props) {
43
- const {
44
- data,
45
- chartId,
46
- getX,
47
- series,
48
- formatValue,
49
- numTicksY = 5,
50
- numTicksX,
51
- yAutoMaxFloor,
52
- plot,
53
- highlightedKey
54
- } = props;
55
- const MARGIN = VX.margin;
56
- const xMax = plot.width - MARGIN.left - MARGIN.right;
57
- const yMax = plot.height - MARGIN.top - MARGIN.bottom;
58
- const seriesByKey = useMemo(() => new Map(series.map((s) => [s.key, s])), [series]);
59
- const groups = useMemo(() => series.map((s) => s.key), [series]);
60
- const xScale = useMemo(
61
- () => scalePoint({
62
- domain: data.map(getX),
63
- range: [0, xMax],
64
- padding: 0
65
- }),
66
- [data, xMax, getX]
67
- );
68
- const yScale = useMemo(() => {
69
- let maxTotal = 0;
70
- for (const d of data) {
71
- let total = 0;
72
- for (const s of series) {
73
- total += s.getValue(d) ?? 0;
74
- }
75
- if (total > maxTotal) maxTotal = total;
76
- }
77
- const upper = Math.max(maxTotal, yAutoMaxFloor ?? maxTotal) * 1.1;
78
- return scaleLinear({ domain: [0, upper], range: [yMax, 0], nice: true });
79
- }, [data, series, yMax, yAutoMaxFloor]);
80
- const tooltipStyles = useTooltipStyles();
81
- const { tip, tooltipRef, syncedPoint, isDirectHover, handleMouse, handleLeave } = useHoverSync(
58
+ function StackedAreaMarks({ getX, ctx }) {
59
+ const { visible, xScale, yScale, highlighted } = ctx;
60
+ const { groups, seriesByKey } = useMemo(() => {
61
+ const stackOrder = visible.toReversed();
62
+ return {
63
+ groups: stackOrder.map((s) => s.key),
64
+ seriesByKey: new Map(stackOrder.map((s) => [s.key, s]))
65
+ };
66
+ }, [visible]);
67
+ const rows = useMemo(() => [...ctx.data], [ctx.data]);
68
+ return /* @__PURE__ */ jsx(
69
+ AreaStack,
82
70
  {
83
- data,
84
- chartId,
85
- getKey: getX,
86
- xScale,
87
- marginLeft: MARGIN.left
88
- }
89
- );
90
- const tickValues = useMemo(
91
- () => numTicksX ? smartTicksEvery(data.map(getX), numTicksX) : smartTicks(data.map(getX), xMax),
92
- [data, xMax, getX, numTicksX]
93
- );
94
- return /* @__PURE__ */ jsxs(Fragment, { children: [
95
- /* @__PURE__ */ jsx("svg", { width: plot.width, height: plot.height, children: /* @__PURE__ */ jsxs(Group, { left: MARGIN.left, top: MARGIN.top, children: [
96
- /* @__PURE__ */ jsx(GridRows, { scale: yScale, width: xMax, stroke: VX.grid, numTicks: numTicksY }),
97
- /* @__PURE__ */ jsx(
98
- AreaStack,
99
- {
100
- data,
101
- keys: groups,
102
- x: (d) => xScale(getX(d.data)) ?? 0,
103
- y0: (d) => yScale(d[0]) ?? 0,
104
- y1: (d) => yScale(d[1]) ?? 0,
105
- value: (d, key) => seriesByKey.get(key)?.getValue(d) ?? 0,
106
- curve: curveMonotoneX,
107
- children: ({ stacks, path }) => stacks.map((stack) => /* @__PURE__ */ jsx(
108
- "path",
109
- {
110
- d: path(stack) || "",
111
- fill: seriesByKey.get(stack.key)?.color,
112
- stroke: "transparent",
113
- fillOpacity: highlightedKey === null || highlightedKey === stack.key ? 1 : 0.25
114
- },
115
- `stack-${stack.key}`
116
- ))
117
- }
118
- ),
119
- syncedPoint && (() => {
120
- const sx = xScale(getX(syncedPoint)) ?? 0;
121
- let cum = 0;
122
- return /* @__PURE__ */ jsxs(Fragment, { children: [
123
- /* @__PURE__ */ jsx(Crosshair, { x: sx, top: 0, bottom: yMax }),
124
- series.map((s) => {
125
- cum += s.getValue(syncedPoint) ?? 0;
126
- return /* @__PURE__ */ jsx(SeriesDot, { cx: sx, cy: yScale(cum), color: s.color }, `dot-${s.key}`);
127
- })
128
- ] });
129
- })(),
130
- /* @__PURE__ */ jsx(AxisLeftNumeric, { scale: yScale, numTicks: numTicksY, tickFormat: formatValue }),
131
- /* @__PURE__ */ jsx(AxisBottomDate, { top: yMax, scale: xScale, tickValues }),
132
- /* @__PURE__ */ jsx(HoverOverlay, { width: xMax, height: yMax, onMove: handleMouse, onLeave: handleLeave })
133
- ] }) }),
134
- /* @__PURE__ */ jsx(ChartTooltip, { tip: isDirectHover ? tip : null, tooltipRef, styles: tooltipStyles, children: tip && isDirectHover && /* @__PURE__ */ jsxs(Fragment, { children: [
135
- /* @__PURE__ */ jsx(TooltipHeader, { date: getX(tip.data) }),
136
- /* @__PURE__ */ jsx(TooltipBody, { children: deriveTooltipRows(series.toReversed(), tip.data, formatValue).map((row) => /* @__PURE__ */ jsx(
137
- TooltipRow,
71
+ data: rows,
72
+ keys: groups,
73
+ x: (d) => xScale(getX(d.data)) ?? 0,
74
+ y0: (d) => yScale(d[0]) ?? 0,
75
+ y1: (d) => yScale(d[1]) ?? 0,
76
+ value: (d, key) => seriesByKey.get(key)?.getValue(d) ?? 0,
77
+ curve: curveMonotoneX,
78
+ children: ({ stacks, path }) => stacks.map((stack) => /* @__PURE__ */ jsx(
79
+ "path",
138
80
  {
139
- color: row.color,
140
- label: row.label,
141
- value: row.value,
142
- shape: row.shape
81
+ d: path(stack) || "",
82
+ fill: seriesByKey.get(stack.key)?.color,
83
+ stroke: "transparent",
84
+ fillOpacity: highlighted === null || highlighted === stack.key ? 1 : 0.25
143
85
  },
144
- row.key
145
- )) })
146
- ] }) })
147
- ] });
86
+ `stack-${stack.key}`
87
+ ))
88
+ }
89
+ );
148
90
  }
149
91
  const StackedArea = memo(StackedAreaInner);
150
92
  export {
@@ -1,4 +1,5 @@
1
- import type { ReactNode } from 'react';
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
  /** @deprecated Use ZoneSpec from primitives/ZoneRects. Kept as an alias for back-compat. */
@@ -16,49 +17,31 @@ export type ZonedLineRefLine = {
16
17
  /** Solid by default; set true for a dashed line. */
17
18
  dashed?: boolean;
18
19
  };
19
- export type ZonedLineTooltipLabel = {
20
- text: string;
21
- color: string;
22
- };
23
20
  export type ZonedLineProps<T> = {
24
21
  data: T[];
25
- /** Fixed height in pixels, forwarded to the internal `ChartFrame`. Default 240. */
22
+ /** Fixed height in pixels, forwarded to `CartesianChart`. Default 240. */
26
23
  height?: number;
27
24
  chartId: string;
28
25
  /** Extracts the x-axis category (date string) from a data point. */
29
26
  getX: (d: T) => string;
30
27
  /** Single-series line — the sole source of truth for color, dash, legend, and tooltip row. Pass
31
- * exactly one entry (kept as an array for parity with the other kinds and so `ChartFrame` /
28
+ * exactly one entry (kept as an array for parity with the other kinds and so `CartesianChart` /
32
29
  * `deriveLegend` / `deriveTooltipRows` can consume it directly). */
33
30
  series: ChartSeries<T>[];
34
- /** Fixed y-domain (e.g. [0, 100]) or 'auto' to compute from data. */
35
- yDomain: [number, number] | 'auto';
36
- /**
37
- * When yDomain is 'auto': the upper bound is at least this value (caps data max).
38
- * e.g. yAutoMaxFloor=2 guarantees the y-axis always reaches 2 even if data is smaller.
39
- */
40
- yAutoMaxFloor?: number;
41
- /**
42
- * When yDomain is 'auto': the lower bound is at most this value.
43
- * Default 0 — always includes zero when data is all positive. Pass a negative
44
- * number (or Infinity to disable) for metrics that can legitimately swing both ways.
45
- */
46
- yAutoMinCeil?: number;
47
- /** Padding multiplier applied to auto-computed bounds. Default 1.1. The lower bound always pads
48
- * DOWN from `min(dataMin, yAutoMinCeil)` (never up, which would clip data) — see
49
- * {@link padAutoLower}. */
50
- yAutoPad?: number;
31
+ /** Y-axis. Collapses the old `yDomain` / `yAutoMaxFloor` / `yAutoMinCeil` / `yAutoPad` /
32
+ * `numTicksY` / `formatYTick` prop soup into one object. */
33
+ y?: AxisConfig<T>;
51
34
  zones?: ZonedLineZone[];
35
+ /** Vertical x-range overlays (time windows), rendered behind the line. Bounds are `getX`
36
+ * domain keys. */
37
+ xZones?: XZoneSpec[];
52
38
  thresholds?: ZonedLineThreshold[];
53
39
  refLines?: ZonedLineRefLine[];
54
- numTicksY?: number;
55
- numTicksX?: number;
56
- /** Label shown at the right of the tooltip header (e.g. zone name with zone color). */
57
- tooltipLabel?: (d: T) => ZonedLineTooltipLabel | null;
58
- /** Formatter for the tooltip value. */
59
- formatValue: (v: number) => string;
60
- /** Optional extra tooltip rows (rendered after the main row). */
61
- renderExtraTooltipRows?: (d: T) => ReactNode;
40
+ /** Exact number of x ticks. Default: as many as fit. */
41
+ xTicks?: number;
42
+ /** Tooltip config — `label` for a right-aligned header badge (e.g. zone name with zone color),
43
+ * `extraRows` for rows appended after the derived row. `false` disables the tooltip entirely. */
44
+ tooltip?: CartesianTooltipConfig<T> | false;
62
45
  /**
63
46
  * Opt-in soft gradient fill under the line. Pass a color token to tint the area
64
47
  * with that hue — the modern single-hue look. `true` falls back to the series color. Off by
@@ -66,21 +49,22 @@ export type ZonedLineProps<T> = {
66
49
  * via `--vx-area-top` / `--vx-area-bottom` (tunable in the dev theme lab).
67
50
  */
68
51
  areaFill?: string | boolean;
69
- /** Legend config forwarded to `ChartFrame`; `false` disables the legend (sparkline escape).
52
+ /** Legend config forwarded to `CartesianChart`; `false` disables the legend (sparkline escape).
70
53
  * Default `{ placement: 'bottom' }`. */
71
54
  legend?: ChartLegendConfig | false;
72
- /** Accessible text alternative, forwarded to `ChartFrame` as `aria-label` (+ `role="img"`). */
55
+ /** Accessible text alternative, forwarded to `CartesianChart` as `aria-label` (+ `role="img"`). */
73
56
  ariaLabel?: string;
74
- /** Forwarded to `ChartFrame` — see `ChartPending`'s JSDoc for the three-state rationale. */
57
+ /** Forwarded to `CartesianChart` — see `ChartPending`'s JSDoc for the three-state rationale. */
75
58
  isPending?: boolean;
76
59
  };
77
60
  /**
78
- * Line chart with zone backgrounds, threshold fills, reference lines, and a
79
- * shared-cursor tooltip. Covers the line-with-zones pattern. Does NOT handle
80
- * dual-panel charts (keep those bespoke).
61
+ * Single-series line chart with zone backgrounds, threshold fills, an optional area gradient,
62
+ * reference lines, and a shared-cursor tooltip. Covers the line-with-zones pattern. Does NOT
63
+ * handle dual-panel charts (keep those bespoke).
81
64
  *
82
- * Composes `ChartFrame` for measuring + the derived legend — single-series, so the legend is
83
- * optional in practice but present by default (gained relative to the pre-redesign kind).
65
+ * Composes `CartesianChart` for measuring, scales, grid, zones/x-zones, axes, the shared cursor,
66
+ * and the derived tooltip — this kind draws ONLY the marks (thresholds, area fill, and the line).
67
+ * Single-series, so the legend is optional in practice but present by default.
84
68
  *
85
69
  * X-axis is built from the full `data` array so the calendar is preserved even
86
70
  * when the series has nulls; the line itself skips null points (creating
@@ -1 +1 @@
1
- {"version":3,"file":"ZonedLine.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/ZonedLine.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AActC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAGvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAK/D,4FAA4F;AAC5F,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAA;AAEpC,mFAAmF;AACnF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,0EAA0E;AAC1E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,IAAI,EAAE,CAAC,EAAE,CAAA;IACT,mFAAmF;IACnF,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,oEAAoE;IACpE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;;wEAEoE;IACpE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACxB,qEAAqE;IACrE,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAA;IAClC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;+BAE2B;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAA;IACvB,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAA;IACjC,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,uFAAuF;IACvF,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,qBAAqB,GAAG,IAAI,CAAA;IACrD,uCAAuC;IACvC,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;IAClC,iEAAiE;IACjE,sBAAsB,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,SAAS,CAAA;IAC5C;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3B;4CACwC;IACxC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC,+FAA+F;IAC/F,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,4FAA4F;IAC5F,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED;;;;;;;;;;;GAWG;AACH,iBAAS,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,+BAsBlD;AA2MD;;;GAGG;AACH,eAAO,MAAM,SAAS,EAA2B,OAAO,cAAc,CAAA"}
1
+ {"version":3,"file":"ZonedLine.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/ZonedLine.tsx"],"names":[],"mappings":"AAKA,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,4FAA4F;AAC5F,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAA;AAEpC,mFAAmF;AACnF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,0EAA0E;AAC1E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,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;;wEAEoE;IACpE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACxB;gEAC4D;IAC5D,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IACjB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAA;IACvB;sBACkB;IAClB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAA;IACpB,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAA;IACjC,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC7B,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;qGACiG;IACjG,OAAO,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;IAC3C;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3B;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;AAiBD;;;;;;;;;;;;GAYG;AACH,iBAAS,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,+BA2DlD;AA8ED;;;GAGG;AACH,eAAO,MAAM,SAAS,EAA2B,OAAO,cAAc,CAAA"}
@@ -1,216 +1,135 @@
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 { AreaClosed, LinePath } from "@visx/shape";
7
4
  import { Threshold } from "@visx/threshold";
8
5
  import { memo, useMemo } from "react";
9
6
  import { AreaGradient, areaFillUrl } from "../primitives/AreaGradient.js";
10
- import { AxisBottomDate, AxisLeftNumeric } from "../primitives/Axes.js";
11
- import {
12
- ChartTooltip,
13
- TooltipBody,
14
- TooltipHeader,
15
- TooltipRow,
16
- useTooltipStyles
17
- } from "../primitives/ChartTooltip.js";
18
- import { ChartFrame, resolveLegend } from "../primitives/ChartFrame.js";
19
- import { Crosshair, SeriesDot } from "../primitives/Crosshair.js";
20
- import { HoverOverlay } from "../primitives/HoverOverlay.js";
21
- import { ZoneRects } from "../primitives/ZoneRects.js";
22
- import { useHoverSync } from "../hooks/useHoverSync.js";
23
- import { deriveTooltipRows, LINE_OVERLAY_STROKE_WIDTH } from "../series.js";
7
+ import { CartesianChart } from "../primitives/CartesianChart.js";
8
+ import { LINE_OVERLAY_STROKE_WIDTH } from "../series.js";
24
9
  import { VX } from "../../tokens/index.js";
25
- import { padAutoLower } from "../utils/domain.js";
26
- import { smartTicks, smartTicksEvery } from "../utils/ticks.js";
10
+ function validPoints(series, data) {
11
+ if (!series) return [];
12
+ const out = [];
13
+ for (const d of data) {
14
+ const y = series.getValue(d);
15
+ if (y !== null && y !== void 0 && !Number.isNaN(y)) {
16
+ out.push(Object.assign({}, d, { __y: y }));
17
+ }
18
+ }
19
+ return out;
20
+ }
27
21
  function ZonedLineInner(props) {
28
- const { series, chartId, height, legend, ariaLabel, isPending } = props;
22
+ const {
23
+ data,
24
+ chartId,
25
+ getX,
26
+ series,
27
+ y,
28
+ zones,
29
+ xZones,
30
+ thresholds,
31
+ refLines,
32
+ xTicks,
33
+ tooltip,
34
+ areaFill,
35
+ height,
36
+ legend,
37
+ ariaLabel,
38
+ isPending
39
+ } = props;
29
40
  const styledSeries = useMemo(
30
- () => series.map((s) => ({ ...s, strokeWidth: s.strokeWidth ?? LINE_OVERLAY_STROKE_WIDTH })),
41
+ () => series.map((s) => ({
42
+ ...s,
43
+ strokeWidth: s.strokeWidth ?? LINE_OVERLAY_STROKE_WIDTH
44
+ })),
31
45
  [series]
32
46
  );
33
47
  return /* @__PURE__ */ jsx(
34
- ChartFrame,
48
+ CartesianChart,
35
49
  {
36
- series: styledSeries,
50
+ data,
37
51
  chartId,
52
+ getX,
53
+ series: styledSeries,
54
+ ...y !== void 0 && { y },
55
+ ...zones !== void 0 && { zones },
56
+ ...xZones !== void 0 && { xZones },
57
+ ...refLines !== void 0 && { refLines },
58
+ ...xTicks !== void 0 && { xTicks },
59
+ ...tooltip !== void 0 && { tooltip },
38
60
  ...height !== void 0 && { height },
61
+ ...legend !== void 0 && { legend },
39
62
  ...ariaLabel !== void 0 && { ariaLabel },
40
63
  ...isPending !== void 0 && { isPending },
41
- legend: resolveLegend(legend),
42
- children: (plot) => /* @__PURE__ */ jsx(ZonedLinePlot, { ...props, series: styledSeries, plot })
64
+ children: (ctx) => /* @__PURE__ */ jsx(
65
+ ZonedLineMarks,
66
+ {
67
+ getX,
68
+ chartId,
69
+ thresholds: thresholds ?? [],
70
+ areaFill,
71
+ ctx
72
+ }
73
+ )
43
74
  }
44
75
  );
45
76
  }
46
- function ZonedLinePlot(props) {
47
- const {
48
- data,
49
- chartId,
50
- getX,
51
- series,
52
- yDomain,
53
- yAutoPad = 1.1,
54
- yAutoMaxFloor,
55
- yAutoMinCeil = 0,
56
- zones = [],
57
- thresholds = [],
58
- refLines = [],
59
- numTicksY = 5,
60
- numTicksX,
61
- tooltipLabel,
62
- formatValue,
63
- renderExtraTooltipRows,
64
- areaFill,
65
- plot
66
- } = props;
67
- const primary = series[0];
68
- const MARGIN = VX.margin;
69
- const xMax = plot.width - MARGIN.left - MARGIN.right;
70
- const yMax = plot.height - MARGIN.top - MARGIN.bottom;
77
+ function ZonedLineMarks({
78
+ getX,
79
+ chartId,
80
+ thresholds,
81
+ areaFill,
82
+ ctx
83
+ }) {
84
+ const { data, visible, xScale, yScale, yMax } = ctx;
85
+ const primary = visible[0];
86
+ const valid = useMemo(() => validPoints(primary, data), [primary, data]);
71
87
  const showArea = areaFill !== void 0 && areaFill !== false;
72
88
  const areaColor = typeof areaFill === "string" ? areaFill : primary?.color;
73
89
  const areaId = `${chartId}-area`;
74
- const valid = useMemo(() => {
75
- const out = [];
76
- for (const d of data) {
77
- const y = primary?.getValue(d) ?? null;
78
- if (y !== null && y !== void 0 && !Number.isNaN(y)) {
79
- out.push(Object.assign({}, d, { __y: y }));
80
- }
81
- }
82
- return out;
83
- }, [data, primary]);
84
- const xScale = useMemo(
85
- () => scalePoint({
86
- // Full calendar — axis does not compress across nulls.
87
- domain: data.map(getX),
88
- range: [0, xMax],
89
- padding: 0.3
90
- }),
91
- [data, xMax, getX]
92
- );
93
- const yScale = useMemo(() => {
94
- if (yDomain === "auto") {
95
- const ys = valid.map((d) => d.__y);
96
- const dataMax = ys.length ? Math.max(...ys) : 0;
97
- const dataMin = ys.length ? Math.min(...ys) : 0;
98
- const upper = Math.max(dataMax, yAutoMaxFloor ?? dataMax) * yAutoPad;
99
- const lower = padAutoLower(Math.min(dataMin, yAutoMinCeil), yAutoPad);
100
- return scaleLinear({ domain: [lower, upper], range: [yMax, 0], nice: true });
101
- }
102
- return scaleLinear({ domain: yDomain, range: [yMax, 0] });
103
- }, [valid, yDomain, yMax, yAutoPad, yAutoMaxFloor, yAutoMinCeil]);
104
- const tooltipStyles = useTooltipStyles();
105
- const { tip, tooltipRef, syncedPoint, isDirectHover, handleMouse, handleLeave } = useHoverSync({
106
- data: valid,
107
- chartId,
108
- getKey: getX,
109
- xScale,
110
- marginLeft: MARGIN.left
111
- });
112
- const tickValues = useMemo(
113
- () => numTicksX ? smartTicksEvery(data.map(getX), numTicksX) : smartTicks(data.map(getX), xMax),
114
- [data, xMax, getX, numTicksX]
115
- );
116
- const tooltipLbl = tip ? tooltipLabel?.(tip.data) ?? null : null;
117
90
  return /* @__PURE__ */ jsxs(Fragment, { children: [
118
- /* @__PURE__ */ jsx("svg", { width: plot.width, height: plot.height, children: /* @__PURE__ */ jsxs(Group, { left: MARGIN.left, top: MARGIN.top, children: [
119
- /* @__PURE__ */ jsx(GridRows, { scale: yScale, width: xMax, stroke: VX.grid, numTicks: numTicksY }),
120
- /* @__PURE__ */ jsx(ZoneRects, { zones, width: xMax, leftScale: yScale }),
121
- thresholds.map((t, i) => /* @__PURE__ */ jsx(
122
- Threshold,
123
- {
124
- id: `${chartId}-thr-${i}`,
125
- data: valid,
126
- x: (d) => xScale(getX(d)) ?? 0,
127
- y0: () => yScale(t.value),
128
- y1: (d) => yScale(d.__y),
129
- clipAboveTo: 0,
130
- clipBelowTo: yMax,
131
- curve: curveMonotoneX,
132
- belowAreaProps: { fill: t.side === "above" ? t.fill : "transparent" },
133
- aboveAreaProps: { fill: t.side === "below" ? t.fill : "transparent" }
134
- },
135
- `thr-${i}`
136
- )),
137
- showArea && areaColor !== void 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
138
- /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(AreaGradient, { id: areaId, color: areaColor }) }),
139
- /* @__PURE__ */ jsx(
140
- AreaClosed,
141
- {
142
- data: valid,
143
- x: (d) => xScale(getX(d)) ?? 0,
144
- y: (d) => yScale(d.__y),
145
- yScale,
146
- curve: curveMonotoneX,
147
- fill: areaFillUrl(areaId)
148
- }
149
- )
150
- ] }),
151
- refLines.map((r, i) => /* @__PURE__ */ jsx(
152
- "line",
153
- {
154
- x1: 0,
155
- x2: xMax,
156
- y1: yScale(r.value),
157
- y2: yScale(r.value),
158
- stroke: r.color,
159
- strokeDasharray: r.dashed ? VX.dashArray : void 0
160
- },
161
- `ref-${i}`
162
- )),
163
- primary && /* @__PURE__ */ jsx(
164
- LinePath,
91
+ thresholds.map((t, i) => /* @__PURE__ */ jsx(
92
+ Threshold,
93
+ {
94
+ id: `${chartId}-thr-${i}`,
95
+ data: valid,
96
+ x: (d) => xScale(getX(d)) ?? 0,
97
+ y0: () => yScale(t.value),
98
+ y1: (d) => yScale(d.__y),
99
+ clipAboveTo: 0,
100
+ clipBelowTo: yMax,
101
+ curve: curveMonotoneX,
102
+ belowAreaProps: { fill: t.side === "above" ? t.fill : "transparent" },
103
+ aboveAreaProps: { fill: t.side === "below" ? t.fill : "transparent" }
104
+ },
105
+ `thr-${i}`
106
+ )),
107
+ showArea && areaColor !== void 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
108
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(AreaGradient, { id: areaId, color: areaColor }) }),
109
+ /* @__PURE__ */ jsx(
110
+ AreaClosed,
165
111
  {
166
112
  data: valid,
167
113
  x: (d) => xScale(getX(d)) ?? 0,
168
114
  y: (d) => yScale(d.__y),
169
- stroke: primary.color,
170
- strokeWidth: primary.strokeWidth ?? VX.lineWidth,
171
- strokeDasharray: primary.dash === "dashed" ? VX.dashArray : void 0,
172
- curve: curveMonotoneX
173
- }
174
- ),
175
- syncedPoint && primary && /* @__PURE__ */ jsxs(Fragment, { children: [
176
- /* @__PURE__ */ jsx(Crosshair, { x: xScale(getX(syncedPoint)) ?? 0, top: 0, bottom: yMax }),
177
- /* @__PURE__ */ jsx(
178
- SeriesDot,
179
- {
180
- cx: xScale(getX(syncedPoint)) ?? 0,
181
- cy: yScale(syncedPoint.__y),
182
- color: primary.color
183
- }
184
- )
185
- ] }),
186
- /* @__PURE__ */ jsx(AxisLeftNumeric, { scale: yScale, numTicks: numTicksY }),
187
- /* @__PURE__ */ jsx(AxisBottomDate, { top: yMax, scale: xScale, tickValues }),
188
- /* @__PURE__ */ jsx(HoverOverlay, { width: xMax, height: yMax, onMove: handleMouse, onLeave: handleLeave })
189
- ] }) }),
190
- /* @__PURE__ */ jsx(ChartTooltip, { tip: isDirectHover ? tip : null, tooltipRef, styles: tooltipStyles, children: tip && isDirectHover && /* @__PURE__ */ jsxs(Fragment, { children: [
191
- /* @__PURE__ */ jsx(
192
- TooltipHeader,
193
- {
194
- date: getX(tip.data),
195
- ...tooltipLbl !== null && { label: tooltipLbl.text, labelColor: tooltipLbl.color }
115
+ yScale,
116
+ curve: curveMonotoneX,
117
+ fill: areaFillUrl(areaId)
196
118
  }
197
- ),
198
- /* @__PURE__ */ jsxs(TooltipBody, { children: [
199
- deriveTooltipRows(series, tip.data, formatValue).map((row) => /* @__PURE__ */ jsx(
200
- TooltipRow,
201
- {
202
- color: row.color,
203
- label: row.label,
204
- value: row.value,
205
- shape: row.shape,
206
- dashed: row.dashed,
207
- ...row.strokeWidth !== void 0 && { strokeWidth: row.strokeWidth }
208
- },
209
- row.key
210
- )),
211
- renderExtraTooltipRows?.(tip.data)
212
- ] })
213
- ] }) })
119
+ )
120
+ ] }),
121
+ primary && /* @__PURE__ */ jsx(
122
+ LinePath,
123
+ {
124
+ data: valid,
125
+ x: (d) => xScale(getX(d)) ?? 0,
126
+ y: (d) => yScale(d.__y),
127
+ stroke: primary.color,
128
+ strokeWidth: primary.strokeWidth ?? LINE_OVERLAY_STROKE_WIDTH,
129
+ strokeDasharray: primary.dash === "dashed" ? VX.dashArray : void 0,
130
+ curve: curveMonotoneX
131
+ }
132
+ )
214
133
  ] });
215
134
  }
216
135
  const ZonedLine = memo(ZonedLineInner);