-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdot_interface.py
109 lines (89 loc) · 3.02 KB
/
dot_interface.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import subprocess
import os.path
class DotInterface(object):
"""
Abstracts dot specific parsing and editing.
"""
'''
digraph graphname {
a [label="Foo"];
b [shape=box];
c [label="XXX", shape=circle];
a -> b -> c [color=blue];
b -> d [style=dotted];
a -> c [color=green, style=dotted];
}
'''
def __init__(self, name, dest_path):
self.name = name
self.dest_path = dest_path
if not os.path.exists(dest_path):
os.mkdir(dest_path)
def create_dotfile(self, AObjects):
"""
Writes AObjects to dot file
1. First pass writes object shapes
2. Second pass writes arrows
3. Does layout
"""
target_path = os.path.join(self.dest_path, self.name)
f = open(target_path, 'w')
f.write("digraph %s {\n\n" % self.name)
f.write("rankdir=LR;\n\n")
""" write dot file """
visited = {}
for aobject in AObjects:
self._write_node(f, aobject)
visited[aobject] = 1
for aobject in AObjects:
for afield in aobject.fields:
if afield.dest:
if afield.dest in visited:
self._write_edge(f, aobject, afield.dest, afield.dest.color)
f.write("\n}\n")
f.close()
def create_pdf(self):
dot_file_path = os.path.join(self.dest_path, self.name)
command = ["dot", "-O", "-Tpdf", dot_file_path]
subprocess.Popen(command)
def _retrieve_color(self, color):
s = "#"
for c in color:
cstr = "%x" % (c * 255)
if len(cstr) < 2:
cstr = "0%s" % cstr
if len(cstr) > 2:
print cstr
cstr = "00"
s += cstr
return s
def _write_node(self, f, aobject):
"""
creates two nodes, one for name, one for list of fields,
and assembles them into a single node group
@return: group
"""
shape = "box"
if aobject.shape == "Rectangle":
shape = "rectangle"
elif aobject.shape == "Circle":
shape = "oval"
if aobject.color == (1, 1, 1):
color = (0, 0, 0)
else:
color = aobject.color
color = self._retrieve_color(color)
properties = {'label': aobject.name,
'shape': shape,
'fillcolor': color}
if color != "#000000":
properties['style'] = "filled"
properties_str = ", ".join(['%s="%s"' % (k, v) for k, v in properties.items()])
f.write('"%s" [%s];\n' % (aobject.name, properties_str))
def _write_edge(self, f, src, dest, color):
if color == (1, 1, 1):
color = (0, 0, 0)
color = self._retrieve_color(color)
f.write('"%s" -> "%s" [color="%s", penwidth=3];\n' % (src.name,
dest.name,
color))