tentative checkpoint ROLL THIS BACK BUT INCLUDES CRUCIAL FIX
[sbp.git] / src / edu / berkeley / sbp / util / GraphViz.java
index d5f1bcf..b3132d7 100644 (file)
@@ -11,18 +11,39 @@ public class GraphViz {
     IdentityHashMap<ToGraphViz,Node> ihm = new IdentityHashMap<ToGraphViz,Node>();
     HashMap<Node,Group> groups = new HashMap<Node,Group>();
 
-    public class Group {
+    public class Group extends Node {
+        private final int idx = master_idx++;
+        public boolean cluster = false;
+        public boolean primary = true;
         public Group() { }
         public void add(Node n) { groups.put(n, this); }
+        public String name() { return cluster?("cluster_"+idx):("subgraph_"+idx); }
+        public boolean simple() { return false; }
+        public void dump(PrintWriter pw, IdentityHashMap<Node,Node> done) {
+            Group g = this;
+            if (done.get(g)!=null) return;
+            done.put(g,g);
+            pw.println("  subgraph "+name()+" { rank=same;\n");
+            pw.println("  label=\""+StringUtil.escapify(label.toString(), "\\\"\r\n")+"\";\n");
+            pw.println("  color="+g.color+";\n");
+            pw.println("  shape="+g.shape+";\n");
+            for(Node n : groups.keySet())
+                if (groups.get(n)==g)
+                    n.dump(pw, done);
+            pw.println("  }\n");
+        }
     }
 
     private static int master_idx=0;
+
     public class Node {
         private final int idx = master_idx++;
         public String label;
         public String comment;
         public boolean directed = false;
         public String color="black";
+        public String fill="white";
+        public String shape="ellipse";
         public ArrayList<Node> edges = new ArrayList<Node>();
         public ArrayList<Object> labels = new ArrayList<Object>();
         public ArrayList<Node> inbound = new ArrayList<Node>();
@@ -62,7 +83,9 @@ public class GraphViz {
                     if (n.inbound.size() > 1) { simple = false; break; }
             return simple;
         }
-        public void dump(PrintWriter pw) {
+        public void dump(PrintWriter pw, IdentityHashMap<Node,Node> done) {
+            if (done.get(this)!=null) return;
+            done.put(this, this);
             if (inbound.size() > 0) {
                 boolean good = false;
                 for(Node n : inbound)
@@ -113,6 +136,14 @@ public class GraphViz {
         return n;
     }
 
+    public Group createGroup(ToGraphViz o) {
+        Group n = (Group)ihm.get(o);
+        if (n!=null) return n;
+        n = new Group();
+        ihm.put(o, n);
+        return n;
+    }
+
     public static interface ToGraphViz {
         public Node    toGraphViz(GraphViz gv);
         public boolean isTransparent();
@@ -126,19 +157,14 @@ public class GraphViz {
     public void dump(OutputStream os) { dump(new PrintWriter(new OutputStreamWriter(os))); }
     public void dump(PrintWriter pw) {
         IdentityHashMap<Node,Node> done = new IdentityHashMap<Node,Node>();
-        pw.println("digraph G { rankdir=LR; ordering=out; \n");
-        for(Group g : groups.values()) {
-            pw.println("  { rank=same;\n");
-            for(Node n : groups.keySet())
-                if (groups.get(n)==g) {
-                    done.put(n,n);
-                    n.dump(pw);
-                }
-            pw.println("  }\n");
-        }
+        pw.println("digraph G { rankdir=LR; ordering=out; compound=true; \n");
+        for(Group g : groups.values())
+            if (g.primary)
+                g.dump(pw, done);
         for(Node n : ihm.values()) {
             if (done.get(n)!=null) continue;
-            n.dump(pw);
+            if (n instanceof Group) continue;
+            n.dump(pw, done);
         }
         for(Node n : ihm.values()) n.edges(pw);
         pw.println("}\n");