@misoto22/design 0.3.1 → 0.6.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/README.md +124 -0
- package/bin/misoto22-design.mjs +205 -0
- package/dist/agent/Accordion.md +41 -0
- package/dist/agent/Alert.md +42 -0
- package/dist/agent/AppShell.md +40 -0
- package/dist/agent/AreaChart.md +68 -0
- package/dist/agent/Article.md +41 -0
- package/dist/agent/Avatar.md +32 -0
- package/dist/agent/Badge.md +40 -0
- package/dist/agent/BarChart.md +65 -0
- package/dist/agent/BarList.md +40 -0
- package/dist/agent/BigNumber.md +45 -0
- package/dist/agent/BoxPlot.md +58 -0
- package/dist/agent/Breadcrumb.md +32 -0
- package/dist/agent/BulletChart.md +48 -0
- package/dist/agent/Button.md +56 -0
- package/dist/agent/Calendar.md +42 -0
- package/dist/agent/Card.md +49 -0
- package/dist/agent/Checkbox.md +35 -0
- package/dist/agent/Collapsible.md +46 -0
- package/dist/agent/Combobox.md +50 -0
- package/dist/agent/Command.md +93 -0
- package/dist/agent/ComposedChart.md +57 -0
- package/dist/agent/ContextMenu.md +59 -0
- package/dist/agent/DatePicker.md +75 -0
- package/dist/agent/Diagram.md +46 -0
- package/dist/agent/Dialog.md +52 -0
- package/dist/agent/DropdownMenu.md +70 -0
- package/dist/agent/EmptyState.md +37 -0
- package/dist/agent/ErrorState.md +41 -0
- package/dist/agent/Facet.md +82 -0
- package/dist/agent/Field.md +37 -0
- package/dist/agent/FigureBand.md +37 -0
- package/dist/agent/FloatingIconButton.md +38 -0
- package/dist/agent/FunnelChart.md +52 -0
- package/dist/agent/Heatmap.md +53 -0
- package/dist/agent/Histogram.md +63 -0
- package/dist/agent/Input.md +30 -0
- package/dist/agent/Kbd.md +29 -0
- package/dist/agent/LineChart.md +60 -0
- package/dist/agent/LinkArrow.md +29 -0
- package/dist/agent/NativeSelect.md +40 -0
- package/dist/agent/NavItem.md +35 -0
- package/dist/agent/Pagination.md +43 -0
- package/dist/agent/PieChart.md +55 -0
- package/dist/agent/Popover.md +57 -0
- package/dist/agent/Progress.md +33 -0
- package/dist/agent/RadarChart.md +54 -0
- package/dist/agent/RadialChart.md +57 -0
- package/dist/agent/RadioGroup.md +44 -0
- package/dist/agent/SankeyChart.md +61 -0
- package/dist/agent/ScatterChart.md +54 -0
- package/dist/agent/ScrollArea.md +40 -0
- package/dist/agent/SearchableMenu.md +46 -0
- package/dist/agent/Select.md +75 -0
- package/dist/agent/Separator.md +35 -0
- package/dist/agent/Sheet.md +57 -0
- package/dist/agent/Skeleton.md +73 -0
- package/dist/agent/Slider.md +39 -0
- package/dist/agent/Sparkline.md +45 -0
- package/dist/agent/Spinner.md +39 -0
- package/dist/agent/StatusDot.md +36 -0
- package/dist/agent/StatusPill.md +28 -0
- package/dist/agent/Steps.md +44 -0
- package/dist/agent/Switch.md +29 -0
- package/dist/agent/Table.md +85 -0
- package/dist/agent/Tabs.md +48 -0
- package/dist/agent/Tag.md +35 -0
- package/dist/agent/Textarea.md +26 -0
- package/dist/agent/Toast.md +26 -0
- package/dist/agent/ToggleGroup.md +44 -0
- package/dist/agent/Tooltip.md +51 -0
- package/dist/agent/TreemapChart.md +52 -0
- package/dist/agent/WaterfallChart.md +62 -0
- package/dist/agent/catalog.json +1791 -0
- package/dist/agent/index.md +131 -0
- package/dist/article.css +393 -0
- package/dist/charts/AreaChart/AreaChart.d.ts +191 -0
- package/dist/charts/AreaChart/AreaChart.js +480 -0
- package/dist/charts/AreaChart/AreaChart.js.map +1 -0
- package/dist/charts/BarChart/BarChart.d.ts +179 -0
- package/dist/charts/BarChart/BarChart.js +591 -0
- package/dist/charts/BarChart/BarChart.js.map +1 -0
- package/dist/charts/BarList/BarList.d.ts +57 -0
- package/dist/charts/BarList/BarList.js +71 -0
- package/dist/charts/BarList/BarList.js.map +1 -0
- package/dist/charts/BigNumber/BigNumber.d.ts +56 -0
- package/dist/charts/BigNumber/BigNumber.js +31 -0
- package/dist/charts/BigNumber/BigNumber.js.map +1 -0
- package/dist/charts/BoxPlot/BoxPlot.d.ts +177 -0
- package/dist/charts/BoxPlot/BoxPlot.js +495 -0
- package/dist/charts/BoxPlot/BoxPlot.js.map +1 -0
- package/dist/charts/BulletChart/BulletChart.d.ts +100 -0
- package/dist/charts/BulletChart/BulletChart.js +162 -0
- package/dist/charts/BulletChart/BulletChart.js.map +1 -0
- package/dist/charts/ComposedChart/ComposedChart.d.ts +171 -0
- package/dist/charts/ComposedChart/ComposedChart.js +667 -0
- package/dist/charts/ComposedChart/ComposedChart.js.map +1 -0
- package/dist/charts/Facet/Facet.d.ts +240 -0
- package/dist/charts/Facet/Facet.js +133 -0
- package/dist/charts/Facet/Facet.js.map +1 -0
- package/dist/charts/Facet/panels.d.ts +187 -0
- package/dist/charts/Facet/panels.js +203 -0
- package/dist/charts/Facet/panels.js.map +1 -0
- package/dist/charts/FunnelChart/FunnelChart.d.ts +101 -0
- package/dist/charts/FunnelChart/FunnelChart.js +147 -0
- package/dist/charts/FunnelChart/FunnelChart.js.map +1 -0
- package/dist/charts/Heatmap/Heatmap.d.ts +78 -0
- package/dist/charts/Heatmap/Heatmap.js +108 -0
- package/dist/charts/Heatmap/Heatmap.js.map +1 -0
- package/dist/charts/Histogram/Histogram.d.ts +165 -0
- package/dist/charts/Histogram/Histogram.js +350 -0
- package/dist/charts/Histogram/Histogram.js.map +1 -0
- package/dist/charts/LineChart/LineChart.d.ts +167 -0
- package/dist/charts/LineChart/LineChart.js +486 -0
- package/dist/charts/LineChart/LineChart.js.map +1 -0
- package/dist/charts/PieChart/PieChart.d.ts +128 -0
- package/dist/charts/PieChart/PieChart.js +309 -0
- package/dist/charts/PieChart/PieChart.js.map +1 -0
- package/dist/charts/RadarChart/RadarChart.d.ts +123 -0
- package/dist/charts/RadarChart/RadarChart.js +299 -0
- package/dist/charts/RadarChart/RadarChart.js.map +1 -0
- package/dist/charts/RadialChart/RadialChart.d.ts +124 -0
- package/dist/charts/RadialChart/RadialChart.js +257 -0
- package/dist/charts/RadialChart/RadialChart.js.map +1 -0
- package/dist/charts/SankeyChart/SankeyChart.d.ts +137 -0
- package/dist/charts/SankeyChart/SankeyChart.js +501 -0
- package/dist/charts/SankeyChart/SankeyChart.js.map +1 -0
- package/dist/charts/ScatterChart/ScatterChart.d.ts +128 -0
- package/dist/charts/ScatterChart/ScatterChart.js +269 -0
- package/dist/charts/ScatterChart/ScatterChart.js.map +1 -0
- package/dist/charts/Sparkline/Sparkline.d.ts +53 -0
- package/dist/charts/Sparkline/Sparkline.js +93 -0
- package/dist/charts/Sparkline/Sparkline.js.map +1 -0
- package/dist/charts/TreemapChart/TreemapChart.d.ts +93 -0
- package/dist/charts/TreemapChart/TreemapChart.js +118 -0
- package/dist/charts/TreemapChart/TreemapChart.js.map +1 -0
- package/dist/charts/WaterfallChart/WaterfallChart.d.ts +164 -0
- package/dist/charts/WaterfallChart/WaterfallChart.js +319 -0
- package/dist/charts/WaterfallChart/WaterfallChart.js.map +1 -0
- package/dist/charts/index.d.ts +41 -0
- package/dist/charts/index.js +128 -0
- package/dist/charts/index.js.map +1 -0
- package/dist/charts/lib/annotations.d.ts +103 -0
- package/dist/charts/lib/annotations.js +99 -0
- package/dist/charts/lib/annotations.js.map +1 -0
- package/dist/charts/lib/axis.d.ts +18 -0
- package/dist/charts/lib/axis.js +21 -0
- package/dist/charts/lib/axis.js.map +1 -0
- package/dist/charts/lib/background.d.ts +33 -0
- package/dist/charts/lib/background.js +173 -0
- package/dist/charts/lib/background.js.map +1 -0
- package/dist/charts/lib/brush.d.ts +94 -0
- package/dist/charts/lib/brush.js +535 -0
- package/dist/charts/lib/brush.js.map +1 -0
- package/dist/charts/lib/chart.d.ts +94 -0
- package/dist/charts/lib/chart.js +134 -0
- package/dist/charts/lib/chart.js.map +1 -0
- package/dist/charts/lib/dot.d.ts +29 -0
- package/dist/charts/lib/dot.js +78 -0
- package/dist/charts/lib/dot.js.map +1 -0
- package/dist/charts/lib/empty.d.ts +31 -0
- package/dist/charts/lib/empty.js +13 -0
- package/dist/charts/lib/empty.js.map +1 -0
- package/dist/charts/lib/export.d.ts +103 -0
- package/dist/charts/lib/export.js +204 -0
- package/dist/charts/lib/export.js.map +1 -0
- package/dist/charts/lib/figure.d.ts +61 -0
- package/dist/charts/lib/figure.js +59 -0
- package/dist/charts/lib/figure.js.map +1 -0
- package/dist/charts/lib/format.d.ts +46 -0
- package/dist/charts/lib/format.js +56 -0
- package/dist/charts/lib/format.js.map +1 -0
- package/dist/charts/lib/legend.d.ts +45 -0
- package/dist/charts/lib/legend.js +117 -0
- package/dist/charts/lib/legend.js.map +1 -0
- package/dist/charts/lib/loading.d.ts +48 -0
- package/dist/charts/lib/loading.js +105 -0
- package/dist/charts/lib/loading.js.map +1 -0
- package/dist/charts/lib/paint.d.ts +154 -0
- package/dist/charts/lib/paint.js +551 -0
- package/dist/charts/lib/paint.js.map +1 -0
- package/dist/charts/lib/sonify-control.d.ts +163 -0
- package/dist/charts/lib/sonify-control.js +172 -0
- package/dist/charts/lib/sonify-control.js.map +1 -0
- package/dist/charts/lib/sonify.d.ts +248 -0
- package/dist/charts/lib/sonify.js +262 -0
- package/dist/charts/lib/sonify.js.map +1 -0
- package/dist/charts/lib/toolbar.d.ts +143 -0
- package/dist/charts/lib/toolbar.js +156 -0
- package/dist/charts/lib/toolbar.js.map +1 -0
- package/dist/charts/lib/tooltip.d.ts +59 -0
- package/dist/charts/lib/tooltip.js +135 -0
- package/dist/charts/lib/tooltip.js.map +1 -0
- package/dist/charts/lib/values.d.ts +56 -0
- package/dist/charts/lib/values.js +71 -0
- package/dist/charts/lib/values.js.map +1 -0
- package/dist/charts/lib/zoom.d.ts +139 -0
- package/dist/charts/lib/zoom.js +314 -0
- package/dist/charts/lib/zoom.js.map +1 -0
- package/dist/components/AppShell/AppShell.d.ts +15 -1
- package/dist/components/AppShell/AppShell.js +8 -4
- package/dist/components/AppShell/AppShell.js.map +1 -1
- package/dist/components/Article/Article.d.ts +51 -0
- package/dist/components/Article/Article.js +21 -0
- package/dist/components/Article/Article.js.map +1 -0
- package/dist/components/Button/Button.js +2 -2
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Calendar/Calendar.d.ts +1 -1
- package/dist/components/Calendar/Calendar.js +259 -24
- package/dist/components/Calendar/Calendar.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.js +1 -1
- package/dist/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/Collapsible/Collapsible.d.ts +15 -1
- package/dist/components/Collapsible/Collapsible.js +18 -0
- package/dist/components/Collapsible/Collapsible.js.map +1 -1
- package/dist/components/Combobox/Combobox.js +1 -1
- package/dist/components/Combobox/Combobox.js.map +1 -1
- package/dist/components/Command/Command.js +7 -7
- package/dist/components/Command/Command.js.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.js +2 -2
- package/dist/components/ContextMenu/ContextMenu.js.map +1 -1
- package/dist/components/Diagram/Diagram.d.ts +81 -0
- package/dist/components/Diagram/Diagram.js +139 -0
- package/dist/components/Diagram/Diagram.js.map +1 -0
- package/dist/components/Dialog/Dialog.js +1 -1
- package/dist/components/Dialog/Dialog.js.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.js +2 -2
- package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/components/FigureBand/FigureBand.js +41 -30
- package/dist/components/FigureBand/FigureBand.js.map +1 -1
- package/dist/components/Popover/Popover.js +1 -1
- package/dist/components/Popover/Popover.js.map +1 -1
- package/dist/components/Select/Select.js +2 -2
- package/dist/components/Select/Select.js.map +1 -1
- package/dist/components/Sheet/Sheet.js +1 -1
- package/dist/components/Sheet/Sheet.js.map +1 -1
- package/dist/components/Slider/Slider.js +1 -1
- package/dist/components/Slider/Slider.js.map +1 -1
- package/dist/components/Steps/Steps.d.ts +65 -0
- package/dist/components/Steps/Steps.js +55 -0
- package/dist/components/Steps/Steps.js.map +1 -0
- package/dist/components/Switch/Switch.js +1 -1
- package/dist/components/Switch/Switch.js.map +1 -1
- package/dist/components/Tooltip/Tooltip.js +1 -1
- package/dist/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/useSelectionIndicator.js +14 -10
- package/dist/lib/useSelectionIndicator.js.map +1 -1
- package/dist/semantic.css +19 -0
- package/dist/styles.css +1 -1
- package/dist/themes.css +103 -7
- package/dist/tokens.css +193 -10
- package/dist/tokens.d.ts +25 -0
- package/dist/tokens.js +154 -8
- package/dist/tokens.json +154 -8
- package/package.json +45 -20
- package/skills/misoto22-design/SKILL.md +171 -0
- package/skills/misoto22-design/evals/claims.json +95 -0
- package/skills/misoto22-design/rules/a11y.md +115 -0
- package/skills/misoto22-design/rules/composition.md +108 -0
- package/skills/misoto22-design/rules/forms.md +128 -0
- package/skills/misoto22-design/rules/naming.md +155 -0
- package/skills/misoto22-design/rules/tokens.md +131 -0
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import {
|
|
4
|
+
Children,
|
|
5
|
+
createContext,
|
|
6
|
+
isValidElement,
|
|
7
|
+
useCallback,
|
|
8
|
+
useContext,
|
|
9
|
+
useId,
|
|
10
|
+
useMemo,
|
|
11
|
+
useState
|
|
12
|
+
} from "react";
|
|
13
|
+
import {
|
|
14
|
+
CartesianGrid,
|
|
15
|
+
Curve,
|
|
16
|
+
Line as RechartsLine,
|
|
17
|
+
LineChart as RechartsLineChart,
|
|
18
|
+
XAxis as RechartsXAxis,
|
|
19
|
+
YAxis as RechartsYAxis
|
|
20
|
+
} from "recharts";
|
|
21
|
+
import { useReducedMotion } from "motion/react";
|
|
22
|
+
import { ChartContainer } from "../lib/chart.js";
|
|
23
|
+
import { ChartFigure } from "../lib/figure.js";
|
|
24
|
+
import { ChartEmpty } from "../lib/empty.js";
|
|
25
|
+
import { axisLabel } from "../lib/axis.js";
|
|
26
|
+
import { defaultTick } from "../lib/format.js";
|
|
27
|
+
import { Annotation, ReferenceBand, ReferenceLine } from "../lib/annotations.js";
|
|
28
|
+
import { Values, findSlot, resolveValues } from "../lib/values.js";
|
|
29
|
+
import {
|
|
30
|
+
ChartSonifyButton,
|
|
31
|
+
Sonify,
|
|
32
|
+
useChartSonifySeries
|
|
33
|
+
} from "../lib/sonify-control.js";
|
|
34
|
+
import { ChartBackground } from "../lib/background.js";
|
|
35
|
+
import { ChartDot } from "../lib/dot.js";
|
|
36
|
+
import { ChartLegend, ChartLegendContent } from "../lib/legend.js";
|
|
37
|
+
import { ChartTooltip, ChartTooltipContent } from "../lib/tooltip.js";
|
|
38
|
+
import { Brush, ChartBrush } from "../lib/brush.js";
|
|
39
|
+
import { ChartControls, Toolbar } from "../lib/toolbar.js";
|
|
40
|
+
import { useChartZoom } from "../lib/zoom.js";
|
|
41
|
+
import { LoadingIndicator, LoadingShimmer, LOADING_KEY, useLoadingRows } from "../lib/loading.js";
|
|
42
|
+
import {
|
|
43
|
+
AnimatedDashedStroke,
|
|
44
|
+
GlowFilter,
|
|
45
|
+
RevealMask,
|
|
46
|
+
SeriesGradient
|
|
47
|
+
} from "../lib/paint.js";
|
|
48
|
+
const STROKE_WIDTH = 1.6;
|
|
49
|
+
const BUFFER_DASH = 4;
|
|
50
|
+
const BUFFER_GAP = 3;
|
|
51
|
+
const CHART_MARGIN = { top: 8, right: 12, bottom: 0, left: 12 };
|
|
52
|
+
const LineChartContext = createContext(null);
|
|
53
|
+
function useLineChart() {
|
|
54
|
+
const context = useContext(LineChartContext);
|
|
55
|
+
if (!context) throw new Error("A line chart part must be rendered inside <LineChart>");
|
|
56
|
+
return context;
|
|
57
|
+
}
|
|
58
|
+
function LineChart({
|
|
59
|
+
config,
|
|
60
|
+
data,
|
|
61
|
+
title,
|
|
62
|
+
showTitle,
|
|
63
|
+
description,
|
|
64
|
+
children,
|
|
65
|
+
className,
|
|
66
|
+
chartProps,
|
|
67
|
+
curveType = "linear",
|
|
68
|
+
animationType = "forward",
|
|
69
|
+
defaultSelectedDataKey = null,
|
|
70
|
+
onSelectionChange,
|
|
71
|
+
isLoading = false,
|
|
72
|
+
loadingPoints,
|
|
73
|
+
xDataKey,
|
|
74
|
+
hideDataTable = false,
|
|
75
|
+
empty
|
|
76
|
+
}) {
|
|
77
|
+
const chartId = useId().replace(/:/g, "");
|
|
78
|
+
const [selectedDataKey, setSelectedDataKey] = useState(defaultSelectedDataKey);
|
|
79
|
+
const { rows: loadingData, onShimmerExit } = useLoadingRows(isLoading, loadingPoints);
|
|
80
|
+
const zoom = useChartZoom({ data, xDataKey });
|
|
81
|
+
const { brushSlot, toolbarSlot, sonifySlot, chartChildren } = useMemo(() => {
|
|
82
|
+
const parts = Children.toArray(children);
|
|
83
|
+
const element = parts.find((child) => isValidElement(child) && child.type === Brush);
|
|
84
|
+
const props = isValidElement(element) ? element.props : {};
|
|
85
|
+
return {
|
|
86
|
+
brushSlot: { present: isValidElement(element), ...props },
|
|
87
|
+
toolbarSlot: findSlot(parts, Toolbar),
|
|
88
|
+
sonifySlot: findSlot(parts, Sonify),
|
|
89
|
+
chartChildren: parts.filter(
|
|
90
|
+
(child) => !(isValidElement(child) && (child.type === Brush || child.type === Toolbar || child.type === Sonify))
|
|
91
|
+
)
|
|
92
|
+
};
|
|
93
|
+
}, [children]);
|
|
94
|
+
const columns = useMemo(
|
|
95
|
+
() => Object.entries(config).map(([key, series]) => ({ key, label: series.label })),
|
|
96
|
+
[config]
|
|
97
|
+
);
|
|
98
|
+
const showBrush = brushSlot.present && !isLoading;
|
|
99
|
+
const showToolbar = toolbarSlot !== null && !isLoading;
|
|
100
|
+
const isEmpty = !isLoading && empty !== false && data.length === 0;
|
|
101
|
+
const displayData = isLoading ? loadingData : showBrush || showToolbar ? zoom.visibleData : data;
|
|
102
|
+
const sonifySeries = useChartSonifySeries(
|
|
103
|
+
sonifySlot,
|
|
104
|
+
displayData,
|
|
105
|
+
config,
|
|
106
|
+
xDataKey
|
|
107
|
+
);
|
|
108
|
+
const selectDataKey = useCallback(
|
|
109
|
+
(next) => {
|
|
110
|
+
setSelectedDataKey(next);
|
|
111
|
+
onSelectionChange?.(next);
|
|
112
|
+
},
|
|
113
|
+
[onSelectionChange]
|
|
114
|
+
);
|
|
115
|
+
const context = useMemo(
|
|
116
|
+
() => ({ config, rows: displayData, curveType, animationType, isLoading, selectedDataKey, selectDataKey }),
|
|
117
|
+
[animationType, config, curveType, displayData, isLoading, selectDataKey, selectedDataKey]
|
|
118
|
+
);
|
|
119
|
+
return /* @__PURE__ */ jsx(LineChartContext.Provider, { value: context, children: /* @__PURE__ */ jsxs(
|
|
120
|
+
ChartFigure,
|
|
121
|
+
{
|
|
122
|
+
title,
|
|
123
|
+
showTitle,
|
|
124
|
+
description,
|
|
125
|
+
className,
|
|
126
|
+
table: hideDataTable ? false : { rows: data, rowKey: xDataKey, columns },
|
|
127
|
+
children: [
|
|
128
|
+
sonifySlot && /* @__PURE__ */ jsx(ChartSonifyButton, { ...sonifySlot, title, series: sonifySeries }),
|
|
129
|
+
isEmpty ? /* @__PURE__ */ jsx(ChartEmpty, { ...empty || {} }) : /* @__PURE__ */ jsx(
|
|
130
|
+
ChartControls,
|
|
131
|
+
{
|
|
132
|
+
toolbar: showToolbar ? toolbarSlot : null,
|
|
133
|
+
zoom,
|
|
134
|
+
title,
|
|
135
|
+
rows: data,
|
|
136
|
+
columns,
|
|
137
|
+
rowKey: xDataKey,
|
|
138
|
+
children: /* @__PURE__ */ jsx(
|
|
139
|
+
ChartContainer,
|
|
140
|
+
{
|
|
141
|
+
config,
|
|
142
|
+
footer: showBrush && /* @__PURE__ */ jsx(
|
|
143
|
+
ChartBrush,
|
|
144
|
+
{
|
|
145
|
+
data,
|
|
146
|
+
config,
|
|
147
|
+
xDataKey,
|
|
148
|
+
variant: "line",
|
|
149
|
+
curveType,
|
|
150
|
+
height: brushSlot.height,
|
|
151
|
+
formatLabel: brushSlot.formatLabel,
|
|
152
|
+
className: "mt-1",
|
|
153
|
+
...zoom.brushProps,
|
|
154
|
+
onChange: (range) => {
|
|
155
|
+
zoom.brushProps.onChange(range);
|
|
156
|
+
brushSlot.onChange?.(range);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
),
|
|
160
|
+
children: /* @__PURE__ */ jsxs(
|
|
161
|
+
RechartsLineChart,
|
|
162
|
+
{
|
|
163
|
+
id: chartId,
|
|
164
|
+
accessibilityLayer: true,
|
|
165
|
+
margin: CHART_MARGIN,
|
|
166
|
+
data: displayData,
|
|
167
|
+
...chartProps,
|
|
168
|
+
children: [
|
|
169
|
+
chartChildren,
|
|
170
|
+
isLoading && /* @__PURE__ */ jsx(LoadingLine, { chartId, curveType, onShimmerExit })
|
|
171
|
+
]
|
|
172
|
+
}
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
),
|
|
178
|
+
/* @__PURE__ */ jsx(LoadingIndicator, { isLoading })
|
|
179
|
+
]
|
|
180
|
+
}
|
|
181
|
+
) });
|
|
182
|
+
}
|
|
183
|
+
function Line({
|
|
184
|
+
dataKey,
|
|
185
|
+
strokeVariant = "solid",
|
|
186
|
+
strokeWidth = STROKE_WIDTH,
|
|
187
|
+
curveType,
|
|
188
|
+
animationType,
|
|
189
|
+
connectNulls = false,
|
|
190
|
+
isClickable = false,
|
|
191
|
+
glowing = false,
|
|
192
|
+
buffer = false,
|
|
193
|
+
children,
|
|
194
|
+
lineProps
|
|
195
|
+
}) {
|
|
196
|
+
const {
|
|
197
|
+
config,
|
|
198
|
+
curveType: defaultCurve,
|
|
199
|
+
animationType: defaultAnimation,
|
|
200
|
+
isLoading,
|
|
201
|
+
rows,
|
|
202
|
+
selectedDataKey,
|
|
203
|
+
selectDataKey
|
|
204
|
+
} = useLineChart();
|
|
205
|
+
const id = useId().replace(/:/g, "");
|
|
206
|
+
const reduceMotion = useReducedMotion();
|
|
207
|
+
if (isLoading) return null;
|
|
208
|
+
const resolvedCurve = curveType ?? defaultCurve;
|
|
209
|
+
const reveal = reduceMotion ? "none" : animationType ?? defaultAnimation;
|
|
210
|
+
const maskId = reveal === "none" ? void 0 : `${id}-reveal-mask`;
|
|
211
|
+
const isSelected = selectedDataKey === dataKey;
|
|
212
|
+
const hasSelection = selectedDataKey !== null;
|
|
213
|
+
const opacity = hasSelection && !isSelected ? { stroke: 0.3, dot: 0.3 } : { stroke: 1, dot: 1 };
|
|
214
|
+
const { dot, activeDot } = resolveDots(children, id, dataKey, opacity.dot, maskId);
|
|
215
|
+
const labels = resolveValues(
|
|
216
|
+
findSlot(children, Values),
|
|
217
|
+
rows.map((row) => Number(row[dataKey])).filter(Number.isFinite)
|
|
218
|
+
);
|
|
219
|
+
const animateDash = strokeVariant === "animated-dashed" && !hasSelection && !reduceMotion;
|
|
220
|
+
const isDashed = strokeVariant !== "solid";
|
|
221
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
222
|
+
/* @__PURE__ */ jsxs("g", { children: [
|
|
223
|
+
isClickable && // A 15px transparent line under the visible one. A 1.6px stroke is
|
|
224
|
+
// not a pointer target, and WCAG 2.5.8 asks for 24; this is the
|
|
225
|
+
// cheapest way to give a hairline a real hit area.
|
|
226
|
+
/* @__PURE__ */ jsx(
|
|
227
|
+
RechartsLine,
|
|
228
|
+
{
|
|
229
|
+
type: resolvedCurve,
|
|
230
|
+
dataKey,
|
|
231
|
+
connectNulls,
|
|
232
|
+
stroke: "transparent",
|
|
233
|
+
strokeWidth: 15,
|
|
234
|
+
dot: false,
|
|
235
|
+
activeDot: false,
|
|
236
|
+
isAnimationActive: false,
|
|
237
|
+
legendType: "none",
|
|
238
|
+
tooltipType: "none",
|
|
239
|
+
style: { cursor: "pointer" },
|
|
240
|
+
onClick: () => selectDataKey(isSelected ? null : dataKey)
|
|
241
|
+
}
|
|
242
|
+
),
|
|
243
|
+
/* @__PURE__ */ jsxs(
|
|
244
|
+
RechartsLine,
|
|
245
|
+
{
|
|
246
|
+
type: resolvedCurve,
|
|
247
|
+
dataKey,
|
|
248
|
+
connectNulls,
|
|
249
|
+
strokeOpacity: opacity.stroke,
|
|
250
|
+
stroke: `url(#${id}-colors-${dataKey})`,
|
|
251
|
+
filter: glowing ? `url(#${id}-glow-${dataKey})` : void 0,
|
|
252
|
+
dot,
|
|
253
|
+
activeDot,
|
|
254
|
+
strokeWidth,
|
|
255
|
+
strokeDasharray: buffer ? void 0 : isDashed ? "5 5" : void 0,
|
|
256
|
+
shape: buffer ? bufferShape : void 0,
|
|
257
|
+
isAnimationActive: false,
|
|
258
|
+
style: {
|
|
259
|
+
...maskId ? { mask: `url(#${maskId})` } : {},
|
|
260
|
+
...isClickable ? { cursor: "pointer" } : {}
|
|
261
|
+
},
|
|
262
|
+
onClick: () => {
|
|
263
|
+
if (!isClickable) return;
|
|
264
|
+
selectDataKey(isSelected ? null : dataKey);
|
|
265
|
+
},
|
|
266
|
+
...lineProps,
|
|
267
|
+
children: [
|
|
268
|
+
animateDash && /* @__PURE__ */ jsx(AnimatedDashedStroke, { dash: 5 }),
|
|
269
|
+
labels
|
|
270
|
+
]
|
|
271
|
+
}
|
|
272
|
+
)
|
|
273
|
+
] }),
|
|
274
|
+
/* @__PURE__ */ jsxs("defs", { children: [
|
|
275
|
+
reveal !== "none" && /* @__PURE__ */ jsx(RevealMask, { id, type: reveal }),
|
|
276
|
+
/* @__PURE__ */ jsx(SeriesGradient, { id, dataKey, config }),
|
|
277
|
+
glowing && /* @__PURE__ */ jsx(GlowFilter, { id, dataKey, spread: 10, intensity: 2 })
|
|
278
|
+
] })
|
|
279
|
+
] });
|
|
280
|
+
}
|
|
281
|
+
const Dot = () => null;
|
|
282
|
+
const ActiveDot = () => null;
|
|
283
|
+
function resolveDots(children, id, dataKey, dotOpacity, maskId) {
|
|
284
|
+
let dot = false;
|
|
285
|
+
let activeDot = false;
|
|
286
|
+
Children.forEach(children, (child) => {
|
|
287
|
+
if (!isValidElement(child)) return;
|
|
288
|
+
const { variant } = child.props;
|
|
289
|
+
if (child.type === Dot) {
|
|
290
|
+
dot = /* @__PURE__ */ jsx(
|
|
291
|
+
ChartDot,
|
|
292
|
+
{
|
|
293
|
+
variant,
|
|
294
|
+
dataKey,
|
|
295
|
+
chartId: id,
|
|
296
|
+
fillOpacity: dotOpacity,
|
|
297
|
+
maskId
|
|
298
|
+
}
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
if (child.type === ActiveDot) {
|
|
302
|
+
activeDot = /* @__PURE__ */ jsx(ChartDot, { variant, dataKey, chartId: id, fillOpacity: dotOpacity });
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
return { dot, activeDot };
|
|
306
|
+
}
|
|
307
|
+
function isDrawable(point) {
|
|
308
|
+
return typeof point.x === "number" && typeof point.y === "number";
|
|
309
|
+
}
|
|
310
|
+
function lengthAtX(path, totalLength, targetX) {
|
|
311
|
+
let low = 0;
|
|
312
|
+
let high = totalLength;
|
|
313
|
+
while (high - low > 0.5) {
|
|
314
|
+
const mid = (low + high) / 2;
|
|
315
|
+
if (path.getPointAtLength(mid).x < targetX) low = mid;
|
|
316
|
+
else high = mid;
|
|
317
|
+
}
|
|
318
|
+
return (low + high) / 2;
|
|
319
|
+
}
|
|
320
|
+
function bufferShape(props) {
|
|
321
|
+
const { points, ...rest } = props;
|
|
322
|
+
if (!points || points.length < 2) return /* @__PURE__ */ jsx(Curve, { ...props });
|
|
323
|
+
const drawable = points.filter(isDrawable);
|
|
324
|
+
if (drawable.length < 2) return /* @__PURE__ */ jsx(Curve, { ...props });
|
|
325
|
+
const splitX = drawable[drawable.length - 2].x;
|
|
326
|
+
return /* @__PURE__ */ jsx(
|
|
327
|
+
"g",
|
|
328
|
+
{
|
|
329
|
+
ref: (group) => {
|
|
330
|
+
const path = group?.querySelector("path");
|
|
331
|
+
if (!path) return;
|
|
332
|
+
const total = path.getTotalLength();
|
|
333
|
+
const solid = lengthAtX(path, total, splitX);
|
|
334
|
+
const remaining = total - solid;
|
|
335
|
+
const repeats = Math.ceil(remaining / (BUFFER_DASH + BUFFER_GAP)) + 1;
|
|
336
|
+
const dashes = Array.from({ length: repeats }, () => `${BUFFER_DASH} ${BUFFER_GAP}`).join(" ");
|
|
337
|
+
path.setAttribute("stroke-dasharray", `${solid} 0 ${dashes}`);
|
|
338
|
+
},
|
|
339
|
+
children: /* @__PURE__ */ jsx(Curve, { ...rest, points: drawable })
|
|
340
|
+
}
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
function XAxis({
|
|
344
|
+
tickLine = false,
|
|
345
|
+
axisLine = false,
|
|
346
|
+
tickMargin = 8,
|
|
347
|
+
minTickGap = 8,
|
|
348
|
+
label,
|
|
349
|
+
...rest
|
|
350
|
+
}) {
|
|
351
|
+
const { isLoading } = useLineChart();
|
|
352
|
+
if (isLoading) return null;
|
|
353
|
+
return /* @__PURE__ */ jsx(
|
|
354
|
+
RechartsXAxis,
|
|
355
|
+
{
|
|
356
|
+
tickLine,
|
|
357
|
+
axisLine,
|
|
358
|
+
tickMargin,
|
|
359
|
+
minTickGap,
|
|
360
|
+
...rest,
|
|
361
|
+
children: axisLabel(label, "x")
|
|
362
|
+
}
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
function YAxis({
|
|
366
|
+
tickLine = false,
|
|
367
|
+
axisLine = false,
|
|
368
|
+
tickMargin = 8,
|
|
369
|
+
minTickGap = 8,
|
|
370
|
+
width = "auto",
|
|
371
|
+
tickFormatter = defaultTick,
|
|
372
|
+
label,
|
|
373
|
+
...rest
|
|
374
|
+
}) {
|
|
375
|
+
const { isLoading } = useLineChart();
|
|
376
|
+
if (isLoading) return null;
|
|
377
|
+
return /* @__PURE__ */ jsx(
|
|
378
|
+
RechartsYAxis,
|
|
379
|
+
{
|
|
380
|
+
tickLine,
|
|
381
|
+
axisLine,
|
|
382
|
+
tickMargin,
|
|
383
|
+
minTickGap,
|
|
384
|
+
width,
|
|
385
|
+
tickFormatter,
|
|
386
|
+
...rest,
|
|
387
|
+
children: axisLabel(label, "y")
|
|
388
|
+
}
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
function Grid({
|
|
392
|
+
vertical = false,
|
|
393
|
+
strokeDasharray = "3 3",
|
|
394
|
+
...rest
|
|
395
|
+
}) {
|
|
396
|
+
return /* @__PURE__ */ jsx(CartesianGrid, { vertical, strokeDasharray, ...rest });
|
|
397
|
+
}
|
|
398
|
+
function Tooltip({ variant, roundness, defaultIndex, cursor = true }) {
|
|
399
|
+
const { isLoading, selectedDataKey } = useLineChart();
|
|
400
|
+
if (isLoading) return null;
|
|
401
|
+
return /* @__PURE__ */ jsx(
|
|
402
|
+
ChartTooltip,
|
|
403
|
+
{
|
|
404
|
+
defaultIndex,
|
|
405
|
+
cursor: cursor ? { strokeDasharray: "3 3", strokeWidth: 1 } : false,
|
|
406
|
+
content: /* @__PURE__ */ jsx(ChartTooltipContent, { selected: selectedDataKey, roundness, variant })
|
|
407
|
+
}
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
function Legend({
|
|
411
|
+
variant,
|
|
412
|
+
align = "right",
|
|
413
|
+
verticalAlign = "top",
|
|
414
|
+
isClickable = false
|
|
415
|
+
}) {
|
|
416
|
+
const { selectedDataKey, selectDataKey } = useLineChart();
|
|
417
|
+
return /* @__PURE__ */ jsx(
|
|
418
|
+
ChartLegend,
|
|
419
|
+
{
|
|
420
|
+
verticalAlign,
|
|
421
|
+
align,
|
|
422
|
+
content: /* @__PURE__ */ jsx(
|
|
423
|
+
ChartLegendContent,
|
|
424
|
+
{
|
|
425
|
+
selected: selectedDataKey,
|
|
426
|
+
onSelectChange: selectDataKey,
|
|
427
|
+
isClickable,
|
|
428
|
+
variant
|
|
429
|
+
}
|
|
430
|
+
)
|
|
431
|
+
}
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
function Background({ variant }) {
|
|
435
|
+
const { isLoading } = useLineChart();
|
|
436
|
+
if (isLoading) return null;
|
|
437
|
+
return /* @__PURE__ */ jsx(ChartBackground, { variant });
|
|
438
|
+
}
|
|
439
|
+
function LoadingLine({
|
|
440
|
+
chartId,
|
|
441
|
+
curveType,
|
|
442
|
+
onShimmerExit
|
|
443
|
+
}) {
|
|
444
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
445
|
+
/* @__PURE__ */ jsx(
|
|
446
|
+
RechartsLine,
|
|
447
|
+
{
|
|
448
|
+
type: curveType,
|
|
449
|
+
dataKey: LOADING_KEY,
|
|
450
|
+
stroke: "currentColor",
|
|
451
|
+
strokeOpacity: 0.5,
|
|
452
|
+
strokeWidth: STROKE_WIDTH,
|
|
453
|
+
isAnimationActive: false,
|
|
454
|
+
legendType: "none",
|
|
455
|
+
tooltipType: "none",
|
|
456
|
+
activeDot: false,
|
|
457
|
+
dot: false,
|
|
458
|
+
className: "text-(--ink)",
|
|
459
|
+
style: { mask: `url(#${chartId}-loading-mask)` }
|
|
460
|
+
}
|
|
461
|
+
),
|
|
462
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(LoadingShimmer, { id: chartId, onShimmerExit }) })
|
|
463
|
+
] });
|
|
464
|
+
}
|
|
465
|
+
LineChart.Line = Line;
|
|
466
|
+
LineChart.Dot = Dot;
|
|
467
|
+
LineChart.ActiveDot = ActiveDot;
|
|
468
|
+
LineChart.XAxis = XAxis;
|
|
469
|
+
LineChart.YAxis = YAxis;
|
|
470
|
+
LineChart.Grid = Grid;
|
|
471
|
+
LineChart.Tooltip = Tooltip;
|
|
472
|
+
LineChart.Legend = Legend;
|
|
473
|
+
LineChart.Background = Background;
|
|
474
|
+
LineChart.ReferenceLine = ReferenceLine;
|
|
475
|
+
LineChart.ReferenceBand = ReferenceBand;
|
|
476
|
+
LineChart.Annotation = Annotation;
|
|
477
|
+
LineChart.Values = Values;
|
|
478
|
+
LineChart.Brush = Brush;
|
|
479
|
+
LineChart.Toolbar = Toolbar;
|
|
480
|
+
LineChart.Sonify = Sonify;
|
|
481
|
+
var LineChart_default = LineChart;
|
|
482
|
+
export {
|
|
483
|
+
LineChart,
|
|
484
|
+
LineChart_default as default
|
|
485
|
+
};
|
|
486
|
+
//# sourceMappingURL=LineChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/charts/LineChart/LineChart.tsx"],"sourcesContent":["'use client'\n\nimport {\n Children,\n createContext,\n isValidElement,\n useCallback,\n useContext,\n useId,\n useMemo,\n useState,\n type ComponentProps,\n type FC,\n type ReactElement,\n type ReactNode,\n} from 'react'\nimport {\n CartesianGrid,\n Curve,\n Line as RechartsLine,\n LineChart as RechartsLineChart,\n XAxis as RechartsXAxis,\n YAxis as RechartsYAxis,\n} from 'recharts'\nimport type { CurveProps } from 'recharts'\nimport { useReducedMotion } from 'motion/react'\nimport { ChartContainer, type ChartConfig } from '../lib/chart'\nimport { ChartFigure } from '../lib/figure'\nimport { ChartEmpty, type ChartEmptyProps } from '../lib/empty'\nimport { axisLabel } from '../lib/axis'\nimport { defaultTick } from '../lib/format'\nimport { Annotation, ReferenceBand, ReferenceLine } from '../lib/annotations'\nimport { Values, findSlot, resolveValues, type ValuesProps } from '../lib/values'\nimport {\n ChartSonifyButton,\n Sonify,\n useChartSonifySeries,\n type SonifyProps,\n} from '../lib/sonify-control'\n\n/**\n * The axis props, with `label` narrowed to a string.\n *\n * Recharts' own `label` accepts a render function and a config object, neither\n * of which a call site should be reaching for to name an axis — and both of\n * which would let a consumer opt out of the system's own axis type styling\n * without noticing.\n */\nexport type ChartXAxisProps = Omit<ComponentProps<typeof RechartsXAxis>, 'label'> & {\n /** What this axis measures. Say the unit here or in the series label, once. */\n label?: string\n}\n\nexport type ChartYAxisProps = Omit<ComponentProps<typeof RechartsYAxis>, 'label'> & {\n /** What this axis measures. Say the unit here or in the series label, once. */\n label?: string\n}\n\nimport { ChartBackground, type ChartBackgroundVariant } from '../lib/background'\nimport { ChartDot, type ChartDotVariant } from '../lib/dot'\nimport { ChartLegend, ChartLegendContent } from '../lib/legend'\nimport { ChartTooltip, ChartTooltipContent } from '../lib/tooltip'\nimport { Brush, ChartBrush, type BrushProps, type ChartBrushRange } from '../lib/brush'\nimport { ChartControls, Toolbar, type ToolbarProps } from '../lib/toolbar'\nimport { useChartZoom } from '../lib/zoom'\nimport { LoadingIndicator, LoadingShimmer, LOADING_KEY, useLoadingRows } from '../lib/loading'\nimport {\n AnimatedDashedStroke,\n GlowFilter,\n RevealMask,\n SeriesGradient,\n type ChartRevealType,\n} from '../lib/paint'\nimport type {\n AreaStrokeVariant,\n ChartCurveType,\n ChartLegendSlotProps,\n ChartTooltipSlotProps,\n} from '../AreaChart/AreaChart'\n\nconst STROKE_WIDTH = 1.6\n\n/** The dash and gap of a buffer segment, in user units. */\nconst BUFFER_DASH = 4\nconst BUFFER_GAP = 3\n\n/**\n * Room around the plot, so the first and last tick labels are not sliced by the\n * container's edge. Recharts' own default is 5px on every side, which is not\n * enough for a label centred on the axis's first point.\n */\nconst CHART_MARGIN = { top: 8, right: 12, bottom: 0, left: 12 }\n\n/** How a line is drawn. Same vocabulary as an area's stroke. */\nexport type LineStrokeVariant = AreaStrokeVariant\n\ninterface LineChartContextValue {\n config: ChartConfig\n /** The rows on screen, so a mark can label its own extremes. */\n rows: Record<string, unknown>[]\n curveType: ChartCurveType\n animationType: ChartRevealType\n isLoading: boolean\n selectedDataKey: string | null\n selectDataKey: (dataKey: string | null) => void\n}\n\nconst LineChartContext = createContext<LineChartContextValue | null>(null)\n\nfunction useLineChart(): LineChartContextValue {\n const context = useContext(LineChartContext)\n if (!context) throw new Error('A line chart part must be rendered inside <LineChart>')\n return context\n}\n\ntype ValidateKeys<TData, TConfig> = {\n [K in keyof TConfig]: K extends keyof TData ? ChartConfig[string] : never\n}\n\nexport interface LineChartProps<\n TData extends Record<string, unknown>,\n TConfig extends Record<string, ChartConfig[string]>,\n> {\n config: TConfig & ValidateKeys<TData, TConfig>\n /** The rows the chart draws. One entry per point, bar or category. */\n data: TData[]\n /**\n * What the chart shows, in a sentence a reader could act on. Required, and\n * announced to a screen reader even when it is not printed.\n */\n title: string\n /** Prints the title above the plot instead of hiding it from sight. */\n showTitle?: boolean\n /** A line under the title — the unit, the window, the caveat. */\n description?: ReactNode\n /**\n * The composed parts — axes, grid, tooltip, legend, and the marks\n * themselves.\n */\n children: ReactNode\n /** Merged onto the figure, last, so a call site can size or space it. */\n className?: string\n /** Escape hatch onto the raw Recharts chart element. */\n chartProps?: ComponentProps<typeof RechartsLineChart>\n /**\n * How the line between two points is interpolated. Every mark inherits it\n * unless it says otherwise.\n */\n curveType?: ChartCurveType\n animationType?: ChartRevealType\n /** The series lit on first render. Selection dims every other series. */\n defaultSelectedDataKey?: string | null\n /** Fires when the selection changes, and with null when it is cleared. */\n onSelectionChange?: (selectedDataKey: string | null) => void\n /**\n * Swaps the marks for an animated skeleton, keeping the measured height so\n * the page does not jump when the data lands.\n */\n isLoading?: boolean\n /** How many points the skeleton draws. */\n loadingPoints?: number\n /**\n * The row field on the category axis. Needed by the brush and by the table\n * view.\n */\n xDataKey?: keyof TData & string\n /**\n * Drops the hidden table view. Only correct when the page prints the data\n * itself.\n */\n hideDataTable?: boolean\n /**\n * What the chart shows when it has nothing to draw.\n *\n * Rendered instead of the plot whenever `data` is empty and the chart is not\n * loading — the state a real dashboard reaches within a week, and the one an\n * empty pair of axes is indistinguishable from a failed load. `false` keeps\n * the axes, for a chart whose emptiness is itself the reading.\n */\n empty?: ChartEmptyProps | false\n}\n\n/**\n * Several series compared over a continuous axis — the shape for \"which of\n * these is going where\".\n *\n * The difference from `<AreaChart>` is what the reader is asked to do: an area\n * says \"read the magnitude under this\", a line says \"compare these against each\n * other\". Filling four overlapping series makes the second question unanswerable,\n * which is why a line chart has no fill variant to offer.\n *\n * @example\n * <LineChart title=\"Visitors per month\" config={config} data={data}>\n * <LineChart.Grid />\n * <LineChart.XAxis dataKey=\"month\" />\n * <LineChart.Tooltip />\n * <LineChart.Line dataKey=\"desktop\">\n * <LineChart.Dot variant=\"border\" />\n * </LineChart.Line>\n * </LineChart>\n */\nexport function LineChart<\n TData extends Record<string, unknown>,\n TConfig extends Record<string, ChartConfig[string]>,\n>({\n config,\n data,\n title,\n showTitle,\n description,\n children,\n className,\n chartProps,\n curveType = 'linear',\n animationType = 'forward',\n defaultSelectedDataKey = null,\n onSelectionChange,\n isLoading = false,\n loadingPoints,\n xDataKey,\n hideDataTable = false,\n empty,\n}: LineChartProps<TData, TConfig>) {\n const chartId = useId().replace(/:/g, '')\n const [selectedDataKey, setSelectedDataKey] = useState<string | null>(defaultSelectedDataKey)\n const { rows: loadingData, onShimmerExit } = useLoadingRows(isLoading, loadingPoints)\n // One window, two views of it: the brush strip below the plot and the\n // toolbar above it both read and write this. See `useChartZoom` for why they\n // are not two separate windows.\n const zoom = useChartZoom({ data, xDataKey })\n\n // The brush, the toolbar and the sonify control are declared as children but\n // never rendered into the Recharts tree — they live in the figure, outside\n // the SVG.\n const { brushSlot, toolbarSlot, sonifySlot, chartChildren } = useMemo(() => {\n const parts = Children.toArray(children)\n const element = parts.find((child) => isValidElement(child) && child.type === Brush)\n const props = (isValidElement(element) ? element.props : {}) as BrushProps\n return {\n brushSlot: { present: isValidElement(element), ...props },\n toolbarSlot: findSlot<ToolbarProps>(parts, Toolbar),\n sonifySlot: findSlot<SonifyProps>(parts, Sonify),\n chartChildren: parts.filter(\n (child) =>\n !(\n isValidElement(child) &&\n (child.type === Brush || child.type === Toolbar || child.type === Sonify)\n ),\n ),\n }\n }, [children])\n\n const columns = useMemo(\n () => Object.entries(config).map(([key, series]) => ({ key, label: series.label })),\n [config],\n )\n\n const showBrush = brushSlot.present && !isLoading\n const showToolbar = toolbarSlot !== null && !isLoading\n // `empty === false` keeps the axes, for a chart whose emptiness is the\n // reading — a monitoring panel that should show a flat, silent range rather\n // than a message.\n const isEmpty = !isLoading && empty !== false && data.length === 0\n const displayData =\n isLoading ? loadingData : showBrush || showToolbar ? zoom.visibleData : data\n\n // The rows on screen, so a brushed range sounds like what it looks like. A\n // skeleton or an empty chart yields no finite value, which is what leaves the\n // control disabled rather than playing silence.\n const sonifySeries = useChartSonifySeries(\n sonifySlot,\n displayData as Record<string, unknown>[],\n config,\n xDataKey,\n )\n\n const selectDataKey = useCallback(\n (next: string | null) => {\n setSelectedDataKey(next)\n onSelectionChange?.(next)\n },\n [onSelectionChange],\n )\n\n const context = useMemo<LineChartContextValue>(\n () => ({ config, rows: displayData as Record<string, unknown>[], curveType, animationType, isLoading, selectedDataKey, selectDataKey }),\n [animationType, config, curveType, displayData, isLoading, selectDataKey, selectedDataKey],\n )\n\n return (\n <LineChartContext.Provider value={context}>\n <ChartFigure\n title={title}\n showTitle={showTitle}\n description={description}\n className={className}\n table={\n hideDataTable\n ? false\n : { rows: data, rowKey: xDataKey, columns }\n }\n >\n {sonifySlot && (\n <ChartSonifyButton {...sonifySlot} title={title} series={sonifySeries} />\n )}\n {isEmpty ? (\n <ChartEmpty {...(empty || {})} />\n ) : (\n <ChartControls\n toolbar={showToolbar ? toolbarSlot : null}\n zoom={zoom}\n title={title}\n rows={data}\n columns={columns}\n rowKey={xDataKey}\n >\n <ChartContainer\n config={config}\n footer={\n showBrush && (\n <ChartBrush\n data={data}\n config={config}\n xDataKey={xDataKey}\n variant=\"line\"\n curveType={curveType}\n height={brushSlot.height}\n formatLabel={brushSlot.formatLabel}\n className=\"mt-1\"\n {...zoom.brushProps}\n onChange={(range: ChartBrushRange) => {\n zoom.brushProps.onChange(range)\n brushSlot.onChange?.(range)\n }}\n />\n )\n }\n >\n <RechartsLineChart\n id={chartId}\n accessibilityLayer\n margin={CHART_MARGIN}\n data={displayData}\n {...chartProps}\n >\n {chartChildren}\n {isLoading && (\n <LoadingLine chartId={chartId} curveType={curveType} onShimmerExit={onShimmerExit} />\n )}\n </RechartsLineChart>\n </ChartContainer>\n </ChartControls>\n )}\n <LoadingIndicator isLoading={isLoading} />\n </ChartFigure>\n </LineChartContext.Provider>\n )\n}\n\nexport interface LineProps {\n dataKey: string\n strokeVariant?: LineStrokeVariant\n strokeWidth?: number\n curveType?: ChartCurveType\n animationType?: ChartRevealType\n connectNulls?: boolean\n isClickable?: boolean\n /** A halo around the line — for the one series that is the point of the figure. */\n glowing?: boolean\n /**\n * Draws the LAST segment dashed.\n *\n * The idiom for a projection or a period still open: the line reaches the\n * same point either way, but the last leg is visibly a different kind of fact.\n */\n buffer?: boolean\n children?: ReactNode\n lineProps?: ComponentProps<typeof RechartsLine>\n}\n\n/** One line series, with its own gradient, glow and reveal scoped to its id. */\nfunction Line({\n dataKey,\n strokeVariant = 'solid',\n strokeWidth = STROKE_WIDTH,\n curveType,\n animationType,\n connectNulls = false,\n isClickable = false,\n glowing = false,\n buffer = false,\n children,\n lineProps,\n}: LineProps) {\n const {\n config,\n curveType: defaultCurve,\n animationType: defaultAnimation,\n isLoading,\n rows,\n selectedDataKey,\n selectDataKey,\n } = useLineChart()\n const id = useId().replace(/:/g, '')\n const reduceMotion = useReducedMotion()\n\n if (isLoading) return null\n\n const resolvedCurve = curveType ?? defaultCurve\n const reveal: ChartRevealType = reduceMotion ? 'none' : (animationType ?? defaultAnimation)\n const maskId = reveal === 'none' ? undefined : `${id}-reveal-mask`\n\n const isSelected = selectedDataKey === dataKey\n const hasSelection = selectedDataKey !== null\n const opacity = hasSelection && !isSelected ? { stroke: 0.3, dot: 0.3 } : { stroke: 1, dot: 1 }\n\n const { dot, activeDot } = resolveDots(children, id, dataKey, opacity.dot, maskId)\n const labels = resolveValues(\n findSlot<ValuesProps>(children, Values),\n rows.map((row) => Number(row[dataKey])).filter(Number.isFinite),\n )\n\n const animateDash = strokeVariant === 'animated-dashed' && !hasSelection && !reduceMotion\n const isDashed = strokeVariant !== 'solid'\n\n return (\n <>\n <g>\n {isClickable && (\n // A 15px transparent line under the visible one. A 1.6px stroke is\n // not a pointer target, and WCAG 2.5.8 asks for 24; this is the\n // cheapest way to give a hairline a real hit area.\n <RechartsLine\n type={resolvedCurve}\n dataKey={dataKey}\n connectNulls={connectNulls}\n stroke=\"transparent\"\n strokeWidth={15}\n dot={false}\n activeDot={false}\n isAnimationActive={false}\n legendType=\"none\"\n tooltipType=\"none\"\n style={{ cursor: 'pointer' }}\n onClick={() => selectDataKey(isSelected ? null : dataKey)}\n />\n )}\n <RechartsLine\n type={resolvedCurve}\n dataKey={dataKey}\n connectNulls={connectNulls}\n strokeOpacity={opacity.stroke}\n stroke={`url(#${id}-colors-${dataKey})`}\n filter={glowing ? `url(#${id}-glow-${dataKey})` : undefined}\n dot={dot}\n activeDot={activeDot}\n strokeWidth={strokeWidth}\n // A buffer line writes its own dasharray from the measured path, so\n // the static one has to stay out of its way.\n strokeDasharray={buffer ? undefined : isDashed ? '5 5' : undefined}\n shape={buffer ? bufferShape : undefined}\n isAnimationActive={false}\n style={{\n ...(maskId ? { mask: `url(#${maskId})` } : {}),\n ...(isClickable ? { cursor: 'pointer' } : {}),\n }}\n onClick={() => {\n if (!isClickable) return\n selectDataKey(isSelected ? null : dataKey)\n }}\n {...lineProps}\n >\n {animateDash && <AnimatedDashedStroke dash={5} />}\n {labels}\n </RechartsLine>\n </g>\n <defs>\n {reveal !== 'none' && <RevealMask id={id} type={reveal} />}\n <SeriesGradient id={id} dataKey={dataKey} config={config} />\n {glowing && <GlowFilter id={id} dataKey={dataKey} spread={10} intensity={2} />}\n </defs>\n </>\n )\n}\n\nexport interface DotProps {\n variant?: ChartDotVariant\n}\n\n/** The resting point marker for the line it is composed inside. A slot. */\nconst Dot: FC<DotProps> = () => null\n\n/** The marker under the pointer. */\nconst ActiveDot: FC<DotProps> = () => null\n\nfunction resolveDots(\n children: ReactNode,\n id: string,\n dataKey: string,\n dotOpacity: number,\n maskId: string | undefined,\n) {\n let dot: ComponentProps<typeof RechartsLine>['dot'] = false\n let activeDot: ComponentProps<typeof RechartsLine>['activeDot'] = false\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return\n const { variant } = (child as ReactElement<DotProps>).props\n\n if (child.type === Dot) {\n dot = (\n <ChartDot\n variant={variant}\n dataKey={dataKey}\n chartId={id}\n fillOpacity={dotOpacity}\n maskId={maskId}\n />\n )\n }\n if (child.type === ActiveDot) {\n activeDot = (\n <ChartDot variant={variant} dataKey={dataKey} chartId={id} fillOpacity={dotOpacity} />\n )\n }\n })\n\n return { dot, activeDot }\n}\n\ntype CurvePoint = NonNullable<NonNullable<CurveProps['points']>[number]>\ntype DrawablePoint = CurvePoint & { x: number; y: number }\n\nfunction isDrawable(point: CurvePoint): point is DrawablePoint {\n return typeof point.x === 'number' && typeof point.y === 'number'\n}\n\n/**\n * Binary-searches a path for the length at which it reaches `targetX`.\n *\n * `getPointAtLength` is the browser's own curve solver, so this is exact for\n * every curve type rather than only for straight segments — which is what an\n * arithmetic split on the point list would give.\n */\nfunction lengthAtX(path: SVGPathElement, totalLength: number, targetX: number): number {\n let low = 0\n let high = totalLength\n // Half a pixel is well under what a dash boundary can show.\n while (high - low > 0.5) {\n const mid = (low + high) / 2\n if (path.getPointAtLength(mid).x < targetX) low = mid\n else high = mid\n }\n return (low + high) / 2\n}\n\n/**\n * A line whose last segment is dashed and whose body is not.\n *\n * `stroke-dasharray` has no way to say \"solid until here\": the pattern repeats\n * from the path's start. So the solid run is written as a single leading dash of\n * exactly the measured length, followed by enough dash/gap pairs to cover the\n * rest — which needs the path's real length, which needs the DOM.\n *\n * The ref callback runs during commit, before paint, so there is no frame where\n * the line is drawn undashed.\n */\nfunction bufferShape(props: CurveProps) {\n const { points, ...rest } = props\n if (!points || points.length < 2) return <Curve {...props} />\n\n const drawable = points.filter(isDrawable)\n if (drawable.length < 2) return <Curve {...props} />\n\n const splitX = drawable[drawable.length - 2]!.x\n\n return (\n <g\n ref={(group) => {\n const path = group?.querySelector('path')\n if (!path) return\n\n const total = path.getTotalLength()\n const solid = lengthAtX(path, total, splitX)\n const remaining = total - solid\n const repeats = Math.ceil(remaining / (BUFFER_DASH + BUFFER_GAP)) + 1\n const dashes = Array.from({ length: repeats }, () => `${BUFFER_DASH} ${BUFFER_GAP}`).join(' ')\n\n path.setAttribute('stroke-dasharray', `${solid} 0 ${dashes}`)\n }}\n >\n <Curve {...rest} points={drawable} />\n </g>\n )\n}\n\n/** The category axis. */\nfunction XAxis({\n tickLine = false,\n axisLine = false,\n tickMargin = 8,\n minTickGap = 8,\n label,\n ...rest\n}: ChartXAxisProps) {\n const { isLoading } = useLineChart()\n if (isLoading) return null\n return (\n <RechartsXAxis\n tickLine={tickLine}\n axisLine={axisLine}\n tickMargin={tickMargin}\n minTickGap={minTickGap}\n {...rest}\n >\n {axisLabel(label, 'x')}\n </RechartsXAxis>\n )\n}\n\n/** The value axis. */\nfunction YAxis({\n tickLine = false,\n axisLine = false,\n tickMargin = 8,\n minTickGap = 8,\n width = 'auto',\n tickFormatter = defaultTick,\n label,\n ...rest\n}: ChartYAxisProps) {\n const { isLoading } = useLineChart()\n if (isLoading) return null\n return (\n <RechartsYAxis\n tickLine={tickLine}\n axisLine={axisLine}\n tickMargin={tickMargin}\n minTickGap={minTickGap}\n width={width}\n tickFormatter={tickFormatter}\n {...rest}\n >\n {axisLabel(label, 'y')}\n </RechartsYAxis>\n )\n}\n\n/** Horizontal dashed rules. */\nfunction Grid({\n vertical = false,\n strokeDasharray = '3 3',\n ...rest\n}: ComponentProps<typeof CartesianGrid>) {\n return <CartesianGrid vertical={vertical} strokeDasharray={strokeDasharray} {...rest} />\n}\n\n/** The hover panel, with a crosshair along the axis. */\nfunction Tooltip({ variant, roundness, defaultIndex, cursor = true }: ChartTooltipSlotProps) {\n const { isLoading, selectedDataKey } = useLineChart()\n if (isLoading) return null\n\n return (\n <ChartTooltip\n defaultIndex={defaultIndex}\n cursor={cursor ? { strokeDasharray: '3 3', strokeWidth: 1 } : false}\n content={\n <ChartTooltipContent selected={selectedDataKey} roundness={roundness} variant={variant} />\n }\n />\n )\n}\n\n/** The key. Required above one series. */\nfunction Legend({\n variant,\n align = 'right',\n verticalAlign = 'top',\n isClickable = false,\n}: ChartLegendSlotProps) {\n const { selectedDataKey, selectDataKey } = useLineChart()\n\n return (\n <ChartLegend\n verticalAlign={verticalAlign}\n align={align}\n content={\n <ChartLegendContent\n selected={selectedDataKey}\n onSelectChange={selectDataKey}\n isClickable={isClickable}\n variant={variant}\n />\n }\n />\n )\n}\n\n/** The decorative plate behind the plot. */\nfunction Background({ variant }: { variant: ChartBackgroundVariant }) {\n const { isLoading } = useLineChart()\n if (isLoading) return null\n return <ChartBackground variant={variant} />\n}\n\n/** The skeleton drawn in place of the real lines. */\nfunction LoadingLine({\n chartId,\n curveType,\n onShimmerExit,\n}: {\n chartId: string\n curveType: ChartCurveType\n onShimmerExit: () => void\n}) {\n return (\n <>\n <RechartsLine\n type={curveType}\n dataKey={LOADING_KEY}\n stroke=\"currentColor\"\n strokeOpacity={0.5}\n strokeWidth={STROKE_WIDTH}\n isAnimationActive={false}\n legendType=\"none\"\n tooltipType=\"none\"\n activeDot={false}\n dot={false}\n className=\"text-(--ink)\"\n style={{ mask: `url(#${chartId}-loading-mask)` }}\n />\n <defs>\n <LoadingShimmer id={chartId} onShimmerExit={onShimmerExit} />\n </defs>\n </>\n )\n}\n\nLineChart.Line = Line\nLineChart.Dot = Dot\nLineChart.ActiveDot = ActiveDot\nLineChart.XAxis = XAxis\nLineChart.YAxis = YAxis\nLineChart.Grid = Grid\nLineChart.Tooltip = Tooltip\nLineChart.Legend = Legend\nLineChart.Background = Background\nLineChart.ReferenceLine = ReferenceLine\nLineChart.ReferenceBand = ReferenceBand\nLineChart.Annotation = Annotation\nLineChart.Values = Values\nLineChart.Brush = Brush\nLineChart.Toolbar = Toolbar\nLineChart.Sonify = Sonify\n\nexport default LineChart\n"],"mappings":"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","names":[]}
|