Arc diagram
Nodes in a row with each link drawn as an arc above them. Ordered by group, a team's own arcs stay short and the links between teams stand out as the long ones. Hover, touch or step to a node to light its arcs.
| Node | Group | Links | Weight | Linked to |
|---|---|---|---|---|
| Amara | Vision | 4 | 12 papers | Chen, Bilal, Dana, Elif |
| Chen | Vision | 4 | 11 papers | Amara, Bilal, Dana, Grace |
| Bilal | Vision | 3 | 10 papers | Amara, Chen, Luca |
| Dana | Vision | 3 | 4 papers | Amara, Chen, Jonas |
| Elif | Language | 4 | 10 papers | Amara, Grace, Farid, Ines |
| Grace | Language | 4 | 11 papers | Chen, Elif, Farid, Hugo |
| Farid | Language | 3 | 11 papers | Elif, Grace, Hugo |
| Hugo | Language | 3 | 7 papers | Grace, Farid, Ines |
| Ines | Language | 3 | 6 papers | Elif, Hugo, Kemi |
| Jonas | Robotics | 3 | 8 papers | Dana, Kemi, Mei |
| Kemi | Robotics | 3 | 10 papers | Ines, Jonas, Luca |
| Luca | Robotics | 3 | 8 papers | Bilal, Kemi, Mei |
| Mei | Robotics | 2 | 6 papers | Jonas, Luca |
Usage
use hydroxy_leptos::arc_diagram_chart::*;
use leptos::prelude::*;
pub fn demo() -> AnyView {
let people = [
("Amara", 0),
("Bilal", 0),
("Chen", 0),
("Dana", 0),
("Elif", 1),
("Farid", 1),
("Grace", 1),
("Hugo", 1),
("Ines", 1),
("Jonas", 2),
("Kemi", 2),
("Luca", 2),
("Mei", 2),
];
let nodes: Vec<Node> = people.iter().map(|(n, g)| Node::new(*n, *g)).collect();
// Papers co-authored over the last three years.
let papers = [
("Amara", "Bilal", 6.0),
("Amara", "Chen", 4.0),
("Bilal", "Chen", 3.0),
("Chen", "Dana", 2.0),
("Amara", "Dana", 1.0),
("Elif", "Farid", 5.0),
("Elif", "Grace", 3.0),
("Farid", "Grace", 4.0),
("Grace", "Hugo", 2.0),
("Hugo", "Ines", 3.0),
("Elif", "Ines", 1.0),
("Farid", "Hugo", 2.0),
("Jonas", "Kemi", 5.0),
("Kemi", "Luca", 3.0),
("Luca", "Mei", 4.0),
("Jonas", "Mei", 2.0),
("Chen", "Grace", 2.0),
("Dana", "Jonas", 1.0),
("Bilal", "Luca", 1.0),
("Ines", "Kemi", 2.0),
("Amara", "Elif", 1.0),
];
let links: Vec<Link> = papers.iter().map(|(a, b, v)| Link::new(*a, *b, *v)).collect();
let teams = vec!["Vision".to_string(), "Language".to_string(), "Robotics".to_string()];
view! {
<ArcDiagramChart
nodes=nodes
links=links
groups=teams
label="Papers co-authored across the lab"
format=|v: f64| format!("{v:.0} papers")
/>
}
.into_any()
}use dioxus::prelude::*;
use hydroxy_dioxus::arc_diagram_chart::{ArcDiagramChart, Link, Node};
#[component]
pub fn ArcDiagramChartDemo() -> Element {
let people = [
("Amara", 0),
("Bilal", 0),
("Chen", 0),
("Dana", 0),
("Elif", 1),
("Farid", 1),
("Grace", 1),
("Hugo", 1),
("Ines", 1),
("Jonas", 2),
("Kemi", 2),
("Luca", 2),
("Mei", 2),
];
let nodes: Vec<Node> = people.iter().map(|(n, g)| Node::new(*n, *g)).collect();
// Papers co-authored over the last three years.
let papers = [
("Amara", "Bilal", 6.0),
("Amara", "Chen", 4.0),
("Bilal", "Chen", 3.0),
("Chen", "Dana", 2.0),
("Amara", "Dana", 1.0),
("Elif", "Farid", 5.0),
("Elif", "Grace", 3.0),
("Farid", "Grace", 4.0),
("Grace", "Hugo", 2.0),
("Hugo", "Ines", 3.0),
("Elif", "Ines", 1.0),
("Farid", "Hugo", 2.0),
("Jonas", "Kemi", 5.0),
("Kemi", "Luca", 3.0),
("Luca", "Mei", 4.0),
("Jonas", "Mei", 2.0),
("Chen", "Grace", 2.0),
("Dana", "Jonas", 1.0),
("Bilal", "Luca", 1.0),
("Ines", "Kemi", 2.0),
("Amara", "Elif", 1.0),
];
let links: Vec<Link> = papers.iter().map(|(a, b, v)| Link::new(*a, *b, *v)).collect();
let teams = vec!["Vision".to_string(), "Language".to_string(), "Robotics".to_string()];
rsx! {
ArcDiagramChart {
nodes,
links,
groups: teams,
label: "Papers co-authored across the lab",
format: |v: f64| format!("{v:.0} papers"),
}
}
}
Anatomy
| Component | data-part | Renders |
|---|---|---|
ArcDiagramChart | root | figure; `data-active` while a node is picked out |
| plot | Focusable group holding the drawing and the tooltip |
| baseline | The line the nodes sit on |
| arc | Semicircle per link, as wide as its value; `data-highlighted` when it touches the picked node |
| node | Dot sized by its links, with a slanted label; `data-highlighted` on the picked node and its neighbours, `data-selected` on the picked node |
| tooltip | Group, link count, total weight and who it links to |
| legend | One swatch per group, when there are two or more |
| sr-live | Announces the picked node |
| sr-table | Every node left to right with its group, links, weight and neighbours |
Keyboard
| Key | Does |
|---|---|
ArrowRight / ArrowLeft | Step to the next or previous node along the line |
Home / End | Jump to the first or last node |
Escape | Clear the picked node |
Props
| Prop | Type | Notes |
|---|---|---|
nodes | Vec<Node> | Required. Node::new(id, group); ids are unique and are the labels |
links | Vec<Link> | Required. Link::new(a, b, value); unknown ids and self-links are ignored |
label | String | Required. What the chart shows; the accessible name |
groups | Vec<String> | Group names by group number. Default: "Group 1", "Group 2"… |
order | Order | Group (default: by group, most-linked first), Degree or Input |
weighted | bool | Arc width follows link value. Default true |
format | Fn(f64) -> String | Formats link values in the tooltip and table |
width | u16 | Drawing width in px. Default 720 |
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 |