Skip to content

Commit 79122c9

Browse files
Update graphviz to output labels
1 parent 8157953 commit 79122c9

File tree

6 files changed

+110
-71
lines changed

6 files changed

+110
-71
lines changed

src/graphviz.rs

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{fmt, io::Write};
1+
use std::{collections::HashMap, fmt, io::Write};
22

33
use crate::EGraph;
44
use graphviz_rust::{
@@ -39,16 +39,23 @@ impl EGraph {
3939
// and create mapping from each node ID to its class
4040
let mut node_to_class = std::collections::HashMap::new();
4141
for (node_id, node) in &self.nodes {
42-
let typ = self
43-
.class_data
44-
.get(&node.eclass)
45-
.and_then(|data| data.typ.clone());
42+
let class_data = self.class_data.get(&node.eclass);
43+
let typ = class_data.and_then(|data| data.typ.clone());
44+
// extra if is none empty
45+
let extra = class_data.and_then(|data| {
46+
if data.extra.is_empty() {
47+
None
48+
} else {
49+
Some(data.extra.clone())
50+
}
51+
});
4652
node_to_class.insert(node_id.clone(), node.eclass.clone());
4753
class_nodes
4854
.entry(typ)
4955
.or_insert_with(std::collections::HashMap::new)
5056
.entry(node.eclass.clone())
51-
.or_insert_with(Vec::new)
57+
.or_insert_with(|| (extra, Vec::new()))
58+
.1
5259
.push((node_id.clone(), node));
5360
}
5461
// 2. Start with configuration
@@ -84,7 +91,7 @@ impl EGraph {
8491
let next_color = (typ_colors.len() + INITIAL_COLOR) % N_COLORS;
8592
let color = typ_colors.entry(typ).or_insert(next_color);
8693
stmts.push(stmt!(attr!("fillcolor", color)));
87-
for (class_id, nodes) in class_to_node {
94+
for (class_id, (extra, nodes)) in class_to_node {
8895
let mut inner_stmts = vec![];
8996

9097
// Add nodes
@@ -113,14 +120,17 @@ impl EGraph {
113120
let outer_subgraph_id = quote(&format!("outer_{subgraph_id}"));
114121
let quoted_subgraph_id = quote(&subgraph_id);
115122

123+
let mut inner_subgraph = subgraph!(quoted_subgraph_id; subgraph!("", inner_stmts));
124+
if let Some(extra) = extra {
125+
inner_subgraph
126+
.add_stmt(stmt!(SubgraphAttributes::label(class_html_label(extra))));
127+
}
128+
// Nest in empty sub-graph so that we can use rank=same
129+
// https://stackoverflow.com/a/55562026/907060
116130
let subgraph = subgraph!(outer_subgraph_id;
117131
// Disable label for now, to reduce size
118132
// NodeAttributes::label(subgraph_html_label(&typ)),
119-
120-
// Nest in empty sub-graph so that we can use rank=same
121-
// https://stackoverflow.com/a/55562026/907060
122-
subgraph!(quoted_subgraph_id; subgraph!("", inner_stmts)),
123-
133+
inner_subgraph,
124134
// Make outer subgraph a cluster but make it invisible, so just used for padding
125135
// https://forum.graphviz.org/t/how-to-add-space-between-clusters/1209/3
126136
SubgraphAttributes::style(quote("invis")),
@@ -166,6 +176,19 @@ fn html_label(label: &str, n_args: usize) -> String {
166176
)
167177
}
168178

179+
fn class_html_label(extra: HashMap<String, String>) -> String {
180+
let mut rows = Vec::new();
181+
for (key, value) in extra {
182+
rows.push(format!(
183+
"<TR><TD ALIGN=\"RIGHT\">{key}</TD><TD ALIGN=\"LEFT\">{value}</TD></TR>"
184+
));
185+
}
186+
format!(
187+
"<<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"2\">{}</TABLE>>",
188+
rows.join("")
189+
)
190+
}
191+
169192
/// Adds double quotes and escapes the quotes in the string
170193
fn quote(s: &str) -> String {
171194
format!("{s:?}")

tests-viz/tiny-inlined-saturated.svg

Lines changed: 23 additions & 19 deletions
Loading

tests-viz/tiny-inlined.svg

Lines changed: 23 additions & 19 deletions
Loading

0 commit comments

Comments
 (0)