Skip to content
Charts

Area Chart

Time series with a filled region. Default and Motion variants.

Examples

Installation

Default is a ready-made wrapper from the registry. Motion is the composable engine at @cronus-ui/ui/charts (peer visx + motion).

bash
npx cronus-ui add area-chart
tsx
import { AreaChart } from "@cronus-ui/ui";

Usage

Default is a ready-made series wrapper. Motion is composable: drop Area, Grid, axes, tooltip, PatternArea, ChartBrush, or markers as children. ChartTooltip from `@cronus-ui/ui/charts` is not the recharts tooltip.

tsx
import { AreaChart, Area, Grid, XAxis, ChartTooltip } from "@cronus-ui/ui/charts";
<AreaChart data={data} animationDuration={1100}>
<Grid horizontal />
<Area dataKey="revenue" fadeEdges fill="var(--chart-line-primary)" fillOpacity={0.3} />
<Area dataKey="costs" fadeEdges fill="var(--chart-line-secondary)" fillOpacity={0.3} />
<XAxis />
<ChartTooltip />
</AreaChart>

Components

Motion API — compose these under the chart root. Default wrapper props are in Default API below.

AreaChart

Root that sizes the SVG, provides scales, and hosts series children.

Skip AreaChartProps props table
PropTypeDefaultDescription
data*
Record<string, unknown>[]Rows with a date (or x) field and numeric series.
xDataKey
string"date"Key for the x-axis.
margin
`Partial<{ top, right, bottom, left }>`{ top: 40, right: 40, bottom: 40, left: 40 }Plot margins.
animationDuration
number1100Clip-reveal duration in ms.
aspectRatio
string"2 / 1"CSS aspect ratio.
status
"loading" | "ready""ready"Loading ↔ ready choreography.
xDomain
[Date, Date]Visible x-range for brush zoom.
className
stringContainer class.
yDomainTween
booleantrueAnimate the y-domain on status/domain changes.

Area

Filled series with an optional stroke, edge fade, markers, and a dashed tail.

Skip AreaProps props table
PropTypeDefaultDescription
dataKey*
stringY-value key.
yAxisId
string | number"left"Scale group for dual axes.
fill
stringvar(--chart-line-primary)Gradient start color.
fillOpacity
number0.4Opacity at the top of the fill.
stroke
stringsame as fillLine color.
strokeWidth
number2Line width.
curve
CurveFactorycurveMonotoneXd3 curve.
fadeEdges
boolean | "left" | "right"falseFade fill/stroke at chart edges.
showMarkers
booleanfalseRing markers at each point.
dashFromIndex
numberIndex from which the stroke becomes dashed.

PatternArea

Filled area using an SVG pattern (`url(#id)`). Define PatternLines (or another visx pattern) as a child, then pair with an Area that has fillOpacity={0} for the stroke.

