Skip to main content
Gremorie

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.

The React edition (@gremorie/rx-data) renders with recharts inside the shadcn chart primitive; the Angular edition (@gremorie/ng-data) renders headless d3 geometry inside a styled SVG. The rendering engine differs; the public surface is identical input-for-input.

Anatomy

<line-chart>
└─ figure (role="img")                  card surface, aspect-video
   ├─ svg (chart frame)
   │  ├─ cartesian grid
   │  ├─ x axis (category from xKey)
   │  ├─ y axis (numeric, optional via yAxis)
   │  ├─ stroked lines, one per config key
   │  └─ dots (optional via dots)
   ├─ tooltip overlay (optional via tooltip)
   ├─ legend (when config has >1 series)
   └─ sr-only data table

The React edition composes this surface through the shadcn chart primitive:

LineChart                       styled wrapper; one Line per config entry
└─ ChartContainer               responsive frame; injects --color-<key> from config
   ├─ CartesianGrid             horizontal rules
   ├─ XAxis                     category axis
   ├─ YAxis                     numeric axis (optional, yAxis)
   ├─ ChartTooltip              hover card
   │  └─ ChartTooltipContent    token-styled tooltip body
   └─ Line                      one per series; 2px stroke; optional dots

Preview

Line chart of Desktop, Mobile by month
monthDesktopMobile
Jan18680
Feb305200
Mar237120
Apr173190
May209130
Jun214140
'use client';import {  LineChart,  type ChartConfig,  type ChartDatum,} from '@gremorie/rx-data';const monthlyData: ChartDatum[] = [  { month: 'Jan', desktop: 186, mobile: 80 },  { month: 'Feb', desktop: 305, mobile: 200 },  { month: 'Mar', desktop: 237, mobile: 120 },  { month: 'Apr', desktop: 173, mobile: 190 },  { month: 'May', desktop: 209, mobile: 130 },  { month: 'Jun', desktop: 214, mobile: 140 },];const monthlyConfig: ChartConfig = {  desktop: { label: 'Desktop', color: 'var(--chart-1)' },  mobile: { label: 'Mobile', color: 'var(--chart-2)' },};export function LineChartPreview() {  return <LineChart data={monthlyData} config={monthlyConfig} xKey="month" />;}

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" />;
}
import { Component } from '@angular/core';
import { LineChart } from '@gremorie/ng-data';
import type { ChartConfig, ChartDatum } from '@gremorie/ng-data';

@Component({
selector: 'app-monthly-trend',
imports: [LineChart],
template: `<line-chart [data]="data" [config]="config" xKey="month" />`,
})
export class MonthlyTrendComponent {
readonly 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 },
];

readonly config: ChartConfig = {
desktop: { label: 'Desktop', color: 'var(--chart-1)' },
mobile: { label: 'Mobile', color: 'var(--chart-2)' },
};
}

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>).

PropTypeDefaultDescription
datareadonly 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.
configChartConfig-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>).
xKeystring-Name of the category field on each row. Drives the X axis ticks.
type"natural" | "monotone" | "linear" | "step""natural"Interpolation curve for the lines.
dotsbooleanfalseRender a marker at each data point.
yAxisbooleantrueRender the numeric Y axis. Set to false for a minimal, axis-free line (sparkline-style).
tooltipbooleantrueShow the hover tooltip.
classNamestring-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:

ExportRole
ChartContainerProvides the chart context, the responsive frame, and injects --color-<key> CSS vars from config.
ChartTooltip / ChartTooltipContentToken-styled hover tooltip.
ChartLegend / ChartLegendContentToken-styled legend.
useChartHook returning the active ChartConfig from context.

Types

TypeShape
ChartDatumRecord<string, string | number> & { fill?: string } - one row of chart data.
ChartConfigRecord<string, { label?: ReactNode; color?: string }> - per-series label and color map.

Composition

  1. Pick xKey first - the ordered category that runs along the bottom.
  2. Author config mapping each value field to a label and a token-driven color. Color tokens (--chart-1 through --chart-5) already encode legible contrast across light and dark themes.
  3. Pass data as an array of records.
  4. 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

Line chart of Desktop by month
monthDesktop
Jan186
Feb305
Mar237
Apr173
May209
Jun214
<LineChart
  data={data}
  config={{ signups: { label: 'Sign-ups', color: 'var(--chart-1)' } }}
  xKey="week"
/>
<line-chart [data]="data" [config]="config" xKey="week" />

The default shape. Reach for a single line when the story is the trajectory of one metric.

Multi-series comparison

Line chart of Desktop, Mobile by month
monthDesktopMobile
Jan18680
Feb305200
Mar237120
Apr173190
May209130
Jun214140
const config: ChartConfig = {
  desktop: { label: 'Desktop', color: 'var(--chart-1)' },
  mobile: { label: 'Mobile', color: 'var(--chart-2)' },
};

<LineChart data={data} config={config} xKey="month" />;
<line-chart [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.

Dots

Set dots to render a marker at each data point. Reach for it when the data is sparse and you want each reading to be individually clickable / readable.

<LineChart data={data} config={config} xKey="month" dots />
<line-chart [data]="data" [config]="config" xKey="month" [dots]="true" />

Curve type

Set type to pick the interpolation curve - "natural" (default), "monotone", "linear" (straight segments), or "step" (stepped edges). Use "linear" to read exact slopes; use "step" for discrete state changes.

<LineChart data={data} config={config} xKey="month" type="monotone" />
<LineChart data={data} config={config} xKey="month" type="step" />
<line-chart [data]="data" [config]="config" xKey="month" type="monotone" />
<line-chart [data]="data" [config]="config" xKey="month" type="step" />

No axis

Set yAxis to false to drop the numeric axis for a minimal, sparkline-style line that leans on the tooltip for exact values.

<LineChart data={data} config={config} xKey="month" yAxis={false} />
<line-chart [data]="data" [config]="config" xKey="month" [yAxis]="false" />

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' accessibilityLayer is enabled, providing keyboard navigation and screen-reader announcements for the data points.
  • Token contrast: --chart-1 through --chart-5 are tuned for WCAG AA contrast against the card background in both light and dark themes.
  • Container element: the wrapper renders a ChartContainer div 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 useDeferredValue boundary.
  • 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.

On this page