Skip to main content

AreaChart

Change over Timechart

Cumulative or part-of-whole trend over time — a filled line.

Area chart, 2 series over Jul 3, 2026–Sep 25, 2026; EMEA peaks at 5.7 in Sep 25, 2026
import { AreaChart } from "@elabs-ai/components-charts";
Install
npm install @elabs-ai/components-tokens @elabs-ai/components-ui @elabs-ai/components-charts

Skipping the @source line is the most common first failure: Tailwind does not scan node_modules, so every component renders unstyled. The one-time wiring

Prompt for your coding agent

Paste it into Claude Code, Cursor, Codex or any other coding agent. Text in [brackets] is yours to fill in.

Add the brand-ui AreaChart chart (from @elabs-ai/components-charts) to this project.

1. Read https://elabs-ai.com/llms.txt first: it maps every package and the rules. If you can use MCP servers, connect https://elabs-ai.com/mcp and use its search, docs and tokens tools. If not, run the same lookups in the terminal: `npx -y @elabs-ai/components-cli search "<what you need>"` and `npx -y @elabs-ai/components-cli docs <Component>`.
2. Look AreaChart up before writing code: `npx -y @elabs-ai/components-cli docs AreaChart` prints its real props, variants, what it pairs with and what to avoid.
3. If @elabs-ai/components-charts is not installed yet: `pnpm add @elabs-ai/components-tokens @elabs-ai/components-ui @elabs-ai/components-charts` (or `npm install @elabs-ai/components-tokens @elabs-ai/components-ui @elabs-ai/components-charts`). If this is the first brand-ui package in the project, wire it once: import `@elabs-ai/components-tokens/styles.css` plus the `themes/light.css` and `themes/dark.css` stylesheets in the CSS entry, add one Tailwind `@source` line per installed @elabs-ai package (Tailwind does not scan node_modules, so without it everything renders unstyled), and wrap the app root in `ThemeProvider` from `@elabs-ai/components-tokens`.
4. Use it here: [the screen or file, and what it should show]
5. Rules: use only @elabs-ai/components-* components and the semantic tokens — no raw colours, no raw font sizes, no arbitrary Tailwind values. Look up each component's real props with the docs tool before you use it; never guess a prop.
6. Done means: the typecheck passes, `npx -y @elabs-ai/components-cli audit src --strict` reports nothing, and you have opened the app and looked at every screen you touched in the light and the dark theme.

Use it for

  • How did it change over time? Volume over time.
  • measures over time where magnitude matters — stacked, or as a stream with offset="wiggle"

Avoid

  • one series, or series that don't add up to a meaningful total — use a line chart; fewer than about 4 points — a bar chart reads the same data faster
  • Stacking areas that are not parts of one whole — a stack asserts summation; use lines.
  • Overlapping opaque areas — either stack them or switch to a LineChart.
  • Leaving status="loading" unhandled — AreaChartLoading is the shipped skeleton.

Works with

Contains

Examples

15 live examples

Default

Multi Series

With Accessible Label

Accessible variant — announces label + description to screen readers on focus.

Loading

Categorical X Scale

Streamgraph

`AreaChart offset="silhouette"` — three product lines composed into a streamgraph, centered around zero rather than a hard baseline. Band order (bottom → top) follows JSX order: desktop, tablet, mobile.

Stream With Seams

`seams={2}` — a `--chart-background` stroke drawn between bands, the F16 "paper seam" that visually separates each ribbon from its neighbour. `seams` IS this package's separator-lines feature for stacked areas (Datawrapper's "separator lines" option) — there is no additional `separatorLines` prop.

Hairline Decoration

High decoration (`data-decoration="10"`) on a SINGLE-series `Area`: renders a `HairlineArea` — one 0.55px vertical hairline per sample, a 1.2px crest — instead of the usual pattern fill (lieflat F3 Hairline Area). `labelPeaks` rings the max sample with a filled dot + value label.

Hairline Decoration Off

`data-decoration="0"` (the default) — the same single-series chart renders its ordinary solid fill, byte-identical to `Default` above; no hairlines.

Nulls

`nulls` (RM-112). `"gap"` (the default) breaks the fill/crest at a non-numeric sample; `"connect"` bridges straight across it; `"zero"` (the pre-RM-112 default) reads it as 0 — same three modes, same resolution, as `Line`'s `nulls`.

