Components / Charts

Ridgeline

Overlapping distributions, one ridge per group: hover to lift a ridge and read its quartiles, switch datasets and every curve morphs.

Install

npx shadcn@latest add https://irisui.dev/r/ridgeline.json
import { Ridgeline } from "@/components/iris/ridgeline/ridgeline";
Registry item ridgelineBrings in foundationRegistry JSON

Preview

Ridgeline

Overlapping density curves, one ridge per group, that compare the shape of many distributions; hover to lift a ridge and read its quartiles.

When to use

  • Comparing spread, skew and bimodality across several groups at once: response times by region, session length by plan, daily highs by month.
  • Raw observations are available (at least about 20 per group); the component smooths them into a density.
  • Not when one summary number per group is enough; use BarChart. Not for more than about 20 groups.

Usage

import { Ridgeline } from "@/components/iris/ridgeline/ridgeline";

h(Ridgeline, {
  label: "FairRent scores by country",
  domain: [0, 100],
  series: [
    { id: "gr", label: "GR", values: [62, 71, 55, 64 /* … raw scores */] },
    { id: "ie", label: "IE", values: [35, 28, 41, 33 /* … */] },
  ],
});

Props

Prop Type Default Description
series { id: string; label: string; values: number[] }[] required One ridge per series, drawn top to bottom. values are raw observations.
label string required What is measured; names the chart for assistive technology.
unit string — Appended to every value and tick, such as " ms" or "°C".
formatValue (value: number) => string — Overrides unit formatting.
domain [number, number] data with a little room Fixed axis range; keeps the axis still across datasets.
overlap number 2.4 How far the tallest ridge rises into the rows above, in row heights.
rowHeight number 30 Height of one row in px.
bandwidth number Silverman's rule Smoothing in value units.
tint boolean true Shades each ridge by its median and shows a stepped scale under the axis.
active / defaultActive / onActiveChange string | null / callback — / null The lifted ridge.
emptyLabel string "No data yet" Shown when there are no values.
className string — Class on the root figure.
ref Ref<HTMLElement> — Forwarded to the root figure.

Notes

  • Keyboard: Up/Down lift the previous or next ridge, Left/Right move the reading cursor one axis step, Home/End lift the first or last ridge, Escape lowers it.
  • Accessibility: the plot is a focusable group; a polite live region announces the lifted ridge's median, middle half, range and count; a hidden table lists the statistics for every series.
  • Gotcha: row labels sit in a fixed 52px gutter (36px on narrow widths), so keep them short (codes or abbreviations) or they truncate. Tick spacing can drop toward 40px on wide plots, so long units (" ms") crowd the axis beyond about 600px of width; use a narrower container, a wider domain step, or a terse formatValue.
  • Colours come from --series-1…4; override them on an ancestor to rebrand. Comfortable up to a few thousand observations per series.