dagre_rust/layout/order/
sort_subgraph.rs1use graphlib_rust::Graph;
2use ordered_hashmap::OrderedHashMap;
3use crate::{GraphConfig, GraphEdge, GraphNode};
4use crate::layout::order::barycenter::{barycenter, Barycenter};
5use crate::layout::order::resolve_conflicts::{resolve_conflicts, ResolvedBaryEntry};
6use crate::layout::order::sort::sort;
7
8#[derive(Debug, Clone, Default)]
9pub struct SubgraphResult {
10 pub vs: Vec<String>,
11 pub barycenter: f32,
12 pub weight: f32
13}
14
15pub fn sort_subgraph(
16 g: &Graph<GraphConfig, GraphNode, GraphEdge>,
17 v: &String,
18 cg: &Graph<GraphConfig, GraphNode,GraphEdge>,
19 bias_right: &bool
20) -> SubgraphResult {
21 let mut movable = g.children(v);
22 let node = g.node(v);
23 let bl = if node.is_some() {
24 node.unwrap().border_left_.clone()
25 } else {
26 None
27 };
28 let br = if node.is_some() {
29 node.unwrap().border_right_.clone()
30 } else {
31 None
32 };
33 let mut subgraphs: OrderedHashMap<String, SubgraphResult> = OrderedHashMap::new();
34
35 if br.is_some() {
36 movable = movable.into_iter().filter(|w| {
37 w != &bl.clone().unwrap() && w != &br.clone().unwrap()
38 }).collect();
39 }
40
41 let mut barycenters = barycenter(g, &movable);
42 barycenters.iter_mut().for_each(|entry| {
43 if g.children(&entry.v).len() > 0 {
44 let subgraph_result = sort_subgraph(g, &entry.v, cg, bias_right);
45 subgraphs.insert(entry.v.clone(), subgraph_result.clone());
46 merge_barycenters(entry, &subgraph_result);
47 }
48 });
49
50 let mut entries = resolve_conflicts(&barycenters, cg);
51 expand_subgraphs(&mut entries, &subgraphs);
52
53 let mut result = sort(&entries, bias_right);
54 if bl.is_some() {
55 let bl_ = bl.clone().unwrap();
56 let br_ = br.clone().unwrap();
57 result.vs = vec![vec![bl_.clone()], result.vs.clone(), vec![br_.clone()]].concat();
58 let bl_preds = g.predecessors(&bl_).unwrap_or(vec![]);
59 if bl_preds.len() > 0 {
60 let bl_pred = g.node(bl_preds.first().unwrap()).unwrap();
61 let br_pred = g.node(g.predecessors(&br_).unwrap_or(vec![]).first().unwrap()).unwrap();
62 let bl_pred_order = bl_pred.order.clone().unwrap_or(0) as f32;
70 let br_pred_order = br_pred.order.clone().unwrap_or(0) as f32;
71 result.barycenter =
72 ( result.barycenter * result.weight + bl_pred_order + br_pred_order ) / (result.weight + 2.0);
73 result.weight += 2.0;
74 }
75 }
76
77 return result;
78}
79
80fn expand_subgraphs(entries: &mut Vec<ResolvedBaryEntry>, subgraphs: &OrderedHashMap<String, SubgraphResult>) {
81 entries.iter_mut().for_each(|entry| {
82 let mut vs: Vec<String> = vec![];
83 entry.vs.iter().for_each(|v| {
84 if subgraphs.contains_key(v) {
85 let subgraph = subgraphs.get(v).unwrap();
86 subgraph.vs.iter().for_each(|v_| {
87 vs.push(v_.clone());
88 });
89 return ();
90 }
91 vs.push(v.clone());
92 });
93
94 entry.vs = vs;
95 });
96}
97
98fn merge_barycenters(target: &mut Barycenter, other: &SubgraphResult) {
99 let target_barycenter = target.barycenter.clone().unwrap_or(0.0);
100 if target.barycenter.is_some() && target_barycenter > 0.0 {
101 let target_weight = target.weight.clone().unwrap_or(0.0);
102
103 target.barycenter = Some(
104 (target_barycenter * target_weight + other.barycenter * other.weight)
105 / (target_weight + other.weight)
106 );
107 target.weight = Some(target_weight + other.weight.clone());
108 } else {
109 target.barycenter = Some(other.barycenter.clone());
110 target.weight = Some(other.weight.clone());
111 }
112}