Skip to main content

ScatterChart

Distributionchart

Point cloud for correlation between two continuous measures.

Scatter chart, 1 series, 28 points; highest dealSize: 93 at Jul 10, 2026
import { ScatterChart } 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 ScatterChart 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 ScatterChart up before writing code: `npx -y @elabs-ai/components-cli docs ScatterChart` 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 is it spread? Two measures per record.
  • two continuous measures per row — correlation, or the shape of a distribution

Avoid

  • one axis is categorical — use a bar or dumbbell chart
  • Connecting the points — a line asserts a sequence a scatter does not have.
  • Plotting tens of thousands of raw points — past ~20k use DensityScatterChart (every point drawn, density as colour); below that, bin or sample.
  • Distinguishing groups by colour only at default opacity — overlapping marks collapse; add shape or facets.

Works with

Contains

Examples

23 live examples

Default

Loading

`status="loading"` (RM-182): a skeleton in the plot box the chart will fill, with one polite status message per chart, at 380, 600 and 900 px.

Legend, hover only

Single Series

With Y Gradient

With Accessible Label

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

Plumb

RM-031 — lieflat F8 "Plumb Scatter": every dot hangs a hairline "plumb line" to the floor so its x position can be read straight off the axis. Unit: sessions per day. `dropLines="x"` renders these under the markers and out of hit-testing.

Extremes

Jitter Strip

Numeric X

Selection states

`selectionStates` paints the host’s tri-state on points (keyed on the datum’s region): 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.

Bubble size, colour-by and a log x-axis

Legend, colour key

Bubble Size

A 4x population draws at 2x radius (RM-039 honesty: AREA, not radius, carries the value).

Shape By Column

Each `team` draws with its own marker shape, not just its own colour (WCAG 1.4.1).

With Trend Line

A least-squares fit drawn as dashed furniture; direction/fit reach `data-trend`/`data-r2`. Deprecated: `<Scatter trend>` (used by this story and both trend-summary stories) is an alias of the shared trend analytic and is removed in 7.0.0. Pass `analytics={[{ kind: "trend", of: "revenue", model: "linear" }]}` on `ScatterChart` instead — it also adds the legend entry and the tooltip row.

Trend line with auto summary

With an `accessibleLabel` and no caller `accessibleDescription`, the trend's direction and r² fold into the auto summary — the text behind `aria-describedby`, read by AT, never drawn on screen.

Trend line with a caller-written description

The same trend, but the caller writes its own `accessibleDescription` — the auto summary (and any trend fragment) never overrides a caller's own text.

With Custom Shapes

Custom lines / areas (Datawrapper "custom lines & areas"): a constant `y=`, a constant `x=`, and a multi-point path — all drawn in data space, behind the marks.

Bubble Labels Wide

`sizeKey` doubles as the label priority by default (RM-115 × RM-110): with no explicit `labels.priority`, the biggest bubble's own `population` value decides who keeps a name when the plot cannot fit every one. Wide: most of the 40 names fit.

Bubble Labels Medium

The same 40 bubbles at 600px — fewer names fit than at 900px, more than at 380px.

Bubble Labels Narrow

The same 40 bubbles at 380px: fewer names paint, but every dropped one stays reachable through the `sr-only` restatement beside the plot.

Lived-in: ticket triage (fit, p90 rule, lasso → flagged list)

A support lead's triage view: eighty tickets, the linear fit that says slow answers score lower, the 90th-percentile response time as a computed rule on the x axis, and a lasso (or rectangle) in `explicit` confirm — the set stays provisional until ✓ or Enter, then ONE `replace` intent lands in a local selection driver and the caption lists the flagged ids. The keyboard path is the crosshair rectangle (`S`, arrows, Space).

API

