Icicle chart
A tree as rows of rectangles, one row per level, each as wide as its share of the row above. Click a cell to drill in; the top row or breadcrumb climbs back out.
| Node | Value |
|---|---|
| main.js | 428 kB |
| main.js > node_modules | 309 kB |
| main.js > node_modules > react-dom | 130 kB |
| main.js > node_modules > react-dom > client | 118 kB |
| main.js > node_modules > react-dom > server | 12 kB |
| main.js > node_modules > date-fns | 62 kB |
| main.js > node_modules > date-fns > locale | 46 kB |
| main.js > node_modules > date-fns > format | 9 kB |
| main.js > node_modules > date-fns > parse | 7 kB |
| main.js > node_modules > chart.js | 93 kB |
| main.js > node_modules > chart.js > controllers | 31 kB |
| main.js > node_modules > chart.js > scales | 24 kB |
| main.js > node_modules > chart.js > core | 38 kB |
| main.js > node_modules > lodash | 24 kB |
| main.js > src | 100 kB |
| main.js > src > pages | 53 kB |
| main.js > src > pages > dashboard | 28 kB |
| main.js > src > pages > settings | 14 kB |
| main.js > src > pages > billing | 11 kB |
| main.js > src > components | 39 kB |
| main.js > src > components > table | 17 kB |
| main.js > src > components > forms | 13 kB |
| main.js > src > components > charts | 9 kB |
| main.js > src > api | 8 kB |
| main.js > polyfills | 19 kB |
Usage
use hydroxy_leptos::icicle_chart::*;
use leptos::prelude::*;
fn module(name: &str, files: &[(&str, f64)]) -> Tree {
Tree::branch(name, files.iter().map(|(n, v)| Tree::leaf(*n, *v)).collect())
}
pub fn demo() -> AnyView {
// A web app's JavaScript bundle, in kB after minification.
let bundle = Tree::branch(
"main.js",
vec![
Tree::branch(
"node_modules",
vec![
module("react-dom", &[("client", 118.0), ("server", 12.0)]),
module("date-fns", &[("locale", 46.0), ("format", 9.0), ("parse", 7.0)]),
module("chart.js", &[("controllers", 31.0), ("scales", 24.0), ("core", 38.0)]),
Tree::leaf("lodash", 24.0),
],
),
Tree::branch(
"src",
vec![
module("pages", &[("dashboard", 28.0), ("settings", 14.0), ("billing", 11.0)]),
module("components", &[("table", 17.0), ("forms", 13.0), ("charts", 9.0)]),
Tree::leaf("api", 8.0),
],
),
Tree::leaf("polyfills", 19.0),
],
);
view! { <IcicleChart root=bundle label="Bundle size by module" format=|v: f64| format!("{v:.0} kB") /> }.into_any()
}use dioxus::prelude::*;
use hydroxy_dioxus::icicle_chart::{IcicleChart, Tree};
fn module(name: &str, files: &[(&str, f64)]) -> Tree {
Tree::branch(name, files.iter().map(|(n, v)| Tree::leaf(*n, *v)).collect())
}
#[component]
pub fn IcicleChartDemo() -> Element {
// A web app's JavaScript bundle, in kB after minification.
let bundle = Tree::branch(
"main.js",
vec![
Tree::branch(
"node_modules",
vec![
module("react-dom", &[("client", 118.0), ("server", 12.0)]),
module("date-fns", &[("locale", 46.0), ("format", 9.0), ("parse", 7.0)]),
module("chart.js", &[("controllers", 31.0), ("scales", 24.0), ("core", 38.0)]),
Tree::leaf("lodash", 24.0),
],
),
Tree::branch(
"src",
vec![
module("pages", &[("dashboard", 28.0), ("settings", 14.0), ("billing", 11.0)]),
module("components", &[("table", 17.0), ("forms", 13.0), ("charts", 9.0)]),
Tree::leaf("api", 8.0),
],
),
Tree::leaf("polyfills", 19.0),
],
);
rsx! {
IcicleChart { root: bundle, label: "Bundle size by module", format: |v: f64| format!("{v:.0} kB") }
}
}
Anatomy
| Component | data-part | Renders |
|---|---|---|
IcicleChart | root | figure with a screen-reader table of every node |
| breadcrumb | Path from the root to the current zoom; earlier steps are buttons |
| marks | Focusable SVG; arrow keys move between cells |
| cell | One node's rectangle and label; `data-depth`, `data-leaf`, `data-active` |
| tooltip | Name, value and share of the zoomed node |
| legend | Top-level branches when there are two or more |
Keyboard
| Key | Does |
|---|---|
Arrow keys | Move between cells in tree order |
Home / End | Jump to the first or last cell |
Enter / Space | Drill into the focused cell, or out from the top row |
Escape | Clear the focused cell, then climb out |
Props
| Prop | Type | Notes |
|---|---|---|
root | Tree | Required. Branch values come from their children |
label | String | Required. What the chart shows; the accessible name |
height | u16 | Plot height in px at an 800px drawing width. Default 320 |
format | Fn(f64) -> String | Formats values in the 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 |
view | Signal<View> | Controlled focused node. Uncontrolled when left off |
on_view_change | Callback<View> | Called when the focused node changes; not for changes that came from `view` |