ChartFrame
Generic chart wrapper — Card header + fixed-height ResponsiveContainer body, plus chartTheme, a token-reading style object for recharts.
Import
ChartFrame is a registry composite — you own the source after installing:
npx ploxum add chart-frameimport { ChartFrame, chartTheme } from "@/components/chart-frame";Requires recharts as an npm dependency (declared in the registry item, installed alongside the source). Also depends on @roger-emerson/ploxum-primitives (Card).
Usage
import { Area, AreaChart, CartesianGrid, Tooltip, XAxis, YAxis } from "recharts";
const throughput = [
{ time: "18:00", scans: 420 },
{ time: "18:30", scans: 980 },
{ time: "19:00", scans: 1640 },
{ time: "19:30", scans: 1210 },
{ time: "20:00", scans: 380 },
];
<ChartFrame height={280} subtitle="Scans per gate · last 2 hours" title="Gate throughput">
<AreaChart data={throughput}>
<CartesianGrid {...chartTheme.grid} />
<XAxis dataKey="time" {...chartTheme.axis} />
<YAxis {...chartTheme.axis} />
<Tooltip {...chartTheme.tooltip} />
<Area
dataKey="scans"
fill="var(--ploxum-color-amber-tint)"
stroke="var(--ploxum-color-chart-series1)"
type="monotone"
/>
</AreaChart>
</ChartFrame>;The child must be a single recharts chart element (AreaChart, BarChart, LineChart, …) — ResponsiveContainer sizes it to the frame.
Props
ChartFrame
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | — | Card header title. |
subtitle | string? | — | Card header subtitle. |
children | ReactElement | — | A single recharts chart element. |
height | number | 280 | Fixed body height in px; ResponsiveContainer fills the width. |
accent | "none" | "amber" | "none" | Passed through to Card — solid amber left border for "this surface matters". |
className | string | — | Extra classes on the root Card. |
ref | Ref<HTMLDivElement> | — | Forwarded to the root Card. |
chartTheme
Exported style objects that read ploxum tokens, so charts re-theme with the active data-theme. Spread onto the matching recharts parts:
| Key | Spread onto | What it sets |
|---|---|---|
chartTheme.grid | <CartesianGrid /> | --ploxum-color-chart-grid stroke, 3 3 dash. |
chartTheme.axis | <XAxis /> / <YAxis /> | Axis stroke, 11px tertiary-toned ticks, no tick/axis lines. |
chartTheme.tooltip | <Tooltip /> | Overlay background, subtle border, mono 12px, amber label. |
ChartTooltipContent
A richer, token-reading replacement for the default recharts tooltip. Pass it as the content prop instead of spreading chartTheme.tooltip:
import { ChartTooltipContent } from "@/components/chart-frame";
<Tooltip
content={
<ChartTooltipContent
formatLabel={(label) => `Hour ${label}`}
formatValue={(value) => `${Number(value).toLocaleString()}`}
/>
}
/>;recharts injects active / label / payload; you supply the formatting. Each series row renders a token-colored swatch, its name, and the formatted value. The optional footer slot takes a delta line or StatusPip. Works across Area / Bar / Pie.
| Prop | Type | Description |
|---|---|---|
formatLabel | (label: string) => string | Map the active axis label to display text. |
formatValue | (value, item) => string | Map each series value (e.g. currency). |
hideIndicator | boolean | Hide the per-series color swatch. |
footer | ReactNode | Trailing slot under the rows (delta / pip). |
Horizontal bars
For per-entity breakdowns (checkpoints, zones, departments) use a BarChart with layout="vertical" — the XAxis becomes numeric and the YAxis carries the category:
<ChartFrame title="Throughput by checkpoint">
<BarChart data={data} layout="vertical">
<CartesianGrid {...chartTheme.grid} horizontal={false} />
<XAxis type="number" {...chartTheme.axis} />
<YAxis dataKey="gate" type="category" width={56} {...chartTheme.axis} />
<Tooltip {...chartTheme.tooltip} />
<Bar dataKey="scans" fill="var(--ploxum-color-chart-series1)" radius={[0, 2, 2, 0]} />
</BarChart>
</ChartFrame>;Design rules
- No 3D charts, no gradient borders, no soft diffuse shadows on data — the frame is flat chrome around flat data.
- Always spread
chartThemerather than hardcoding hex values; that's what keeps charts correct across themes. - Series colors come from
--ploxum-color-chart-series1..n— don't introduce off-palette strokes. - Fixed
heightis deliberate: charts in a grid must not reflow as data arrives.
