use graphlib_rust::{Edge, Graph, GraphOption};
use crate::{GraphConfig, GraphEdge, GraphNode};
use crate::layout::util::unique_id;
#[derive(Debug, Copy, Clone)]
pub enum GraphRelationship {
InEdges,
OutEdges
}
pub fn build_layer_graph(g: &mut Graph<GraphConfig, GraphNode, GraphEdge>, rank: &i32, relationship: GraphRelationship) -> Graph<GraphConfig, GraphNode, GraphEdge> {
let root = create_root_node(g);
let mut result: Graph<GraphConfig, GraphNode, GraphEdge> = Graph::new(Some(GraphOption {
directed: Some(true),
compound: Some(true),
multigraph: None
}));
let graph_label = result.graph_mut();
graph_label.root = Some(root.clone());
g.nodes().iter().for_each(|v| {
let node = g.node(v).unwrap();
let parent = g.parent(v);
let node_rank = node.rank.clone().unwrap_or(0);
let node_min_rank = node.min_rank.unwrap_or(0);
let node_max_rank = node.max_rank.unwrap_or(0);
let mut _relationship: Vec<Edge> = g.in_edges(v, None).unwrap_or(vec![]);
match relationship {
GraphRelationship::OutEdges => {
_relationship = g.out_edges(v, None).unwrap_or(vec![]);
},
_ => ()
}
if &node_rank == rank || &node_min_rank <= rank && rank <= &node_max_rank {
result.set_node(v.clone(), Some(node.clone()));
if parent.is_some() {
let _ = result.set_parent(v, parent.cloned());
} else {
let _ = result.set_parent(v, Some(root.clone()));
}
_relationship.iter().for_each(|e| {
let u = if &e.v == v {
e.w.clone()
} else {
e.v.clone()
};
let edge = result.edge(&u, &v, None);
let weight = if edge.is_some() {
edge.unwrap().weight.clone().unwrap_or(0.0)
} else {
0.0
};
let mut edge_label = GraphEdge::default();
edge_label.weight = Some(g.edge_with_obj(&e).unwrap().weight.clone().unwrap_or(0.0) + weight);
let _ = result.set_edge(&u, &v, Some(edge_label), None);
});
if node.min_rank.is_some() {
let mut graph_node = GraphNode::default();
graph_node.border_left_ = node.border_left.as_ref().unwrap().get(rank).cloned();
graph_node.border_right_ = node.border_right.as_ref().unwrap().get(rank).cloned();
result.set_node(v.clone(), Some(graph_node));
}
}
});
result
}
pub fn create_root_node(g: &Graph<GraphConfig, GraphNode, GraphEdge>) -> String {
let mut v = format!("_root{}", unique_id());
while g.has_node(&v) {
v = format!("_root{}", unique_id());
}
v
}