ridgelineY draws horizontal profiles above categorical y baselines. ridgelineX transposes the contract and extends vertical profiles to the right of categorical x baselines.
import { ridgelineY } from '@tanstack/charts/ridgeline'
const mark = ridgelineY(profileRows, {
x: 'x',
y: 'category',
height: 'height',
overlap: 0.8,
color: 'category',
})Both marks are also exported from @tanstack/charts and @tanstack/charts/universal.
The mark lays out prepared profile samples. It does not bin observations, estimate a density, or normalize values. Keep those decisions visible with transforms or application data preparation.
const bins = binX(rows, {
value: 'rating',
by: 'season',
thresholds: boundaries,
outputs: { count: { reduce: 'count' } },
})
const profiles = normalize(bins, {
value: 'count',
by: 'season',
basis: 'max',
as: 'height',
})
defineChart({
marks: [
ridgelineY(profiles, {
x: 'x',
y: 'season',
height: 'height',
overlap: 0.78,
color: 'season',
}),
],
x: { scale: scaleLinear().domain([4, 10]) },
y: {
scale: scalePoint<number>().domain(seasons).padding(0.78),
reverse: true,
},
})height must be finite and within [0, 1]. Nullish and nonfinite profile positions or heights create gaps. Sort samples into the intended profile order before passing them to the mark.
function ridgelineY<TDatum>(
source: Iterable<TDatum>,
options: RidgelineYOptions<TDatum>,
): ChartMark<TDatum>
function ridgelineX<TDatum>(
source: Iterable<TDatum>,
options: RidgelineXOptions<TDatum>,
): ChartMark<TDatum>The profile position is numeric or temporal. The category is a numeric or string ChartKey.
The public type surface includes RidgelinePosition, RidgelineCurve, RidgelineStateStyle, RidgelineYOptions, and RidgelineXOptions.
| Option | Type | Default | Meaning |
|---|---|---|---|
| x | Channel<TDatum, number | Date?> | Required by Y | Horizontal profile position for ridgelineY |
| y | Channel<TDatum, ChartKey?> | Required by Y | Categorical baseline for ridgelineY |
| x | Channel<TDatum, ChartKey?> | Required by X | Categorical baseline for ridgelineX |
| y | Channel<TDatum, number | Date?> | Required by X | Vertical profile position for ridgelineX |
| height | Channel<TDatum, number?> | Required | Normalized displacement from the category baseline |
| overlap | number | 1 | Peak displacement in category-step units |
| id | string | Layer-derived | Stable mark ID |
| key | Channel<TDatum, ChartKey> | Inferred | Stable profile-sample identity |
| color | Channel<TDatum, ChartKey?> | Category | Value sent to the chart color scale |
| fill, stroke | VisualChannel<TDatum, string> | Resolved color | Category profile paint; stroke: null omits the outline |
| fillOpacity, strokeOpacity, and strokeWidth | number | Renderer default | Area and outline presentation |
| strokeDasharray | string | None | Outline dash pattern |
| curve | RidgelineCurve | Straight | Renderer-neutral profile path generator |
| states | readonly ChartMarkState[] | None | Focus-driven opacity styles shared by area and outline |
| motion | ChartMarkMotionOptions<TDatum>['motion'] | None | Keyed area and outline motion policy |
overlap must be positive and finite. A value of 1 reaches the next category baseline, values below 1 leave space, and values above 1 overlap adjacent profiles.
The categorical axis must resolve to a point or band scale. Ridge displacement uses the smallest step in the complete configured domain, including categories without profile rows. This keeps geometry stable when a category is empty.
Point-scale padding controls room outside the first and last baseline. Set its padding to at least overlap when peaks must remain inside the plot. Use reverse: true on a y scale when the first authored category should appear at the bottom.
Categories paint in first-occurrence order; each category's area paints before all outlines. Source order therefore controls which profile is on top when overlap exceeds 1.
Each valid sample contributes one semantic interaction point even though the mark paints both an area and an outline. The point retains the exact source datum and index. ridgelineY reports the profile position as xValue and the category as yValue; ridgelineX transposes them.
Profile areas and outlines share the same points, focus affinity, state opacity, and keyed motion. Use an explicit key when positions repeat within a category.