ScatterChart

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"
xScaleScatterXScaleTypeHow `xDataKey` values are interpreted (#302). Default: `"time"`, unless every value is already a `number`, which infers `"linear"` — a numeric x (weight, price, …) then renders numeric tick labels and a numeric tooltip title instead of an epoch date. A categorical x remains unsupported (still warns); only `"time"`/`"linear"` are offered.
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)
enterTransitionTransition
revealSignaturestring
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 (RM-182). `"loading"` shows a skeleton in the plot box the chart will fill, with one polite status message, until the data is ready. Default: `"ready"`.
childrenrequiredReactNodeChild components (Scatter, Grid, ChartTooltip, XAxis, etc.)
onPhaseChange(phase: ChartPhase) => void
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).
legendContainerLegendPropRenders a legend beside the plot via `useContainerLegend` (RM-118). Unset renders nothing (R1). `true` uses the default placement/layout; `{ position, layout, values, title }` refines it — `interactive` is capped at `"hover"` (a legend row highlights on hover/focus but never toggles a series' visibility — Scatter has no per-series hide, unlike `BarChart`). One key per chart (RM-118 R4): when any `<Scatter colorBy>` child resolves a non-empty colour key (`resolveColorBy`, `scatter-encodings.ts` — the same categorical/sequential/diverging stops the points themselves draw), the legend lists THAT key instead of the plain per-series (`dataKey`) rows, so only one key ever shows. `shapeBy`'s categories are not represented here — the legend engine has no shape-swatch marker yet (`ChartLegendEntry.marker` doesn't cover it); a `shapeBy`-only chart keeps the plain per-series legend. `{ values: true }` prints a point count per entry: rows with a finite value in the series' `dataKey`, or rows the colour stop paints.
analyticsreadonly ChartAnalytic[]Statistical overlays computed from `data` (ADR 0040 §1, RM-138 / RM-139): computed `line`/`band`s on EITHER axis (`axis: "x"` reduces the x column), and `trend` (linear, log, exp, pow, polynomial, loess) / `window` / `errorBars` drawn as derived series with a legend entry and a tooltip row.
annotationsreadonly ChartAnnotation[]Declarative annotations in data units — text notes, ranges and reference lines (RM-111). Always honoured at runtime through the shared annotation layer; RM-188 declares the prop so it is typed and documented.
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 `Scatter` that sets no `fill` / `stroke` of its own takes the next colour of `resolvePalette(palette, n)`. Unset: series cycle the twelve categorical colours, 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.
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, ChartSelectionGestureProps, FrameSizeGroupProps, Pick<LegendGroupProps, "legend">, Pick<ChartStateGroupProps, "status">, Pick<TooltipGroupProps, "tooltip">

Scatter

PropTypeDescription
namestringSeries display name: legend and tooltip text. Unset falls back to `dataKey`, same as `Line`/`Area`'s `name`.
yAxisIdstring | numberY-scale group id (Recharts `yAxisId`). Default: `"left"`.
animatebooleanWhether to animate points with clip reveal. Default: true
yGradientboolean | { from?: string; to?: string }Color each dot by its vertical position using a chart-space linear gradient. Lower values use `from`; higher values use `to`. Default stops: red (bottom) → green (top).
dropLines"x" | "y" | "both" | falseDraw a hairline "drop line" from each point down to the axis it names — `"x"` to the bottom (x) axis, `"y"` to the left (y) axis, `"both"` for both. Rendered UNDER the markers and excluded from hit-testing (`pointer-events: none`, `aria-hidden`). Default: `false` — no drop lines, today's behavior.
labelExtremes{ /** Rank by the series' own value (`"y"`) or by x-axis position (`"x"`). */ by: "y" | "x"; /** How many points to label at EACH end (best and worst). Default: 1. */ count?: number; /** Data field to read the point's display label from. */ labelKey?: string; /** Formats the ranked numeric value next to the label. */ format?: (value: number) => string; }Hero-and-rest labeling (lieflat F8 "Plumb Scatter"): mark the `count` highest AND `count` lowest points (ranked `by`) in full-opacity ink with a `HaloText` label, fading every other point to `fadedOpacity`. `labelKey` names the data field to read the display label from; when omitted the label falls back to the chart's own x-axis date label for that row. `format`, when given, formats the numeric value alongside the label (only applied when the ranked value is a number, i.e. `by: "y"`).
fadedOpacitynumberOpacity applied to points NOT selected by `labelExtremes`. Default: 0.35.
jitternumberDeterministic jitter (`seededRnd` — identical across re-renders and test runs), as a fraction of the row band, `0–0.5`. Requires `yType="category"`; ignored otherwise.
yType"number" | "category"Treat this series' values (`d[dataKey]`) as category labels laid out on a local band scale (one row per distinct value) rather than a numeric y position on the chart's shared y-scale. Default: `"number"` — today's behavior.
highlightKeystring | ((d: Record<string, unknown>) => boolean)Highlight matching points with a non-color ring (`PeakRing` — shape, not hue, carries the emphasis; see `.claude/rules/accessibility.md`). A string names a data field read as a truthy flag (`d[highlightKey]`); a function is called with the row and returns whether it is highlighted.
sizeKeystringBubble size by a numeric column (RM-115) — `d[sizeKey]` scales the marker's radius by `sqrt(value / max)` (honesty gate: AREA, not radius, carries the value — see `areaRadius`). Rows missing `sizeKey` (or the whole series, when `sizeKey` is set but every value is non-numeric) draw at `sizeRange[0]`. Unset (default): every marker draws at `radius`.
sizeRange[number, number]`[minRadius, maxRadius]` in px for `sizeKey`. Default: `[4, 22]`.
colorByScatterColorByConfigColour each point by a fixed/categorical/numeric column (RM-115) instead of the series' own colour. A row whose `colorBy.key` is missing/unusable keeps drawing in the series' own `fill`. See `scatter-encodings.ts`' `resolveColorBy` — a consumer building a legend (RM-118) calls it with the same `data`/`colorBy` to get the identical colour stops.
shapeByScatterShapeByConfigShape each point by a categorical column (RM-115), cycling through the series-marker ramp (≤ 6 shapes; a 7th+ distinct value repeats the last shape). See `resolveShapeBy` for the legend a consumer (RM-118) reads.
trend"linear" | "log" | falseA least-squares trend line (RM-115): `"linear"` (`y = a + bx`) or `"log"` (`y = a + b·ln(x)`, points with a non-positive x dropped). `false` (default): no trend line. See `trend-line.tsx` for the regression space it fits in and its accuracy caveat for `"log"` on a `xScale="linear"` chart. @deprecated Use `analytics={[{ kind: "trend", of: dataKey, model }]}` on `ScatterChart` — the shared trend analytic, which adds the legend entry, the tooltip row and every trend model. `trend` keeps drawing the same line as an alias of it until its removal in 7.0.0.
labelsScatterLabelsPoint labels with collision avoidance (RM-110): `{ key, mode?, priority? }` — `key` is the row field holding the label text; `mode` `"auto"` (default: thinned by plot area, fewer at narrow widths) | `"all"` | a predicate; `priority` decides who survives (default: the y value). Wave-1 integration (RM-115 × RM-110): when `sizeKey` is set and `labels` does not supply its own `priority`, the bubble's OWN `sizeKey` value becomes the priority reader — the biggest bubbles keep their labels first, matching what the eye already reads as "important" on a bubble chart. Every label that is not painted is restated `sr-only` by the chart. Unlike `labelExtremes` it never fades the unlabelled points.
dataKeyrequiredstring
fillstringMarker fill color. Defaults to series stroke or chart palette color.
placement"all" | "ends" | "first" | "last"Which points get a marker (RM-112, `Line`/`Area` `symbols`). `"all"` (today's behaviour, and the default when unset) renders one per point; `"ends"` only the first and last defined point; `"first"`/`"last"` only that one.
pointSlotstring`data-slot` for every point's `<g>` (opt-in, #549) — `Scatter` passes `"scatter-point"` so its animated path names points like its static one.
strokestringOuter ring stroke color. Default: same as `fill`
strokeWidthnumberOuter ring stroke width in px. Default: 2. Set to 0 to disable.
ringGapnumberGap between the inner fill and outer ring in px. Default: 2
outlineWidthnumberOptional outer outline beyond the ring. Default: 0
outlineColorstringOuter outline color. Default: same as `stroke`
radiusnumberPoint radius in px. Default: 5
fadeOnHoverbooleanDim non-active points while hovering. Default: true
inactiveOpacitynumberOpacity for non-hovered points when `fadeOnHover` is true. Default: 0.5
inactiveBlurnumberBlur in px for non-hovered points when `fadeOnHover` is true. Applied once on the dimmed layer (not per dot) for performance. Default: 2
enterBlurnumberInitial blur in px during enter animation. Default: 2
showActiveHighlightbooleanEnlarge the active point while hovering. Default: true
shapeSeriesMarkerShapeMarker shape. Default: "circle". Used for series differentiation under high decoration. Does not affect the ring — only the filled inner shape.

Also accepts: Omit<SeriesMarkersProps, "animate">

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

Grid

PropTypeDescription
modeGridModeGrid painting mode (RM-108). Default: `"lines"`.
horizontalbooleanShow horizontal grid lines. Default: true
verticalbooleanShow vertical grid lines. Default: false
numTicksRowsnumberNumber of horizontal grid lines. Default: the height-derived target shared with `YAxis` (`tickTargetForHeight(innerHeight)` — 3 under 200 px, else 5), so rows and labels stay aligned (RM-108).
numTicksColumnsnumberNumber of vertical grid lines. Default: 10
rowTickValuesnumber[]Explicit tick values for horizontal grid lines. Overrides numTicksRows.
strokestringGrid line stroke color. Default: var(--chart-grid)
loadingStrokestringGrid stroke while loading chrome is active. Falls back to `stroke`.
strokeOpacitynumberGrid line stroke opacity. Default: 1
strokeWidthnumberGrid line stroke width. Default: `CHART_HAIRLINE_WIDTH` — the one furniture weight.
strokeDasharraystringGrid line dash array. Default: "4,4" for dashed lines
highlightRowValuesnumber[]Horizontal row values rendered with alternate styling (e.g. zero baseline).
highlightRowStrokestringStroke for highlighted rows. Default: var(--chart-foreground-muted)
highlightRowStrokeOpacitynumberStroke opacity for highlighted rows. Default: 1
highlightRowStrokeWidthnumberStroke width for highlighted rows. Default: 1
highlightRowStrokeDasharraystringDash array for highlighted rows. Default: solid line
highlightRowLabel(value: number) => string | undefinedText label drawn at the right edge of each `highlightRowValues` entry (`HaloText`, so it survives sitting on the grid) — a KPI target/goal line the reader can name, not just see. Return `undefined`/`""` to skip the label for a given value. Unset (default): no label, byte-identical to before this prop existed.
highlightColumnValuesArray<number | Date>Vertical reference lines at these `xDataKey`-domain values (e.g. "today" on a forecast chart) — the column counterpart of `highlightRowValues`. Default: none.
highlightColumnStrokestringStroke for highlighted columns. Default: var(--chart-foreground-muted)
highlightColumnStrokeOpacitynumberStroke opacity for highlighted columns. Default: 1
highlightColumnStrokeWidthnumberStroke width for highlighted columns. Default: 1
highlightColumnStrokeDasharraystringDash array for highlighted columns. Default: solid line
highlightColumnLabel(value: number | Date) => string | undefinedText label drawn at the bottom-inside, left of each `highlightColumnValues` entry (`HaloText`), e.g. "Today". Return `undefined`/`""` to skip the label for a given value. Unset (default): no label.
fadeHorizontalbooleanEnable horizontal fade effect on grid rows (fades at left/right). Default: true
fadeVerticalbooleanEnable vertical fade effect on grid columns (fades at top/bottom). Default: false
yAxisIdstring | numberY-scale for horizontal grid lines. Default: primary (`"left"`) axis.
shimmerbooleanAnimate a shimmer band across horizontal grid lines. Default: false
shimmerStrokestringShimmer band stroke (color and opacity via color-mix or oklch alpha).
shimmerLengthnumberShimmer band width in pixels. Default: 140
shimmerSpeednumberShimmer speed multiplier (higher = faster). Default: 1
shimmerSyncbooleanMatch loop timing to the loading line pulse (cycle + inter-loop pause).