Line Chart
Trend over an ordered domain, one stroke per series, color-tokened from chart variables.
Overview
LineChart is a recharts chart wired to Gremorie's design tokens through the shadcn chart primitive (ChartContainer) for trend lines over an ordered category. Pass tabular data, a serializable config that maps each value field to a label plus a color, and the xKey that names the category field. ChartContainer injects each series color as var(--color-<key>), and recharts renders the cartesian grid, axis ticks, and per-series stroked paths. Pass type to choose the interpolation curve or dots to mark each point.
Reach for LineChart when shape and direction are the headline - month-over-month conversion, weekly active users, deploys per day. Use AreaChart when the filled magnitude is the story; use BarChart for discrete category comparisons; use ScatterChart when the X axis is itself numeric and continuous.
Preview
Installation
bash npx gremorie@latest add rx-line-chart bash pnpm dlx gremorie@latest add rx-line-chart bash yarn dlx gremorie@latest add rx-line-chart bash bunx --bun gremorie@latest add rx-line-chart
Usage
import { LineChart } from "@gremorie/rx-data";
import type { ChartConfig, ChartDatum } from "@gremorie/rx-data";
const data: ChartDatum[] = [
{ month: "Jan", desktop: 186, mobile: 80 },
{ month: "Feb", desktop: 305, mobile: 200 },
{ month: "Mar", desktop: 237, mobile: 120 },
{ month: "Apr", desktop: 73, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "Jun", desktop: 214, mobile: 140 },
];
const config: ChartConfig = {
desktop: { label: "Desktop", color: "var(--chart-1)" },
mobile: { label: "Mobile", color: "var(--chart-2)" },
};
export function MonthlyTrend() {
return <LineChart data={data} config={config} xKey="month" />;
}Angular edition planned for a follow-up release; it mirrors this component's anatomy.
API
<LineChart>
The styled wrapper. Renders a ChartContainer div wrapping a recharts <LineChart> (with accessibilityLayer enabled): a cartesian grid, X axis, and one stroked <Line> per series in config, each stroked with var(--color-<key>).
| Prop | Type | Default | Description |
|---|---|---|---|
data | readonly ChartDatum[] | - | Tabular data. Each row maps string keys to numeric or category values. The column at xKey is the category; every key in config must exist on every row as a numeric value. |
config | ChartConfig | - | Maps each series key to { label, color }. The color is any CSS color or token, typically "var(--chart-1)" through "var(--chart-5)"; ChartContainer exposes it as var(--color-<key>). |
xKey | string | - | Name of the category field on each row. Drives the X axis ticks. |
type | "natural" | "monotone" | "linear" | "step" | "natural" | Interpolation curve for the lines. |
dots | boolean | false | Render a marker at each data point. |
tooltip | boolean | true | Show the hover tooltip. |
className | string | - | Merged onto the ChartContainer. Use for sizing escape hatches; the bundled style already supplies a rounded card surface plus aspect ratio. |
Chart primitive exports
@gremorie/rx-data re-exports the shadcn chart primitive so you can compose custom charts. Wrap raw recharts (Line, Area, Bar, CartesianGrid, XAxis, YAxis) inside ChartContainer:
| Export | Role |
|---|---|
ChartContainer | Provides the chart context, the responsive frame, and injects --color-<key> CSS vars from config. |
ChartTooltip / ChartTooltipContent | Token-styled hover tooltip. |
ChartLegend / ChartLegendContent | Token-styled legend. |
useChart | Hook returning the active ChartConfig from context. |
Types
| Type | Shape |
|---|---|
ChartDatum | Record<string, string | number> & { fill?: string } - one row of chart data. |
ChartConfig | Record<string, { label?: ReactNode; color?: string }> - per-series label and color map. |
Composition
- Pick
xKeyfirst - the ordered category that runs along the bottom. - Author
configmapping each value field to a label and a token-driven color. Color tokens (--chart-1through--chart-5) already encode legible contrast across light and dark themes. - Pass
dataas an array of records. - For custom layouts (different stroke widths, a custom legend, mixed series), compose raw recharts inside
<ChartContainer>(see Composing with the chart primitive).
The chart auto-sizes to its parent via recharts' ResponsiveContainer, so the wrapping surface controls the width. The default class on the ChartContainer pins the chart to aspect-video for a stable card shape.
Variations
Single series
<LineChart
data={data}
config={{ signups: { label: 'Sign-ups', color: 'var(--chart-1)' } }}
xKey="week"
/>The default shape. Reach for a single line when the story is the trajectory of one metric.
Multi-series comparison
const config: ChartConfig = {
desktop: { label: 'Desktop', color: 'var(--chart-1)' },
mobile: { label: 'Mobile', color: 'var(--chart-2)' },
};
<LineChart data={data} config={config} xKey="month" />;For shape-to-shape comparison across cohorts. Keep the count under five lines before a ScatterChart or small-multiples layout reads better.
Interpolation and dots
Set type to pick the interpolation curve ("natural", "monotone", "linear", or "step"), or dots to mark each data point:
<LineChart data={data} config={config} xKey="month" type="monotone" />
<LineChart data={data} config={config} xKey="month" dots />Composing with the chart primitive
When you need full control, skip LineChart and compose raw recharts inside ChartContainer. The container still injects your token colors and tooltip styling.
import {
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from '@gremorie/rx-data';
import { CartesianGrid, Line, LineChart, XAxis } from 'recharts';
<ChartContainer config={config}>
<LineChart accessibilityLayer data={data} margin={{ left: 12, right: 12 }}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} tickMargin={8} />
<ChartTooltip cursor={false} content={<ChartTooltipContent />} />
<Line
dataKey="desktop"
type="natural"
stroke="var(--color-desktop)"
strokeWidth={2}
dot={false}
/>
<Line
dataKey="mobile"
type="natural"
stroke="var(--color-mobile)"
strokeWidth={2}
dot={false}
/>
</LineChart>
</ChartContainer>;Compose raw recharts when you need thicker strokes, dashed segments, a reference line, or a custom legend. ChartContainer owns the responsive frame and the token color vars.
Accessibility
- Accessibility layer: recharts'
accessibilityLayeris enabled, providing keyboard navigation and screen-reader announcements for the data points. - Token contrast:
--chart-1through--chart-5are tuned for WCAG AA contrast against the card background in both light and dark themes. - Container element: the wrapper renders a
ChartContainerdiv with the series colors applied as CSS variables. - No streaming UI: charts do not implement a streaming append affordance. For live data, throttle parent updates or render inside a
useDeferredValueboundary.
Related
- AreaChart - same axes, filled under the curve, when magnitude is the story.
- BarChart - discrete categories instead of an ordered domain.
- ScatterChart - independent X plus Y when the X axis is numeric.