1 ############################################################################
2 # Copyright (C) 2006 by Reithinger GmbH
5 # This file is part of faces.
7 # faces is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # faces is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the
19 # Free Software Foundation, Inc.,
20 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 ############################################################################
26 import faces
.charting
.charts
as charts
27 import faces
.charting
.faxes
as faxes
28 import faces
.charting
.widgets
as widgets
29 import faces
.charting
.patches
as patches
30 import faces
.charting
.connector
as connector
31 from faces
.charting
.tools
import *
32 import faces
.charting
.printer
as printer
37 class Graphviz(object):
38 def __init__(self
, go
):
41 def __getattr__(self
, name
):
42 return gv
.getv(self
._go
, name
)
45 def __setattr__(self
, name
, value
):
47 super(Graphviz
, self
).__setattr
__(name
, value
)
49 gv
.setv(self
._go
, name
, str(value
))
54 return gv
.nameof(self
._go
)
62 return Node(gv
.headof(self
._go
))
67 return Node(gv
.tailof(self
._go
))
73 class Digraph(Graphviz
):
74 def __init__(self
, graph
=None, name
=None):
76 self
._go
= gv
.readstring(str(input))
78 self
._go
= gv
.digraph(name
)
87 def add_node(self
, name
=None, **kwargs
):
90 name
= str(self
._counter
)
92 node
= Node(gv
.node(self
._go
, name
))
93 for k
, v
in kwargs
.items():
98 def add_edge(self
, tail
, head
, **kwargs
):
99 edge
= Edge(gv
.edge(tail
._go
, head
._go
))
100 for k
, v
in kwargs
.items():
106 def layout(self
, engine
):
107 gv
.layout(self
._go
, engine
)
109 def render(self
, format
, filename
=None):
111 gv
.render(self
._go
, format
, filename
)
113 gv
.render(self
._go
, format
)
115 def __getattr__(self
, name
):
116 return gv
.getv(self
._go
, name
)
120 return gv
.nameof(self
._go
)
122 name
= property(name
)
126 node
= gv
.firstnode(self
._go
)
129 node
= gv
.nextnode(self
._go
, node
)
131 nodes
= property(nodes
)
134 edge
= gv
.firstedge(self
._go
)
139 edge
= gv
.nextedge(self
._go
, edge
)
142 edges
= property(edges
)
146 class GraphVizChart(charts
.MatplotChart
):
148 properties
= {#"size" : "sularge",
149 "facecolor" : "white",
150 "edgecolor" : "black",
152 "antialiased" : True }
154 def create_axes(self
, rect
=None, **kwargs
):
155 pprop
= self
.get_patch
156 rect
= rect
or [0, 0, 1, 1]
158 ax
= fig
.add_axes(faxes
.PointAxes(fig
, rect
, **kwargs
))
160 ax
.set_marker(pprop("focused.marker"), pprop("marker"))
163 def get_nodes(self
, data
):
168 def printer(cls
, **kwargs
):
169 return printer
.PointPrinter(cls
, **kwargs
)
171 printer
= classmethod(printer
)
173 def create_node_widget(self
, node
):
175 pprop
= self
.get_patch
177 debug
= node
.name
== "Task3"
178 big
= widgets
.TableWidget(2, 1)
179 small
= widgets
.TableWidget(2, 2)
180 title
= widgets
.BoxedTextWidget(node
.title
, node
, fattrib
="title")
181 start
= widgets
.BoxedTextWidget(node
.to_string
.start
, node
, fattrib
="start", left
=2)
182 end
= widgets
.BoxedTextWidget(node
.to_string
.end
, node
, fattrib
="end", left
=2)
183 effort
= widgets
.BoxedTextWidget(node
.to_string
.effort
, node
, fattrib
="effort", left
=2)
184 length
= widgets
.BoxedTextWidget(node
.to_string
.length
, node
, fattrib
="length", left
=2)
186 big
.debug
= debug
and "big %s" % node
.name
187 end
.debug
= debug
and "end"
189 big
.set_cell(0, 0, title
)
190 big
.set_cell(1, 0, small
)
191 small
.set_cell(0, 0, start
, halign
="left")
192 small
.set_cell(0, 1, end
, halign
="left")
193 small
.set_cell(1, 0, length
, halign
="left")
194 small
.set_cell(1, 1, effort
, halign
="left")
195 big
.add_artist(patches
.Rectangle((LEFT
, BOTTOM
),
203 def get_edges(self
, nodes
):
206 for sources
in t
._sources
.values():
208 path
, sattrib
= faces
.task
._split
_path
(s
)
209 yield t
.get_task(path
), t
211 def create_graph(self
):
213 graph
= graphviz
.Digraph(name
="G")
214 graph
.nodesep
= "0,5"
216 graph
.ordering
= "in"
217 graph
.outputorder
= "nodesfirst"
218 graph
.ranksep
= "1.4 equally"
219 graph
.splines
= False
220 graph
.start
= "regular"
227 w
= widgets
.TableWidget(3, 2)
229 helper
= faxes
.PointAxes(self
.figure
, [0, 0, 1, 1])
230 helper
.check_limits()
233 graph
= self
.create_graph()
237 for n
in self
.get_nodes(self
.data
):
238 widget
= self
.create_node_widget(n
)
239 helper
.add_widget(widget
)
240 l
, b
, w
, h
= widget
.bbox
.get_bounds()
241 w
= "%.2f" % (w
/72.0)
242 h
= "%.2f" % (h
/72.0)
243 w
= w
.replace(".", ",")
244 h
= h
.replace(".", ",")
245 node
= nodes
[n
] = graph
.add_node(shape
="box", width
=w
, height
=h
)
246 node_to_widget
[node
.name
] = widget
251 for n1
, n2
in self
.get_edges(nodes
.keys()):
252 edges
.append((n1
, n2
))
253 graph
.add_edge(nodes
[n1
], nodes
[n2
])
258 graph
.render("dot", "/home/michael/temp/test.dot")
259 l
, b
, r
, gheight
= map(int, graph
.bb
.split(","))
261 for n
in graph
.nodes
:
262 w
= node_to_widget
[n
.name
]
263 x
, y
= map(int, n
.pos
.split(","))
264 w
.set_pos(x
, - gheight
+ y
)
265 self
.axes
.add_widget(w
)
268 w1
= node_to_widget
[nodes
[n1
].name
]
269 w2
= node_to_widget
[nodes
[n2
].name
]
270 c
= connector
.ShortConnector(w1
, w2
)
271 self
.axes
.add_widget(c
)
277 if __name__
== "__main__":
278 graph
= Digraph(name
="G")
279 graph
.nodesep
= "0,05"
281 graph
.ordering
= "in"
282 graph
.outputorder
= "nodesfirst"
283 graph
.ranksep
= "1.4 equally"
284 graph
.splines
= False
285 graph
.start
= "regular"
286 n1
= graph
.add_node(label
="1", width
="3,23", shape
="box")
287 n2
= graph
.add_node(label
="2")
288 print "n1", n1
.label
, n1
.name
, n1
.width
289 e
= graph
.add_edge(n1
, n2
)
295 #out.render("png", "/home/michael/temp/test.png")
296 #out.render("dot", "/home/michael/temp/test1.dot")
298 for n
in graph
.nodes
:
299 print " ", n
.name
, n
.label
, n
.width
, n
.pos
302 print " ", e
.head
.label
, e
.tail
.label
, e
.pos
303 #for e in graph.edges:
304 # print " ", e.head.label, e.tail.label, e.pos