Skip PatternAreaProps props table
PropTypeDefaultDescription
dataKey*
stringY-value key.
fill*
stringPattern URL, e.g. url(#hatch).
curve
CurveFactorycurveMonotoneXd3 curve.

Grid

Plot-area grid lines. Horizontal by default; optional shimmer while loading.

Skip GridProps props table
PropTypeDefaultDescription
horizontal
booleantrueShow horizontal lines.
vertical
booleanfalseShow vertical lines.
numTicksRows
number5Horizontal line count.
numTicksColumns
number10Vertical line count.
stroke
stringvar(--chart-grid)Line color while ready.
strokeDasharray
string"4,4"Dash pattern.
shimmer
booleanfalseAnimate a band across horizontal lines.
highlightRowValues
number[]Rows drawn with alternate styling (e.g. zero).

Background

Pattern fill for the plot area when you omit Grid, or as a texture behind series.

Skip BackgroundProps props table
PropTypeDefaultDescription
pattern
PatternPresetId | "none"Pattern preset. `none` renders nothing.
color
stringvar(--chart-grid)Pattern stroke color.
opacity
number1Pattern fill opacity.
fadeHorizontal
booleantrueFade at left/right edges.

YAxis

Value labels on the left or right. Pair `yAxisId` with series for dual axes.

Skip YAxisProps props table
PropTypeDefaultDescription
yAxisId
string | number"left"Scale group id.
orientation
"left" | "right""left"Which side to render.
numTicks
number5Approximate tick count.
formatLargeNumbers
booleantrueFormat 1000 as "1k".
formatValue
(value: number) => stringCustom tick formatter. Overrides formatLargeNumbers.

XAxis

Time-axis labels that fade when the crosshair passes.

Skip XAxisProps props table
PropTypeDefaultDescription
numTicks
number5Tick labels to show, including first and last.
tickerHalfWidth
number50Fade radius around the date pill.
tickMode
"data" | "domain""data"`data` snaps labels to rows (crosshair-aligned). `domain` spaces ticks evenly.

ChartTooltip

Motion tooltip: crosshair, series dots, floating panel, optional date pill. This is not the recharts ChartTooltip from `@cronus-ui/ui`.

Skip ChartTooltipProps props table
PropTypeDefaultDescription
showDatePill
booleantrueAnimated date ticker on the x-axis.
showCrosshair
booleantrueVertical crosshair.
showDots
booleantrueDots on series at the hovered x.
dotVariant
"dot" | "ring""dot"Filled circle or ring.
indicatorColor
string | (point) => stringCrosshair and dot color.
indicatorDasharray
stringDash pattern for the crosshair.
indicatorFadeEdges
"both" | "top" | "bottom" | "none""both"Vertical crosshair fade.
matchCrosshair
booleanfalsePanel uses the crosshair spring when true.
damping
number20Panel follow when matchCrosshair is false. 0 = instant.
content
(props) => ReactNodeCustom tooltip renderer.
rows
(point) => TooltipRow[]Custom row generator.

Pattern fills

Declare a visx pattern as a child of AreaChart, paint PatternArea with url(#id), and keep a transparent Area for the stroke line.

tsx
import { AreaChart, Area, PatternArea, PatternLines, XAxis, ChartTooltip } from "@cronus-ui/ui/charts";
<AreaChart data={data}>
<PatternLines id="hatch" height={6} width={6} stroke="var(--chart-1)" strokeWidth={1} orientation={["diagonal"]} />
<PatternArea dataKey="revenue" fill="url(#hatch)" />
<Area dataKey="revenue" fillOpacity={0} stroke="var(--chart-1)" />
<XAxis />
<ChartTooltip />
</AreaChart>

Brush zoom

Wrap the main chart in ChartBrushLayout. Render a simplified strip in brushStrip with ChartBrush. Pass xDomain and xDomainSlotCount to the main AreaChart so the visible window follows the selection.

tsx
import { AreaChart, Area, ChartBrush, ChartBrushLayout, Grid, XAxis, ChartTooltip } from "@cronus-ui/ui/charts";
<ChartBrushLayout data={data} enabled height={72} brushStrip={(layout) => (
<AreaChart data={data} animationDuration={0} status="ready">
<Area dataKey="revenue" fillOpacity={0.15} animate={false} />
<ChartBrush initialSelection={layout.brushSelection ?? undefined} onSelectionChange={layout.onBrushSelectionChange} />
</AreaChart>
)}>
{(layout) => (
<AreaChart data={data} xDomain={layout.xDomain} xDomainSlotCount={layout.xDomainSlotCount} tweenYDomainOnXDomainChange>
<Grid horizontal />
<Area dataKey="revenue" />
<XAxis />
<ChartTooltip />
</AreaChart>
)}
</ChartBrushLayout>

Loading

Keep one chart instance and flip `status` between `"loading"` and `"ready"`. Grid shimmer and series pulse/sweep stay in sync. `loadingLabel` draws a centered shimmer caption.

tsx
<AreaChart data={data} status={ready ? "ready" : "loading"} loadingLabel="Loading">
<Grid horizontal shimmer />
<Area dataKey="revenue" />
<XAxis />
</AreaChart>

Data format

`xDataKey` defaults to `date`. Values must be numbers.

ts
type Point = {
date: Date;
revenue: number;
costs: number;
};
const data: Point[] = [
{ date: new Date("2026-01-01"), revenue: 12000, costs: 8500 },
{ date: new Date("2026-01-02"), revenue: 13500, costs: 9200 },
];

Theming

Motion charts read `--chart-*` aliases that map onto Cronus semantic tokens (`--cronus-chart-1`…`--cronus-chart-5`, `--cronus-border`, `--cronus-fg`, surfaces). Override the aliases or the tokens — never palette scales (`bg-zinc-900`). Default wrappers use `ChartConfig` with `var(--cronus-chart-*)` / `var(--cronus-primary)`.

Full token reference: Theming.

Dependencies

Default needs the recharts peer. Motion needs visx (and sometimes d3) as optional peers — install only what this chart uses.

bash
bun add recharts
bash
bun add @visx/curve @visx/responsive @visx/scale @visx/shape motion react-use-measure @visx/gradient @visx/pattern @visx/brush

Default API

Generated from the Default wrapper's exported types. Motion subcomponents are documented above.

AreaChartProps

Extends HTMLAttributes<HTMLDivElement>

Skip AreaChartProps props table
PropTypeDefaultDescription
data*
Record<string, unknown>[]
xKey
string"date"Category / time field.
series*
ChartSeries[]
formatValue
(value: number, name: string) => string