A scrubbable chart with one line or several. Read any point by hover, drag or keys; lines morph on change.
Visitors
pnpm dlx shadcn@latest add @latheui/line-chartPart of Lathe Pro. Set up your project once with your license key: npx latheui init --key <key>. See Lathe Pro.
Line Chart is part of Lathe Pro
The preview is live and free to try. The source, the install and every assembly come with Pro: $79 once, with lifetime updates.
Depends on
Also accepts native div attributes. The width follows the container.
| Prop | Type | Default | Description |
|---|---|---|---|
| data* (required) | { label: string; value?: number; values?: Record<string, number>; color?: string }[] | — | Points in order. Use value for one line, or values keyed by series for several. A point's color overrides the line color around it on one-line charts. |
| series | { key: string; label: string; color?: string; dashed?: boolean; area?: boolean }[] | — | The lines to draw. Leave it out for a single line read from value. Keep keys stable so lines morph. |
| hiddenSeries | string[] | — | Controlled list of switched-off series keys. |
| defaultHiddenSeries | string[] | [] | Series switched off at first. |
| onHiddenSeriesChange | (keys: string[]) => void | — | Called when a legend button is pressed. |
| legend | boolean | true with several series | Shows the buttons that switch lines on and off. |
| curve | "linear" | "smooth" | "linear" | Straight segments, or a smooth curve that never overshoots the data. |
| onActiveChange | (index: number | null, point) => void | — | Called as the crosshair moves, and with null when it is released. |
| label* (required) | string | — | Accessible name, for example “Revenue, last 30 days”. |
| height | number | 220 | Height of the plot and its axes in pixels. |
| color | string | "var(--chart-1)" | Line color. Any CSS color. |
| negativeColor | string | color | Color of the line and tint below zero. |
| colorTransition | "blend" | "step" | "blend" | How per-point colors meet: a gradient between points, or a hard change halfway between them. |
| area | boolean | true | Tints the area between the line and the baseline. |
| yAxis | "left" | "right" | false | "left" | Side of the value labels. false hides them. |
| xAxis | "bottom" | "top" | false | "bottom" | Side of the point labels. false hides them. |
| grid | "horizontal" | "vertical" | "both" | "none" | "horizontal" | Which grid lines to draw. |
| gridStyle | "dashed" | "dotted" | "solid" | "dashed" | How grid lines are drawn. The baseline is always solid. |
| readout | boolean | true | Shows the current point's value and label above the plot. |
| valueTransition | "none" | "roll" | "slide" | "none" | How the readout value changes: digits roll, or the number slides up for a rise and down for a fall. |
| labelTransition | "none" | "slide" | "fade" | "none" | How the readout label changes between points. |
| formatValue | (value: number) => string | en-US grouping | Formats the readout and the spoken value. |
| formatTick | (value: number) => string | formatValue | Formats the value axis labels, for example without a unit. |
| classNames | { value?, caption?, axis?, grid?, baseline?, cursor? } | — | Classes for each part. Text utilities for value, caption and axis; stroke utilities for grid, baseline and cursor. |
| loading | boolean | false | With data, dims the lines while new data loads. Without data, shows a placeholder. |
| emptyMessage | ReactNode | "No data yet" | Shown when data is empty. |
Give each point a values object and list the series. A dashed line suits a comparison.
<LineChart
label="Visitors against the previous period"
curve="smooth"
data={[
{ label: "Mon", values: { current: 420, previous: 380 } },
{ label: "Tue", values: { current: 510, previous: 410 } },
]}
series={[
{ key: "current", label: "This period" },
{ key: "previous", label: "Previous", color: "var(--muted-foreground)", dashed: true },
]}
/>Axis labels are HTML and grid lines are SVG, so text and stroke utilities restyle them.
<LineChart
label="Orders per week"
data={orders}
yAxis="right"
xAxis="top"
grid="both"
gridStyle="dotted"
classNames={{
value: "font-mono text-3xl",
axis: "font-mono text-chart-2",
grid: "stroke-chart-2/25",
}}
/>negativeColor colors everything below zero. A color on a point wins over both series colors.
<LineChart label="Net cash flow" data={net} color="var(--chart-4)" negativeColor="var(--destructive)" />
<LineChart
label="Hours per phase"
colorTransition="step"
data={[
{ label: "Research", value: 18, color: "var(--chart-2)" },
{ label: "Design", value: 34, color: "var(--chart-5)" },
{ label: "Build", value: 62, color: "var(--chart-1)" },
]}
/><LineChart label="Visitors" data={visitors} valueTransition="roll" labelTransition="slide" /><LineChart
label="Response time"
data={latency}
color="var(--chart-2)"
area={false}
formatValue={(ms) => `${ms} ms`}
/>New data morphs the lines. To draw them in from the left again instead, give the chart a key that changes with the dataset.
<LineChart key={range} label="Revenue" data={series[range]} />