@kind-ui/charts 0.1.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/CHANGELOG.md +20 -0
- package/LICENSE +21 -0
- package/README.md +966 -0
- package/dist/activity-rings.d.ts +47 -0
- package/dist/activity-rings.js +55 -0
- package/dist/animation.d.ts +27 -0
- package/dist/animation.js +102 -0
- package/dist/area-chart.d.ts +9 -0
- package/dist/area-chart.js +33 -0
- package/dist/area-clay.d.ts +2 -0
- package/dist/area-clay.js +6 -0
- package/dist/area-material.d.ts +8 -0
- package/dist/area-material.js +66 -0
- package/dist/area-series.d.ts +11 -0
- package/dist/area-series.js +34 -0
- package/dist/bar-category.d.ts +5 -0
- package/dist/bar-category.js +35 -0
- package/dist/bar-chart.d.ts +17 -0
- package/dist/bar-chart.js +42 -0
- package/dist/bar-clay.d.ts +4 -0
- package/dist/bar-clay.js +6 -0
- package/dist/bar-material.d.ts +8 -0
- package/dist/bar-material.js +19 -0
- package/dist/bar-paper.d.ts +2 -0
- package/dist/bar-paper.js +6 -0
- package/dist/bar-series.d.ts +13 -0
- package/dist/bar-series.js +178 -0
- package/dist/box-material.d.ts +14 -0
- package/dist/box-material.js +30 -0
- package/dist/box-plot.d.ts +50 -0
- package/dist/box-plot.js +218 -0
- package/dist/category-cells.d.ts +6 -0
- package/dist/category-cells.js +41 -0
- package/dist/chart-context.d.ts +11 -0
- package/dist/chart-context.js +9 -0
- package/dist/combo-chart.d.ts +16 -0
- package/dist/combo-chart.js +64 -0
- package/dist/configured-line-chart.d.ts +79 -0
- package/dist/configured-line-chart.js +77 -0
- package/dist/emphasis.d.ts +44 -0
- package/dist/emphasis.js +128 -0
- package/dist/heatmap-model.d.ts +38 -0
- package/dist/heatmap-model.js +73 -0
- package/dist/heatmap.d.ts +56 -0
- package/dist/heatmap.js +366 -0
- package/dist/histogram-chart.d.ts +14 -0
- package/dist/histogram-chart.js +27 -0
- package/dist/histogram-data.d.ts +17 -0
- package/dist/histogram-data.js +66 -0
- package/dist/histogram-material.d.ts +13 -0
- package/dist/histogram-material.js +8 -0
- package/dist/histogram-series.d.ts +16 -0
- package/dist/histogram-series.js +67 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +36 -0
- package/dist/legend.d.ts +16 -0
- package/dist/legend.js +30 -0
- package/dist/line-chart.d.ts +41 -0
- package/dist/line-chart.js +160 -0
- package/dist/line-material.d.ts +9 -0
- package/dist/line-material.js +24 -0
- package/dist/line-series.d.ts +15 -0
- package/dist/line-series.js +40 -0
- package/dist/pie-chart.d.ts +17 -0
- package/dist/pie-chart.js +68 -0
- package/dist/pie-material.d.ts +19 -0
- package/dist/pie-material.js +16 -0
- package/dist/pie-series.d.ts +14 -0
- package/dist/pie-series.js +208 -0
- package/dist/polar-chart.d.ts +33 -0
- package/dist/polar-chart.js +145 -0
- package/dist/polar-material.d.ts +7 -0
- package/dist/polar-material.js +9 -0
- package/dist/polar-series.d.ts +17 -0
- package/dist/polar-series.js +169 -0
- package/dist/radar-interaction.d.ts +29 -0
- package/dist/radar-interaction.js +138 -0
- package/dist/radial-bar-label.d.ts +15 -0
- package/dist/radial-bar-label.js +136 -0
- package/dist/radial-category.d.ts +4 -0
- package/dist/radial-category.js +4 -0
- package/dist/root.d.ts +14 -0
- package/dist/root.js +29 -0
- package/dist/sankey-chart.d.ts +33 -0
- package/dist/sankey-chart.js +142 -0
- package/dist/sankey-colors.d.ts +10 -0
- package/dist/sankey-colors.js +6 -0
- package/dist/sankey-data.d.ts +30 -0
- package/dist/sankey-data.js +65 -0
- package/dist/sankey-finish.d.ts +13 -0
- package/dist/sankey-finish.js +10 -0
- package/dist/sankey-legend.d.ts +14 -0
- package/dist/sankey-legend.js +9 -0
- package/dist/sankey-marks.d.ts +31 -0
- package/dist/sankey-marks.js +67 -0
- package/dist/sankey-table.d.ts +11 -0
- package/dist/sankey-table.js +8 -0
- package/dist/scatter-chart.d.ts +16 -0
- package/dist/scatter-chart.js +64 -0
- package/dist/scatter-material.d.ts +8 -0
- package/dist/scatter-material.js +39 -0
- package/dist/scatter-series.d.ts +11 -0
- package/dist/scatter-series.js +74 -0
- package/dist/scatter-tooltip.d.ts +24 -0
- package/dist/scatter-tooltip.js +96 -0
- package/dist/styles.css +443 -0
- package/dist/surface-material.d.ts +13 -0
- package/dist/surface-material.js +7 -0
- package/dist/tooltip-content.d.ts +19 -0
- package/dist/tooltip-content.js +60 -0
- package/dist/tooltip-number.d.ts +4 -0
- package/dist/tooltip-number.js +68 -0
- package/dist/tooltip.d.ts +29 -0
- package/dist/tooltip.js +73 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.js +1 -0
- package/dist/waterfall-data.d.ts +24 -0
- package/dist/waterfall-data.js +45 -0
- package/dist/waterfall-series.d.ts +15 -0
- package/dist/waterfall-series.js +35 -0
- package/package.json +49 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export { type ActiveDotProps, AreaRevealShape, type AreaRevealShapeProps, type AxisDomainItem, type BarShapeProps, BarStack, type BarStackProps, Brush, type BrushProps, CartesianGrid, type CartesianGridProps, Cell, type CellProps, type Coordinate, Curve, type CurveProps, type DataKey, Dot, type DotItemDotProps, type DotProps, ErrorBar, type ErrorBarProps, getRelativeCoordinate, Label, LabelList, type LabelListProps, type LabelProps, LineDrawShape, type LineDrawShapeProps, type Margin, type NumberDomain, type PieLabelRenderProps, type PieSectorShapeProps, PolarAngleAxis, type PolarAngleAxisProps, PolarGrid, type PolarGridProps, PolarRadiusAxis, type PolarRadiusAxisProps, Polygon, type PolygonProps, type RadialBarSectorProps, Rectangle, type RectangleProps, ReferenceArea, type ReferenceAreaProps, ReferenceDot, type ReferenceDotProps, ReferenceLine, type ReferenceLineProps, ResponsiveContainer, type ResponsiveContainerProps, type ScaleFunction, type ScatterShapeProps, Sector, type SectorProps, Symbols, type SymbolsProps, type TooltipContentProps as TooltipRenderProps, type TooltipPayloadEntry, type TooltipValueType, useChartHeight, useChartWidth, useXAxisScale, useYAxisScale, XAxis, type XAxisProps, type XAxisTickContentProps, YAxis, type YAxisProps, type YAxisTickContentProps, ZAxis, type ZAxisProps, } from "recharts";
|
|
2
|
+
export { type ActivityRing, type ActivityRingDatum, ActivityRings, type ActivityRingsProps, } from "./activity-rings.js";
|
|
3
|
+
export { type LineAnimation, LineSeries, type LineSeriesProps, Tooltip, type TooltipProps, } from "./animation.js";
|
|
4
|
+
export { type AreaAnimation, AreaChart, type AreaChartProps } from "./area-chart.js";
|
|
5
|
+
export type { AreaMaterial } from "./area-material.js";
|
|
6
|
+
export { AreaSeries, type AreaSeriesProps } from "./area-series.js";
|
|
7
|
+
export { type BarAnimation, BarChart, BarChart as WaterfallChart, type BarChartProps, type BarChartProps as WaterfallChartProps, } from "./bar-chart.js";
|
|
8
|
+
export type { BarMaterial } from "./bar-material.js";
|
|
9
|
+
export { BarSeries, type BarSeriesProps } from "./bar-series.js";
|
|
10
|
+
export type { BoxPlotMaterial } from "./box-material.js";
|
|
11
|
+
export { BoxPlotChart, type BoxPlotChartProps, BoxPlotMark, type BoxPlotMarkProps, BoxPlotSeries, type BoxPlotSeriesProps, type BoxPlotShapeProps, type BoxPlotSummary, boxPlotExtent, validateBoxPlotSummary, } from "./box-plot.js";
|
|
12
|
+
export { type ComboAnimation, ComboChart, type ComboChartProps } from "./combo-chart.js";
|
|
13
|
+
export { type ConfiguredLineChartProps, type ConfiguredLineSeries, LineChart, type LineChartProps, } from "./configured-line-chart.js";
|
|
14
|
+
export { EmphasisMark, type EmphasisMarkProps, type EmphasisTarget, useEmphasis, } from "./emphasis.js";
|
|
15
|
+
export { HeatmapCellContent, type HeatmapCellContentProps, HeatmapChart, type HeatmapChartProps, HeatmapDataTable, type HeatmapDataTableProps, HeatmapGrid, type HeatmapGridProps, HeatmapLegend, type HeatmapLegendProps, type HeatmapMaterial, HeatmapTooltip, type HeatmapTooltipProps, } from "./heatmap.js";
|
|
16
|
+
export { createHeatmapModel, createHeatmapScale, type HeatmapCell, type HeatmapDatum, type HeatmapDuplicatePolicy, type HeatmapModel, type HeatmapModelOptions, type HeatmapScale, type HeatmapScaleOptions, } from "./heatmap-model.js";
|
|
17
|
+
export { HistogramChart, type HistogramChartProps } from "./histogram-chart.js";
|
|
18
|
+
export { binHistogram, type HistogramBin, type HistogramBinningResult, type HistogramMeasure, } from "./histogram-data.js";
|
|
19
|
+
export { HistogramSeries, type HistogramSeriesProps, type HistogramShapeProps, } from "./histogram-series.js";
|
|
20
|
+
export { Legend, type LegendProps } from "./legend.js";
|
|
21
|
+
export type { LineMaterial } from "./line-material.js";
|
|
22
|
+
export { type PieAnimation, PieChart, type PieChartProps } from "./pie-chart.js";
|
|
23
|
+
export type { PieMaterial } from "./pie-material.js";
|
|
24
|
+
export { PieSeries, type PieSeriesProps } from "./pie-series.js";
|
|
25
|
+
export { type RadarAnimation, RadarChart, type RadarChartProps, type RadialBarAnimation, RadialBarChart, type RadialBarChartProps, } from "./polar-chart.js";
|
|
26
|
+
export type { PolarMaterial } from "./polar-material.js";
|
|
27
|
+
export { RadarSeries, type RadarSeriesProps, RadialBarSeries, type RadialBarSeriesProps, } from "./polar-series.js";
|
|
28
|
+
export type { RadarSelectionProps } from "./radar-interaction.js";
|
|
29
|
+
export { RadialBarLabel, type RadialBarLabelProps } from "./radial-bar-label.js";
|
|
30
|
+
export { Root, type RootProps } from "./root.js";
|
|
31
|
+
export { type SankeyAnimation, SankeyChart, type SankeyChartProps } from "./sankey-chart.js";
|
|
32
|
+
export type { SankeyNodeConfig } from "./sankey-colors.js";
|
|
33
|
+
export { prepareSankeyData, type SankeyFlowData, type SankeyFlowLink, type SankeyFlowNode, } from "./sankey-data.js";
|
|
34
|
+
export type { SankeyFinish } from "./sankey-finish.js";
|
|
35
|
+
export { SankeyLegend, type SankeyLegendProps } from "./sankey-legend.js";
|
|
36
|
+
export { SankeyLink, type SankeyLinkProps, type SankeyMaterial, SankeyNode, type SankeyNodeProps, } from "./sankey-marks.js";
|
|
37
|
+
export { SankeyTable, type SankeyTableProps } from "./sankey-table.js";
|
|
38
|
+
export { type ScatterAnimation, ScatterChart, type ScatterChartProps } from "./scatter-chart.js";
|
|
39
|
+
export type { ScatterMaterial } from "./scatter-material.js";
|
|
40
|
+
export { ScatterSeries, type ScatterSeriesProps } from "./scatter-series.js";
|
|
41
|
+
export { type ScatterSizeDimension, ScatterTooltip, ScatterTooltipContent, type ScatterTooltipContentProps, type ScatterTooltipProps, } from "./scatter-tooltip.js";
|
|
42
|
+
export { TooltipContent, type TooltipContentProps } from "./tooltip-content.js";
|
|
43
|
+
export type { SeriesConfig } from "./types.js";
|
|
44
|
+
export { computeWaterfallData, type WaterfallDatum, type WaterfallEntry, } from "./waterfall-data.js";
|
|
45
|
+
export { WaterfallConnectors, type WaterfallConnectorsProps, WaterfallSeries, type WaterfallSeriesProps, } from "./waterfall-series.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
// Native composition parts preserve identity, registration, props and defaults.
|
|
3
|
+
export { AreaRevealShape, BarStack, Brush, CartesianGrid, Cell, Curve, Dot, ErrorBar, getRelativeCoordinate, Label, LabelList, LineDrawShape, PolarAngleAxis, PolarGrid, PolarRadiusAxis, Polygon, Rectangle, ReferenceArea, ReferenceDot, ReferenceLine, ResponsiveContainer, Sector, Symbols, useChartHeight, useChartWidth, useXAxisScale, useYAxisScale, XAxis, YAxis, ZAxis, } from "recharts";
|
|
4
|
+
export { ActivityRings, } from "./activity-rings.js";
|
|
5
|
+
export { LineSeries, Tooltip, } from "./animation.js";
|
|
6
|
+
export { AreaChart } from "./area-chart.js";
|
|
7
|
+
export { AreaSeries } from "./area-series.js";
|
|
8
|
+
export { BarChart, BarChart as WaterfallChart, } from "./bar-chart.js";
|
|
9
|
+
export { BarSeries } from "./bar-series.js";
|
|
10
|
+
export { BoxPlotChart, BoxPlotMark, BoxPlotSeries, boxPlotExtent, validateBoxPlotSummary, } from "./box-plot.js";
|
|
11
|
+
export { ComboChart } from "./combo-chart.js";
|
|
12
|
+
export { LineChart, } from "./configured-line-chart.js";
|
|
13
|
+
export { EmphasisMark, useEmphasis, } from "./emphasis.js";
|
|
14
|
+
export { HeatmapCellContent, HeatmapChart, HeatmapDataTable, HeatmapGrid, HeatmapLegend, HeatmapTooltip, } from "./heatmap.js";
|
|
15
|
+
export { createHeatmapModel, createHeatmapScale, } from "./heatmap-model.js";
|
|
16
|
+
export { HistogramChart } from "./histogram-chart.js";
|
|
17
|
+
export { binHistogram, } from "./histogram-data.js";
|
|
18
|
+
export { HistogramSeries, } from "./histogram-series.js";
|
|
19
|
+
export { Legend } from "./legend.js";
|
|
20
|
+
export { PieChart } from "./pie-chart.js";
|
|
21
|
+
export { PieSeries } from "./pie-series.js";
|
|
22
|
+
export { RadarChart, RadialBarChart, } from "./polar-chart.js";
|
|
23
|
+
export { RadarSeries, RadialBarSeries, } from "./polar-series.js";
|
|
24
|
+
export { RadialBarLabel } from "./radial-bar-label.js";
|
|
25
|
+
export { Root } from "./root.js";
|
|
26
|
+
export { SankeyChart } from "./sankey-chart.js";
|
|
27
|
+
export { prepareSankeyData, } from "./sankey-data.js";
|
|
28
|
+
export { SankeyLegend } from "./sankey-legend.js";
|
|
29
|
+
export { SankeyLink, SankeyNode, } from "./sankey-marks.js";
|
|
30
|
+
export { SankeyTable } from "./sankey-table.js";
|
|
31
|
+
export { ScatterChart } from "./scatter-chart.js";
|
|
32
|
+
export { ScatterSeries } from "./scatter-series.js";
|
|
33
|
+
export { ScatterTooltip, ScatterTooltipContent, } from "./scatter-tooltip.js";
|
|
34
|
+
export { TooltipContent } from "./tooltip-content.js";
|
|
35
|
+
export { computeWaterfallData, } from "./waterfall-data.js";
|
|
36
|
+
export { WaterfallConnectors, WaterfallSeries, } from "./waterfall-series.js";
|
package/dist/legend.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef, ReactNode } from "react";
|
|
2
|
+
export type LegendProps = Omit<ComponentPropsWithRef<"ul">, "children"> & {
|
|
3
|
+
/** Use the existing square color swatch instead of configured icons or symbols. */
|
|
4
|
+
hideIcon?: boolean;
|
|
5
|
+
/** Explicit series emphasis; visibility click behavior remains controlled by Root. */
|
|
6
|
+
emphasis?: "none" | "series";
|
|
7
|
+
/** Compose each item's noninteractive content; Kind retains list/button/state ownership. */
|
|
8
|
+
children?: (item: {
|
|
9
|
+
key: string;
|
|
10
|
+
label: string;
|
|
11
|
+
visible: boolean;
|
|
12
|
+
marker: ReactNode;
|
|
13
|
+
}) => ReactNode;
|
|
14
|
+
};
|
|
15
|
+
/** Displays configured series; becomes interactive only when a controlled change callback exists. */
|
|
16
|
+
export declare function Legend({ hideIcon, emphasis, children, ...props }: LegendProps): import("react").JSX.Element;
|
package/dist/legend.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Symbols } from "recharts";
|
|
4
|
+
import { useChart } from "./chart-context.js";
|
|
5
|
+
import { useEmphasis } from "./emphasis.js";
|
|
6
|
+
/** Displays configured series; becomes interactive only when a controlled change callback exists. */
|
|
7
|
+
export function Legend({ hideIcon = false, emphasis = "none", children, ...props }) {
|
|
8
|
+
const { config, visibleSeries, onVisibleSeriesChange } = useChart();
|
|
9
|
+
return (_jsx("ul", { "aria-label": "Chart legend", ...props, "data-kind-ui": "chart-legend", children: Object.entries(config).map(([key, item]) => {
|
|
10
|
+
const visible = visibleSeries?.includes(key) ?? true;
|
|
11
|
+
const marker = item.icon && !hideIcon ? (_jsx("span", { "aria-hidden": "true", "data-kind-ui": "chart-icon", children: _jsx(item.icon, {}) })) : item.legendShape && !hideIcon ? (_jsx("svg", { "aria-hidden": "true", focusable: "false", "data-kind-ui": "chart-indicator", "data-legend-shape": item.legendShape, viewBox: "-8 -8 16 16", style: { "--kind-ui-chart-indicator-color": `var(--color-${key})` }, children: _jsx(Symbols, { type: item.legendShape, cx: 0, cy: 0, size: 64 }) })) : (_jsx("span", { "aria-hidden": "true", "data-kind-ui": "chart-indicator", style: { "--kind-ui-chart-indicator-color": `var(--color-${key})` } }));
|
|
12
|
+
const content = children ? (children({ key, label: item.label, visible, marker })) : (_jsxs(_Fragment, { children: [marker, item.label] }));
|
|
13
|
+
return (_jsx(LegendItem, { seriesKey: key, enabled: emphasis === "series" && visible, interactive: Boolean(onVisibleSeriesChange && visibleSeries), children: onVisibleSeriesChange && visibleSeries ? (_jsx("button", { type: "button", "aria-pressed": visible, "data-kind-ui": "chart-legend-button", onClick: () => onVisibleSeriesChange(visible
|
|
14
|
+
? visibleSeries.filter((value) => value !== key)
|
|
15
|
+
: [...visibleSeries, key]), children: content })) : (_jsxs("span", { children: [content, visible ? null : " (hidden)"] })) }, key));
|
|
16
|
+
}) }));
|
|
17
|
+
}
|
|
18
|
+
function LegendItem({ seriesKey, enabled, interactive, children, }) {
|
|
19
|
+
const emphasis = useEmphasis({ kind: "series", key: seriesKey, scope: "legend", seriesKey }, enabled);
|
|
20
|
+
return (_jsx("li", { "data-kind-ui": "chart-legend-item", "data-series": seriesKey, tabIndex: enabled && !interactive ? 0 : undefined, onPointerEnter: (event) => {
|
|
21
|
+
if (event.pointerType !== "touch")
|
|
22
|
+
emphasis.enter("pointer");
|
|
23
|
+
}, onPointerLeave: () => emphasis.leave("pointer"), onPointerCancel: () => emphasis.leave("pointer"), onFocus: (event) => {
|
|
24
|
+
if (event.target.matches(":focus-visible"))
|
|
25
|
+
emphasis.enter("keyboard");
|
|
26
|
+
}, onBlur: (event) => {
|
|
27
|
+
if (!event.currentTarget.contains(event.relatedTarget))
|
|
28
|
+
emphasis.leave("keyboard");
|
|
29
|
+
}, children: children }));
|
|
30
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type Attributes, type ComponentProps, type ComponentType } from "react";
|
|
2
|
+
import { LineChart as EngineLineChart, type RadarChart as EngineRadarChart } from "recharts";
|
|
3
|
+
export type LineChartProps = ComponentProps<typeof EngineLineChart>;
|
|
4
|
+
type Point = {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
} | null;
|
|
8
|
+
type Interaction = {
|
|
9
|
+
pointer: Point;
|
|
10
|
+
motionReady: boolean;
|
|
11
|
+
keyboard: ReturnType<typeof createKeyboardModality>;
|
|
12
|
+
emphasisScope: string;
|
|
13
|
+
data: LineChartProps["data"];
|
|
14
|
+
categoryEmphasis: boolean;
|
|
15
|
+
registerCategoryEligibility: (id: string, safe: boolean, hidden: boolean) => () => void;
|
|
16
|
+
invalidate: () => void;
|
|
17
|
+
seriesKeys: Map<string, string>;
|
|
18
|
+
registerSeries: (id: string, key: string) => () => void;
|
|
19
|
+
};
|
|
20
|
+
export declare const LineInteraction: import("react").Context<Interaction | null>;
|
|
21
|
+
export declare function useLineInteraction(): Interaction;
|
|
22
|
+
declare function createKeyboardModality(): {
|
|
23
|
+
snapshot: () => boolean;
|
|
24
|
+
subscribe: (listener: () => void) => () => void;
|
|
25
|
+
set: (next: boolean) => void;
|
|
26
|
+
};
|
|
27
|
+
export declare function useChartKeyboard(): boolean;
|
|
28
|
+
/** Internal boundary shared by the static and optional Motion entry points. */
|
|
29
|
+
type NativeChartProps = LineChartProps | ComponentProps<typeof EngineRadarChart>;
|
|
30
|
+
export declare function LineChartFrame<Props extends NativeChartProps & Attributes = LineChartProps>({ engine: EngineChart, interrupt, clip, motionEnabled, categoryEmphasis, chartProps: props, children, }: {
|
|
31
|
+
chartProps: Props;
|
|
32
|
+
engine: ComponentType<Props>;
|
|
33
|
+
children?: Props["children"];
|
|
34
|
+
interrupt?: () => void;
|
|
35
|
+
clip?: string;
|
|
36
|
+
motionEnabled?: boolean;
|
|
37
|
+
categoryEmphasis?: boolean;
|
|
38
|
+
}): import("react").JSX.Element;
|
|
39
|
+
/** Recharts owns geometry and keyboard selection; Kind shares pointer/keyboard modality. */
|
|
40
|
+
export declare function LineChart(props: LineChartProps): import("react").JSX.Element;
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, use, useCallback, useId, useLayoutEffect, useRef, useState, useSyncExternalStore, } from "react";
|
|
4
|
+
import { LineChart as EngineLineChart, getRelativeCoordinate, useChartHeight, useChartWidth, } from "recharts";
|
|
5
|
+
import { useChart } from "./chart-context.js";
|
|
6
|
+
import { useEmphasisActions } from "./emphasis.js";
|
|
7
|
+
export const LineInteraction = createContext(null);
|
|
8
|
+
export function useLineInteraction() {
|
|
9
|
+
const value = use(LineInteraction);
|
|
10
|
+
if (!value)
|
|
11
|
+
throw new Error("LineSeries and Tooltip must be inside LineChart");
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
// Modality is observed only by decorating marks. Changing it must not rerender
|
|
15
|
+
// the native engine and replace a consumer shape during pointer-down/click.
|
|
16
|
+
function createKeyboardModality() {
|
|
17
|
+
let current = false;
|
|
18
|
+
const listeners = new Set();
|
|
19
|
+
return {
|
|
20
|
+
snapshot: () => current,
|
|
21
|
+
subscribe: (listener) => {
|
|
22
|
+
listeners.add(listener);
|
|
23
|
+
return () => {
|
|
24
|
+
listeners.delete(listener);
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
set: (next) => {
|
|
28
|
+
if (current === next)
|
|
29
|
+
return;
|
|
30
|
+
current = next;
|
|
31
|
+
for (const listener of listeners)
|
|
32
|
+
listener();
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export function useChartKeyboard() {
|
|
37
|
+
const { keyboard } = useLineInteraction();
|
|
38
|
+
return useSyncExternalStore(keyboard.subscribe, keyboard.snapshot, () => false);
|
|
39
|
+
}
|
|
40
|
+
// Geometry and data changes end entrance animation and discard stale pointer pixels.
|
|
41
|
+
function Lifecycle({ data, invalidate }) {
|
|
42
|
+
const width = useChartWidth();
|
|
43
|
+
const height = useChartHeight();
|
|
44
|
+
const { visibleSeries } = useChart();
|
|
45
|
+
const previous = useRef({ width, height, data, visibleSeries });
|
|
46
|
+
useLayoutEffect(() => {
|
|
47
|
+
const old = previous.current;
|
|
48
|
+
if ((old.width && old.height && (width !== old.width || height !== old.height)) ||
|
|
49
|
+
data !== old.data ||
|
|
50
|
+
visibleSeries !== old.visibleSeries)
|
|
51
|
+
invalidate();
|
|
52
|
+
previous.current = { width, height, data, visibleSeries };
|
|
53
|
+
}, [width, height, data, visibleSeries, invalidate]);
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
export function LineChartFrame({ engine: EngineChart, interrupt = () => { }, clip, motionEnabled, categoryEmphasis = false, chartProps: props, children = props.children, }) {
|
|
57
|
+
const { onMouseMove, onMouseLeave } = props;
|
|
58
|
+
const emphasis = useEmphasisActions();
|
|
59
|
+
const frame = useRef(null);
|
|
60
|
+
const [keyboard] = useState(createKeyboardModality);
|
|
61
|
+
const setKeyboard = keyboard.set;
|
|
62
|
+
const emphasisScope = useId();
|
|
63
|
+
const clearPlotPointer = emphasis.clearScope;
|
|
64
|
+
useLayoutEffect(() => {
|
|
65
|
+
const node = frame.current;
|
|
66
|
+
if (!node)
|
|
67
|
+
return;
|
|
68
|
+
const leave = () => clearPlotPointer(emphasisScope);
|
|
69
|
+
node.addEventListener("pointerleave", leave);
|
|
70
|
+
node.addEventListener("mouseleave", leave);
|
|
71
|
+
node.addEventListener("pointercancel", leave);
|
|
72
|
+
return () => {
|
|
73
|
+
node.removeEventListener("pointerleave", leave);
|
|
74
|
+
node.removeEventListener("mouseleave", leave);
|
|
75
|
+
node.removeEventListener("pointercancel", leave);
|
|
76
|
+
};
|
|
77
|
+
}, [clearPlotPointer, emphasisScope]);
|
|
78
|
+
const [motionReady, setMotionReady] = useState(true);
|
|
79
|
+
const [pointer, setPointer] = useState(null);
|
|
80
|
+
const [categoryPeers, setCategoryPeers] = useState(() => new Map());
|
|
81
|
+
const registerCategoryEligibility = useCallback((id, safe, hidden) => {
|
|
82
|
+
setCategoryPeers((old) => old.get(id)?.safe === safe && old.get(id)?.hidden === hidden
|
|
83
|
+
? old
|
|
84
|
+
: new Map(old).set(id, { safe, hidden }));
|
|
85
|
+
return () => setCategoryPeers((old) => {
|
|
86
|
+
if (!old.has(id))
|
|
87
|
+
return old;
|
|
88
|
+
const next = new Map(old);
|
|
89
|
+
next.delete(id);
|
|
90
|
+
return next;
|
|
91
|
+
});
|
|
92
|
+
}, []);
|
|
93
|
+
const eligibleCategoryPlot = categoryEmphasis &&
|
|
94
|
+
emphasis.enabled &&
|
|
95
|
+
categoryPeers.size > 0 &&
|
|
96
|
+
[...categoryPeers.values()].every((peer) => peer.hidden || peer.safe);
|
|
97
|
+
const [seriesKeys, setSeriesKeys] = useState(() => new Map());
|
|
98
|
+
const registerSeries = useCallback((id, key) => {
|
|
99
|
+
setSeriesKeys((current) => (current.get(id) === key ? current : new Map(current).set(id, key)));
|
|
100
|
+
return () => setSeriesKeys((current) => {
|
|
101
|
+
if (!current.has(id))
|
|
102
|
+
return current;
|
|
103
|
+
const next = new Map(current);
|
|
104
|
+
next.delete(id);
|
|
105
|
+
return next;
|
|
106
|
+
});
|
|
107
|
+
}, []);
|
|
108
|
+
const invalidate = useCallback(() => {
|
|
109
|
+
setPointer(null);
|
|
110
|
+
setMotionReady(false);
|
|
111
|
+
interrupt();
|
|
112
|
+
}, [interrupt]);
|
|
113
|
+
return (_jsx(LineInteraction, { value: {
|
|
114
|
+
pointer,
|
|
115
|
+
keyboard,
|
|
116
|
+
emphasisScope,
|
|
117
|
+
data: props.data,
|
|
118
|
+
categoryEmphasis: eligibleCategoryPlot,
|
|
119
|
+
registerCategoryEligibility,
|
|
120
|
+
motionReady,
|
|
121
|
+
invalidate,
|
|
122
|
+
seriesKeys,
|
|
123
|
+
registerSeries,
|
|
124
|
+
}, children: _jsx("div", { ref: frame, "data-kind-ui": "line-frame", "data-motion": motionEnabled === undefined ? undefined : motionEnabled ? "on" : "off", style: { display: "contents" }, onFocusCapture: (event) => {
|
|
125
|
+
interrupt();
|
|
126
|
+
if (event.target.matches(":focus-visible"))
|
|
127
|
+
setKeyboard(true);
|
|
128
|
+
}, onPointerDownCapture: () => {
|
|
129
|
+
setKeyboard(false);
|
|
130
|
+
interrupt();
|
|
131
|
+
}, onPointerLeave: () => emphasis.clearScope(emphasisScope), onPointerCancel: () => emphasis.clearScope(emphasisScope), onPointerOverCapture: () => setKeyboard(false), onPointerMoveCapture: () => {
|
|
132
|
+
setKeyboard(false);
|
|
133
|
+
interrupt();
|
|
134
|
+
}, onKeyDownCapture: (event) => {
|
|
135
|
+
setKeyboard(event.key !== "Escape");
|
|
136
|
+
interrupt();
|
|
137
|
+
setMotionReady(true);
|
|
138
|
+
setPointer(null);
|
|
139
|
+
}, onBlurCapture: (event) => {
|
|
140
|
+
if (!event.currentTarget.contains(event.relatedTarget)) {
|
|
141
|
+
setPointer(null);
|
|
142
|
+
setKeyboard(false);
|
|
143
|
+
emphasis.clear("keyboard");
|
|
144
|
+
}
|
|
145
|
+
}, children: _jsxs(EngineChart, { ...props, className: ["kind-ui-line-chart", props.className].filter(Boolean).join(" "), style: { ...props.style, "--kind-ui-line-clip": clip ?? "none" }, onMouseMove: (state, event) => {
|
|
146
|
+
const { relativeX, relativeY } = getRelativeCoordinate(event);
|
|
147
|
+
setKeyboard(false);
|
|
148
|
+
setMotionReady(true);
|
|
149
|
+
setPointer({ x: relativeX, y: relativeY });
|
|
150
|
+
interrupt();
|
|
151
|
+
onMouseMove?.(state, event);
|
|
152
|
+
}, onMouseLeave: (state, event) => {
|
|
153
|
+
setPointer(null);
|
|
154
|
+
onMouseLeave?.(state, event);
|
|
155
|
+
}, children: [_jsx(Lifecycle, { data: props.data, invalidate: invalidate }), children] }) }) }));
|
|
156
|
+
}
|
|
157
|
+
/** Recharts owns geometry and keyboard selection; Kind shares pointer/keyboard modality. */
|
|
158
|
+
export function LineChart(props) {
|
|
159
|
+
return _jsx(LineChartFrame, { chartProps: props, engine: EngineLineChart });
|
|
160
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type LineDrawShapeProps } from "recharts";
|
|
2
|
+
export type LineMaterial = "plain" | "paper" | "clay" | "glow";
|
|
3
|
+
/** Uses engine points only for filter bounds; Curve retains the original geometry and pathRef. */
|
|
4
|
+
export declare function MaterialCurve({ material, filterId, materialWidth, animationElapsedTime: _time, isAnimating: _active, isEntrance: _entrance, visibleLength: _length, clipPath, ...props }: Omit<LineDrawShapeProps, "pathRef"> & {
|
|
5
|
+
pathRef?: LineDrawShapeProps["pathRef"];
|
|
6
|
+
material: Exclude<LineMaterial, "plain">;
|
|
7
|
+
filterId: string;
|
|
8
|
+
materialWidth: number | string;
|
|
9
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Curve } from "recharts";
|
|
4
|
+
/** Uses engine points only for filter bounds; Curve retains the original geometry and pathRef. */
|
|
5
|
+
export function MaterialCurve({ material, filterId, materialWidth, animationElapsedTime: _time, isAnimating: _active, isEntrance: _entrance, visibleLength: _length, clipPath, ...props }) {
|
|
6
|
+
const points = props.points?.filter((p) => Number.isFinite(p.x) && Number.isFinite(p.y)) ?? [];
|
|
7
|
+
if (!points.length)
|
|
8
|
+
return _jsx(Curve, { ...props, strokeWidth: materialWidth, clipPath: clipPath });
|
|
9
|
+
let minX = Infinity;
|
|
10
|
+
let minY = Infinity;
|
|
11
|
+
let maxX = -Infinity;
|
|
12
|
+
let maxY = -Infinity;
|
|
13
|
+
for (const point of points) {
|
|
14
|
+
minX = Math.min(minX, point.x);
|
|
15
|
+
minY = Math.min(minY, point.y);
|
|
16
|
+
maxX = Math.max(maxX, point.x);
|
|
17
|
+
maxY = Math.max(maxY, point.y);
|
|
18
|
+
}
|
|
19
|
+
const width = Number(materialWidth);
|
|
20
|
+
const pad = (Number.isFinite(width) ? width : 12) / 2 + 6;
|
|
21
|
+
const x = minX - pad;
|
|
22
|
+
const y = minY - pad;
|
|
23
|
+
return (_jsxs("g", { "data-kind-ui": "line-material", "data-material": material, clipPath: clipPath, children: [_jsx("defs", { pointerEvents: "none", children: _jsx("filter", { id: filterId, filterUnits: "userSpaceOnUse", x: x, y: y, width: maxX - x + pad, height: maxY - y + pad, colorInterpolationFilters: "sRGB", children: material === "paper" ? (_jsxs(_Fragment, { children: [_jsx("feTurbulence", { type: "fractalNoise", baseFrequency: "0.7 0.25", numOctaves: 1, seed: 7, result: "fiber" }), _jsx("feFlood", { floodColor: "var(--kind-ui-line-paper-fiber, #fff)", floodOpacity: "var(--kind-ui-line-paper-grain, 0.38)" }), _jsx("feComposite", { in2: "fiber", operator: "in", result: "texture" }), _jsx("feComposite", { in: "texture", in2: "SourceAlpha", operator: "in", result: "grain" }), _jsxs("feMerge", { children: [_jsx("feMergeNode", { in: "SourceGraphic" }), _jsx("feMergeNode", { in: "grain" })] })] })) : material === "glow" ? (_jsxs(_Fragment, { children: [_jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: 2, result: "halo" }), _jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: 0.65, result: "nearHalo" }), _jsx("feFlood", { floodOpacity: "var(--kind-ui-line-glow-opacity, 0.5)", result: "strength" }), _jsx("feComposite", { in: "halo", in2: "strength", operator: "in", result: "softHalo" }), _jsx("feComposite", { in: "nearHalo", in2: "strength", operator: "in", result: "closeHalo" }), _jsx("feMorphology", { in: "SourceAlpha", operator: "erode", radius: 0.55, result: "core" }), _jsx("feFlood", { floodColor: "var(--kind-ui-line-glow-light, #fff)", floodOpacity: 0.5 }), _jsx("feComposite", { in2: "core", operator: "in", result: "lightCore" }), _jsxs("feMerge", { children: [_jsx("feMergeNode", { in: "softHalo" }), _jsx("feMergeNode", { in: "closeHalo" }), _jsx("feMergeNode", { in: "SourceGraphic" }), _jsx("feMergeNode", { in: "lightCore" })] })] })) : (_jsxs(_Fragment, { children: [_jsx("feGaussianBlur", { in: "SourceAlpha", stdDeviation: 0.8, result: "rounded" }), _jsx("feSpecularLighting", { in: "rounded", surfaceScale: 1.5, specularConstant: 0.4, specularExponent: 8, lightingColor: "var(--kind-ui-line-clay-light, #fff)", result: "light", children: _jsx("feDistantLight", { azimuth: 225, elevation: 45 }) }), _jsx("feComposite", { in: "light", in2: "SourceAlpha", operator: "in", result: "bevel" }), _jsx("feOffset", { in: "SourceAlpha", dx: -0.6, dy: -1, result: "offset" }), _jsx("feComposite", { in: "SourceAlpha", in2: "offset", operator: "out", result: "edge" }), _jsx("feFlood", { floodColor: "var(--kind-ui-line-clay-shade, #17212b)", floodOpacity: 0.16 }), _jsx("feComposite", { in2: "edge", operator: "in", result: "shade" }), _jsxs("feMerge", { result: "body", children: [_jsx("feMergeNode", { in: "SourceGraphic" }), _jsx("feMergeNode", { in: "shade" })] }), _jsx("feComposite", { in: "body", in2: "bevel", operator: "arithmetic", k2: 1, k3: 0.7, result: "lit" }), _jsx("feOffset", { in: "rounded", dx: 0, dy: 1.5, result: "dropped" }), _jsx("feFlood", { floodColor: "var(--kind-ui-line-clay-shade, #17212b)", floodOpacity: 0.16 }), _jsx("feComposite", { in2: "dropped", operator: "in", result: "shadow" }), _jsxs("feMerge", { children: [_jsx("feMergeNode", { in: "shadow" }), _jsx("feMergeNode", { in: "lit" })] })] })) }) }), _jsx(Curve, { ...props, strokeWidth: materialWidth, filter: `url(#${filterId})` })] }));
|
|
24
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ComponentProps } from "react";
|
|
2
|
+
import { Line } from "recharts";
|
|
3
|
+
import { type LineMaterial } from "./line-material.js";
|
|
4
|
+
type DefaultLineDataKey = Extract<ComponentProps<typeof Line>["dataKey"], (row: never) => unknown>;
|
|
5
|
+
export type LineSeriesProps<DataPoint = Parameters<DefaultLineDataKey>[0], Value = ReturnType<DefaultLineDataKey>> = ComponentProps<typeof Line<DataPoint, Value>> & {
|
|
6
|
+
/** Metadata/visibility key, required only for function or numeric data keys. */
|
|
7
|
+
seriesKey?: string;
|
|
8
|
+
/** Material on the default SVG curve; custom shape/filter retain consumer ownership. */
|
|
9
|
+
material?: LineMaterial;
|
|
10
|
+
};
|
|
11
|
+
/** A registered Recharts Line with Root colors and controlled visibility. */
|
|
12
|
+
export declare function LineSeries<DataPoint = Parameters<DefaultLineDataKey>[0], Value = ReturnType<DefaultLineDataKey>>({ seriesKey, hide, stroke, className, material, renderWhileHidden, ...props }: LineSeriesProps<DataPoint, Value> & {
|
|
13
|
+
renderWhileHidden?: boolean;
|
|
14
|
+
}): import("react").JSX.Element;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useId, useLayoutEffect, useRef } from "react";
|
|
4
|
+
import { Line } from "recharts";
|
|
5
|
+
import { useChart } from "./chart-context.js";
|
|
6
|
+
import { useLineInteraction } from "./line-chart.js";
|
|
7
|
+
import { MaterialCurve } from "./line-material.js";
|
|
8
|
+
/** A registered Recharts Line with Root colors and controlled visibility. */
|
|
9
|
+
export function LineSeries({ seriesKey, hide, stroke, className, material = "plain", renderWhileHidden = false, ...props }) {
|
|
10
|
+
const { config, visibleSeries } = useChart();
|
|
11
|
+
const { registerSeries, invalidate } = useLineInteraction();
|
|
12
|
+
const generatedId = useId();
|
|
13
|
+
const id = props.id || generatedId;
|
|
14
|
+
const key = seriesKey ?? (typeof props.dataKey === "string" ? props.dataKey : undefined);
|
|
15
|
+
const effectiveHide = hide === true || (visibleSeries !== undefined && !visibleSeries.includes(key ?? ""));
|
|
16
|
+
const renderedHide = hide === true || (!renderWhileHidden && effectiveHide);
|
|
17
|
+
const previous = useRef({ data: props.data, hide: effectiveHide, renderedHide });
|
|
18
|
+
useLayoutEffect(() => {
|
|
19
|
+
if (props.data !== previous.current.data ||
|
|
20
|
+
effectiveHide !== previous.current.hide ||
|
|
21
|
+
renderedHide !== previous.current.renderedHide)
|
|
22
|
+
invalidate();
|
|
23
|
+
previous.current = { data: props.data, hide: effectiveHide, renderedHide };
|
|
24
|
+
}, [props.data, effectiveHide, renderedHide, invalidate]);
|
|
25
|
+
useLayoutEffect(() => {
|
|
26
|
+
if (key === undefined)
|
|
27
|
+
return;
|
|
28
|
+
return registerSeries(id, key);
|
|
29
|
+
}, [id, key, registerSeries]);
|
|
30
|
+
if (key === undefined && visibleSeries !== undefined)
|
|
31
|
+
throw new Error("LineSeries requires seriesKey for controlled non-string dataKey");
|
|
32
|
+
const color = stroke ?? (key && Object.hasOwn(config, key) ? `var(--color-${key})` : undefined);
|
|
33
|
+
return (_jsx(Line, { isAnimationActive: false, ...props, ...(material !== "plain" && props.shape === undefined && props.filter === undefined
|
|
34
|
+
? {
|
|
35
|
+
shape: (_jsx(MaterialCurve, { material: material, filterId: `${generatedId}-material`, materialWidth: props.strokeWidth ?? (material === "clay" ? 6 : material === "paper" ? 2.5 : 3) })),
|
|
36
|
+
strokeLinecap: props.strokeLinecap ?? (props.strokeDasharray ? "butt" : "round"),
|
|
37
|
+
strokeLinejoin: props.strokeLinejoin ?? "round",
|
|
38
|
+
}
|
|
39
|
+
: {}), id: id, hide: renderedHide, ...(color !== undefined ? { stroke: color } : {}), className: ["kind-ui-line-series", className].filter(Boolean).join(" ") }));
|
|
40
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ComponentProps } from "react";
|
|
2
|
+
import { PieChart as EnginePieChart } from "recharts";
|
|
3
|
+
import { type LineAnimation } from "./animation.js";
|
|
4
|
+
export type PieAnimation = LineAnimation;
|
|
5
|
+
export type PieChartProps = ComponentProps<typeof EnginePieChart> & {
|
|
6
|
+
animate?: boolean | PieAnimation | undefined;
|
|
7
|
+
/** Entrance sweep only; native start/end angles and data order are unchanged. */
|
|
8
|
+
animationDirection?: "clockwise" | "anticlockwise" | undefined;
|
|
9
|
+
};
|
|
10
|
+
export declare const PieMotion: import("react").Context<{
|
|
11
|
+
reveal: boolean;
|
|
12
|
+
options: PieAnimation;
|
|
13
|
+
progress: number;
|
|
14
|
+
direction: "clockwise" | "anticlockwise";
|
|
15
|
+
}>;
|
|
16
|
+
/** Native polar composition, shared interaction, and optional Motion-owned sector entrance. */
|
|
17
|
+
export declare function PieChart({ animate, animationDirection, children, ...props }: PieChartProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { animate as animateValue } from "motion/react";
|
|
4
|
+
import { createContext, useCallback, useLayoutEffect, useRef, useState, useSyncExternalStore, } from "react";
|
|
5
|
+
import { PieChart as EnginePieChart } from "recharts";
|
|
6
|
+
import { MotionContext } from "./animation.js";
|
|
7
|
+
import { LineChartFrame } from "./line-chart.js";
|
|
8
|
+
export const PieMotion = createContext({
|
|
9
|
+
reveal: false,
|
|
10
|
+
options: {},
|
|
11
|
+
progress: 1,
|
|
12
|
+
direction: "clockwise",
|
|
13
|
+
});
|
|
14
|
+
const query = "(prefers-reduced-motion: reduce)";
|
|
15
|
+
function subscribe(change) {
|
|
16
|
+
const media = window.matchMedia(query);
|
|
17
|
+
media.addEventListener("change", change);
|
|
18
|
+
return () => media.removeEventListener("change", change);
|
|
19
|
+
}
|
|
20
|
+
const snapshot = () => window.matchMedia(query).matches;
|
|
21
|
+
const serverSnapshot = () => true;
|
|
22
|
+
const defaultHover = { type: "spring", stiffness: 210, damping: 28, mass: 0.8 };
|
|
23
|
+
/** Native polar composition, shared interaction, and optional Motion-owned sector entrance. */
|
|
24
|
+
export function PieChart({ animate = false, animationDirection = "clockwise", children, ...props }) {
|
|
25
|
+
const reduced = useSyncExternalStore(subscribe, snapshot, serverSnapshot);
|
|
26
|
+
const [interacted, setInteracted] = useState(false);
|
|
27
|
+
const finish = useCallback(() => setInteracted(true), []);
|
|
28
|
+
const enabled = animate !== false && !reduced;
|
|
29
|
+
const interrupt = useCallback(() => {
|
|
30
|
+
if (enabled)
|
|
31
|
+
finish();
|
|
32
|
+
}, [enabled, finish]);
|
|
33
|
+
const options = typeof animate === "object" ? animate : {};
|
|
34
|
+
const previousEnabled = useRef(enabled);
|
|
35
|
+
useLayoutEffect(() => {
|
|
36
|
+
if (previousEnabled.current && !enabled)
|
|
37
|
+
finish();
|
|
38
|
+
previousEnabled.current = enabled;
|
|
39
|
+
}, [enabled, finish]);
|
|
40
|
+
const reveal = enabled && !interacted;
|
|
41
|
+
const [progress, setProgress] = useState(1);
|
|
42
|
+
const duration = options.revealDurationMs ?? 1000;
|
|
43
|
+
const easing = options.revealEasing ?? "easeOut";
|
|
44
|
+
const started = useRef(false);
|
|
45
|
+
const previous = useRef([duration, easing, animationDirection]);
|
|
46
|
+
useLayoutEffect(() => {
|
|
47
|
+
const inputs = [duration, easing, animationDirection];
|
|
48
|
+
if (started.current && inputs.some((value, index) => value !== previous.current[index]))
|
|
49
|
+
finish();
|
|
50
|
+
previous.current = inputs;
|
|
51
|
+
});
|
|
52
|
+
useLayoutEffect(() => {
|
|
53
|
+
if (!reveal) {
|
|
54
|
+
setProgress(1);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
started.current = true;
|
|
58
|
+
setProgress(0);
|
|
59
|
+
const controls = animateValue(0, 1, {
|
|
60
|
+
duration: Math.max(0, duration) / 1000,
|
|
61
|
+
ease: easing,
|
|
62
|
+
onUpdate: setProgress,
|
|
63
|
+
onComplete: finish,
|
|
64
|
+
});
|
|
65
|
+
return () => controls.stop();
|
|
66
|
+
}, [reveal, duration, easing, finish]);
|
|
67
|
+
return (_jsx(MotionContext, { value: { enabled, transition: options.hoverTransition ?? defaultHover }, children: _jsx(PieMotion, { value: { reveal, options, progress, direction: animationDirection }, children: _jsx(LineChartFrame, { chartProps: props, engine: EnginePieChart, motionEnabled: enabled, interrupt: interrupt, children: children }) }) }));
|
|
68
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { LineMaterial } from "./line-material.js";
|
|
2
|
+
export type PieMaterial = LineMaterial;
|
|
3
|
+
export type PiePaintBounds = {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
};
|
|
9
|
+
/** Native Sector retains angles, radii and paint alpha; Glow alone emits a decorative halo. */
|
|
10
|
+
export declare function PieMaterialFilter({ material, id, radius, thickness, cx, cy, strokeWidth, bounds, }: {
|
|
11
|
+
material: Exclude<PieMaterial, "plain">;
|
|
12
|
+
id: string;
|
|
13
|
+
radius: number;
|
|
14
|
+
thickness: number;
|
|
15
|
+
cx: number;
|
|
16
|
+
cy: number;
|
|
17
|
+
strokeWidth: number;
|
|
18
|
+
bounds?: PiePaintBounds | undefined;
|
|
19
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/** Native Sector retains angles, radii and paint alpha; Glow alone emits a decorative halo. */
|
|
4
|
+
export function PieMaterialFilter({ material, id, radius, thickness, cx, cy, strokeWidth, bounds, }) {
|
|
5
|
+
const relief = Math.max(1, Math.min(14, radius * 0.12, thickness * 0.22));
|
|
6
|
+
const margin = 16 + strokeWidth / 2;
|
|
7
|
+
const x = Math.floor(cx - radius - margin);
|
|
8
|
+
const y = Math.floor(cy - radius - margin);
|
|
9
|
+
const width = Math.ceil(cx + radius + margin) - x;
|
|
10
|
+
const height = Math.ceil(cy + radius + margin) - y;
|
|
11
|
+
return (_jsx("filter", { id: id, filterUnits: "userSpaceOnUse", x: bounds?.x ?? x, y: bounds?.y ?? y, width: bounds?.width ?? width, height: bounds?.height ?? height, colorInterpolationFilters: "sRGB", children: material === "clay" ? (_jsxs(_Fragment, { children: [_jsx("feComponentTransfer", { in: "SourceAlpha", result: "footprint", children: _jsx("feFuncA", { type: "linear", slope: 100000 }) }), _jsx("feGaussianBlur", { in: "footprint", stdDeviation: relief, result: "rounded" }), _jsx("feOffset", { in: "rounded", dx: relief * 0.7, dy: relief * 0.9, result: "lower" }), _jsx("feComposite", { in: "footprint", in2: "lower", operator: "out", result: "top" }), _jsx("feGaussianBlur", { in: "top", stdDeviation: relief * 0.45, result: "softTop" }), _jsx("feFlood", { floodColor: "var(--kind-ui-pie-clay-light, #fff)", floodOpacity: "var(--kind-ui-pie-clay-highlight, 0.55)" }), _jsx("feComposite", { in2: "softTop", operator: "in", result: "light" }), _jsx("feOffset", { in: "rounded", dx: -relief * 0.8, dy: -relief, result: "upper" }), _jsx("feComposite", { in: "footprint", in2: "upper", operator: "out", result: "bottom" }), _jsx("feGaussianBlur", { in: "bottom", stdDeviation: relief * 0.45, result: "softBottom" }), _jsx("feFlood", { floodColor: "var(--kind-ui-pie-clay-shade, #17212b)", floodOpacity: "var(--kind-ui-pie-clay-shadow, 0.32)" }), _jsx("feComposite", { in2: "softBottom", operator: "in", result: "shade" }), _jsx("feComposite", { in: "shade", in2: "SourceGraphic", operator: "atop", result: "shaded" }), _jsx("feComposite", { in: "light", in2: "shaded", operator: "atop", result: "finished" }), _jsx(NativePaintColor, {})] })) : material === "paper" ? (_jsxs(_Fragment, { children: [_jsx("feTurbulence", { type: "fractalNoise", x: bounds?.x ?? x, y: bounds?.y ?? y, width: 32, height: 32, baseFrequency: "0.2 0.3", numOctaves: 1, seed: 7, result: "fiberTile" }), _jsx("feTile", { in: "fiberTile", result: "fiber" }), _jsx("feFlood", { floodColor: "var(--kind-ui-pie-paper-fiber, #fff)", floodOpacity: "var(--kind-ui-pie-paper-grain, 0.16)" }), _jsx("feComposite", { in2: "fiber", operator: "in", result: "texture" }), _jsx("feComposite", { in: "texture", in2: "SourceGraphic", operator: "atop", result: "paper" }), _jsx("feComponentTransfer", { in: "SourceAlpha", result: "footprint", children: _jsx("feFuncA", { type: "linear", slope: 100000 }) }), _jsx("feGaussianBlur", { in: "footprint", stdDeviation: 1.2, result: "inside" }), _jsx("feComposite", { in: "footprint", in2: "inside", operator: "out", result: "edge" }), _jsx("feComponentTransfer", { in: "edge", result: "pencilEdge", children: _jsx("feFuncA", { type: "linear", slope: 6 }) }), _jsx("feColorMatrix", { in: "fiber", type: "luminanceToAlpha", result: "sketch" }), _jsx("feComposite", { in: "pencilEdge", in2: "sketch", operator: "in", result: "contour" }), _jsx("feFlood", { floodColor: "var(--kind-ui-pie-paper-ink, #17212b)", floodOpacity: 0.72 }), _jsx("feComposite", { in2: "contour", operator: "in", result: "ink" }), _jsx("feComposite", { in: "ink", in2: "paper", operator: "atop", result: "outlined" }), _jsx("feOffset", { in: "pencilEdge", dx: 1.2, dy: 1.2, result: "inset" }), _jsx("feComposite", { in: "inset", in2: "footprint", operator: "in", result: "pencilLine" }), _jsx("feComposite", { in: "pencilLine", in2: "sketch", operator: "in", result: "brokenLine" }), _jsx("feFlood", { floodColor: "var(--kind-ui-pie-paper-ink, #17212b)", floodOpacity: 0.45 }), _jsx("feComposite", { in2: "brokenLine", operator: "in", result: "pencilPaint" }), _jsx("feComposite", { in: "pencilPaint", in2: "outlined", operator: "atop", result: "finished" }), _jsx(NativePaintColor, {})] })) : (_jsxs(_Fragment, { children: [_jsx("feComponentTransfer", { in: "SourceAlpha", result: "footprint", children: _jsx("feFuncA", { type: "linear", slope: 100000 }) }), _jsx("feMorphology", { in: "footprint", operator: "dilate", radius: 1.5, result: "haloGuard" }), _jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: 4.5, result: "soft" }), _jsx("feFlood", { floodOpacity: "var(--kind-ui-pie-glow-opacity, 0.8)", result: "strength" }), _jsx("feComposite", { in: "soft", in2: "strength", operator: "in", result: "haloPaint" }), _jsx("feComposite", { in: "haloPaint", in2: "haloGuard", operator: "out", result: "halo" }), _jsx("feMerge", { children: _jsx("feMergeNode", { in: "halo" }) })] })) }));
|
|
12
|
+
}
|
|
13
|
+
/** The enclosing native-paint mask owns alpha; this surface contributes color only. */
|
|
14
|
+
function NativePaintColor() {
|
|
15
|
+
return (_jsx("feColorMatrix", { in: "finished", type: "matrix", values: "1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1" }));
|
|
16
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type ComponentProps } from "react";
|
|
2
|
+
import { Pie } from "recharts";
|
|
3
|
+
import { type CategoryKey } from "./category-cells.js";
|
|
4
|
+
import { type PieMaterial } from "./pie-material.js";
|
|
5
|
+
export type PieSeriesProps<DataPoint = unknown, Value = unknown> = Omit<ComponentProps<typeof Pie<DataPoint, Value>>, "isAnimationActive"> & {
|
|
6
|
+
/** Opt-in category colors from Root.config; requires explicit series data. */
|
|
7
|
+
categoryKey?: CategoryKey<DataPoint> | undefined;
|
|
8
|
+
/** Finish on default native sectors; custom shapes, filters and CSS transforms keep ownership. */
|
|
9
|
+
material?: PieMaterial | undefined;
|
|
10
|
+
/** Stable sector identity; defaults to the native nameKey value. */
|
|
11
|
+
emphasisKey?: ((payload: unknown) => string | number | undefined) | undefined;
|
|
12
|
+
};
|
|
13
|
+
/** A native Pie. Use innerRadius for donuts; category data, Cells and visibility are consumer-owned. */
|
|
14
|
+
export declare function PieSeries<DataPoint = unknown, Value = unknown>(props: PieSeriesProps<DataPoint, Value>): import("react").JSX.Element;
|