Skip to main content
Gremorie

Area Chart

Cumulative quantity over an ordered domain, filled under the curve and color-tokened by series.

Overview

AreaChart is a recharts chart wired to Gremorie's design tokens through the shadcn chart primitive (ChartContainer) for filled-area 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 filled paths. Pass stacked to layer the series or type to choose the interpolation curve.

Reach for AreaChart when the magnitude of a series matters as much as its trend - traffic by month, revenue by week, error count by day. For pure shape comparison without magnitude emphasis, prefer LineChart; for discrete category-vs-category comparisons, prefer BarChart.

Preview

Installation

bash npx gremorie@latest add rx-area-chart
bash pnpm dlx gremorie@latest add rx-area-chart
bash yarn dlx gremorie@latest add rx-area-chart

bash bunx --bun gremorie@latest add rx-area-chart

Usage

import { AreaChart } 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 MonthlyVisitors() {
  return <AreaChart data={data} config={config} xKey="month" />;
}

Angular edition planned for a follow-up release; it mirrors this component's anatomy.

API

<AreaChart>

The styled wrapper. Renders a ChartContainer div wrapping a recharts <AreaChart> (with accessibilityLayer enabled): a cartesian grid, X axis, and one filled <Area> per series in config, each filled and stroked with var(--color-<key>).

PropTypeDefaultDescription
datareadonly ChartDatum[]-Tabular data. Each row is a record from 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.
stackedbooleanfalseStack the series instead of overlaying them.
type"natural" | "monotone" | "linear" | "step""natural"Interpolation curve for the areas.
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 (Area, Bar, Line, 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 category that runs along the bottom (months, weeks, version numbers).
  2. Author config mapping each value field to a label and a token-driven color. The --chart-1 through --chart-5 tokens already encode legible contrast across light and dark themes.
  3. Pass data as an array of records.
  4. For custom layouts (different grid density, 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

<AreaChart
  data={data}
  config={{ visits: { label: 'Visits', color: 'var(--chart-1)' } }}
  xKey="month"
/>

The default shape. Reach for a single area when one metric is the headline.

Multi-series

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

<AreaChart data={data} config={config} xKey="month" />;

For side-by-side comparison. Areas overlap with fillOpacity at 0.4 so the lower series stays visible behind the higher one. Limit to three series before reaching for LineChart instead.

Stacked and interpolation

Set stacked to layer the series, or type to pick the interpolation curve ("natural", "monotone", "linear", or "step"):

<AreaChart data={data} config={config} xKey="month" stacked />
<AreaChart data={data} config={config} xKey="month" type="step" />

Composing with the chart primitive

When you need full control, skip AreaChart 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 { Area, AreaChart, CartesianGrid, XAxis } from 'recharts';

<ChartContainer config={config}>
  <AreaChart 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 indicator="dot" />}
    />
    <Area
      dataKey="desktop"
      type="natural"
      fill="var(--color-desktop)"
      fillOpacity={0.4}
      stroke="var(--color-desktop)"
    />
  </AreaChart>
</ChartContainer>;

Compose raw recharts when the surface needs a different aspect, 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: the --chart-1 through --chart-5 tokens 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, render the chart inside a useDeferredValue boundary or throttle parent updates to a sustainable frame budget.
  • LineChart - same axes, no fill, when shape matters more than magnitude.
  • BarChart - discrete categories instead of an ordered domain.
  • ScatterChart - independent X plus Y when the X axis is itself numeric.

On this page