pub(crate) mod bk;
use crate::graph::Graph;
use crate::layout::types::{EdgeLabel, GraphLabel, NodeLabel, RankAlign};
use crate::layout::util::build_layer_matrix;
pub(crate) fn position(g: &mut Graph<NodeLabel, EdgeLabel>) {
position_y(g);
position_x(g);
}
fn position_y(g: &mut Graph<NodeLabel, EdgeLabel>) {
let layering = build_layer_matrix(g);
let graph_label = g.graph_label::<GraphLabel>();
let ranksep = graph_label.map_or(50.0, |gl| gl.ranksep);
let rank_align = graph_label.map_or(RankAlign::Center, |gl| gl.rank_align);
let mut prev_y: f64 = 0.0;
for layer in &layering {
let max_height = layer
.iter()
.filter(|v| !v.is_empty())
.filter_map(|v| g.node(v).map(|n| n.height))
.fold(0.0_f64, f64::max);
let assignments: Vec<(String, f64)> = layer
.iter()
.filter(|v| !v.is_empty())
.filter_map(|v| g.node(v).map(|n| (v.clone(), n.height)))
.collect();
for (v, node_height) in assignments {
let y = match rank_align {
RankAlign::Top => prev_y + node_height / 2.0,
RankAlign::Bottom => prev_y + max_height - node_height / 2.0,
RankAlign::Center => prev_y + max_height / 2.0,
};
if let Some(node) = g.node_mut(&v) {
node.y = Some(y);
}
}
prev_y += max_height + ranksep;
}
}
fn position_x(g: &mut Graph<NodeLabel, EdgeLabel>) {
let xs = bk::position_x(g);
for (v, x) in xs {
if let Some(node) = g.node_mut(&v) {
node.x = Some(x);
}
}
}