Line Chart
Show how one or several measures change over time or across ordered categories.
A line chart shows how one or several measures rise and fall over time or across ordered categories, such as months. Each series is a line on one shared value axis, in a shade of the brand color by default. Hover the plot to read every series at the nearest point, or focus it and step through the points with the arrow keys; the card trails beside the crosshair.
Installation
pnpm dlx shadcn@4.18.0 add @siteplane/line-chartComplete the one-time setup first. Registry JSON lists source files and dependencies.
For this page’s examples, also install:
pnpm dlx shadcn@4.18.0 add @siteplane/card @siteplane/toggle-groupUsage
import { LineChart } from "@/siteplane/components/line-chart";
<LineChart
label="Active users by month"
data={[
{ month: "Jan", users: 1840 },
{ month: "Feb", users: 2210 },
{ month: "Mar", users: 2050 },
]}
x="month"
series={[{ key: "users", label: "Active users" }]}
/>;x names the key of the x value in each row, and each series names the key of its numbers.
Multiple lines
Pass several series to draw a line for each on the same value axis. A series that names no color takes a shade of the brand color, from strong to light, spread over the number of series. The tooltip lists every series at the active point, and the legend names them below the plot.
- Desktop
- Mobile
- Tablet
Categorical palette
palette="categorical" gives each series its own chart color, --chart-1 to --chart-8, and the eight colors repeat after the eighth series. A color on a series always wins. Pass formatValue to write the values in the tooltip and on the value axis, here as percentages.
- Email
- Search
- Social
Curves
curve sets how the line joins its points. monotone, the default, bends through every point and never swings past the data, so a line never dips below 0 or rises above its highest value, however large the numbers are. smooth is a natural spline that bends evenly across the points and can swing a little past the data between two of them. linear draws straight segments, and step holds each value until the middle between two points.
monotone (default)
smooth
linear
step
Dots
Set dots to mark every point with a dot. While a point is active, the dots outside the stretch around it step back with their line.
Dates
Pass Date objects as x values for a time axis: the rows are placed by their dates, and the labels fall on calendar days, weeks or months, as many as fit. Date values on the x axis are written in UTC, so use dates at midnight UTC for days. Text values are categories, shown in the order given. The axis writes a day as Sep 3 and the tooltip as Sep 3, 2026; pass formatX to write them another way.
Fill height
With height="fill", the chart is as tall as its box, which takes its height from the container: a flex item that grows, a grid cell, or a box with a height of its own. The chart never goes lower than minHeight, 240 px by default, and keeps that height until it has measured its box, on the server too. Its own content never makes the box taller, so a card can hand the chart whatever room the rest of the card leaves. Here the grid row is as tall as the list beside the chart, and the chart fills the room its card leaves in that row. The Bar Chart fills its box the same way.
- United States812
- Germany455
- United Kingdom318
- France267
- Canada214
- Japan196
- Brazil143
- Spain121
Changing data
New data glides in: the lines morph to it, whatever its length, and the value axis moves with them. Axis labels fade through, the old ones out before the new ones in. A series with a gap or a single point, and a change in the number of series, show at once.
- Visits
- Returning
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
Line | readonly ChartDatum[] | required | Rows of the chart: an x value and one number per series. |
Line | string | required | Key of the x value in each row: category text, or a Date for a time axis. |
Line | readonly ChartSeries[] | required | The series to draw, in order. |
Line | string | required | Accessible name of the chart. |
Line | string | unset | Id of an element that describes the chart, read after the summary of the data that the chart gives screen readers. |
Line | monotone | smooth | linear | step | monotone | How the points are joined: monotone bends through every point and never swings past the data, smooth is a natural spline that can swing a little past the data between two points, linear draws straight segments and step holds each value until the middle between two points. |
Line | boolean | false | Marks every point with a dot. A point on its own always has one. |
Line | number | fill | 240 | Height of the chart in pixels, the legend included, or fill to take the height of its box down to minHeight; the width follows the container. |
Line | number | 240 | With height fill, the least height of the chart in pixels, the legend included. |
Line | brand | categorical | brand | brand shades the brand color from strong to light; categorical gives each series its own chart color. A series’ own color wins either way. |
Line | boolean | true with more than one series | Lists the series below the plot. |
Line | boolean | true | Grid lines at the value axis ticks. |
Line | boolean | true | Labels along the x axis. |
Line | boolean | true | Labels along the value axis. |
Line | (value: number) => string | locale number (1,234.5); compact on the axis (1.2K) | Formats values in the tooltip and on the value axis. |
Line | (value: ChartXValue) => string | text as given; a date as Jan 5, and Jan 5, 2026 in the tooltip | Formats x values on the axis and in the tooltip heading. |
Line | string | en-US | Locale of numbers and dates. |
Line | string | No data | Shown in place of the marks when there is nothing to draw. |
Line | Partial<CartesianChartLabels> | English words | Replaces the words that the chart gives screen readers, each one on its own. Pass their translation when the application is in another language. |
Line | string | unset | Additional classes. |
Chart | string | required | Key of the numbers of this series in each row. |
Chart | string | required | Name shown in the legend and the tooltip. |
Chart | string | palette color | A CSS color, such as var(--chart-3), that replaces the palette color of this series. |
Cartesian | string | chart | What screen readers call the chart. |
Cartesian | string | Use the arrow keys to move between data points. | Read after the description of the chart while it is a focus stop. An empty text leaves the hint out. |
Cartesian | string | to | Joins the first and the last x value in the summary of the data, as in Jan to Jun. |
Cartesian | string | lowest | Comes before the lowest value of each series in the summary. |
Cartesian | string | highest | Comes before the highest value of each series in the summary. |
LineChartProps exports this contract. ChartDatum, ChartSeries, ChartXValue,
ChartCurve, ChartPalette and CartesianChartLabels come from the chart core,
@/siteplane/components/chart, which installs with the chart. The chart renders
a figure with the plot and, for several series, a legend; it takes no native
props or ref beyond className and aria-describedby. The categorical palette
has eight chart colors and the brand palette spreads up to eight shades, and
both repeat after the eighth series.
Usage notes
Use a line chart for a trend over time or over ordered categories, with up to five series. When the categories have no order, such as countries, use a Bar Chart. The axis gives a rough scale and the tooltip one point at a time, so show a Table when readers need exact values. Several series share one value axis, which always includes 0; there is no second axis.
A missing value (null, undefined or anything that is not a number) breaks the line at that point and leaves the series out of the tooltip there. A point on its own is drawn as a dot.
The plot is one focus stop. On hover, focus or tap, the nearest x position becomes the active item, and the chart shows:
- a hairline crosshair;
- a dot per series that glides to it;
- an inverse label on the axis that names the item;
- the tooltip card beside the crosshair, trailing it. The card’s values roll to the new ones.
The rest of the chart steps back slightly: the lines go to 80%, and the stretch around the active point stays at full strength. The legend is on by default when there is more than one series, and sits below the plot. A mouse over an entry steps the other series back; the legend does not toggle series, and the chart has no click or selection API.
Left and Right arrow keys step through the x positions, Home and End jump to the ends, and Escape closes the tooltip. Keyboard focus starts at the first x position. A tap or pen press pins the item until the next press elsewhere or Escape. Screen readers meet the plot as a chart named by label. Its description sums up the data with the first and the last x value and the lowest and the highest value of each series; a chart with no value is described by emptyLabel. While the chart is a focus stop, a hint that the arrow keys move between the data points follows the description. labels replaces these words and the role description, for example with their translation. While the keyboard or a tap moves between the items, a polite live region reads what the tooltip shows. Each row of the tooltip names its series, so the color never carries the information alone. A chart with no values is not a focus stop.
Everything that moves runs on the Motion tokens: new data glides over --motion-duration-value, and the crosshair, the dots and the axis label follow the active item over --motion-duration-follow, with the card trailing over --motion-duration-follow-trail. All of it is instant under reduced motion: the system setting, html with data-motion-reduce="true" or SiteplaneMotionProvider preset="reduced". The chart draws its plot once it has measured the width of its container. Until then, and in the server HTML, it renders the box of the plot at its full height, the legend and what screen readers read, so nothing on the page moves when the plot appears. The tooltip comes from Tooltip. The chart opens and closes it itself, so it needs no TooltipProvider, which only shares hover delays between tooltips.