Adjacency matrix chart
Nodes against nodes, each cell shaded by the link between them. Order by name, by degree, or by cluster so that tightly linked groups form blocks along the diagonal.
| Source | Target | Value |
|---|---|---|
| Ana | Bo | 34 |
| Ana | Cy | 21 |
| Bo | Cy | 18 |
| Ana | Jun | 12 |
| Cy | Jun | 9 |
| Dee | Eko | 27 |
| Dee | Fin | 15 |
| Eko | Fin | 22 |
| Gia | Hal | 30 |
| Gia | Ines | 16 |
| Hal | Ines | 11 |
| Bo | Dee | 4 |
| Fin | Gia | 6 |
| Jun | Ines | 3 |
Usage
use hydroxy_leptos::adjacency_matrix_chart::*;
use leptos::prelude::*;
pub fn demo() -> AnyView {
let people = [
("Ana", 0),
("Bo", 0),
("Cy", 0),
("Dee", 1),
("Eko", 1),
("Fin", 1),
("Gia", 2),
("Hal", 2),
("Ines", 2),
("Jun", 0),
];
let nodes: Vec<Node> = people.iter().map(|(n, g)| Node::new(*n, *g)).collect();
// Messages exchanged last week between people on three teams.
let pairs = [
("Ana", "Bo", 34.0),
("Ana", "Cy", 21.0),
("Bo", "Cy", 18.0),
("Ana", "Jun", 12.0),
("Cy", "Jun", 9.0),
("Dee", "Eko", 27.0),
("Dee", "Fin", 15.0),
("Eko", "Fin", 22.0),
("Gia", "Hal", 30.0),
("Gia", "Ines", 16.0),
("Hal", "Ines", 11.0),
("Bo", "Dee", 4.0),
("Fin", "Gia", 6.0),
("Jun", "Ines", 3.0),
];
let links: Vec<Link> = pairs.iter().map(|(a, b, v)| Link::new(*a, *b, *v)).collect();
view! { <AdjacencyMatrixChart nodes=nodes links=links label="Messages between people" order=MatrixOrder::Cluster /> }.into_any()
}use dioxus::prelude::*;
use hydroxy_dioxus::adjacency_matrix_chart::{AdjacencyMatrixChart, Link, MatrixOrder, Node};
#[component]
pub fn AdjacencyMatrixChartDemo() -> Element {
let people = [
("Ana", 0),
("Bo", 0),
("Cy", 0),
("Dee", 1),
("Eko", 1),
("Fin", 1),
("Gia", 2),
("Hal", 2),
("Ines", 2),
("Jun", 0),
];
let nodes: Vec<Node> = people.iter().map(|(n, g)| Node::new(*n, *g)).collect();
// Messages exchanged last week between people on three teams.
let pairs = [
("Ana", "Bo", 34.0),
("Ana", "Cy", 21.0),
("Bo", "Cy", 18.0),
("Ana", "Jun", 12.0),
("Cy", "Jun", 9.0),
("Dee", "Eko", 27.0),
("Dee", "Fin", 15.0),
("Eko", "Fin", 22.0),
("Gia", "Hal", 30.0),
("Gia", "Ines", 16.0),
("Hal", "Ines", 11.0),
("Bo", "Dee", 4.0),
("Fin", "Gia", 6.0),
("Jun", "Ines", 3.0),
];
let links: Vec<Link> = pairs.iter().map(|(a, b, v)| Link::new(*a, *b, *v)).collect();
rsx! {
AdjacencyMatrixChart { nodes, links, label: "Messages between people", order: MatrixOrder::Cluster }
}
}
Anatomy
| Component | data-part | Renders |
|---|---|---|
AdjacencyMatrixChart | root | figure |
| row-label / col-label | Node names; `data-active` on the active cell's row and column |
| cell | Shaded by `--level`; `data-empty` with no link, `data-cross` on the active row and column |
| tooltip | Source, target and value of the active cell |
| sr-table | Every link as source, target and value |
Keyboard
| Key | Does |
|---|---|
Arrow keys | Move between cells |
Home / End | First or last cell in the row |
Escape | Clear the active cell |
Props
| Prop | Type | Notes |
|---|---|---|
nodes | Vec<Node> | Required. Unique ids, which are also the labels |
links | Vec<Link> | Required. Links by node id; repeats add up, unknown ids are ignored |
label | String | Required. What the chart shows; the accessible name |
order | MatrixOrder | Name (default), Degree or Cluster |
directed | bool | Links run one way. Default false, which mirrors each link |
cell_size | u16 | Cell size in px. Default 28 |
format | Fn(f64) -> String | Formats values in the tooltip, readout 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 |