Ridgeline chart
One density curve per group, stacked in overlapping rows. Each ridge is scaled to its own peak, so it reads shape and shift across many groups, such as months or cohorts, rather than absolute counts.
| Group | Value |
|---|---|
| January | 6°C |
| January | 8°C |
| January | 7°C |
| January | 5°C |
| January | 9°C |
| January | 4°C |
| January | 7°C |
| January | 8°C |
| January | 6°C |
| January | 10°C |
| January | 7°C |
| January | 5°C |
| January | 3°C |
| January | 8°C |
| January | 7°C |
| January | 6°C |
| February | 7°C |
| February | 9°C |
| February | 8°C |
| February | 6°C |
| February | 10°C |
| February | 5°C |
| February | 8°C |
| February | 11°C |
| February | 7°C |
| February | 9°C |
| February | 6°C |
| February | 8°C |
| February | 4°C |
| February | 9°C |
| February | 10°C |
| February | 7°C |
| March | 10°C |
| March | 12°C |
| March | 9°C |
| March | 11°C |
| March | 14°C |
| March | 8°C |
| March | 13°C |
| March | 10°C |
| March | 12°C |
| March | 11°C |
| March | 15°C |
| March | 9°C |
| March | 10°C |
| March | 13°C |
| March | 11°C |
| March | 12°C |
| April | 13°C |
| April | 15°C |
| April | 12°C |
| April | 16°C |
| April | 14°C |
| April | 11°C |
| April | 17°C |
| April | 13°C |
| April | 15°C |
| April | 14°C |
| April | 18°C |
| April | 12°C |
| April | 16°C |
| April | 13°C |
| April | 15°C |
| April | 14°C |
| May | 16°C |
| May | 18°C |
| May | 17°C |
| May | 20°C |
| May | 15°C |
| May | 19°C |
| May | 22°C |
| May | 17°C |
| May | 18°C |
| May | 16°C |
| May | 21°C |
| May | 18°C |
| May | 19°C |
| May | 17°C |
| May | 23°C |
| May | 18°C |
| June | 19°C |
| June | 21°C |
| June | 20°C |
| June | 24°C |
| June | 18°C |
| June | 22°C |
| June | 26°C |
| June | 20°C |
| June | 23°C |
| June | 21°C |
| June | 25°C |
| June | 19°C |
| June | 22°C |
| June | 20°C |
| June | 27°C |
| June | 21°C |
Usage
use hydroxy_leptos::ridgeline_chart::{Group, RidgelineChart};
use leptos::prelude::*;
pub fn demo() -> AnyView {
let groups = vec![
Group::new("January", [6.0, 8.0, 7.0, 5.0, 9.0, 4.0, 7.0, 8.0, 6.0, 10.0, 7.0, 5.0, 3.0, 8.0, 7.0, 6.0]),
Group::new("February", [7.0, 9.0, 8.0, 6.0, 10.0, 5.0, 8.0, 11.0, 7.0, 9.0, 6.0, 8.0, 4.0, 9.0, 10.0, 7.0]),
Group::new(
"March",
[10.0, 12.0, 9.0, 11.0, 14.0, 8.0, 13.0, 10.0, 12.0, 11.0, 15.0, 9.0, 10.0, 13.0, 11.0, 12.0],
),
Group::new(
"April",
[13.0, 15.0, 12.0, 16.0, 14.0, 11.0, 17.0, 13.0, 15.0, 14.0, 18.0, 12.0, 16.0, 13.0, 15.0, 14.0],
),
Group::new(
"May",
[16.0, 18.0, 17.0, 20.0, 15.0, 19.0, 22.0, 17.0, 18.0, 16.0, 21.0, 18.0, 19.0, 17.0, 23.0, 18.0],
),
Group::new(
"June",
[19.0, 21.0, 20.0, 24.0, 18.0, 22.0, 26.0, 20.0, 23.0, 21.0, 25.0, 19.0, 22.0, 20.0, 27.0, 21.0],
),
];
view! { <RidgelineChart groups=groups label="Daily high temperature by month" format=|v: f64| format!("{v:.0}°C") /> }.into_any()
}use dioxus::prelude::*;
use hydroxy_dioxus::ridgeline_chart::{Group, RidgelineChart};
#[component]
pub fn RidgelineChartDemo() -> Element {
let groups = vec![
Group::new("January", [6.0, 8.0, 7.0, 5.0, 9.0, 4.0, 7.0, 8.0, 6.0, 10.0, 7.0, 5.0, 3.0, 8.0, 7.0, 6.0]),
Group::new("February", [7.0, 9.0, 8.0, 6.0, 10.0, 5.0, 8.0, 11.0, 7.0, 9.0, 6.0, 8.0, 4.0, 9.0, 10.0, 7.0]),
Group::new(
"March",
[10.0, 12.0, 9.0, 11.0, 14.0, 8.0, 13.0, 10.0, 12.0, 11.0, 15.0, 9.0, 10.0, 13.0, 11.0, 12.0],
),
Group::new(
"April",
[13.0, 15.0, 12.0, 16.0, 14.0, 11.0, 17.0, 13.0, 15.0, 14.0, 18.0, 12.0, 16.0, 13.0, 15.0, 14.0],
),
Group::new(
"May",
[16.0, 18.0, 17.0, 20.0, 15.0, 19.0, 22.0, 17.0, 18.0, 16.0, 21.0, 18.0, 19.0, 17.0, 23.0, 18.0],
),
Group::new(
"June",
[19.0, 21.0, 20.0, 24.0, 18.0, 22.0, 26.0, 20.0, 23.0, 21.0, 25.0, 19.0, 22.0, 20.0, 27.0, 21.0],
),
];
rsx! {
RidgelineChart { groups, label: "Daily high temperature by month", format: move |v: f64| format!("{v:.0}°C") }
}
}
Anatomy
| Component | data-part | Renders |
|---|---|---|
RidgelineChart | root | figure with a screen-reader table of every observation |
| overlay | Focusable plot; arrow keys move between rows |
| area | Filled ridge per group |
| line | Ridge outline |
| tooltip | Count, median, peak and bandwidth of the active row |
| annotation | Reference line, band or point |
Keyboard
| Key | Does |
|---|---|
ArrowDown / ArrowUp | Next or previous row (Right and Left work too) |
Home / End | First or last row |
Escape | Clear |
Props
| Prop | Type | Notes |
|---|---|---|
groups | Vec<Group> | Required. One ridge each, from the top |
label | String | Required. What the chart shows; the accessible name |
overlap | f64 | How far a ridge rises into the rows above, in rows. Default 1 |
bandwidth | f64 | Kernel bandwidth in data units. Default: Silverman's rule |
annotations | Vec<Annotation> | X in data values, y in row indices |
height | u16 | Plot height in px. Default 280 |
format | Fn(f64) -> String | Formats value ticks, tooltip and table |
Events
| Prop | Type | Notes |
|---|---|---|
on_hover | Callback<Option<Datum>> | The mark under the pointer or keyboard focus changes, or is left. Fires only on a change |
on_select | Callback<Datum> | Click, tap or Enter on a mark |