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

Side by Side 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, 5 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 unified diff | Download patch
« no previous file with comments | « cros_generate_deps_graphs ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/python
2 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """Helper functions for building graphs with dot."""
7
8 import subprocess
9
10 class Subgraph(object):
11 """A subgraph in dot. Contains nodes, arcs, and other subgraphs."""
12
13 _valid_ranks = set(['source', 'sink', 'same', 'min', 'max', None])
14
15 def __init__(self, rank=None):
16 self.SetRank(rank)
17 self._nodes = []
18 self._subgraphs = []
19 self._arcs = set()
20
21 def SetRank(self, rank):
22 """Sets the rank for the nodes in the graph.
23
24 Can be one of 'source', 'sink', 'same', 'min', 'max' or None. See dot
25 documentation at http://www.graphviz.org/Documentation.php for exact
26 semantics."""
27 assert(rank in self._valid_ranks)
28 self._rank = rank
29
30 def AddNode(self, id, name=None, color=None, href=None):
31 """Adds a node to the subgraph."""
32 tags = {}
33 if name:
34 tags['label'] = name
35 if color:
36 tags['color'] = color
37 tags['fontcolor'] = color
38 if href:
39 tags['href'] = href
40 self._nodes.append({'id': id, 'tags': tags})
41
42 def AddSubgraph(self, subgraph):
43 """Adds a subgraph to the subgraph."""
44 self._subgraphs.append(subgraph)
45
46 def AddNewSubgraph(self, rank=None):
47 """Adds a new subgraph to the subgraph. The new subgraph is returned."""
48 subgraph = Subgraph(rank)
49 self.AddSubgraph(subgraph)
50 return subgraph
51
52 def AddArc(self, node_from, node_to):
53 """Adds an arc between two nodes."""
54 self._arcs.add((node_from, node_to))
55
56 def _GenNodes(self):
57 """Generates the code for all the nodes."""
58 lines = []
59 for node in self._nodes:
60 tags = ['%s="%s"' % (k, v) for (k, v) in node['tags'].iteritems()]
61 lines.append('"%s" [%s];' % (node['id'], ', '.join(tags)))
62 return lines
63
64 def _GenSubgraphs(self):
65 """Generates the code for all the subgraphs contained in this subgraph."""
66 lines = []
67 for subgraph in self._subgraphs:
68 lines += subgraph.Gen();
69 return lines
70
71 def _GenArcs(self):
72 """Generates the code for all the arcs."""
73 lines = []
74 for node_from, node_to in self._arcs:
75 lines.append('"%s" -> "%s";' % (node_from, node_to))
76 return lines
77
78 def _GenInner(self):
79 """Generates the code for the inner contents of the subgraph."""
80 lines = []
81 if self._rank:
82 lines.append('rank=%s;' % self._rank)
83 lines += self._GenSubgraphs()
84 lines += self._GenNodes()
85 lines += self._GenArcs()
86 return lines
87
88 def Gen(self):
89 """Generates the code for the subgraph."""
90 return ['subgraph {'] + self._GenInner() + ['}']
91
92
93 class Graph(Subgraph):
94 """A top-level graph in dot. It's basically a subgraph with a name."""
95
96 def __init__(self, name):
97 Subgraph.__init__(self)
98 self._name = name
99
100 def Gen(self):
101 """Generates the code for the graph."""
102 return ['digraph "%s" {' % self._name,
103 'graph [name="%s"];' % self._name] + self._GenInner() + ['}']
104
105
106 def GenerateImage(lines, filename, format='svg', save_dot_filename=None):
107 """Generates the image by calling dot on the input lines."""
108 data = '\n'.join(lines)
109 proc = subprocess.Popen(['dot', '-T' + format, '-o' + filename],
110 stdin=subprocess.PIPE)
111 proc.communicate(data)
112
113 if save_dot_filename:
114 file = open(save_dot_filename, 'w')
115 file.write(data)
116 file.close()
OLDNEW
« 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