Symbols

`symbols` (RM-112) — the same shared `resolveSeriesSymbols` rule as `Line symbols`: unset placement on a ≤12-point series defaults to hollow markers at the first/last point only.

Focus on hover

`focusOnHover` (RM-112) dims every OTHER series to `SELECTION_EXCLUDED_OPACITY` while the pointer is over one — same behaviour, same wide invisible hit-stroke, as `Line`'s `focusOnHover`. No `legend` here (the chart's own default configuration): `SeriesFocusTargets` (issue 545) still gives a keyboard user the identical spotlight — Tab lands on one of its invisible-until-focused targets, and focusing it drives the same dim.

Selection states

`selectionStates` paints the host’s tri-state on each category’s column: selected marks carry a compound foreground/background outline, excluded marks dim AND carry a full-opacity dashed frame, so the three states stay distinguishable in greyscale.

Legend toggle

Container legend (RM-118): `legend={{ interactive: "toggle" }}` mounts `ChartLegend` above the plot with real `aria-pressed` buttons — click, or Tab then Enter, hides a series and the y-domain re-tweens around what is left visible. `focusOnHover` reuses the same fade a pointer-hovered area already had for a keyboard-focused legend item (issue 545).

Lived-in: demand desk (rolling mean, σ band, forecast, navigator)

A grid operator's demand view: two years of daily readings, a 7-day rolling mean drawn over the raw fill, a one-standard-deviation band for the usual corridor, and a fortnight's forecast with a weekly season appended at the end. The navigator's axis reaches the forecast horizon, so the default window opens on the last quarter AND the projection; the value axis keeps the full data's domain so a moved window never re-scales the picture.

API

AreaChart

