use crate::adt::dag::NodeHandle;
use crate::core::format::Visible;
use crate::std_shapes::shapes::ShapeKind;
use crate::topo::layout::VisualGraph;
fn get_row_width(vg: &mut VisualGraph, idx: usize) -> f64 {
let mut sum = 0.;
let row = vg.dag.row(idx);
for elem in row {
sum += vg.pos(*elem).size(true).x;
}
sum
}
fn move_label(
vg: &mut VisualGraph,
curr: NodeHandle,
pred: NodeHandle,
) -> bool {
let curr_shape = vg.element(curr).shape.clone();
let pred_shape = vg.element(pred).shape.clone();
if let ShapeKind::Connector(txt) = pred_shape {
if txt.is_some() {
return false;
}
} else {
return false;
}
if let ShapeKind::Connector(txt) = curr_shape {
if txt.is_none() {
return false;
}
vg.element_mut(pred).shape = ShapeKind::Connector(txt);
vg.element_mut(curr).shape = ShapeKind::Connector(None);
vg.element_mut(pred).resize();
vg.element_mut(curr).resize();
return true;
}
false
}
fn move_text_up(vg: &mut VisualGraph) -> usize {
let mut prev_row_size = get_row_width(vg, 0);
let mut cnt = 0;
for i in 1..vg.dag.num_levels() {
let row = vg.dag.row(i).clone();
let mut curr_row_size = get_row_width(vg, i);
for elem in row.iter() {
if !vg.is_connector(*elem) {
continue;
}
if vg.dag.predecessors(*elem).len() != 1 {
continue;
}
let pred = vg.dag.predecessors(*elem)[0];
if !vg.is_connector(pred) {
continue;
}
let pred_node_size = vg.pos(pred).size(true).x;
let curr_node_size = vg.pos(*elem).size(true).x;
if prev_row_size + curr_node_size < curr_row_size {
if move_label(vg, *elem, pred) {
curr_row_size -= curr_node_size;
prev_row_size += curr_node_size;
cnt += 1;
continue;
}
}
if prev_row_size > curr_row_size + pred_node_size {
if move_label(vg, pred, *elem) {
curr_row_size += pred_node_size;
prev_row_size -= pred_node_size;
cnt += 1;
continue;
}
}
}
}
cnt
}
#[cfg_attr(not(feature = "log"), allow(unused_assignments, unused_variables))]
pub fn do_it(vg: &mut VisualGraph) {
let mut cnt = 0;
for _ in 0..3 {
cnt += move_text_up(vg);
}
#[cfg(feature = "log")]
log::info!("Moved {} labels between rows", cnt);
}