1 // Copyright 2006 all rights reserved; see LICENSE file for BSD-style license
3 package edu.berkeley.sbp.util;
4 import edu.berkeley.sbp.util.*;
5 import edu.berkeley.sbp.*;
8 import java.lang.reflect.*;
9 import java.lang.ref.*;
11 public class GraphViz {
13 IdentityHashMap<ToGraphViz,Node> ihm = new IdentityHashMap<ToGraphViz,Node>();
14 HashMap<Node,Group> groups = new HashMap<Node,Group>();
16 public class Group extends Node {
17 private final int idx = master_idx++;
18 public boolean cluster = false;
19 public boolean primary = true;
21 public void add(Node n) { groups.put(n, this); }
22 public String name() { return cluster?("cluster_"+idx):("subgraph_"+idx); }
23 public boolean simple() { return false; }
24 public void dump(PrintWriter pw, IdentityHashMap<Node,Node> done) {
26 if (done.get(g)!=null) return;
28 pw.println(" subgraph "+name()+" { rank=same;\n");
29 pw.println(" label=\""+StringUtil.escapify(label.toString(), "\\\"\r\n")+"\";\n");
30 pw.println(" color="+g.color+";\n");
31 pw.println(" shape="+g.shape+";\n");
32 for(Node n : groups.keySet())
39 private static int master_idx=0;
42 private final int idx = master_idx++;
44 public String comment;
45 public boolean directed = false;
46 public String color="black";
47 public String fill="white";
48 public String shape="ellipse";
49 public ArrayList<Node> edges = new ArrayList<Node>();
50 public ArrayList<Object> labels = new ArrayList<Object>();
51 public ArrayList<Node> inbound = new ArrayList<Node>();
52 public void edge(ToGraphViz o, Object label) {
53 Node n = o.toGraphViz(GraphViz.this);
59 public String getParentName() {
60 if (inbound.size()==1 && inbound.get(0).simple())
61 return inbound.get(0).getParentName();
64 public String name() {
65 if (inbound.size()==1 && inbound.get(0).simple())
66 return inbound.get(0).getParentName()+":node_"+idx;
69 public void edges(PrintWriter pw) {
71 for(int i=0; i<edges.size(); i++) {
72 Node n = edges.get(i);
73 Object label = labels.get(i);
74 pw.println(" "+name()+" -> " + n.name() + " [color="+color+" "
75 +(label==null?"":("label=\""+StringUtil.escapify(label.toString(), "\\\"\r\n")+"\""))+ "];\n");
78 public int numEdges() { return edges.size(); }
79 public boolean simple() {
80 boolean simple = true;
81 if (label!=null && !label.equals("")) simple = false;
84 //if (n.numEdges()>0) { simple = false; break; }
85 if (n.inbound.size() > 1) { simple = false; break; }
88 public void dump(PrintWriter pw, IdentityHashMap<Node,Node> done) {
89 if (done.get(this)!=null) return;
91 if (inbound.size() > 0) {
95 { good = true; break; }
100 if (directed) pw.print("ordering=out");
102 pw.print(" shape=record ");
103 pw.print(" label=\"");
104 boolean complex = false;
106 if (n.edges.size()>0)
108 if (!complex) pw.print("{");
109 boolean first = true;
110 for(Node n : edges) {
111 if (!first) pw.print("|");
113 pw.print("<node_"+n.idx+">");
114 pw.print(StringUtil.escapify(n.label,"\\\"\r\n"));
116 if (!complex) pw.print("}");
119 pw.print(" label=\"");
120 pw.print(StringUtil.escapify(label,"\\\"\r\n"));
123 pw.print("color="+color);
124 if (comment!=null) pw.print(" comment=\""+StringUtil.escapify(comment,"\\\"\r\n")+"\" ");
129 public boolean hasNode(ToGraphViz o) {
130 return ihm.get(o)!=null;
133 public Node createNode(ToGraphViz o) {
135 if (n!=null) return n;
141 public Group createGroup(ToGraphViz o) {
142 Group n = (Group)ihm.get(o);
143 if (n!=null) return n;
149 public static interface ToGraphViz {
150 Node toGraphViz(GraphViz gv);
151 boolean isTransparent();
155 public void show() throws IOException {
156 Runtime.getRuntime().exec(new String[] { "dot", "-Tsvg" });
159 public void dump(OutputStream os) { dump(new PrintWriter(new OutputStreamWriter(os))); }
160 public void dump(PrintWriter pw) {
161 IdentityHashMap<Node,Node> done = new IdentityHashMap<Node,Node>();
162 pw.println("digraph G { rankdir=LR; ordering=out; compound=true; \n");
163 for(Group g : groups.values())
166 for(Node n : ihm.values()) {
167 if (done.get(n)!=null) continue;
168 if (n instanceof Group) continue;
171 for(Node n : ihm.values()) n.edges(pw);