use crate::data_structures::{drawing::Drawing, lattice::Lattice, poset::Poset};
use crate::traits::DrawingAlgorithm;
pub struct Sugiyama {
pub vertex_spacing: usize,
}
impl Sugiyama {
fn layout_from_edges(&self, edges: &[(u32, u32)], n: usize) -> Option<Drawing> {
if n == 0 {
return None;
}
if edges.is_empty() {
let coords: Vec<(f64, f64)> = (0..n)
.map(|i| (i as f64 * self.vertex_spacing as f64, 0.0))
.collect();
return Some(Drawing::new(coords));
}
let layouts = rust_sugiyama::from_edges(edges)
.vertex_spacing(self.vertex_spacing)
.build();
let mut coords = vec![(0.0f64, 0.0f64); n];
let mut x_offset = 0.0f64;
for (layout_points, width, _height) in layouts {
if layout_points.is_empty() {
continue;
}
for (node_id, (x, y)) in &layout_points {
let idx = *node_id;
if idx < n {
coords[idx] = (x_offset + *x as f64, *y as f64);
}
}
x_offset += width as f64 + self.vertex_spacing as f64;
}
Some(Drawing::new(coords))
}
}
impl DrawingAlgorithm for Sugiyama {
fn draw<T>(&self, lattice: &Lattice<T>) -> Option<Drawing> {
self.layout_from_edges(&lattice.poset.covering_edges, lattice.poset.nodes.len())
}
fn draw_poset<T: Clone>(&self, poset: &Poset<T>) -> Option<Drawing> {
self.layout_from_edges(&poset.covering_edges, poset.nodes.len())
}
}