PropTypeDescription
datarequiredRecord<string, unknown>[]Data array - each item should have a date field and numeric values
xDataKeystringKey in data for the x-axis (date). Default: "date"
xScaleChartXScaleTypeHow `xDataKey` values are interpreted (#352). Default: `"time"`. - `"time"` — Date (or Date-coercible) x values on a time scale. - `"band"` — categorical x values (`"Turn 1"`, `"Step A"`), evenly spaced in first-seen order. Axis ticks, the ticker and the tooltip title all show your own value, not a formatted date. - `"linear"` — numeric x values spaced by magnitude. Omitting it keeps today's behaviour, except that a dataset whose x values are ALL non-Date-coercible degrades to `"band"` (with a dev warning) instead of collapsing.
marginnumber | Partial<Margin>Chart margins: one number for every side, or per side. Default: 40 on every side.
animationDurationnumberAnimation duration in milliseconds. Default: 1100
animationEasingstringCSS easing for clip-reveal. Default: cubic-bezier(0.85, 0, 0.15, 1)
enterTransitionTransitionMotion enter transition (spring or cubic-bezier tween).
revealSignaturestringSignature of motion URL state — triggers reveal replay when it changes.
revealOnChartRevealOnWhen the enter reveal is allowed to play (#175). `"mount"` (default) plays as soon as the chart renders — no change from today. `"inView"` holds the reveal at width 0 until this chart's own container scrolls to 30% visible.
replayOnClickbooleanClicking the chart body replays the enter reveal (#175). Default `false`.
aspectRatiostringAspect ratio as "width / height". Default: "2 / 1"
plotHeightResponsive<ChartPlotHeight>The plot's own height (ADR 0039): px, or `{ aspect }` (width ÷ height), optionally per breakpoint. Wins over `aspectRatio`, which stays an alias.
classNamestringAdditional class name for the container
statusChartStatusLoading vs ready — drives chart phase and loading chrome. Default: `"ready"`.
loadingLabelstringCentered shimmer label while loading.
yDomainTweenDurationnumberAnimate y-domain over this duration (ms) on status transitions. Default: 500.
yDomainTweenbooleanAnimate y-domain when status or target domain changes. Default: true
xDomain[Date, Date]Visible x-domain for brush zoom.
xDomainSlotCountnumberFull dataset length for x-scale padding when `xDomain` is set.
tweenYDomainOnXDomainChangebooleanTween y-domain when brush changes the visible x-range. Default: false
styleCSSPropertiesInline container styles (e.g. fixed height for brush strip).
onPhaseChange(phase: ChartPhase) => voidFires when the internal chart phase changes (e.g. OG capture readiness).
childrenrequiredReactNodeChild components (Area, Grid, ChartTooltip, etc.)
onDatapointClickChartDatapointClickHandlerDrill-down (#349). Fires when a datapoint is activated by pointer OR keyboard. Setting it mounts a keyboard-operable target layer OUTSIDE the aria-hidden SVG — one tab stop, arrow keys to traverse. Leaving it unset changes nothing: no extra DOM, no new focusables.
copyValueOnActivatebooleanPut the datapoint's exact value on the clipboard when it is activated — the recovery path for a compact axis label. Default `false`; a chart with no interaction props still renders byte-identical DOM. A consumer-supplied `onDatapointClick` always wins.
datapointLabelChartDatapointLabelOverride the accessible name of each keyboard drill-down target (#349).
maxInteractiveDatapointsnumberDev-warning threshold on the number of keyboard targets. Default 500 (#349).
accessibleLabelChartA11yProps["accessibleLabel"]Accessible name for the chart region (announces to AT on focus).
accessibleDescriptionChartA11yProps["accessibleDescription"]Supplemental description read by AT (e.g. series names + value range).
offsetAreaStackOffsetStreamgraph baseline (RM-029) — maps to `d3-shape`'s `stackOffsetNone` / `Silhouette` / `Wiggle` / `Expand`. Unset (default): no stacking — every child `Area` renders independently, exactly as today. Set it to stack every child `Area` (in JSX order) using that baseline; `"silhouette"` is the F16 lieflat "Stream Ribbon" look.
seamsnumberPaper gap between stacked bands, in px — a `--chart-background` stroke drawn along each band's own top edge. Only takes effect when `offset` is set. Default: 0 (no seam). 2 is the F16 lieflat value. When set (> 0), the seam owns the band's edge (#245): the band's own crest stroke is suppressed there so the paper gap is what separates the ribbons, rather than the two painting the same path on top of each other.
labelBandsbooleanLabel each stacked band with its series name at the band's widest x (`HaloText`, clamped inside the plot). Only takes effect when `offset` is set. Default: false.
nullsNullsModeContainer-level default for an `Area`'s own `nulls` prop (RM-112). Unset — every `Area` keeps its own default (`"gap"`).
focusOnHoverbooleanHovering (or, on touch, tapping) one series dims every other series to the shared selection-excluded opacity (RM-112, `dw-river.md` §2.3). Default false — today's behaviour.
legendContainerLegendPropLegend engine (RM-118): `true` or a config object mounts `ChartLegend` beside the plot via `useContainerLegend`; `{ interactive: "toggle" }` hides a band and re-tweens the y-domain. Unset (default) renders NOTHING new (R1, moved into `useContainerLegend` itself) — RM-110's end labels stay the default multi-series key for `AreaChart`. `{ values: true }` prints each series' own last point inside the visible x window (never a stack total), in the format of the `YAxis` on its `yAxisId`; plain numbers when the series' axes format differently.
annotationsreadonly ChartAnnotation[]Declarative annotations in data units: text notes, ranges, reference lines, row notes.
analyticsreadonly ChartAnalytic[]Statistical overlays computed from `data` (ADR 0040 §1): computed `line`/`band`s (average, median, percentile, std-dev, CI) drawn through the annotation layer, and `trend`/`window`/`forecast`/`errorBars` drawn as derived series with a legend entry, a tooltip row and an accessible sentence. Unset: no change.
tooltipbooleanShow a hover/focus tooltip. Default `true`: with no `<ChartTooltip>` child the chart adds a default one; a `<ChartTooltip>` child (for `variant`, `rows`, `content`, …) replaces it. `false` turns the default off.
paletteChartPaletteColour ramp for the series (RM-186): each series child that sets no colour of its own takes the next colour of `resolvePalette(palette, n)`. Unset: every such series keeps `--chart-line-primary`, as before.
selectionStatesChartSelectionStatesResolver<Record<string, unknown>>Maps a mark (category, optional series key, optional raw row) to its selection state. Unset → the chart renders exactly as before.
dimExcludedbooleanDim `excluded` marks and add their non-hue channel (the dashed frame). Default `true`; `false` keeps the `data-selection` attribute (so a host can style it) but paints nothing.
hoverCategoryChartHoverCategoryThe category hovered in a SIBLING chart (or by the host). `null`/unset → none.
onHoverCategory(category: ChartHoverCategory) => voidFires with the category under the pointer on move, and `null` on leave.
scrollbarChartScrollbarModeStrip style. Default `"none"` — a chart never grows a strip on its own (ADR 0040 decision b); a `window` / `defaultWindow` turns it on, as does `"miniChart"` / `"bar"` / `"auto"`.
windowNavigatorWindow | nullControlled window.
defaultWindowNavigatorWindowInitial window for the uncontrolled case.
onWindowChange(window: NavigatorWindow | null, meta: NavigatorChangeMeta) => void
minSpannumberSmallest window the user can make: a duration in ms (time) or a row count (index). Default: 5× the median step (time; the stock-chart library' rule) / 3 (index).
align"start" | "end"Where an automatic first window sits. `"end"` = the latest data (the associative BI suite `scrollStartPos: 1`). Default `"start"`.
maxVisibleItemsResponsive<number | "auto">Category families (RM-141): how many categories the plot shows at once (the associative BI suite "Number of bars"). Default `"auto"` — as many as keep a readable band (`maxReadableCategories`); with `scrollbar="auto"` the strip appears only once the categories overflow that count.
maxVisiblePointsnumberTime-series families: with `scrollbar="auto"`, rows above this show the strip. Default 2000.
windowDomain"all" | "visible"Category families: `"all"` (default) keeps the value axis on the FULL data's domain while scrolling; `"visible"` refits it to the window.
zoombooleanPinch-to-zoom along the x axis (time x): two fingers on a touch screen, a trackpad pinch, or Ctrl/⌘ + wheel narrow the same window the strip moves; a two-finger drag pans it. `+` / `−` / `0` on the focused chart and the zoom buttons that appear once zoomed do the same from the keyboard. No strip is needed; with one, it follows. Default `true`; `false` leaves the gestures to the page. Off while the caller drives `xDomain` itself.
selectionGesturesreadonly ChartSelectionGesture[]Gestures to enable. Unset → no gesture layer, DOM byte-identical to today.
onSelectionIntentChartSelectionIntentHandler<Record<string, unknown>>Fires with every intent. Required for the gesture layer to mount.
selectionConfirmChartSelectionConfirmDefault `"immediate"`.
selectionFieldstringThe field name carried in intents. Default: the chart's `xDataKey`.
selectionHitRuleChartSelectionHitRuleRect / lasso hit rule. Default `"overlap"` (the report-builder BI suite).
selectionToolbar"auto" | "none"`"auto"` (default): a toolbar appears when gestures are enabled; `"none"` hides it.

Also accepts: ChartSelectionProps, ChartHoverLinkProps, ChartNavigatorProps, ChartSelectionGestureProps, FrameSizeGroupProps, Pick<LegendGroupProps, "legend">, Pick<ChartStateGroupProps, "status">, Pick<TooltipGroupProps, "tooltip">

Area

PropTypeDescription
dataKeyrequiredstringKey in data to use for y values
yAxisIdstring | numberY-scale group id (Recharts `yAxisId`). Default: `"left"`.
fillstringFill color for the area gradient start. Default: var(--chart-line-primary)
fillOpacitynumberFill opacity at the top of the area. Default: 0.4
strokestringStroke color for the line. Default: same as fill
strokeWidthnumberStroke width. Default: 2
curveCurveFactory | CurveAliasCurve interpolation — a named alias (`"linear"` | `"monotone"` | `"natural"` | `"step"` | `"step-before"` | `"step-after"`, RM-112) or a raw `@visx/curve` factory. Default: `"monotone"` (unchanged).
animatebooleanWhether to animate the area. Default: true
showLinebooleanWhether to show the stroke line. Default: true
showHighlightbooleanWhether to show highlight segment on hover. Default: true
gradientToOpacitynumberGradient opacity at bottom. Default: `0` (fully transparent) for an ordinary, unstacked area — the bottom edge is the y-axis baseline, not the encoding, so fading toward it costs no information. For a STACKED band (`AreaChart offset` set, #245) the default instead follows `fillOpacity` — a flat wash — because in a stacked/stream area BOTH edges are the encoding (band thickness is the value) and fading one away destroys it. Pass an explicit value (including `0`) to override either default.
gradientSpannumberVertical extent of the fill gradient (0–1). `1` fades across the full height; lower values compress the gradient toward the top.
fadeEdgesFadeEdgesFade the area fill (and stroke) toward transparent at the chart edges. - `true` fades both edges, `false` disables the fade entirely. - `"left"` / `"right"` fades only that side — useful when the opposite edge butts up against another element you don't want to fade into. Default: false
showMarkersbooleanRender scatter-style circle markers at each data point. Default: false
markersSeriesPointMarkerStyleMarker styling (same options as Scatter).
symbolsSeriesSymbolsSpecPlacement/style wrapper over `showMarkers`/`markers` (RM-112) — same shape and resolution rule as `Line symbols` (shared helper, `resolveSeriesSymbols`): unset → no symbols; set without a `placement` on a series with more than 12 points → also no symbols (avoid symbols on a dense, regularly-sampled series); otherwise `placement` defaults `"ends"`, `style` defaults `"hollow"`. Setting this turns markers on regardless of `showMarkers`.
dashFromIndexnumberData index from which the line stroke becomes dashed (inclusive). Useful for projecting incomplete periods, e.g. dashed from yesterday through today.
dashArraystringDash pattern for the tail segment when `dashFromIndex` is set. Default: "6,4"
nullsNullsModeHow this area draws a non-numeric sample (RM-112). Overrides the container-level `AreaChart nulls` default. Unset — read the container default, or `"gap"` with no container default (a visible break in the fill/crest at that sample, never a silent zero).
loadingStrokestringPulse stroke color while chart is loading. Default: var(--chart-foreground)
loadingStrokeOpacitynumberPulse stroke opacity while chart is loading. Default: 0.5
loadingbooleanShow the loading pulse overlay. Default: follows chart loading phase. Set `false` to disable even during loading.
loadingPulseModeLineLoadingPulseModeOverride pulse animation mode (loop / exit / enter).
labelPeaksLabelPeaksSpec | boolean`true` rings the peak sample with a filled dot + value label (RM-029) — only takes effect when this `Area` renders as a `HairlineArea`, a single-series chart under high decoration (`data-decoration` ≥ 8). A number or `{ count, minGap? }` instead labels the top-k highest points, the SAME engine `Line.labelPeaks` uses — never a forked copy. Default: `false` — no peak label, today's behaviour.
namestringSeries display name — the text of its end label, key item and auto summary (RM-110). Default: `dataKey`.
seriesLabelResponsive<SeriesLabelMode>Where the series names itself (RM-110): `"end"` | `"key"` | `"none"`, or a `Responsive` value. Default: as `LineProps.seriesLabel` (two or more series, and only for a series with a real `name`). Read by the chart shell, which reserves the margin and places every label in one pass.
valueLabelsChartValueLabelsAutomatic value labels (RM-110) — see `LineProps.valueLabels`.

AreaBand

PropTypeDescription
lowKeystringKey in data for the band's lower edge. Ignored (and optional) when `from="zero"` — the low edge is the value-axis zero line instead.
highKeyrequiredstringKey in data for the band's upper edge.
from"zero"Bracket the band between `highKey` and the value-axis zero line instead of a second series (Datawrapper: area fill "between a line and zero"). `lowKey` is ignored when set.
fillstringFill colour. Default `var(--chart-ring-background)` — the same quiet "normal range" wash `Sparkline`'s `band` prop already draws with.
fillOpacitynumberFill opacity. Default 1 — the token itself already carries the wash.
negativeFillstringFill colour for any segment where the high edge dips BELOW the low edge (`highKey < lowKey`, or `highKey < 0` under `from="zero"`) — Datawrapper's negative-difference fill (River bar-line combination recipe). Unset: the whole band paints `fill` regardless of sign — today's behaviour.
curveCurveFactory | CurveAliasCurve function, matching the series it brackets. Default `curveMonotoneX`.
yAxisIdstring | numberY-scale group id (Recharts `yAxisId`). Default: `"left"`.
classNamestring

AreaChartLoading

PropTypeDescription
marginPartial<Margin>Chart margins
strokestringStroke color for the animated loading segment.
strokeOpacitynumberStroke opacity for the animated loading segment. Default: 0.5
gridStrokestringGrid line stroke (color and opacity via color-mix or oklch alpha).
gridShimmerStrokestringShimmer band stroke (color and opacity via color-mix or oklch alpha).
gridShimmerbooleanAnimate a shimmer band across grid lines. Default: true
gridShimmerLengthnumberShimmer band width in pixels. Default: 140
gridShimmerSpeednumberShimmer speed multiplier (higher = faster). Default: 1
gridShimmerSyncbooleanMatch shimmer loop to the loading line pulse (cycle + inter-loop pause).
labelstringCentered shimmer label text. Default: "Loading"
aspectRatiostringAspect ratio as "width / height". Default: "2 / 1"
plotHeightResponsive<ChartPlotHeight>The plot height, as on the chart it stands in for — px, `{ aspect }`, or per breakpoint. Wins over `aspectRatio`, so the placeholder holds the box the loaded chart will fill.
classNamestringAdditional class name for the container

XAxis

PropTypeDescription
numTicksnumber@deprecated Use `tickCount` — `numTicks` still wins when both are set, exactly as before (ADR 0042 A.2, row 6). Read until 7.0.0, with one development warning.
tickCountAxisTickCountTick target (RM-108). `"auto"` (default) derives it from the plot width — `tickTargetForWidth(innerWidth)`, about one tick per 90 px, clamped 2–10, and never more than the number of data rows on a time axis (6 monthly rows get at most 6 ticks, not 9 labels between them).
ticksDate[] | number[]RM-108 naming, shared with `YAxis`. On a time axis: an alias of `tickValues` (`tickValues` wins). On a numeric x with `domain`/`scale` (ScatterChart): exactly these raw x values.
domainAxisDomainNumeric x only (ScatterChart with numeric `xDataKey`, RM-108): pin either end of the x domain in raw units; `"auto"` keeps the data-derived end. Read by the chart container, so place `XAxis` as a direct child. Setting `domain` or `scale` also switches the labels from one per data row to a numeric ruler. Ignored on a time axis.
scaleValueScaleTypeNumeric x only (RM-108): `"linear"` (default), `"log"` (refuses data or a domain touching 0 — dev warning, renders linear) or `"sqrt"`.
positionXAxisOrientationWhich edge the labels sit on (RM-108). Default: `"bottom"`.
orientationXAxisOrientation@deprecated Use `position` — the same values (ADR 0042 A.2, row 10). Read until 7.0.0, with one development warning; when both are set, `position` wins.
titleReactNodeAxis title (RM-108).
titlePlacementAxisTitlePlacement`"outside"` (default) — in the margin beyond the tick labels, at the far end; `"inside"` — `HaloText` at the far end inside the plot.
tickerHalfWidthnumberWidth of the date ticker box for fade calculation. Default: 50
tickMode"domain" | "data"`"domain"` — evenly spaced ticks across the time domain (default). `"data"` — one label per data row at its x value (better with sparse or monthly bars).
tickFormat(value: Date) => stringOverride the default `Intl`-based tick label formatter. Applied to every tick this axis renders (generated or `tickValues`). #357. **Time scale only.** Ignored (with a dev warning) when the chart runs `xScale="band" | "linear"` — those modes project onto a synthetic instant, so a `Date` formatter would print a fabricated calendar date instead of your x value. Format categorical/numeric x values in your data. #352.
dateFormatDateFormatPreset | ((value: Date) => string)The date-format LADDER (RM-109): a preset from `date-format.ts` (`"year"` → `"yearShort"` → `"month"` → `"day"` → `"weekday"` → `"hour"` → `"minute"`), or a formatter function for full control. Unset (default) — the axis picks a rung itself via `dateFormatForSpan`, from the time domain's span and how many ticks are on screen, instead of the old fixed `"Mon d"` shape whatever the span. A ten-year series reads years; a 36-hour series reads hours. `tickFormat` still wins outright when both are set — it is the raw escape hatch this package has always had; `dateFormat` is the smart default underneath it. Same time-scale-only caveat as `tickFormat` (#352).
tickValuesDate[]Render exactly these tick positions, bypassing tick generation AND the default label-collision de-dupe entirely — use when the default de-dupe would collapse the axis (e.g. dense data whose formatted labels collide). #357. **Time scale only** — see `tickFormat`. #352.
periodTicksXAxisPeriodTicks | falseDraw a `HairlineFloor` (RM-017) below the plot — one hairline tick per calendar period, whether or not a data row falls on it, with the long tick anchored to a real calendar boundary (day → the first day of the week, week → the first week of the month, month → January), not an index stride from wherever the series happens to start (#253). Lieflat provenance: the ruled foot of a ledger page gives a reader the passage of time with no labels and no axis. This is a SEPARATE visual layer from the labelled ticks above (`numTicks` / `tickMode`) — it never changes which labels render or where. `false` (default) draws nothing — today's behaviour.

YAxis

PropTypeDescription
yAxisIdstring | numberScale group id (Recharts `yAxisId`). Default: `"left"`.
positionYAxisOrientationWhich side of the chart to render labels. Default: `"left"`.
orientationYAxisOrientation@deprecated Use `position` — the same values (ADR 0042 A.2, row 11). Read until 7.0.0, with one development warning; when both are set, `position` wins.
numTicksnumber@deprecated Use `tickCount` — `numTicks` still wins when both are set, exactly as before (ADR 0042 A.2, row 7). Clamped to {@link Y_AXIS_MIN_TICK_COUNT}–{@link Y_AXIS_MAX_TICK_COUNT}. Read until 7.0.0, with one development warning.
tickCountAxisTickCountTick target (RM-108). `"auto"` (default) derives it from the plot height — `tickTargetForHeight(innerHeight)`: 3 under 200 px, else 5.
ticksnumber[]Render exactly these tick values (RM-108), bypassing generation.
domainAxisDomainPin either end of the value domain (RM-108); `"auto"` keeps the data-derived end. Read by the chart container, so place `YAxis` as a direct child. On a length encoding (bars) the domain always includes 0 — a non-zero lower bound is ignored with a dev warning (`charts-honesty`).
scaleValueScaleTypeHow values map to pixels (RM-108). `"log"` refuses data or a domain that touches 0 (dev warning, renders linear); bars are linear only. Default: `"linear"`.
titleReactNodeAxis title — names the unit of every tick (RM-108).
titlePlacementAxisTitlePlacement`"outside"` (default) — above the top tick label in the margin; `"inside"` — `HaloText` at the top of the axis inside the plot.
labelPlacementAxisLabelPlacement`"outside"` (default) — tick labels in the margin beside the plot; `"inside"` — labels sit just above their grid line inside the plot.
valueFormatChartValueFormatHow tick values are rendered. Default: `"compact"` — `1.5M`, not `1500k` and not `1500000`. Pass `"number"` for every digit.
currencystringISO 4217 code for `valueFormat: "currency"`. Falls back to `ChartConfigProvider`, then `"USD"`.
formatValue(value: number) => stringCustom formatter for tick labels. Overrides `valueFormat` entirely when set.
unitstringUnit text appended to {@link unitOn} tick(s) — `<YAxis unit="%" />` paints `"80 %"` on that tick, not every tick (RM-109). The tooltip is the place a unit repeats on every value (the blog's "3.4 % unemployed", not a bare "3.4 %"); see `TooltipRow.unit`.
unitOn"last" | "first" | "all"Which tick(s) {@link unit} paints on. Default: `"last"`.
matchSeriesColorbooleanPaint the tick labels and title in the colour of this axis' series when it carries exactly ONE series; neutral otherwise (RM-121, Datawrapper's "label colour: match data"). The text goes through `seriesLabelInk` — the stroke mixed toward the label ink so it still reads at 4.5:1. Default `false`.
sideLabelReactNode | "auto"A caption naming which scale this is, above the tick column (RM-121). `"auto"` → "Left scale" / "Right scale" by `position`, through the locale seam (`charts.axis.leftScale` / `charts.axis.rightScale`).

ChartTooltip

PropTypeDescription
showDatePillbooleanWhether to show the date pill under the plot. Default: shown when it fits the chart's bottom margin (≥ 36px) — never painted over a small plot.
showCrosshairbooleanWhether to show the vertical crosshair line. Default: true
showDotsbooleanWhether to show dots on the lines. Default: true
indicatorColorstring | ((point: Record<string, unknown>) => string)Color for the crosshair/indicator line. When a function, receives the hovered point (e.g. for candlestick: match candle color from close vs open). Default: --chart-crosshair.
content(props: { point: Record<string, unknown>; index: number }) => React.ReactNodeCustom content renderer for the tooltip box
rows(point: Record<string, unknown>) => TooltipRow[]Custom row renderer - return array of TooltipRow
variantChartTooltipVariantBox layout preset (RM-119). `"rows"` (default) is today's stacked `ChartTooltipContent`. `"table"` renders `ChartTooltipTable` — one column per series with a header row, the date in the `<caption>` (Datawrapper's dual-axis / multi-series shape, `dw-charts.md` §2.22). `"inline"` renders no box at all — `ChartTooltipInline` paints the hovered (or `focus`-nearest) series' value directly at the mark with `HaloText` (the bikes chart). Ignored when `content` is set — a custom renderer already owns the whole box.
focusbooleanDrive RM-112's per-series dim (`SeriesHoverDim`) from the tooltip's OWN nearest-series resolution: whichever series' y position is closest to the pointer, at ANY x along the crosshair, counts as hovered — not only a direct hover on that series' own 2px stroke. Works standalone: it registers "focus requested" on the shared series-mode context, so the dim fires with no `focusOnHover` prop on the `LineChart`/`AreaChart` container (a container `focusOnHover` still works exactly as before, and the two compose — either one turns the dim on). Also the default target series for `variant="inline"`. Default false.
pinbooleanTap-to-pin (RM-119): on a coarse pointer, a tap keeps the tooltip open instead of clearing the instant the finger lifts. A second tap on the mark, `Esc`, or a tap outside the chart releases it (announced once via `role="status" aria-live="polite"`). Default: `true` only when the pointer is coarse (`(pointer: coarse)` media query); pass an explicit boolean to force either way regardless of pointer type.
valueInTitlebooleanSwap the tooltip box's own title for nothing — the hovered value moves to the chart's OWN title instead (RM-119, #610). Inside a `ChartFrame` that shows a title this is automatic: while a row is hovered, pinned or keyboard-focused the frame's title reads "Apr: Revenue 40" and is announced once through the frame's polite status; leaving restores the title. No wiring. Outside a frame (or in `chrome="bare"`, a custom `headerSlot`, the expanded dialog) only the box title is dropped — the date/category is still on `useChart().tooltipData` for a custom title. Default false.
dotColorstring | ((point: Record<string, unknown>, line: LineConfig) => string)Override tooltip dot fill. When omitted and `rows` is set, dot colors match row colors. When a function, receives the hovered point and line config.
childrenReact.ReactNodeAdditional content to show below rows (e.g., markers)
classNamestringCustom class name
springConfigSpringConfigPer-chart override for the crosshair / dot / date-pill spring.
boxSpringConfigSpringConfigPer-chart override for the floating-panel spring.
panelStyleReact.CSSPropertiesInline styles for the tooltip panel (background, blur, etc.).
unitstringUnit text appended to every DEFAULT row's value (RM-109) — the same `unit` `<YAxis>` paints on one tick. Set automatically from the chart's own `<YAxis unit>` when unset (the shell threads it through); pass it explicitly only to override. Ignored when `rows` is set — a custom row builder owns its own `TooltipRow.unit` per row.
valueFormatChartValueFormatSTYLE to borrow from the chart's own `<YAxis valueFormat>` for DEFAULT rows (RM-109) — a currency symbol, a percent sign — never abbreviation (`ChartTooltipContent`'s doc). Set automatically from `<YAxis valueFormat>` when unset; ignored when `rows` is set.
currencystringISO 4217 code for `valueFormat`'s `style: "currency"`.

Theming

The tokens each state resolves to. Change the token and every theme follows.

StateToken
statusstatus="loading" → AreaChartLoading skeleton; "ready" → the plot