1#[cfg(feature = "log")]
8extern crate log;
9
10use crate::adt::dag::*;
11use crate::core::base::Orientation;
12use crate::core::format::RenderBackend;
13use crate::core::format::Renderable;
14use crate::core::format::Visible;
15use crate::core::geometry::Position;
16use crate::std_shapes::render::*;
17use crate::std_shapes::shapes::*;
18use crate::topo::optimizer::EdgeCrossOptimizer;
19use crate::topo::optimizer::RankOptimizer;
20use std::mem::swap;
21use std::vec;
22
23use super::placer::Placer;
24
25#[derive(Debug)]
26pub struct VisualGraph {
27 nodes: Vec<Element>,
29 edges: Vec<(Arrow, Vec<NodeHandle>)>,
31 self_edges: Vec<(Arrow, NodeHandle)>,
35 pub dag: DAG,
40 orientation: Orientation,
42}
43
44impl VisualGraph {
45 pub fn new(orientation: Orientation) -> Self {
46 VisualGraph {
47 nodes: Vec::new(),
48 edges: Vec::new(),
49 self_edges: Vec::new(),
50 dag: DAG::new(),
51 orientation,
52 }
53 }
54
55 pub fn orientation(&self) -> Orientation {
56 self.orientation
57 }
58
59 pub fn num_nodes(&self) -> usize {
60 self.dag.len()
61 }
62
63 pub fn iter_nodes(&self) -> NodeIterator {
64 self.dag.iter()
65 }
66
67 pub fn succ(&self, node: NodeHandle) -> &Vec<NodeHandle> {
68 self.dag.successors(node)
69 }
70
71 pub fn preds(&self, node: NodeHandle) -> &Vec<NodeHandle> {
72 self.dag.predecessors(node)
73 }
74
75 pub fn pos(&self, n: NodeHandle) -> Position {
76 self.element(n).position()
77 }
78
79 pub fn pos_mut(&mut self, n: NodeHandle) -> &mut Position {
80 self.element_mut(n).position_mut()
81 }
82
83 pub fn is_connector(&self, n: NodeHandle) -> bool {
84 return self.element(n).is_connector();
85 }
86
87 pub fn transpose(&mut self) {
88 for node in self.dag.iter() {
89 self.element_mut(node).transpose();
90 }
91 }
92
93 pub fn element(&self, node: NodeHandle) -> &Element {
94 &self.nodes[node.get_index()]
95 }
96
97 pub fn element_mut(&mut self, node: NodeHandle) -> &mut Element {
98 &mut self.nodes[node.get_index()]
99 }
100
101 pub fn add_node(&mut self, elem: Element) -> NodeHandle {
104 let res = self.dag.new_node();
105 assert!(res.get_index() == self.nodes.len());
106 self.nodes.push(elem);
107 res
108 }
109
110 pub fn add_edge(&mut self, arrow: Arrow, from: NodeHandle, to: NodeHandle) {
112 assert!(from.get_index() < self.nodes.len(), "Invalid handle");
113 assert!(to.get_index() < self.nodes.len(), "Invalid handle");
114 let lst = vec![from, to];
115 self.edges.push((arrow, lst));
116 }
117}
118
119impl VisualGraph {
121 fn render(&self, debug: bool, rb: &mut dyn RenderBackend) {
122 for node in &self.nodes {
124 node.render(debug, rb);
125 }
126
127 for arrow in &self.edges {
129 let mut elements = Vec::new();
130 for h in &arrow.1 {
131 elements.push(self.nodes[h.get_index()].clone());
132 }
133 render_arrow(rb, debug, &elements[..], &arrow.0);
134 }
135 }
136}
137
138impl VisualGraph {
139 pub fn do_it(
140 &mut self,
141 debug_mode: bool,
142 disable_opt: bool,
143 disable_layout: bool,
144 rb: &mut dyn RenderBackend,
145 ) {
146 self.lower(disable_opt);
147 Placer::new(self).layout(disable_layout);
148 self.render(debug_mode, rb);
149 }
150
151 fn lower(&mut self, disable_optimizations: bool) {
152 #[cfg(feature = "log")]
153 log::info!("Lowering a graph with {} nodes.", self.num_nodes());
154 self.to_valid_dag();
155 self.split_text_edges();
156 self.split_long_edges(disable_optimizations);
157
158 for elem in self.dag.iter() {
159 self.element_mut(elem).resize();
160 }
161 }
162
163 pub fn to_valid_dag(&mut self) {
166 let edges = self.edges.clone();
167 self.edges.clear();
168
169 assert_eq!(self.nodes.len(), self.dag.len(), "bad number of nodes");
172
173 for edge in edges {
175 let mut arrow = edge.0;
176 let lst = edge.1;
177 assert_eq!(lst.len(), 2);
178 let mut from = lst[0];
179 let mut to = lst[1];
180
181 if from == to {
182 self.self_edges.push((arrow, from));
183 continue;
184 }
185
186 if self.dag.is_reachable(to, from) {
188 swap(&mut from, &mut to);
189 arrow = arrow.reverse();
190 }
191
192 self.dag.add_edge(from, to);
193 self.add_edge(arrow, from, to);
194
195 self.dag.verify();
196 }
197 }
198
199 pub fn split_text_edges(&mut self) {
203 let mut edges = self.edges.clone();
204 for edge in edges.iter_mut() {
207 let lst = &edge.1;
208 assert_eq!(lst.len(), 2);
209 let arrow = &edge.0;
210 let from = lst[0];
211 let to = lst[1];
212
213 if edge.0.text.is_empty() {
215 continue;
216 }
217
218 let text = arrow.text.clone();
219
220 let dir = self.element(from).orientation;
222 let conn = Element::create_connector(&text, &arrow.look, dir);
223 let conn = self.add_node(conn);
224
225 edge.1 = vec![from, conn, to];
227 edge.0.text = String::new();
228
229 let res = self.dag.remove_edge(from, to);
231 assert!(res, "Expected the edge to be in the graph!");
232 self.dag.add_edge(from, conn);
233 self.dag.add_edge(conn, to);
234 }
235
236 self.edges = edges;
237 }
238
239 pub fn split_long_edges(&mut self, disable_optimizations: bool) {
240 self.dag.recompute_node_ranks();
242 self.dag.verify();
243 if !disable_optimizations {
244 RankOptimizer::new(&mut self.dag).optimize();
245 }
246
247 let mut edges = self.edges.clone();
248 self.edges.clear();
249
250 for edge in edges.iter_mut() {
251 let mut lst = edge.1.clone();
252
253 let mut i = 1;
256 while i < lst.len() {
257 let prev = lst[i - 1];
258 let curr = lst[i];
259
260 let prev_level = self.dag.level(prev);
261 let curr_level = self.dag.level(curr);
262
263 assert!(prev_level < curr_level, "Invalid edge");
265 if prev_level + 1 == curr_level {
266 i += 1;
267 continue;
268 }
269
270 let dir = self.element(prev).orientation;
272 let conn = Element::empty_connector(dir);
273 let conn = self.add_node(conn);
274 lst.insert(i, conn);
275
276 self.dag.remove_edge(prev, curr);
278 self.dag.add_edge(prev, conn);
279 self.dag.add_edge(conn, curr);
280
281 self.dag.update_node_rank_level(conn, prev_level + 1, None);
283 }
284
285 edge.1 = lst;
286 }
287 self.edges = edges;
288
289 if !disable_optimizations {
290 EdgeCrossOptimizer::new(&mut self.dag).optimize();
291 }
292 self.expand_self_edges()
293 }
294
295 pub fn expand_self_edges(&mut self) {
297 for se in self.self_edges.clone().iter() {
298 let mut arrow = se.0.clone();
299 let node = se.1;
300 let level = self.dag.level(node);
301 let text = arrow.text.to_string();
302 arrow.text = String::new();
303 let dir = self.element(node).orientation;
304 let conn = Element::create_connector(&text, &arrow.look, dir);
305 let conn = self.add_node(conn);
306 self.dag.update_node_rank_level(conn, level, Some(node));
307 self.edges.push((arrow, vec![node, conn, node]));
308 }
309
310 self.self_edges.clear();
312 }
313}