X-Git-Url: http://git.megacz.com/?p=sbp.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2Futil%2FGraphViz.java;h=1d85e11d4058eb035fa985ff8276d7ea4c9e9110;hp=a92e298b5af1c2087cc434bd8f2b298b13e9a6d3;hb=f069d11a0bc59d63b078df8a4aa488498c4e9cc2;hpb=142b31e063c97d2d6dc141a9e687d49b7f2ab826 diff --git a/src/edu/berkeley/sbp/util/GraphViz.java b/src/edu/berkeley/sbp/util/GraphViz.java index a92e298..1d85e11 100644 --- a/src/edu/berkeley/sbp/util/GraphViz.java +++ b/src/edu/berkeley/sbp/util/GraphViz.java @@ -1,3 +1,5 @@ +// Copyright 2006-2007 all rights reserved; see LICENSE file for BSD-style license + package edu.berkeley.sbp.util; import edu.berkeley.sbp.util.*; import edu.berkeley.sbp.*; @@ -8,52 +10,87 @@ import java.lang.ref.*; public class GraphViz { - IdentityHashMap ihm = new IdentityHashMap(); - HashMap groups = new HashMap(); + IdentityHashMap ihm = new IdentityHashMap(); + HashMap groups = new HashMap(); - public class Group { + public class Group extends StateNode { + 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 void add(StateNode 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 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(StateNode n : groups.keySet()) + if (groups.get(n)==g) + n.dump(pw, done); + pw.println(" }\n"); + } } private static int master_idx=0; - public class Node { + + public class StateNode { private final int idx = master_idx++; public String label; + public String comment; public boolean directed = false; public String color="black"; - public ArrayList edges = new ArrayList(); - public ArrayList inbound = new ArrayList(); - public void edge(ToGraphViz o) { - Node n = o.toGraphViz(GraphViz.this); + public String fill="white"; + public String shape="ellipse"; + public ArrayList edges = new ArrayList(); + public ArrayList labels = new ArrayList(); + public ArrayList inbound = new ArrayList(); + public void edge(ToGraphViz o, Object label) { + StateNode n = o.toGraphViz(GraphViz.this); if (n==null) return; edges.add(n); + labels.add(label); n.inbound.add(this); } + public String getParentName() { + if (inbound.size()==1 && inbound.get(0).simple()) + return inbound.get(0).getParentName(); + return name(); + } public String name() { if (inbound.size()==1 && inbound.get(0).simple()) - return inbound.get(0).name()+":node_"+idx; + return inbound.get(0).getParentName()+":node_"+idx; return "node_"+idx; } public void edges(PrintWriter pw) { if (simple()) return; - for(Node n : edges) - pw.println(" "+name()+" -> " + n.name()); + for(int i=0; i " + n.name() + " [color="+color+" " + +(label==null?"":("label=\""+StringUtil.escapify(label.toString(), "\\\"\r\n")+"\""))+ "];\n"); + } } public int numEdges() { return edges.size(); } public boolean simple() { boolean simple = true; if (label!=null && !label.equals("")) simple = false; if (simple) - for(Node n : edges) + for(StateNode n : edges) //if (n.numEdges()>0) { simple = false; break; } if (n.inbound.size() > 1) { simple = false; break; } return simple; } - public void dump(PrintWriter pw) { + public void dump(PrintWriter pw, IdentityHashMap done) { + if (done.get(this)!=null) return; + done.put(this, this); if (inbound.size() > 0) { boolean good = false; - for(Node n : inbound) + for(StateNode n : inbound) if (!n.simple()) { good = true; break; } if (!good) return; @@ -63,21 +100,28 @@ public class GraphViz { if (directed) pw.print("ordering=out"); if (simple()) { pw.print(" shape=record "); - pw.print(" label=\"{"); + pw.print(" label=\""); + boolean complex = false; + for(StateNode n : edges) + if (n.edges.size()>0) + complex = true; + if (!complex) pw.print("{"); boolean first = true; - for(Node n : edges) { + for(StateNode n : edges) { if (!first) pw.print("|"); first = false; - pw.print("<"+n.name()+">"); - pw.print(StringUtil.escapify(n.label,"\\\"")); + pw.print(""); + pw.print(StringUtil.escapify(n.label,"\\\"\r\n")); } - pw.print("}\""); + if (!complex) pw.print("}"); + pw.print("\" "); } else { pw.print(" label=\""); - pw.print(StringUtil.escapify(label,"\\\"")); - pw.print("\""); + pw.print(StringUtil.escapify(label,"\\\"\r\n")); + pw.print("\" "); } pw.print("color="+color); + if (comment!=null) pw.print(" comment=\""+StringUtil.escapify(comment,"\\\"\r\n")+"\" "); pw.print("];\n"); } } @@ -86,38 +130,47 @@ public class GraphViz { return ihm.get(o)!=null; } - public Node createNode(ToGraphViz o) { - Node n = ihm.get(o); + public StateNode createNode(ToGraphViz o) { + StateNode n = ihm.get(o); if (n!=null) return n; - n = new Node(); + n = new StateNode(); + ihm.put(o, n); + 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(); - public boolean isHidden(); + StateNode toGraphViz(GraphViz gv); + boolean isTransparent(); + boolean isHidden(); } + public void show() throws IOException { + Runtime.getRuntime().exec(new String[] { "dot", "-Tsvg" }); + } + + public void dump(OutputStream os) { dump(new PrintWriter(new OutputStreamWriter(os))); } public void dump(PrintWriter pw) { - IdentityHashMap done = new IdentityHashMap(); - pw.println("digraph G {\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"); - } - for(Node n : ihm.values()) { + IdentityHashMap done = new IdentityHashMap(); + pw.println("digraph G { rankdir=LR; ordering=out; compound=true; \n"); + for(Group g : groups.values()) + if (g.primary) + g.dump(pw, done); + for(StateNode 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); + for(StateNode n : ihm.values()) n.edges(pw); pw.println("}\n"); + pw.flush(); } }