@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,103 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ComponentProps, ReactNode } from 'react';
|
|
3
|
+
import { Label, ReferenceLine as ReferenceLine$1, ReferenceArea, ReferenceDot } from 'recharts';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Where each annotation sits in the stack, and the numbers are not arbitrary:
|
|
7
|
+
* they are the rule editorial charting settled on, expressed in Recharts' own
|
|
8
|
+
* z-index scale (grid -100, area 100, bar 300, line 400, axis 500, dot 1200).
|
|
9
|
+
*
|
|
10
|
+
* A BAND is context, so it goes behind everything — behind the data AND
|
|
11
|
+
* behind the grid. A band drawn over its own gridlines reads as a second
|
|
12
|
+
* surface rather than as a region of the first.
|
|
13
|
+
*
|
|
14
|
+
* A LINE is a claim about the data — a target, a threshold, a limit — so it
|
|
15
|
+
* goes above the marks. A reference line hidden behind a bar is a reference
|
|
16
|
+
* nobody can check.
|
|
17
|
+
*
|
|
18
|
+
* A TEXT annotation explains both, so it goes above both, and above the
|
|
19
|
+
* hover dot too. It is the last thing drawn because it is the last thing to
|
|
20
|
+
* be occluded.
|
|
21
|
+
*
|
|
22
|
+
* The decorative plate sits below the band, because a plate is not context —
|
|
23
|
+
* it is wallpaper.
|
|
24
|
+
*/
|
|
25
|
+
declare const ANNOTATION_LAYER: {
|
|
26
|
+
readonly plate: -300;
|
|
27
|
+
readonly band: -200;
|
|
28
|
+
readonly line: 450;
|
|
29
|
+
readonly text: 1500;
|
|
30
|
+
};
|
|
31
|
+
/** How much a reference mark insists. */
|
|
32
|
+
type AnnotationWeight = 'quiet' | 'firm';
|
|
33
|
+
interface ReferenceLineProps {
|
|
34
|
+
/** The value on the category axis. Give exactly one of `x` or `y`. */
|
|
35
|
+
x?: string | number;
|
|
36
|
+
/** The value on the value axis. Give exactly one of `x` or `y`. */
|
|
37
|
+
y?: string | number;
|
|
38
|
+
/** Printed at the end of the line. Keep it to a couple of words. */
|
|
39
|
+
label?: string;
|
|
40
|
+
weight?: AnnotationWeight;
|
|
41
|
+
/** Where the label sits. Defaults to the line's far end. */
|
|
42
|
+
labelPosition?: ComponentProps<typeof Label>['position'];
|
|
43
|
+
referenceLineProps?: ComponentProps<typeof ReferenceLine$1>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A target, a threshold, a limit, a budget — one number the data is being read
|
|
47
|
+
* against.
|
|
48
|
+
*
|
|
49
|
+
* Worth reaching for more often than it is: most charts that look like they
|
|
50
|
+
* need a second series actually need this. "Are we above the line" is a
|
|
51
|
+
* question a reference line answers at a glance and a second series does not.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* <LineChart.ReferenceLine y={250} label="Target" weight="firm" />
|
|
55
|
+
*/
|
|
56
|
+
declare function ReferenceLine({ x, y, label, weight, labelPosition, referenceLineProps, }: ReferenceLineProps): react.JSX.Element;
|
|
57
|
+
interface ReferenceBandProps {
|
|
58
|
+
/** A span on the category axis, as `[from, to]`. */
|
|
59
|
+
x?: [string | number, string | number];
|
|
60
|
+
/** A span on the value axis, as `[from, to]`. */
|
|
61
|
+
y?: [string | number, string | number];
|
|
62
|
+
/** Printed inside the band's top edge. */
|
|
63
|
+
label?: string;
|
|
64
|
+
referenceAreaProps?: ComponentProps<typeof ReferenceArea>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* A region the data is read against — a healthy range, a recession, a period
|
|
68
|
+
* the numbers should not be trusted for.
|
|
69
|
+
*
|
|
70
|
+
* Drawn behind the grid, so it reads as a stretch of the ground rather than as
|
|
71
|
+
* a mark on it. That placement is the whole difference between "this period"
|
|
72
|
+
* and "this value".
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* <AreaChart.ReferenceBand x={['Mar', 'May']} label="Migration" />
|
|
76
|
+
*/
|
|
77
|
+
declare function ReferenceBand({ x, y, label, referenceAreaProps }: ReferenceBandProps): react.JSX.Element;
|
|
78
|
+
interface AnnotationProps {
|
|
79
|
+
/** Where on the category axis the note points. */
|
|
80
|
+
x?: string | number;
|
|
81
|
+
/** Where on the value axis the note points. */
|
|
82
|
+
y?: number;
|
|
83
|
+
/** The note itself. One short sentence at most. */
|
|
84
|
+
text: ReactNode;
|
|
85
|
+
/** Draws a dot at the anchor, for when the note sits away from its point. */
|
|
86
|
+
showAnchor?: boolean;
|
|
87
|
+
position?: ComponentProps<typeof Label>['position'];
|
|
88
|
+
referenceDotProps?: ComponentProps<typeof ReferenceDot>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* A note on the plot — what happened here, and why the shape changed.
|
|
92
|
+
*
|
|
93
|
+
* The part of a chart that most often does the actual explaining, and the part
|
|
94
|
+
* almost no component library ships. A reader who is told "deploy freeze"
|
|
95
|
+
* beside the flat stretch does not have to guess, and no amount of axis work
|
|
96
|
+
* substitutes for that sentence.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* <LineChart.Annotation x="Apr" y={280} text="Pricing change" showAnchor />
|
|
100
|
+
*/
|
|
101
|
+
declare function Annotation({ x, y, text, showAnchor, position, referenceDotProps, }: AnnotationProps): react.JSX.Element;
|
|
102
|
+
|
|
103
|
+
export { ANNOTATION_LAYER, Annotation, type AnnotationProps, type AnnotationWeight, ReferenceBand, type ReferenceBandProps, ReferenceLine, type ReferenceLineProps };
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import {
|
|
4
|
+
Label,
|
|
5
|
+
ReferenceArea as RechartsReferenceArea,
|
|
6
|
+
ReferenceDot as RechartsReferenceDot,
|
|
7
|
+
ReferenceLine as RechartsReferenceLine,
|
|
8
|
+
ZIndexLayer
|
|
9
|
+
} from "recharts";
|
|
10
|
+
const ANNOTATION_LAYER = {
|
|
11
|
+
plate: -300,
|
|
12
|
+
band: -200,
|
|
13
|
+
line: 450,
|
|
14
|
+
text: 1500
|
|
15
|
+
};
|
|
16
|
+
const STROKE = {
|
|
17
|
+
// A dashed hairline in the rule colour: present, and clearly not data.
|
|
18
|
+
quiet: { width: 1, dash: "4 4", color: "var(--chart-cursor)" },
|
|
19
|
+
// Solid ink. For the one threshold the chart is actually about.
|
|
20
|
+
firm: { width: 1.5, color: "var(--ink)" }
|
|
21
|
+
};
|
|
22
|
+
function ReferenceLine({
|
|
23
|
+
x,
|
|
24
|
+
y,
|
|
25
|
+
label,
|
|
26
|
+
weight = "quiet",
|
|
27
|
+
labelPosition,
|
|
28
|
+
referenceLineProps
|
|
29
|
+
}) {
|
|
30
|
+
const stroke = STROKE[weight];
|
|
31
|
+
const horizontal = y !== void 0;
|
|
32
|
+
return /* @__PURE__ */ jsx(ZIndexLayer, { zIndex: ANNOTATION_LAYER.line, children: /* @__PURE__ */ jsx(
|
|
33
|
+
RechartsReferenceLine,
|
|
34
|
+
{
|
|
35
|
+
x,
|
|
36
|
+
y,
|
|
37
|
+
stroke: stroke.color,
|
|
38
|
+
strokeWidth: stroke.width,
|
|
39
|
+
strokeDasharray: stroke.dash,
|
|
40
|
+
ifOverflow: "extendDomain",
|
|
41
|
+
...referenceLineProps,
|
|
42
|
+
children: label && /* @__PURE__ */ jsx(
|
|
43
|
+
Label,
|
|
44
|
+
{
|
|
45
|
+
value: label,
|
|
46
|
+
position: labelPosition ?? (horizontal ? "insideTopRight" : "insideTopLeft"),
|
|
47
|
+
className: "fill-(--ink-2) text-[11px]"
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
) });
|
|
52
|
+
}
|
|
53
|
+
function ReferenceBand({ x, y, label, referenceAreaProps }) {
|
|
54
|
+
return /* @__PURE__ */ jsx(ZIndexLayer, { zIndex: ANNOTATION_LAYER.band, children: /* @__PURE__ */ jsx(
|
|
55
|
+
RechartsReferenceArea,
|
|
56
|
+
{
|
|
57
|
+
x1: x?.[0],
|
|
58
|
+
x2: x?.[1],
|
|
59
|
+
y1: y?.[0],
|
|
60
|
+
y2: y?.[1],
|
|
61
|
+
fill: "var(--ink)",
|
|
62
|
+
fillOpacity: "calc(var(--chart-fill) * 0.4)",
|
|
63
|
+
stroke: "none",
|
|
64
|
+
ifOverflow: "extendDomain",
|
|
65
|
+
...referenceAreaProps,
|
|
66
|
+
children: label && /* @__PURE__ */ jsx(Label, { value: label, position: "insideTopLeft", className: "fill-(--ink-3-aa) text-[11px]" })
|
|
67
|
+
}
|
|
68
|
+
) });
|
|
69
|
+
}
|
|
70
|
+
function Annotation({
|
|
71
|
+
x,
|
|
72
|
+
y,
|
|
73
|
+
text,
|
|
74
|
+
showAnchor = false,
|
|
75
|
+
position = "top",
|
|
76
|
+
referenceDotProps
|
|
77
|
+
}) {
|
|
78
|
+
return /* @__PURE__ */ jsx(ZIndexLayer, { zIndex: ANNOTATION_LAYER.text, children: /* @__PURE__ */ jsx(
|
|
79
|
+
RechartsReferenceDot,
|
|
80
|
+
{
|
|
81
|
+
x,
|
|
82
|
+
y,
|
|
83
|
+
r: showAnchor ? 3 : 0,
|
|
84
|
+
fill: showAnchor ? "var(--ink)" : "none",
|
|
85
|
+
stroke: showAnchor ? "var(--chart-surface)" : "none",
|
|
86
|
+
strokeWidth: showAnchor ? 1.5 : 0,
|
|
87
|
+
ifOverflow: "extendDomain",
|
|
88
|
+
...referenceDotProps,
|
|
89
|
+
children: /* @__PURE__ */ jsx(Label, { value: String(text), position, className: "fill-(--ink) text-[11px]" })
|
|
90
|
+
}
|
|
91
|
+
) });
|
|
92
|
+
}
|
|
93
|
+
export {
|
|
94
|
+
ANNOTATION_LAYER,
|
|
95
|
+
Annotation,
|
|
96
|
+
ReferenceBand,
|
|
97
|
+
ReferenceLine
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=annotations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/charts/lib/annotations.tsx"],"sourcesContent":["'use client'\n\nimport type { ComponentProps, ReactNode } from 'react'\nimport {\n Label,\n ReferenceArea as RechartsReferenceArea,\n ReferenceDot as RechartsReferenceDot,\n ReferenceLine as RechartsReferenceLine,\n ZIndexLayer,\n} from 'recharts'\n\n/**\n * Where each annotation sits in the stack, and the numbers are not arbitrary:\n * they are the rule editorial charting settled on, expressed in Recharts' own\n * z-index scale (grid -100, area 100, bar 300, line 400, axis 500, dot 1200).\n *\n * A BAND is context, so it goes behind everything — behind the data AND\n * behind the grid. A band drawn over its own gridlines reads as a second\n * surface rather than as a region of the first.\n *\n * A LINE is a claim about the data — a target, a threshold, a limit — so it\n * goes above the marks. A reference line hidden behind a bar is a reference\n * nobody can check.\n *\n * A TEXT annotation explains both, so it goes above both, and above the\n * hover dot too. It is the last thing drawn because it is the last thing to\n * be occluded.\n *\n * The decorative plate sits below the band, because a plate is not context —\n * it is wallpaper.\n */\nexport const ANNOTATION_LAYER = {\n plate: -300,\n band: -200,\n line: 450,\n text: 1500,\n} as const\n\n/** How much a reference mark insists. */\nexport type AnnotationWeight = 'quiet' | 'firm'\n\nconst STROKE: Record<AnnotationWeight, { width: number; dash?: string; color: string }> = {\n // A dashed hairline in the rule colour: present, and clearly not data.\n quiet: { width: 1, dash: '4 4', color: 'var(--chart-cursor)' },\n // Solid ink. For the one threshold the chart is actually about.\n firm: { width: 1.5, color: 'var(--ink)' },\n}\n\nexport interface ReferenceLineProps {\n /** The value on the category axis. Give exactly one of `x` or `y`. */\n x?: string | number\n /** The value on the value axis. Give exactly one of `x` or `y`. */\n y?: string | number\n /** Printed at the end of the line. Keep it to a couple of words. */\n label?: string\n weight?: AnnotationWeight\n /** Where the label sits. Defaults to the line's far end. */\n labelPosition?: ComponentProps<typeof Label>['position']\n referenceLineProps?: ComponentProps<typeof RechartsReferenceLine>\n}\n\n/**\n * A target, a threshold, a limit, a budget — one number the data is being read\n * against.\n *\n * Worth reaching for more often than it is: most charts that look like they\n * need a second series actually need this. \"Are we above the line\" is a\n * question a reference line answers at a glance and a second series does not.\n *\n * @example\n * <LineChart.ReferenceLine y={250} label=\"Target\" weight=\"firm\" />\n */\nexport function ReferenceLine({\n x,\n y,\n label,\n weight = 'quiet',\n labelPosition,\n referenceLineProps,\n}: ReferenceLineProps) {\n const stroke = STROKE[weight]\n const horizontal = y !== undefined\n\n return (\n <ZIndexLayer zIndex={ANNOTATION_LAYER.line}>\n <RechartsReferenceLine\n x={x}\n y={y}\n stroke={stroke.color}\n strokeWidth={stroke.width}\n strokeDasharray={stroke.dash}\n // Clamped rather than dropped: a target above every value is exactly\n // the case a reader most needs to see, and `ifOverflow=\"discard\"`\n // would silently remove it.\n ifOverflow=\"extendDomain\"\n {...referenceLineProps}\n >\n {label && (\n <Label\n value={label}\n position={labelPosition ?? (horizontal ? 'insideTopRight' : 'insideTopLeft')}\n className=\"fill-(--ink-2) text-[11px]\"\n />\n )}\n </RechartsReferenceLine>\n </ZIndexLayer>\n )\n}\n\nexport interface ReferenceBandProps {\n /** A span on the category axis, as `[from, to]`. */\n x?: [string | number, string | number]\n /** A span on the value axis, as `[from, to]`. */\n y?: [string | number, string | number]\n /** Printed inside the band's top edge. */\n label?: string\n referenceAreaProps?: ComponentProps<typeof RechartsReferenceArea>\n}\n\n/**\n * A region the data is read against — a healthy range, a recession, a period\n * the numbers should not be trusted for.\n *\n * Drawn behind the grid, so it reads as a stretch of the ground rather than as\n * a mark on it. That placement is the whole difference between \"this period\"\n * and \"this value\".\n *\n * @example\n * <AreaChart.ReferenceBand x={['Mar', 'May']} label=\"Migration\" />\n */\nexport function ReferenceBand({ x, y, label, referenceAreaProps }: ReferenceBandProps) {\n return (\n <ZIndexLayer zIndex={ANNOTATION_LAYER.band}>\n <RechartsReferenceArea\n x1={x?.[0]}\n x2={x?.[1]}\n y1={y?.[0]}\n y2={y?.[1]}\n fill=\"var(--ink)\"\n // Deliberately fainter than a data fill: the band is the ground the\n // data is read against, and a ground that competes stops being one.\n fillOpacity=\"calc(var(--chart-fill) * 0.4)\"\n stroke=\"none\"\n ifOverflow=\"extendDomain\"\n {...referenceAreaProps}\n >\n {label && (\n <Label value={label} position=\"insideTopLeft\" className=\"fill-(--ink-3-aa) text-[11px]\" />\n )}\n </RechartsReferenceArea>\n </ZIndexLayer>\n )\n}\n\nexport interface AnnotationProps {\n /** Where on the category axis the note points. */\n x?: string | number\n /** Where on the value axis the note points. */\n y?: number\n /** The note itself. One short sentence at most. */\n text: ReactNode\n /** Draws a dot at the anchor, for when the note sits away from its point. */\n showAnchor?: boolean\n position?: ComponentProps<typeof Label>['position']\n referenceDotProps?: ComponentProps<typeof RechartsReferenceDot>\n}\n\n/**\n * A note on the plot — what happened here, and why the shape changed.\n *\n * The part of a chart that most often does the actual explaining, and the part\n * almost no component library ships. A reader who is told \"deploy freeze\"\n * beside the flat stretch does not have to guess, and no amount of axis work\n * substitutes for that sentence.\n *\n * @example\n * <LineChart.Annotation x=\"Apr\" y={280} text=\"Pricing change\" showAnchor />\n */\nexport function Annotation({\n x,\n y,\n text,\n showAnchor = false,\n position = 'top',\n referenceDotProps,\n}: AnnotationProps) {\n return (\n <ZIndexLayer zIndex={ANNOTATION_LAYER.text}>\n <RechartsReferenceDot\n x={x}\n y={y}\n r={showAnchor ? 3 : 0}\n fill={showAnchor ? 'var(--ink)' : 'none'}\n stroke={showAnchor ? 'var(--chart-surface)' : 'none'}\n strokeWidth={showAnchor ? 1.5 : 0}\n ifOverflow=\"extendDomain\"\n {...referenceDotProps}\n >\n <Label value={String(text)} position={position} className=\"fill-(--ink) text-[11px]\" />\n </RechartsReferenceDot>\n </ZIndexLayer>\n )\n}\n"],"mappings":";AAkGU;AA/FV;AAAA,EACE;AAAA,EACA,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB;AAAA,OACK;AAsBA,MAAM,mBAAmB;AAAA,EAC9B,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AACR;AAKA,MAAM,SAAoF;AAAA;AAAA,EAExF,OAAO,EAAE,OAAO,GAAG,MAAM,OAAO,OAAO,sBAAsB;AAAA;AAAA,EAE7D,MAAM,EAAE,OAAO,KAAK,OAAO,aAAa;AAC1C;AA0BO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AACF,GAAuB;AACrB,QAAM,SAAS,OAAO,MAAM;AAC5B,QAAM,aAAa,MAAM;AAEzB,SACE,oBAAC,eAAY,QAAQ,iBAAiB,MACpC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,QAAQ,OAAO;AAAA,MACf,aAAa,OAAO;AAAA,MACpB,iBAAiB,OAAO;AAAA,MAIxB,YAAW;AAAA,MACV,GAAG;AAAA,MAEH,mBACC;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,UACP,UAAU,kBAAkB,aAAa,mBAAmB;AAAA,UAC5D,WAAU;AAAA;AAAA,MACZ;AAAA;AAAA,EAEJ,GACF;AAEJ;AAuBO,SAAS,cAAc,EAAE,GAAG,GAAG,OAAO,mBAAmB,GAAuB;AACrF,SACE,oBAAC,eAAY,QAAQ,iBAAiB,MACpC;AAAA,IAAC;AAAA;AAAA,MACC,IAAI,IAAI,CAAC;AAAA,MACT,IAAI,IAAI,CAAC;AAAA,MACT,IAAI,IAAI,CAAC;AAAA,MACT,IAAI,IAAI,CAAC;AAAA,MACT,MAAK;AAAA,MAGL,aAAY;AAAA,MACZ,QAAO;AAAA,MACP,YAAW;AAAA,MACV,GAAG;AAAA,MAEH,mBACC,oBAAC,SAAM,OAAO,OAAO,UAAS,iBAAgB,WAAU,iCAAgC;AAAA;AAAA,EAE5F,GACF;AAEJ;AA0BO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb,WAAW;AAAA,EACX;AACF,GAAoB;AAClB,SACE,oBAAC,eAAY,QAAQ,iBAAiB,MACpC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,GAAG,aAAa,IAAI;AAAA,MACpB,MAAM,aAAa,eAAe;AAAA,MAClC,QAAQ,aAAa,yBAAyB;AAAA,MAC9C,aAAa,aAAa,MAAM;AAAA,MAChC,YAAW;AAAA,MACV,GAAG;AAAA,MAEJ,8BAAC,SAAM,OAAO,OAAO,IAAI,GAAG,UAAoB,WAAU,4BAA2B;AAAA;AAAA,EACvF,GACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The name of what an axis measures, drawn beside it.
|
|
5
|
+
*
|
|
6
|
+
* The most-skipped part of a chart and one of the cheapest to get right: an
|
|
7
|
+
* axis reading 0 · 100 · 200 says nothing about whether those are people,
|
|
8
|
+
* milliseconds or dollars, and the reader is left inferring it from the title —
|
|
9
|
+
* if there is one. Every serious charting system has this and most component
|
|
10
|
+
* libraries leave it to the call site.
|
|
11
|
+
*
|
|
12
|
+
* Not always needed, which is why it is a prop rather than a requirement: when
|
|
13
|
+
* the series' own label already carries the unit ("Load time (ms)"), a second
|
|
14
|
+
* copy on the axis is noise. The rule is that the unit appears once.
|
|
15
|
+
*/
|
|
16
|
+
declare function axisLabel(label: string | undefined, axis: 'x' | 'y'): react.JSX.Element | null;
|
|
17
|
+
|
|
18
|
+
export { axisLabel };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Label } from "recharts";
|
|
4
|
+
function axisLabel(label, axis) {
|
|
5
|
+
if (!label) return null;
|
|
6
|
+
return /* @__PURE__ */ jsx(
|
|
7
|
+
Label,
|
|
8
|
+
{
|
|
9
|
+
value: label,
|
|
10
|
+
angle: axis === "y" ? -90 : 0,
|
|
11
|
+
position: axis === "y" ? "insideLeft" : "insideBottom",
|
|
12
|
+
offset: axis === "y" ? 0 : -2,
|
|
13
|
+
className: "fill-(--chart-axis) text-[11px]",
|
|
14
|
+
style: { textAnchor: "middle" }
|
|
15
|
+
}
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
export {
|
|
19
|
+
axisLabel
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=axis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/charts/lib/axis.tsx"],"sourcesContent":["'use client'\n\nimport { Label } from 'recharts'\n\n/**\n * The name of what an axis measures, drawn beside it.\n *\n * The most-skipped part of a chart and one of the cheapest to get right: an\n * axis reading 0 · 100 · 200 says nothing about whether those are people,\n * milliseconds or dollars, and the reader is left inferring it from the title —\n * if there is one. Every serious charting system has this and most component\n * libraries leave it to the call site.\n *\n * Not always needed, which is why it is a prop rather than a requirement: when\n * the series' own label already carries the unit (\"Load time (ms)\"), a second\n * copy on the axis is noise. The rule is that the unit appears once.\n */\nexport function axisLabel(label: string | undefined, axis: 'x' | 'y') {\n if (!label) return null\n\n return (\n <Label\n value={label}\n // The vertical axis reads bottom-to-top, which is the convention every\n // print and screen tradition shares — and the only orientation that does\n // not force the reader to tilt their head the wrong way.\n angle={axis === 'y' ? -90 : 0}\n position={axis === 'y' ? 'insideLeft' : 'insideBottom'}\n offset={axis === 'y' ? 0 : -2}\n className=\"fill-(--chart-axis) text-[11px]\"\n style={{ textAnchor: 'middle' }}\n />\n )\n}\n"],"mappings":";AAqBI;AAnBJ,SAAS,aAAa;AAef,SAAS,UAAU,OAA2B,MAAiB;AACpE,MAAI,CAAC,MAAO,QAAO;AAEnB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,MAIP,OAAO,SAAS,MAAM,MAAM;AAAA,MAC5B,UAAU,SAAS,MAAM,eAAe;AAAA,MACxC,QAAQ,SAAS,MAAM,IAAI;AAAA,MAC3B,WAAU;AAAA,MACV,OAAO,EAAE,YAAY,SAAS;AAAA;AAAA,EAChC;AAEJ;","names":[]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The decorative plate behind a plot.
|
|
5
|
+
*
|
|
6
|
+
* Eleven, and the count is the point: with hue spent, a chart's personality has
|
|
7
|
+
* to come from somewhere, and a plate is the one place texture can be loud
|
|
8
|
+
* without competing with the marks — it sits behind them, at a fraction of the
|
|
9
|
+
* rule's weight, under a mask that dissolves it before it reaches an axis.
|
|
10
|
+
*
|
|
11
|
+
* To add one: extend this union, write the `<pattern>`, register it in
|
|
12
|
+
* `PATTERNS`. The union is what makes a missing registration a type error.
|
|
13
|
+
*/
|
|
14
|
+
type ChartBackgroundVariant = 'dots' | 'grid' | 'cross-hatch' | 'diagonal-lines' | 'plus' | 'falling-triangles' | '4-pointed-star' | 'tiny-checkers' | 'overlapping-circles' | 'wiggle-lines' | 'bubbles';
|
|
15
|
+
interface ChartBackgroundProps {
|
|
16
|
+
variant: ChartBackgroundVariant;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Renders the plate under the plot. Compose it inside any cartesian chart:
|
|
20
|
+
* `<LineChart.Background variant="dots" />`.
|
|
21
|
+
*
|
|
22
|
+
* `ZIndexLayer` at -1 is what keeps it behind the marks — SVG paints in
|
|
23
|
+
* document order, so without it the plate would depend on where the consumer
|
|
24
|
+
* happened to write the element.
|
|
25
|
+
*
|
|
26
|
+
* The plate is masked by a blurred inset rectangle, which is why it fades out
|
|
27
|
+
* before it reaches the axes instead of stopping at a hard edge against them.
|
|
28
|
+
* The blur is on a MASK, not on the artwork: nothing in the system draws a
|
|
29
|
+
* blurred mark.
|
|
30
|
+
*/
|
|
31
|
+
declare function ChartBackground({ variant }: ChartBackgroundProps): react.JSX.Element | null;
|
|
32
|
+
|
|
33
|
+
export { ChartBackground, type ChartBackgroundProps, type ChartBackgroundVariant };
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useId } from "react";
|
|
4
|
+
import { ZIndexLayer, usePlotArea } from "recharts";
|
|
5
|
+
const Dots = ({ id }) => /* @__PURE__ */ jsx("pattern", { id, x: "0", y: "0", width: "20", height: "20", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx("circle", { cx: "2", cy: "2", r: "1", fill: "currentColor" }) });
|
|
6
|
+
const Grid = ({ id }) => /* @__PURE__ */ jsx("pattern", { id, x: "0", y: "0", width: "20", height: "20", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx("path", { d: "M 20 0 L 0 0 0 20", fill: "none", stroke: "currentColor", strokeWidth: "0.5" }) });
|
|
7
|
+
const CrossHatch = ({ id }) => /* @__PURE__ */ jsx("pattern", { id, x: "0", y: "0", width: "20", height: "20", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx(
|
|
8
|
+
"path",
|
|
9
|
+
{
|
|
10
|
+
d: "M 0 0 L 20 20 M 20 0 L 0 20",
|
|
11
|
+
fill: "none",
|
|
12
|
+
stroke: "currentColor",
|
|
13
|
+
strokeOpacity: "0.6",
|
|
14
|
+
strokeWidth: "0.5"
|
|
15
|
+
}
|
|
16
|
+
) });
|
|
17
|
+
const DiagonalLines = ({ id }) => /* @__PURE__ */ jsx(
|
|
18
|
+
"pattern",
|
|
19
|
+
{
|
|
20
|
+
id,
|
|
21
|
+
x: "0",
|
|
22
|
+
y: "0",
|
|
23
|
+
width: "6",
|
|
24
|
+
height: "6",
|
|
25
|
+
patternUnits: "userSpaceOnUse",
|
|
26
|
+
patternTransform: "rotate(45)",
|
|
27
|
+
children: /* @__PURE__ */ jsx("line", { x1: "0", y1: "0", x2: "0", y2: "6", stroke: "currentColor", strokeWidth: "0.5" })
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
const Plus = ({ id }) => /* @__PURE__ */ jsx("pattern", { id, x: "0", y: "0", width: "16", height: "16", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx(
|
|
31
|
+
"path",
|
|
32
|
+
{
|
|
33
|
+
d: "M 8 4 L 8 12 M 4 8 L 12 8",
|
|
34
|
+
fill: "none",
|
|
35
|
+
stroke: "currentColor",
|
|
36
|
+
strokeWidth: "0.5",
|
|
37
|
+
strokeLinecap: "round"
|
|
38
|
+
}
|
|
39
|
+
) });
|
|
40
|
+
const FallingTriangles = ({ id }) => /* @__PURE__ */ jsx("pattern", { id, x: "0", y: "0", width: "18", height: "36", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx(
|
|
41
|
+
"path",
|
|
42
|
+
{
|
|
43
|
+
d: "M2 6h12L8 18 2 6zm18 36h12l-6 12-6-12z",
|
|
44
|
+
transform: "scale(0.5)",
|
|
45
|
+
fill: "currentColor",
|
|
46
|
+
fillOpacity: "0.4"
|
|
47
|
+
}
|
|
48
|
+
) });
|
|
49
|
+
const FourPointedStar = ({ id }) => /* @__PURE__ */ jsx("pattern", { id, x: "0", y: "0", width: "16", height: "16", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx(
|
|
50
|
+
"polygon",
|
|
51
|
+
{
|
|
52
|
+
fillRule: "evenodd",
|
|
53
|
+
points: "5 3 8 4 5 5 4 8 3 5 0 4 3 3 4 0 5 3",
|
|
54
|
+
fill: "currentColor",
|
|
55
|
+
fillOpacity: "0.4"
|
|
56
|
+
}
|
|
57
|
+
) });
|
|
58
|
+
const TinyCheckers = ({ id }) => /* @__PURE__ */ jsx("pattern", { id, x: "0", y: "0", width: "8", height: "8", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx(
|
|
59
|
+
"path",
|
|
60
|
+
{
|
|
61
|
+
fillRule: "evenodd",
|
|
62
|
+
d: "M0 0h4v4H0V0zm4 4h4v4H4V4z",
|
|
63
|
+
fill: "currentColor",
|
|
64
|
+
fillOpacity: "0.2"
|
|
65
|
+
}
|
|
66
|
+
) });
|
|
67
|
+
const OverlappingCircles = ({ id }) => /* @__PURE__ */ jsx("pattern", { id, x: "0", y: "0", width: "40", height: "40", patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx(
|
|
68
|
+
"path",
|
|
69
|
+
{
|
|
70
|
+
fillRule: "evenodd",
|
|
71
|
+
d: "M25 25c0-2.762 2.238-5 5-5s5 2.238 5 5-2.238 5-5 5c0 2.762-2.238 5-5 5s-5-2.238-5-5 2.238-5 5-5zM5 5c0-2.762 2.238-5 5-5s5 2.238 5 5-2.238 5-5 5c0 2.762-2.238 5-5 5S0 12.762 0 10s2.238-5 5-5zm5 4c2.209 0 4-1.791 4-4s-1.791-4-4-4-4 1.791-4 4 1.791 4 4 4zm20 20c2.209 0 4-1.791 4-4s-1.791-4-4-4-4 1.791-4 4 1.791 4 4 4z",
|
|
72
|
+
fill: "currentColor",
|
|
73
|
+
fillOpacity: "0.4"
|
|
74
|
+
}
|
|
75
|
+
) });
|
|
76
|
+
const WiggleLines = ({ id }) => /* @__PURE__ */ jsx(
|
|
77
|
+
"pattern",
|
|
78
|
+
{
|
|
79
|
+
id,
|
|
80
|
+
x: "0",
|
|
81
|
+
y: "0",
|
|
82
|
+
width: "52",
|
|
83
|
+
height: "26",
|
|
84
|
+
patternUnits: "userSpaceOnUse",
|
|
85
|
+
patternTransform: "scale(0.6)",
|
|
86
|
+
children: /* @__PURE__ */ jsx(
|
|
87
|
+
"path",
|
|
88
|
+
{
|
|
89
|
+
d: "M10 10c0-2.21-1.79-4-4-4-3.314 0-6-2.686-6-6h2c0 2.21 1.79 4 4 4 3.314 0 6 2.686 6 6 0 2.21 1.79 4 4 4 3.314 0 6 2.686 6 6 0 2.21 1.79 4 4 4v2c-3.314 0-6-2.686-6-6 0-2.21-1.79-4-4-4-3.314 0-6-2.686-6-6zm25.464-1.95l8.486 8.486-1.414 1.414-8.486-8.486 1.414-1.414z",
|
|
90
|
+
fill: "currentColor",
|
|
91
|
+
fillOpacity: "0.4"
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
const Bubbles = ({ id }) => /* @__PURE__ */ jsx(
|
|
97
|
+
"pattern",
|
|
98
|
+
{
|
|
99
|
+
id,
|
|
100
|
+
x: "0",
|
|
101
|
+
y: "0",
|
|
102
|
+
width: "100",
|
|
103
|
+
height: "100",
|
|
104
|
+
patternUnits: "userSpaceOnUse",
|
|
105
|
+
patternTransform: "scale(0.6667)",
|
|
106
|
+
children: /* @__PURE__ */ jsx(
|
|
107
|
+
"path",
|
|
108
|
+
{
|
|
109
|
+
d: "M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z",
|
|
110
|
+
fill: "currentColor",
|
|
111
|
+
fillOpacity: "0.4",
|
|
112
|
+
fillRule: "evenodd"
|
|
113
|
+
}
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
const PATTERNS = {
|
|
118
|
+
dots: Dots,
|
|
119
|
+
grid: Grid,
|
|
120
|
+
plus: Plus,
|
|
121
|
+
bubbles: Bubbles,
|
|
122
|
+
"cross-hatch": CrossHatch,
|
|
123
|
+
"diagonal-lines": DiagonalLines,
|
|
124
|
+
"falling-triangles": FallingTriangles,
|
|
125
|
+
"4-pointed-star": FourPointedStar,
|
|
126
|
+
"tiny-checkers": TinyCheckers,
|
|
127
|
+
"overlapping-circles": OverlappingCircles,
|
|
128
|
+
"wiggle-lines": WiggleLines
|
|
129
|
+
};
|
|
130
|
+
function ChartBackground({ variant }) {
|
|
131
|
+
const base = useId().replace(/:/g, "");
|
|
132
|
+
const patternId = `${base}-bg-${variant}`;
|
|
133
|
+
const maskId = `${base}-bg-fade`;
|
|
134
|
+
const blurId = `${base}-bg-blur`;
|
|
135
|
+
const Pattern = PATTERNS[variant];
|
|
136
|
+
const plot = usePlotArea();
|
|
137
|
+
if (!plot || plot.width <= 0 || plot.height <= 0) return null;
|
|
138
|
+
const inset = Math.min(plot.width, plot.height) * 0.06;
|
|
139
|
+
const blur = Math.max(8, Math.min(plot.width, plot.height) * 0.08);
|
|
140
|
+
return /* @__PURE__ */ jsxs(ZIndexLayer, { zIndex: -1, children: [
|
|
141
|
+
/* @__PURE__ */ jsxs("defs", { children: [
|
|
142
|
+
/* @__PURE__ */ jsx(Pattern, { id: patternId }),
|
|
143
|
+
/* @__PURE__ */ jsx("filter", { id: blurId, children: /* @__PURE__ */ jsx("feGaussianBlur", { stdDeviation: blur }) }),
|
|
144
|
+
/* @__PURE__ */ jsx("mask", { id: maskId, maskUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx(
|
|
145
|
+
"rect",
|
|
146
|
+
{
|
|
147
|
+
x: plot.x + inset,
|
|
148
|
+
y: plot.y + inset,
|
|
149
|
+
width: Math.max(0, plot.width - inset * 2),
|
|
150
|
+
height: Math.max(0, plot.height - inset * 2),
|
|
151
|
+
fill: "white",
|
|
152
|
+
filter: `url(#${blurId})`
|
|
153
|
+
}
|
|
154
|
+
) })
|
|
155
|
+
] }),
|
|
156
|
+
/* @__PURE__ */ jsx(
|
|
157
|
+
"rect",
|
|
158
|
+
{
|
|
159
|
+
className: "text-(--chart-pattern)",
|
|
160
|
+
x: plot.x,
|
|
161
|
+
y: plot.y,
|
|
162
|
+
width: plot.width,
|
|
163
|
+
height: plot.height,
|
|
164
|
+
fill: `url(#${patternId})`,
|
|
165
|
+
mask: `url(#${maskId})`
|
|
166
|
+
}
|
|
167
|
+
)
|
|
168
|
+
] });
|
|
169
|
+
}
|
|
170
|
+
export {
|
|
171
|
+
ChartBackground
|
|
172
|
+
};
|
|
173
|
+
//# sourceMappingURL=background.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/charts/lib/background.tsx"],"sourcesContent":["'use client'\n\nimport { useId, type FC } from 'react'\nimport { ZIndexLayer, usePlotArea } from 'recharts'\n\n/**\n * The decorative plate behind a plot.\n *\n * Eleven, and the count is the point: with hue spent, a chart's personality has\n * to come from somewhere, and a plate is the one place texture can be loud\n * without competing with the marks — it sits behind them, at a fraction of the\n * rule's weight, under a mask that dissolves it before it reaches an axis.\n *\n * To add one: extend this union, write the `<pattern>`, register it in\n * `PATTERNS`. The union is what makes a missing registration a type error.\n */\nexport type ChartBackgroundVariant =\n | 'dots'\n | 'grid'\n | 'cross-hatch'\n | 'diagonal-lines'\n | 'plus'\n | 'falling-triangles'\n | '4-pointed-star'\n | 'tiny-checkers'\n | 'overlapping-circles'\n | 'wiggle-lines'\n | 'bubbles'\n\ninterface PatternProps {\n id: string\n}\n\n/** Every pattern paints in `currentColor`, which the layer sets to the token. */\nconst Dots: FC<PatternProps> = ({ id }) => (\n <pattern id={id} x=\"0\" y=\"0\" width=\"20\" height=\"20\" patternUnits=\"userSpaceOnUse\">\n <circle cx=\"2\" cy=\"2\" r=\"1\" fill=\"currentColor\" />\n </pattern>\n)\n\nconst Grid: FC<PatternProps> = ({ id }) => (\n <pattern id={id} x=\"0\" y=\"0\" width=\"20\" height=\"20\" patternUnits=\"userSpaceOnUse\">\n <path d=\"M 20 0 L 0 0 0 20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n </pattern>\n)\n\nconst CrossHatch: FC<PatternProps> = ({ id }) => (\n <pattern id={id} x=\"0\" y=\"0\" width=\"20\" height=\"20\" patternUnits=\"userSpaceOnUse\">\n <path\n d=\"M 0 0 L 20 20 M 20 0 L 0 20\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeOpacity=\"0.6\"\n strokeWidth=\"0.5\"\n />\n </pattern>\n)\n\nconst DiagonalLines: FC<PatternProps> = ({ id }) => (\n <pattern\n id={id}\n x=\"0\"\n y=\"0\"\n width=\"6\"\n height=\"6\"\n patternUnits=\"userSpaceOnUse\"\n patternTransform=\"rotate(45)\"\n >\n <line x1=\"0\" y1=\"0\" x2=\"0\" y2=\"6\" stroke=\"currentColor\" strokeWidth=\"0.5\" />\n </pattern>\n)\n\nconst Plus: FC<PatternProps> = ({ id }) => (\n <pattern id={id} x=\"0\" y=\"0\" width=\"16\" height=\"16\" patternUnits=\"userSpaceOnUse\">\n <path\n d=\"M 8 4 L 8 12 M 4 8 L 12 8\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"0.5\"\n strokeLinecap=\"round\"\n />\n </pattern>\n)\n\nconst FallingTriangles: FC<PatternProps> = ({ id }) => (\n <pattern id={id} x=\"0\" y=\"0\" width=\"18\" height=\"36\" patternUnits=\"userSpaceOnUse\">\n <path\n d=\"M2 6h12L8 18 2 6zm18 36h12l-6 12-6-12z\"\n transform=\"scale(0.5)\"\n fill=\"currentColor\"\n fillOpacity=\"0.4\"\n />\n </pattern>\n)\n\nconst FourPointedStar: FC<PatternProps> = ({ id }) => (\n <pattern id={id} x=\"0\" y=\"0\" width=\"16\" height=\"16\" patternUnits=\"userSpaceOnUse\">\n <polygon\n fillRule=\"evenodd\"\n points=\"5 3 8 4 5 5 4 8 3 5 0 4 3 3 4 0 5 3\"\n fill=\"currentColor\"\n fillOpacity=\"0.4\"\n />\n </pattern>\n)\n\nconst TinyCheckers: FC<PatternProps> = ({ id }) => (\n <pattern id={id} x=\"0\" y=\"0\" width=\"8\" height=\"8\" patternUnits=\"userSpaceOnUse\">\n <path\n fillRule=\"evenodd\"\n d=\"M0 0h4v4H0V0zm4 4h4v4H4V4z\"\n fill=\"currentColor\"\n fillOpacity=\"0.2\"\n />\n </pattern>\n)\n\nconst OverlappingCircles: FC<PatternProps> = ({ id }) => (\n <pattern id={id} x=\"0\" y=\"0\" width=\"40\" height=\"40\" patternUnits=\"userSpaceOnUse\">\n <path\n fillRule=\"evenodd\"\n d=\"M25 25c0-2.762 2.238-5 5-5s5 2.238 5 5-2.238 5-5 5c0 2.762-2.238 5-5 5s-5-2.238-5-5 2.238-5 5-5zM5 5c0-2.762 2.238-5 5-5s5 2.238 5 5-2.238 5-5 5c0 2.762-2.238 5-5 5S0 12.762 0 10s2.238-5 5-5zm5 4c2.209 0 4-1.791 4-4s-1.791-4-4-4-4 1.791-4 4 1.791 4 4 4zm20 20c2.209 0 4-1.791 4-4s-1.791-4-4-4-4 1.791-4 4 1.791 4 4 4z\"\n fill=\"currentColor\"\n fillOpacity=\"0.4\"\n />\n </pattern>\n)\n\nconst WiggleLines: FC<PatternProps> = ({ id }) => (\n <pattern\n id={id}\n x=\"0\"\n y=\"0\"\n width=\"52\"\n height=\"26\"\n patternUnits=\"userSpaceOnUse\"\n patternTransform=\"scale(0.6)\"\n >\n <path\n d=\"M10 10c0-2.21-1.79-4-4-4-3.314 0-6-2.686-6-6h2c0 2.21 1.79 4 4 4 3.314 0 6 2.686 6 6 0 2.21 1.79 4 4 4 3.314 0 6 2.686 6 6 0 2.21 1.79 4 4 4v2c-3.314 0-6-2.686-6-6 0-2.21-1.79-4-4-4-3.314 0-6-2.686-6-6zm25.464-1.95l8.486 8.486-1.414 1.414-8.486-8.486 1.414-1.414z\"\n fill=\"currentColor\"\n fillOpacity=\"0.4\"\n />\n </pattern>\n)\n\nconst Bubbles: FC<PatternProps> = ({ id }) => (\n <pattern\n id={id}\n x=\"0\"\n y=\"0\"\n width=\"100\"\n height=\"100\"\n patternUnits=\"userSpaceOnUse\"\n patternTransform=\"scale(0.6667)\"\n >\n <path\n d=\"M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z\"\n fill=\"currentColor\"\n fillOpacity=\"0.4\"\n fillRule=\"evenodd\"\n />\n </pattern>\n)\n\nconst PATTERNS: Record<ChartBackgroundVariant, FC<PatternProps>> = {\n dots: Dots,\n grid: Grid,\n plus: Plus,\n bubbles: Bubbles,\n 'cross-hatch': CrossHatch,\n 'diagonal-lines': DiagonalLines,\n 'falling-triangles': FallingTriangles,\n '4-pointed-star': FourPointedStar,\n 'tiny-checkers': TinyCheckers,\n 'overlapping-circles': OverlappingCircles,\n 'wiggle-lines': WiggleLines,\n}\n\nexport interface ChartBackgroundProps {\n variant: ChartBackgroundVariant\n}\n\n/**\n * Renders the plate under the plot. Compose it inside any cartesian chart:\n * `<LineChart.Background variant=\"dots\" />`.\n *\n * `ZIndexLayer` at -1 is what keeps it behind the marks — SVG paints in\n * document order, so without it the plate would depend on where the consumer\n * happened to write the element.\n *\n * The plate is masked by a blurred inset rectangle, which is why it fades out\n * before it reaches the axes instead of stopping at a hard edge against them.\n * The blur is on a MASK, not on the artwork: nothing in the system draws a\n * blurred mark.\n */\nexport function ChartBackground({ variant }: ChartBackgroundProps) {\n const base = useId().replace(/:/g, '')\n const patternId = `${base}-bg-${variant}`\n const maskId = `${base}-bg-fade`\n const blurId = `${base}-bg-blur`\n const Pattern = PATTERNS[variant]\n const plot = usePlotArea()\n\n // Nothing to sit behind until the chart has measured itself.\n if (!plot || plot.width <= 0 || plot.height <= 0) return null\n\n // The plate is drawn to the PLOT rectangle, not to the whole SVG.\n //\n // Recharts puts the axes inside the same `<svg>`, so a plate sized to the\n // surface runs underneath the tick labels — which is how a row of month names\n // ended up sitting on a field of dots with nothing between them. Bounding it\n // to the plot means the pattern stops where the data stops, whatever the axis\n // ends up needing.\n const inset = Math.min(plot.width, plot.height) * 0.06\n const blur = Math.max(8, Math.min(plot.width, plot.height) * 0.08)\n\n return (\n <ZIndexLayer zIndex={-1}>\n <defs>\n <Pattern id={patternId} />\n <filter id={blurId}>\n <feGaussianBlur stdDeviation={blur} />\n </filter>\n {/* A blurred inset rectangle, so the plate dissolves before it reaches\n the plot's own edges rather than stopping against them. The blur is\n on the MASK; nothing in the system draws a blurred mark. */}\n <mask id={maskId} maskUnits=\"userSpaceOnUse\">\n <rect\n x={plot.x + inset}\n y={plot.y + inset}\n width={Math.max(0, plot.width - inset * 2)}\n height={Math.max(0, plot.height - inset * 2)}\n fill=\"white\"\n filter={`url(#${blurId})`}\n />\n </mask>\n </defs>\n <rect\n className=\"text-(--chart-pattern)\"\n x={plot.x}\n y={plot.y}\n width={plot.width}\n height={plot.height}\n fill={`url(#${patternId})`}\n mask={`url(#${maskId})`}\n />\n </ZIndexLayer>\n )\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { FC, ComponentProps } from 'react';
|
|
3
|
+
import { Area } from 'recharts';
|
|
4
|
+
import { ChartConfig } from './chart.js';
|
|
5
|
+
|
|
6
|
+
/** The slice of the data a brush has selected, as row indexes. */
|
|
7
|
+
interface ChartBrushRange {
|
|
8
|
+
startIndex: number;
|
|
9
|
+
endIndex: number;
|
|
10
|
+
}
|
|
11
|
+
/** Which mark the miniature strip is drawn with. */
|
|
12
|
+
type ChartBrushVariant = 'line' | 'area' | 'bar';
|
|
13
|
+
interface BrushProps {
|
|
14
|
+
/** Strip height in pixels. */
|
|
15
|
+
height?: number;
|
|
16
|
+
/** Turns a row's x value into a handle label. */
|
|
17
|
+
formatLabel?: (value: unknown, index: number) => string;
|
|
18
|
+
onChange?: (range: ChartBrushRange) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Declares the zoom brush under a chart.
|
|
22
|
+
*
|
|
23
|
+
* Renders nothing itself — its PRESENCE among the chart's children turns the
|
|
24
|
+
* footer on, and its props configure it. A marker rather than a `showBrush`
|
|
25
|
+
* prop because the brush is composed like every other part, so a consumer does
|
|
26
|
+
* not have to remember which knobs are children and which are props.
|
|
27
|
+
*/
|
|
28
|
+
declare const Brush: FC<BrushProps>;
|
|
29
|
+
interface ChartBrushProps {
|
|
30
|
+
/** The whole dataset. The strip always draws all of it. */
|
|
31
|
+
data: Record<string, unknown>[];
|
|
32
|
+
config: ChartConfig;
|
|
33
|
+
/** Which series the strip draws. Defaults to every key in the config. */
|
|
34
|
+
dataKeys?: string[];
|
|
35
|
+
/** The row field behind a handle's label. */
|
|
36
|
+
xDataKey?: string;
|
|
37
|
+
variant?: ChartBrushVariant;
|
|
38
|
+
height?: number;
|
|
39
|
+
className?: string;
|
|
40
|
+
stacked?: boolean;
|
|
41
|
+
strokeVariant?: 'solid' | 'dashed';
|
|
42
|
+
connectNulls?: boolean;
|
|
43
|
+
barRadius?: number;
|
|
44
|
+
startIndex?: number;
|
|
45
|
+
endIndex?: number;
|
|
46
|
+
defaultStartIndex?: number;
|
|
47
|
+
defaultEndIndex?: number;
|
|
48
|
+
onChange?: (range: ChartBrushRange) => void;
|
|
49
|
+
formatLabel?: (value: unknown, index: number) => string;
|
|
50
|
+
curveType?: ComponentProps<typeof Area>['type'];
|
|
51
|
+
/** The fewest rows that may stay selected. */
|
|
52
|
+
minSpan?: number;
|
|
53
|
+
showLabels?: boolean;
|
|
54
|
+
/** Names the control for a screen reader. */
|
|
55
|
+
label?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The range selector under a chart: a miniature of the whole series, with a lit
|
|
59
|
+
* window over the part the chart above is showing.
|
|
60
|
+
*
|
|
61
|
+
* Both handles are real `slider` controls — focusable, arrow-key driven, with
|
|
62
|
+
* `aria-valuetext` reading out the row they sit on. The shape this was ported
|
|
63
|
+
* from was pointer-only, which made zooming a chart something a keyboard user
|
|
64
|
+
* could watch but not do.
|
|
65
|
+
*
|
|
66
|
+
* Position is written as inline style rather than as `start-`/`end-` classes on
|
|
67
|
+
* purpose. The strip's axis is the DATA's, and Recharts lays a cartesian plot
|
|
68
|
+
* out left-to-right in every writing direction — so mirroring the handles under
|
|
69
|
+
* `dir="rtl"` would put the "earlier" handle at the end of a chart that still
|
|
70
|
+
* runs the other way.
|
|
71
|
+
*/
|
|
72
|
+
declare function ChartBrush({ data, config, dataKeys, xDataKey, variant, height, className, stacked, strokeVariant, connectNulls, barRadius, startIndex: controlledStart, endIndex: controlledEnd, defaultStartIndex, defaultEndIndex, onChange, formatLabel, curveType, minSpan, showLabels, label, }: ChartBrushProps): react.JSX.Element | null;
|
|
73
|
+
/**
|
|
74
|
+
* Holds the brush's range and hands back the rows the chart above should draw.
|
|
75
|
+
*
|
|
76
|
+
* The slicing runs on a deferred copy of the range: the handles move at pointer
|
|
77
|
+
* cadence while the chart re-renders at whatever cadence it can manage, which
|
|
78
|
+
* is what keeps a drag smooth over a few thousand rows.
|
|
79
|
+
*/
|
|
80
|
+
declare function useChartBrush<TData extends Record<string, unknown>>({ data, defaultStartIndex, defaultEndIndex, }: {
|
|
81
|
+
data: TData[];
|
|
82
|
+
defaultStartIndex?: number;
|
|
83
|
+
defaultEndIndex?: number;
|
|
84
|
+
}): {
|
|
85
|
+
range: ChartBrushRange;
|
|
86
|
+
visibleData: TData[];
|
|
87
|
+
brushProps: {
|
|
88
|
+
startIndex: number;
|
|
89
|
+
endIndex: number;
|
|
90
|
+
onChange: react.Dispatch<react.SetStateAction<ChartBrushRange>>;
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
export { Brush, type BrushProps, ChartBrush, type ChartBrushProps, type ChartBrushRange, type ChartBrushVariant, useChartBrush };
|