Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(654)

Unified Diff: dot_helper.py

Issue 2859039: Refactor the dot graph generation out of cros_generate_deps_graphs (Closed) Base URL: ssh://git@chromiumos-git//crosutils.git
Patch Set: address review comments Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cros_generate_deps_graphs ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dot_helper.py
diff --git a/dot_helper.py b/dot_helper.py
new file mode 100644
index 0000000000000000000000000000000000000000..d22f901f92fb19a2cb630793e8e52f89e14657a6
--- /dev/null
+++ b/dot_helper.py
@@ -0,0 +1,116 @@
+#!/usr/bin/python
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Helper functions for building graphs with dot."""
+
+import subprocess
+
+class Subgraph(object):
+ """A subgraph in dot. Contains nodes, arcs, and other subgraphs."""
+
+ _valid_ranks = set(['source', 'sink', 'same', 'min', 'max', None])
+
+ def __init__(self, rank=None):
+ self.SetRank(rank)
+ self._nodes = []
+ self._subgraphs = []
+ self._arcs = set()
+
+ def SetRank(self, rank):
+ """Sets the rank for the nodes in the graph.
+
+ Can be one of 'source', 'sink', 'same', 'min', 'max' or None. See dot
+ documentation at http://www.graphviz.org/Documentation.php for exact
+ semantics."""
+ assert(rank in self._valid_ranks)
+ self._rank = rank
+
+ def AddNode(self, id, name=None, color=None, href=None):
+ """Adds a node to the subgraph."""
+ tags = {}
+ if name:
+ tags['label'] = name
+ if color:
+ tags['color'] = color
+ tags['fontcolor'] = color
+ if href:
+ tags['href'] = href
+ self._nodes.append({'id': id, 'tags': tags})
+
+ def AddSubgraph(self, subgraph):
+ """Adds a subgraph to the subgraph."""
+ self._subgraphs.append(subgraph)
+
+ def AddNewSubgraph(self, rank=None):
+ """Adds a new subgraph to the subgraph. The new subgraph is returned."""
+ subgraph = Subgraph(rank)
+ self.AddSubgraph(subgraph)
+ return subgraph
+
+ def AddArc(self, node_from, node_to):
+ """Adds an arc between two nodes."""
+ self._arcs.add((node_from, node_to))
+
+ def _GenNodes(self):
+ """Generates the code for all the nodes."""
+ lines = []
+ for node in self._nodes:
+ tags = ['%s="%s"' % (k, v) for (k, v) in node['tags'].iteritems()]
+ lines.append('"%s" [%s];' % (node['id'], ', '.join(tags)))
+ return lines
+
+ def _GenSubgraphs(self):
+ """Generates the code for all the subgraphs contained in this subgraph."""
+ lines = []
+ for subgraph in self._subgraphs:
+ lines += subgraph.Gen();
+ return lines
+
+ def _GenArcs(self):
+ """Generates the code for all the arcs."""
+ lines = []
+ for node_from, node_to in self._arcs:
+ lines.append('"%s" -> "%s";' % (node_from, node_to))
+ return lines
+
+ def _GenInner(self):
+ """Generates the code for the inner contents of the subgraph."""
+ lines = []
+ if self._rank:
+ lines.append('rank=%s;' % self._rank)
+ lines += self._GenSubgraphs()
+ lines += self._GenNodes()
+ lines += self._GenArcs()
+ return lines
+
+ def Gen(self):
+ """Generates the code for the subgraph."""
+ return ['subgraph {'] + self._GenInner() + ['}']
+
+
+class Graph(Subgraph):
+ """A top-level graph in dot. It's basically a subgraph with a name."""
+
+ def __init__(self, name):
+ Subgraph.__init__(self)
+ self._name = name
+
+ def Gen(self):
+ """Generates the code for the graph."""
+ return ['digraph "%s" {' % self._name,
+ 'graph [name="%s"];' % self._name] + self._GenInner() + ['}']
+
+
+def GenerateImage(lines, filename, format='svg', save_dot_filename=None):
+ """Generates the image by calling dot on the input lines."""
+ data = '\n'.join(lines)
+ proc = subprocess.Popen(['dot', '-T' + format, '-o' + filename],
+ stdin=subprocess.PIPE)
+ proc.communicate(data)
+
+ if save_dot_filename:
+ file = open(save_dot_filename, 'w')
+ file.write(data)
+ file.close()
« no previous file with comments | « cros_generate_deps_graphs ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698