Components / Charts
LineChart
A multi-series line chart with a gliding crosshair, legend toggles, and paths that morph between ranges.
Install
npx shadcn@latest add https://irisui.dev/r/line-chart.jsonimport { LineChart } from "@/components/iris/line-chart/line-chart";Preview
LineChart
A multi-series line chart with a gliding crosshair, legend toggles and paths that morph between ranges.
When to use
- One to three measures over time where the shape of the trend matters more than any single value, such as this period against the previous one.
- A metric card whose headline follows the crosshair: drive it from
onActiveChange. - Not for comparing categories or a handful of periods; use
BarChart. Not for parts of a whole; useDonutChart. For a long dense history with zoom, useBrushChart.
Usage
import { LineChart } from "@/components/iris/line-chart/line-chart";
const data = [
{ key: "2026-10-19", label: "Mon 19 Oct", axisLabel: "19 Oct", values: { capydb: 3186, previous: 2702 } },
{ key: "2026-10-20", label: "Tue 20 Oct", values: { capydb: 3241, previous: 2755 } },
{ key: "2026-10-21", label: "Wed 21 Oct", axisLabel: "21 Oct", values: { capydb: 3305, previous: 2690 } },
];
h(LineChart, {
label: "Daily visitors",
unit: "visitors",
data,
series: [
{ key: "capydb", label: "capydb.dev" },
{ key: "previous", label: "capydb.dev, previous 30 days", dashed: true },
],
onActiveChange: (index, datum) => setActive(datum),
});
Props
| Prop | Type | Default | Description |
|---|---|---|---|
data |
{ key; label; axisLabel?; values: Record<string, number> }[] |
required | Points in time. values holds one number per series key; missing counts as zero. Set axisLabel only on dates you want shown. |
series |
{ key; label; color?; dashed?; area? }[] |
required | Lines. The first takes the accent and an area fill by default; later ones take quieter neutral steps. |
label |
string |
required | What is measured; names the chart for assistive technology. |
unit |
string |
"" |
Unit after values in the tooltip and table. |
height |
number |
220 |
Plot height; width follows the container. |
formatValue |
(value, series) => string |
grouped, one decimal | Tooltip and table values. |
formatTick |
(value) => string |
compact (1.2K) | Value axis ticks. |
hiddenSeries / defaultHiddenSeries / onHiddenSeriesChange |
string[] / callback |
— | Controlled or initial hidden series keys. |
onActiveChange |
(index, datum) => void |
— | Fires as the crosshair moves and with null when it leaves. |
loading |
boolean |
false |
Dims the current lines while the next range loads, or shows a skeleton with no data. |
legend |
boolean |
on with 2+ series | Series toggles above the plot. |
curve |
"smooth" | "linear" |
"smooth" |
Monotone curves that never overshoot, or straight segments. |
emptyLabel / categoryLabel |
string |
"No data for this range" / "Date" | Empty state text; first column of the hidden table. |
className |
string |
— | Class on the root figure. |
ref |
Ref<HTMLElement> |
— | Forwarded to the root figure. |
Notes
- Keyboard: the plot is a slider. Left/Right (or Down/Up) step points, Page Up/Down jump about a sixth, Home/End go to the ends, Escape releases the crosshair.
- Accessibility: the figure is named by
label; a hidden summary and table list every point; legend toggles are buttons witharia-pressed. The SVG and tooltip are hidden so values are not read twice. - Motion: keep
keys stable across ranges so paths morph rather than redraw. Reduced motion swaps without animation. - Axis labels thin to about one per 76px and always keep the newest.
- Reads
--accent/--series-*,--line,--line-strong,--ink-2and--ink-3.