import * as React from "react";
import {
ResponsiveContainer, LineChart as RLineChart, Line, BarChart as RBarChart, Bar,
AreaChart as RAreaChart, Area, CartesianGrid, XAxis, YAxis, Tooltip, Legend,
} from "recharts";
import { cn } from "../../utils/cn";
export interface ChartSeries {
key: string;
label?: string;
/** Defaults to the token-based palette below, cycling if there are more series than colors. */
color?: string;
}
/** Token-driven default palette — the first color is the current accent (so charts repaint when the color picker changes), the rest are fixed semantic tones for contrast against it. */
const DEFAULT_PALETTE = [
"var(--ui-primary)",
"var(--ui-success)",
"var(--ui-warning)",
"var(--ui-danger)",
"var(--ui-color-neutral-400)",
];
function resolveColor(series: ChartSeries, index: number) {
return series.color ?? DEFAULT_PALETTE[index % DEFAULT_PALETTE.length];
}
interface ChartTooltipProps {
active?: boolean;
label?: string | number;
payload?: { name: string; value: number | string; color: string }[];
}
function ChartTooltipContent({ active, label, payload }: ChartTooltipProps) {
if (!active || !payload?.length) return null;
return (
{label !== undefined &&
{label}
}
{payload.map((entry) => (
{entry.name}: {entry.value}
))}
);
}
interface BaseChartProps {
data: Record[];
xKey: string;
series: ChartSeries[];
height?: number;
showGrid?: boolean;
showLegend?: boolean;
className?: string;
}
const axisStyle = { fontSize: 12, fill: "var(--ui-fg-muted)" };
/** Line chart — trends over time/sequence. Reads its colors from the current design tokens by default, so it repaints with the accent color picker like every other component. */
export function LineChart({ data, xKey, series, height = 320, showGrid = true, showLegend = series.length > 1, className }: BaseChartProps) {
return (
{showGrid && }
} />
{showLegend && }
{series.map((s, i) => (
))}
);
}
/** Bar chart — comparisons across categories. */
export function BarChart({ data, xKey, series, height = 320, showGrid = true, showLegend = series.length > 1, className }: BaseChartProps) {
return (
{showGrid && }
} cursor={{ fill: "var(--ui-bg-subtle)" }} />
{showLegend && }
{series.map((s, i) => (
))}
);
}
/** Area chart — volume/magnitude over time. */
export function AreaChart({ data, xKey, series, height = 320, showGrid = true, showLegend = series.length > 1, className }: BaseChartProps) {
return (
{showGrid && }
} />
{showLegend && }
{series.map((s, i) => (
))}
);
}