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,30 +1,41 @@
|
|
|
1
|
+
import type { AxisConfig } from '../primitives/CartesianChart.js';
|
|
1
2
|
import type { ChartLegendConfig, ChartSeries } from '../series.js';
|
|
2
3
|
export type StackedAreaProps<T> = {
|
|
3
4
|
data: T[];
|
|
4
|
-
/** Fixed height in pixels, forwarded to
|
|
5
|
+
/** Fixed height in pixels, forwarded to `CartesianChart`. Default 240. */
|
|
5
6
|
height?: number;
|
|
6
7
|
chartId: string;
|
|
7
8
|
getX: (d: T) => string;
|
|
8
9
|
/** The stacked bands, bottom to top — the single source of truth for color, legend, and tooltip
|
|
9
10
|
* rows. Typically `mark: 'area'` (rendered as a `bar`-shaped legend/tooltip swatch). */
|
|
10
11
|
series: ChartSeries<T>[];
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
/**
|
|
12
|
+
/** Axis config for ticks/format/grid. `domain` defaults to the summed per-point stack total
|
|
13
|
+
* (padded ×1.1, or `autoMaxFloor` if higher) rather than a per-series max — the seam a stacked
|
|
14
|
+
* chart needs, since the plotted quantity is the cumulative band top, not any one series' own
|
|
15
|
+
* value. Pass a fixed tuple or your own function to override. */
|
|
16
|
+
y?: AxisConfig<T>;
|
|
17
|
+
/** X tick count override. Default: as many as fit. */
|
|
18
|
+
xTicks?: number;
|
|
19
|
+
/** Legend config forwarded to `CartesianChart`; `false` disables the legend (sparkline escape).
|
|
17
20
|
* Default `{ placement: 'bottom' }`. */
|
|
18
21
|
legend?: ChartLegendConfig | false;
|
|
19
|
-
/** Accessible text alternative, forwarded
|
|
22
|
+
/** Accessible text alternative, forwarded as `aria-label` (+ `role="img"`). */
|
|
20
23
|
ariaLabel?: string;
|
|
21
|
-
/** Forwarded to `
|
|
24
|
+
/** Forwarded to `CartesianChart` — see `ChartPending`'s JSDoc for the three-state rationale. */
|
|
22
25
|
isPending?: boolean;
|
|
23
26
|
};
|
|
24
27
|
/**
|
|
25
28
|
* Multi-series stacked-area chart with an optional derived legend (default on) and legend-hover
|
|
26
29
|
* dimming. Each band's fillOpacity is dimmed when a different key is highlighted via the legend.
|
|
27
|
-
*
|
|
30
|
+
*
|
|
31
|
+
* Composes `CartesianChart` (`docs/CHARTS-SPEC.md` §2) — margin, scale, grid, axes, cursor, and
|
|
32
|
+
* tooltip are the primitive's job. This file draws only the `AreaStack` bands.
|
|
33
|
+
*
|
|
34
|
+
* The tooltip must render top-to-bottom (matching the visual stack read from the top), but the
|
|
35
|
+
* marks must stack bottom-to-top (matching `series`' own order) — the two can't share one order.
|
|
36
|
+
* `CartesianChart`'s `series` prop drives BOTH the derived tooltip rows and legend, so `series` is
|
|
37
|
+
* passed reversed to it (tooltip/legend read top-first); the marks then reverse `ctx.visible` back
|
|
38
|
+
* to restore the original bottom-to-top stacking order for `AreaStack`'s `keys`.
|
|
28
39
|
*/
|
|
29
40
|
declare function StackedAreaInner<T>(props: StackedAreaProps<T>): import("react").JSX.Element;
|
|
30
41
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StackedArea.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/StackedArea.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"StackedArea.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/StackedArea.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,8BAA8B,CAAA;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAE/D,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAChC,IAAI,EAAE,CAAC,EAAE,CAAA;IACT,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;4FACwF;IACxF,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACxB;;;qEAGiE;IACjE,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAA;IACjB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;4CACwC;IACxC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gGAAgG;IAChG,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,iBAAS,gBAAgB,CAAC,CAAC,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,+BAgEtD;AA+CD;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAA6B,OAAO,gBAAgB,CAAA"}
|
|
@@ -1,150 +1,92 @@
|
|
|
1
|
-
import {
|
|
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,
|
|
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 { 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 {
|
|
25
|
-
const
|
|
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
|
-
|
|
41
|
+
CartesianChart,
|
|
28
42
|
{
|
|
29
|
-
|
|
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
|
-
|
|
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
|
|
43
|
-
const {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
|
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 `
|
|
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
|
-
/**
|
|
35
|
-
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
|
|
58
|
-
|
|
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 `
|
|
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 `
|
|
55
|
+
/** Accessible text alternative, forwarded to `CartesianChart` as `aria-label` (+ `role="img"`). */
|
|
73
56
|
ariaLabel?: string;
|
|
74
|
-
/** Forwarded to `
|
|
57
|
+
/** Forwarded to `CartesianChart` — see `ChartPending`'s JSDoc for the three-state rationale. */
|
|
75
58
|
isPending?: boolean;
|
|
76
59
|
};
|
|
77
60
|
/**
|
|
78
|
-
*
|
|
79
|
-
* shared-cursor tooltip. Covers the line-with-zones pattern. Does NOT
|
|
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 `
|
|
83
|
-
*
|
|
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":"
|
|
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;AA+ED;;;GAGG;AACH,eAAO,MAAM,SAAS,EAA2B,OAAO,cAAc,CAAA"}
|