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).
npx cronus-ui add area-chart
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.
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.
| Prop | Type | Default | Description |
|---|---|---|---|
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 | number | 1100 | Clip-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 | string | — | Container class. |
yDomainTween | boolean | true | Animate the y-domain on status/domain changes. |
Area
Filled series with an optional stroke, edge fade, markers, and a dashed tail.
| Prop | Type | Default | Description |
|---|---|---|---|
dataKey* | string | — | Y-value key. |
yAxisId | string | number | "left" | Scale group for dual axes. |
fill | string | var(--chart-line-primary) | Gradient start color. |
fillOpacity | number | 0.4 | Opacity at the top of the fill. |
stroke | string | same as fill | Line color. |
strokeWidth | number | 2 | Line width. |
curve | CurveFactory | curveMonotoneX | d3 curve. |
fadeEdges | boolean | "left" | "right" | false | Fade fill/stroke at chart edges. |
showMarkers | boolean | false | Ring markers at each point. |
dashFromIndex | number | — | Index 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.
| Prop | Type | Default | Description |
|---|---|---|---|
dataKey* | string | — | Y-value key. |
fill* | string | — | Pattern URL, e.g. url(#hatch). |
curve | CurveFactory | curveMonotoneX | d3 curve. |
Grid
Plot-area grid lines. Horizontal by default; optional shimmer while loading.
| Prop | Type | Default | Description |
|---|---|---|---|
horizontal | boolean | true | Show horizontal lines. |
vertical | boolean | false | Show vertical lines. |
numTicksRows | number | 5 | Horizontal line count. |
numTicksColumns | number | 10 | Vertical line count. |
stroke | string | var(--chart-grid) | Line color while ready. |
strokeDasharray | string | "4,4" | Dash pattern. |
shimmer | boolean | false | Animate 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.
| Prop | Type | Default | Description |
|---|---|---|---|
pattern | PatternPresetId | "none" | — | Pattern preset. `none` renders nothing. |
color | string | var(--chart-grid) | Pattern stroke color. |
opacity | number | 1 | Pattern fill opacity. |
fadeHorizontal | boolean | true | Fade at left/right edges. |
YAxis
Value labels on the left or right. Pair `yAxisId` with series for dual axes.
| Prop | Type | Default | Description |
|---|---|---|---|
yAxisId | string | number | "left" | Scale group id. |
orientation | "left" | "right" | "left" | Which side to render. |
numTicks | number | 5 | Approximate tick count. |
formatLargeNumbers | boolean | true | Format 1000 as "1k". |
formatValue | (value: number) => string | — | Custom tick formatter. Overrides formatLargeNumbers. |
XAxis
Time-axis labels that fade when the crosshair passes.
| Prop | Type | Default | Description |
|---|---|---|---|
numTicks | number | 5 | Tick labels to show, including first and last. |
tickerHalfWidth | number | 50 | Fade 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`.
| Prop | Type | Default | Description |
|---|---|---|---|
showDatePill | boolean | true | Animated date ticker on the x-axis. |
showCrosshair | boolean | true | Vertical crosshair. |
showDots | boolean | true | Dots on series at the hovered x. |
dotVariant | "dot" | "ring" | "dot" | Filled circle or ring. |
indicatorColor | string | (point) => string | — | Crosshair and dot color. |
indicatorDasharray | string | — | Dash pattern for the crosshair. |
indicatorFadeEdges | "both" | "top" | "bottom" | "none" | "both" | Vertical crosshair fade. |
matchCrosshair | boolean | false | Panel uses the crosshair spring when true. |
damping | number | 20 | Panel follow when matchCrosshair is false. 0 = instant. |
content | (props) => ReactNode | — | Custom 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.
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.
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.
<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.
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.
bun add recharts
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>
| Prop | Type | Default | Description |
|---|---|---|---|
data* | Record<string, unknown>[] | — | — |
xKey | string | "date" | Category / time field. |
series* | ChartSeries[] | — | — |
formatValue | (value: number, name: string) => string | — | — |