def gv_layout(nodes, edges, mode="dot"): G = gv.graph("root") s = gv.graph(G, "test") for i in nodes: sg = "%02x %s" % (i, nodes[i][0]) n = gv.node(s, sg) if nodes[i][0] in gv_colors: gv.setv(n, "color", gv_colors[nodes[i][0]]) gv.setv(n, "style", "filled") for i in edges: if i[0] in nodes and i[1] in nodes: e = gv.edge(G, "%02x %s" % (i[0], nodes[i[0]][0]), "%02x %s" % (i[1], nodes[i[1]][0])) gv.setv(e, "dir", "none") gv.layout(G, mode) gv.render(G) # for debugging purposes gv.render(G, 'svg', 'test.svg') devs = {} fn = gv.firstnode(G) try: devs[gv.nameof(fn)] = gv.getv(fn, "pos").split(",") except: print 'Failed in gv_render' for i in range(len(nodes) - 1): fn = gv.nextnode(G, fn) devs[gv.nameof(fn)] = gv.getv(fn, "pos").split(",") return devs
def gv_layout(nodes,edges,mode="dot"): G = gv.graph("root") s = gv.graph(G,"test") for i in nodes: sg = "%02x %s"%(i,nodes[i][0]) n = gv.node(s,sg) if nodes[i][0] in gv_colors: gv.setv(n,"color",gv_colors[nodes[i][0]]) gv.setv(n,"style","filled") for i in edges: if i[0] in nodes and i[1] in nodes: e = gv.edge(G,"%02x %s"%(i[0],nodes[i[0]][0]),"%02x %s"%(i[1],nodes[i[1]][0])) gv.setv(e,"dir","none") gv.layout(G, mode) gv.render(G) # for debugging purposes gv.render(G,'svg','test.svg') devs = {} fn = gv.firstnode(G) try: devs[gv.nameof(fn)] = gv.getv(fn,"pos").split(",") except: print 'Failed in gv_render' for i in range(len(nodes)-1): fn = gv.nextnode(G,fn) devs[gv.nameof(fn)] = gv.getv(fn,"pos").split(",") return devs
def mark(): ok = False n = gv.firstnode(gr) while gv.ok(n): if gv.getv(n, 'color') == 'green': nh = gv.firsthead(n) while gv.ok(nh): if gv.getv(nh, 'color') != 'green': gv.setv(nh, 'color', 'green') ok = True nh = gv.nexthead(n, nh) n = gv.nextnode(gr, n) return ok
def __iter__(self): """ Iterates over item attributes. """ attr = gv.firstattr(self.handle) while gv.ok(attr): yield gv.nameof(attr), \ decode_page(gv.getv(self.handle, attr)) attr = gv.nextattr(self.handle, attr)
def GetAttrs(obj): attrs={} gsym=gv.firstattr(obj) while gsym: name=gv.nameof(gsym) attrs[name]=gv.getv(obj,gsym) gsym=gv.nextattr(obj,gsym) return attrs
def main(): # create a new empty graph G = gv.digraph('G') # define a simple graph ( A->B ) gv.edge(gv.node(G, 'A'), gv.node(G, 'B')) # compute a directed graph layout gv.layout(G, 'dot') # annotate the graph with the layout information gv.render(G) # do something with the layout n = gv.firstnode(G) while n: print 'node ' + gv.nameof(n) + ' is at ' + gv.getv(n, 'pos') e = gv.firstout(n) while e: print 'edge ' + gv.nameof(gv.tailof(e)) + '->' + gv.nameof( gv.headof(e)) + ' is at ' + gv.getv(e, 'pos') e = gv.nextout(n, e) n = gv.nextnode(G, n)
def initialise_nodes(self): # Bake in the node attributes from 'dot' layout gv.layout(self.gvo, 'dot') gv.render(self.gvo) # iterate over node attributes to get/set node positions # see gv.3python.pdf for more info # as well as https://mailman.research.att.com/pipermail/graphviz-interest/2006q1/003182.html n = gv.firstnode(self.gvo) #store min and max x and y minx = 0 miny = 0 maxx = None maxy = None # store the node label and position as reported by Dot layout nodepos = {} # {<node object>:(x,y)} while gv.ok(n) : # check that the iterator returned by firstnode is ok label = gv.nameof(n) spos = gv.getv(n,'pos').split(',') # list of strings (xpos,ypos) = [float(i) for i in spos] # convert to float node = self.dag.get_node_from_label(label) pos = node.get_position() if pos != None: # Set xpos and ypos if they are already defined in node.get_position() (xpos,ypos) = pos print xpos, ypos # set min and max values if minx > xpos: minx = xpos if maxx < xpos: maxx = xpos if miny > ypos: miny = ypos if maxy < ypos: maxy = ypos nodepos[node] = (xpos, ypos) #change node before iteration n = gv.nextnode(self.gvo, n) print "min", minx, miny print "max", maxx, maxy # Set the position in all nodes for node, pos in nodepos.iteritems(): node.set_position(pos)
def _iterattrs(self, handle=""): """ Iterate over the attributes of a graph item. If no handle attribute is given, iterates over the attributes of the root graph """ if not handle: handle = self.handle attr = gv.firstattr(handle) while gv.ok(attr): yield gv.nameof(attr), decode_page(gv.getv(handle, attr)) attr = gv.nextattr(handle, attr)
def __getattr__(self, name): """ Finds the named attribute, returns its value """ handle = self.__dict__['handle'] name = encode_page(name) retval = gv.getv(handle, gv.findattr(handle, name)) # Needed mainly for dict() for work, getattribute excepts # and so __iter__ is called. Non-gv attrs are not returned. if not retval: object.__getattribute__(self, name) return decode_page(retval)
def generate(self, filename): ''' Displays the graph on the canvas Uses python-igraph fruchterman-reingold algorithm to decide about position of the nodes, then draw these nodes on the canvas and draw connections between them Author: Jan Vorcak <*****@*****.**> ''' g = gv.readstring(self.source) gv.layout(g, 'dot') gv.render(g) context = CanvasContext().dictionary node = gv.firstnode(g) while node is not None: props = { 'filepath' : gv.getv(node, 'filepath'), 'title' : gv.getv(node, 'label'), 'lineno' : gv.getv(node, 'lineno'), } pos = gv.getv(node, 'pos').split(',') width = gv.getv(node, 'width') height = gv.getv(node, 'height') x, y = map(int, pos) class_box = ClassBox(props, width, height) class_box.matrix.translate(x, y) self.view.canvas.add(class_box) context[(props['filepath'], props['title'])] = class_box node = gv.nextnode(g, node) edge = gv.firstedge(g) while edge is not None: props = { 'arrowhead' : gv.getv(edge, 'arrowhead'), 'arrowtail' : gv.getv(edge, 'arrowtail'), } head = gv.headof(edge) tail = gv.tailof(edge) head_str = (gv.getv(head, 'filepath'), gv.getv(head, 'label')) tail_str = (gv.getv(tail, 'filepath'), gv.getv(tail, 'label')) context[head_str] context[tail_str] edge = gv.nextedge(g, edge) set_association(self.view.canvas, context[head_str], \ context[tail_str], props)
if 0: import gv nodes=[] g = gv.digraph("G") n=gv.node(g,"hello") nodes.append(n) for i in range(0,100,1): m = gv.node(g,str(i)) nodes.append(m) e = gv.edge(n,m) gv.layout(g, "dot") gv.render(g,"xdot","test.xdot") for node in nodes: print "pos=",gv.getv(node,"pos") #print "pos=",gv.getv(n,"pos") #print "pos=",gv.getv(e,"pos") if 0: g=gv.digraph("G") g=gv.read("test.dot") gv.layout(g, "dot") gv.render(g, "gif","test.gif") if 0: def main(): app=QApplication() win= () win.show()
#!/usr/bin/python import gv g = gv.digraph("G") print gv.setv(g, "aaa", "xxx") print gv.getv(g, "aaa") n = gv.node(g, "hello") print gv.getv(n, "label") print gv.setv(n, "aaa", "xxx") print gv.getv(n, "aaa") m = gv.node(g, "world") print gv.getv(m, "aaa") e = gv.edge(n, m) print gv.setv(e, "aaa", "xxx") print gv.getv(e, "aaa") gv.rm(e) gv.rm(m) gv.rm(n) gv.rm(g) g = gv.readstring("digraph G {a->b}") gv.rm(g) g = gv.read("hello.gv") gv.layout(g, "dot") gv.render(g, "png", "hello.png") gv.rm(g)
#!/usr/bin/python import sys import gv # create a new empty graph G = gv.digraph('G') # define a simple graph ( A->B ) gv.edge(gv.node(G, 'A'), gv.node(G, 'B')) # compute a directed graph layout gv.layout(G, 'dot') # annotate the graph with the layout information gv.render(G) # do something with the layout n = gv.firstnode(G) while n: print 'node ' + gv.nameof(n) + ' is at ' + gv.getv(n, 'pos') e = gv.firstout(n) while e: print 'edge ' + gv.nameof(gv.tailof(e)) + '->' + gv.nameof( gv.headof(e)) + ' is at ' + gv.getv(e, 'pos') e = gv.nextout(n, e) n = gv.nextnode(G, n)
def graph_draw(g, pos=None, size=(15, 15), pin=False, layout="neato", maxiter=None, ratio="fill", overlap=False, splines=False, mode="major", vsize=0.1, penwidth=1.0, eweight=None, ewidth=None, gprops={}, vprops={}, eprops={}, vcolor=None, ecolor=None, vcmap=matplotlib.cm.jet, vnorm=True, ecmap=matplotlib.cm.jet, enorm=True, output="", output_format="auto", returngv=False, fork=False, seed=0): """Draw a graph using graphviz.""" if output != "": output = os.path.expanduser(output) # check opening file for writing, since graphview will bork if it is not # possible to open file if os.path.dirname(output) != "" and \ not os.access(os.path.dirname(output), os.W_OK): raise IOError("cannot write to " + os.path.dirname(output)) if g.is_directed(): gvg = gv.digraph("G") else: gvg = gv.graph("G") # main graph properties gv.setv(gvg, "outputorder", "edgesfirst") gv.setv(gvg, "mode", mode) if overlap == False: if layout == "neato" and mode == "ipsep": overlap = "ipsep" else: overlap = "false" else: overlap = "true" if isinstance(overlap, str): gv.setv(gvg, "overlap", overlap) if splines: gv.setv(gvg, "splines", "true") gv.setv(gvg, "ratio", str(ratio)) gv.setv(gvg, "size", "%f,%f" % (size[0] / 2.54, size[1] / 2.54)) # centimeters if maxiter != None: gv.setv(gvg, "maxiter", str(maxiter)) if seed != 0: if type(seed) == int: gv.setv(gvg, "start", "%d" % seed) else: gv.setv(gvg, "start", seed) # apply all user supplied properties for k, val in gprops.iteritems(): if isinstance(val, PropertyMap): gv.setv(gvg, k, str(val[g])) else: gv.setv(gvg, k, str(val)) # normalize color properties if vcolor != None and not isinstance(vcolor, str): minmax = [float("inf"), -float("inf")] for v in g.vertices(): c = vcolor[v] minmax[0] = min(c, minmax[0]) minmax[1] = max(c, minmax[1]) if minmax[0] == minmax[1]: minmax[1] += 1 if vnorm: vnorm = matplotlib.colors.normalize(vmin=minmax[0], vmax=minmax[1]) if ecolor != None and not isinstance(ecolor, str): minmax = [float("inf"), -float("inf")] for e in g.edges(): c = ecolor[e] minmax[0] = min(c, minmax[0]) minmax[1] = max(c, minmax[1]) if minmax[0] == minmax[1]: minmax[1] += 1 if enorm: enorm = matplotlib.colors.normalize(vmin=minmax[0], vmax=minmax[1]) nodes = [] edges = [] # add nodes for v in g.vertices(): n = gv.node(gvg, str(g.vertex_index[v])) if type(vsize) != tuple: vw = vh = vsize else: vw, vh = vsize if type(vw) == PropertyMap: vw = vw[v] if type(vh) == PropertyMap: vh = vh[v] if type(vw) == str and vw == "in": vw = v.in_degree() if type(vw) == str and vw == "out": vw = v.out_degree() if type(vw) == str and vw == "total": vw = v.in_degree() + v.out_degree() if type(vh) == str and vh == "in": vh = v.in_degree() if type(vh) == str and vh == "out": vh = v.out_degree() if type(vh) == str and vh == "total": vh = v.in_degree() + v.out_degree() gv.setv(n, "width", "%g" % vw) gv.setv(n, "height", "%g" % vh) gv.setv(n, "style", "filled") gv.setv(n, "color", "black") # apply color if vcolor != None: if isinstance(vcolor, str): gv.setv(n, "fillcolor", vcolor) else: color = tuple( [int(c * 255.0) for c in vcmap(vnorm(vcolor[v]))]) gv.setv(n, "fillcolor", "#%.2x%.2x%.2x%.2x" % color) else: gv.setv(n, "fillcolor", "red") gv.setv(n, "label", "") # user supplied position if pos != None: gv.setv(n, "pos", "%f,%f" % (pos[0][v], pos[1][v])) gv.setv(n, "pin", str(pin)) # apply all user supplied properties for k, val in vprops.iteritems(): if isinstance(val, PropertyMap): gv.setv(n, k, str(val[v])) else: gv.setv(n, k, str(val)) nodes.append(n) for e in g.edges(): ge = gv.edge(nodes[g.vertex_index[e.source()]], nodes[g.vertex_index[e.target()]]) gv.setv(ge, "arrowsize", "0.3") if g.is_directed(): gv.setv(ge, "arrowhead", "vee") # apply color if ecolor != None: if isinstance(ecolor, str): gv.setv(ge, "color", ecolor) else: color = tuple( [int(c * 255.0) for c in ecmap(enorm(ecolor[e]))]) gv.setv(ge, "color", "#%.2x%.2x%.2x%.2x" % color) # apply weight if eweight != None: if isinstance(eweight, PropertyMap): gv.setv(ge, "weight", str(eweight[e])) else: gv.setv(ge, "weight", str(eweight)) # apply width if ewidth != None: if isinstance(ewidth, PropertyMap): gv.setv(ge, "penwidth", str(ewidth[e])) else: gv.setv(ge, "penwidth", str(ewidth)) # apply all user supplied properties for k, v in eprops.iteritems(): if isinstance(v, PropertyMap): gv.setv(ge, k, str(v[e])) else: gv.setv(ge, k, str(v)) edges.append(ge) gv.layout(gvg, layout) gv.render(gvg, "dot", "/dev/null") # retrieve postitions if pos == None: pos = (g.new_vertex_property("double"), g.new_vertex_property("double")) for n in xrange(0, len(nodes)): p = gv.getv(nodes[n], "pos") p = p.split(",") pos[0][g.vertex(n)] = float(p[0]) pos[1][g.vertex(n)] = float(p[1]) if output_format == "auto": if output == "": output_format = "xlib" else: output_format = output.split(".")[-1] # if using xlib we need to fork the process, otherwise good ol' graphviz # will call exit() when the window is closed if output_format == "xlib" or fork: pid = os.fork() if pid == 0: gv.render(gvg, output_format, output) os._exit(0) # since we forked, it's good to be sure if output_format != "xlib": os.wait() else: gv.render(gvg, output_format, output) if returngv: return pos, gv else: gv.rm(gvg) del gvg return pos
#!/usr/bin/python import gv g = gv.digraph("G") print gv.setv(g,"aaa","xxx") print gv.getv(g,"aaa") n = gv.node(g,"hello") print gv.getv(n,"label") print gv.setv(n,"aaa","xxx") print gv.getv(n,"aaa") m = gv.node(g,"world") print gv.getv(m,"aaa") e = gv.edge(n,m) print gv.setv(e,"aaa","xxx") print gv.getv(e,"aaa") gv.rm(e) gv.rm(m) gv.rm(n) gv.rm(g) g = gv.readstring("digraph G {a->b}") gv.rm(g) g = gv.read("hello.gv") gv.layout(g, "dot") gv.render(g, "png", "hello.png") gv.rm(g)
def graph_draw(g, pos=None, size=(15,15), pin=False, layout="neato", maxiter=None, ratio="fill", overlap=False, splines=False, mode="major", vsize=0.1, penwidth=1.0, eweight=None, ewidth=None, gprops={}, vprops={}, eprops={}, vcolor=None, ecolor=None, vcmap=matplotlib.cm.jet, vnorm=True, ecmap=matplotlib.cm.jet, enorm=True, output="", output_format="auto", returngv=False, fork=False, seed=0): """Draw a graph using graphviz.""" if output != "": output = os.path.expanduser(output) # check opening file for writing, since graphview will bork if it is not # possible to open file if os.path.dirname(output) != "" and \ not os.access(os.path.dirname(output), os.W_OK): raise IOError("cannot write to " + os.path.dirname(output)) if g.is_directed(): gvg = gv.digraph("G") else: gvg = gv.graph("G") # main graph properties gv.setv(gvg,"outputorder", "edgesfirst") gv.setv(gvg,"mode", mode) if overlap == False: if layout == "neato" and mode == "ipsep": overlap = "ipsep" else: overlap = "false" else: overlap = "true" if isinstance(overlap,str): gv.setv(gvg,"overlap", overlap) if splines: gv.setv(gvg,"splines", "true") gv.setv(gvg,"ratio", str(ratio)) gv.setv(gvg,"size", "%f,%f" % (size[0]/2.54,size[1]/2.54)) # centimeters if maxiter != None: gv.setv(gvg,"maxiter", str(maxiter)) if seed != 0: if type(seed) == int: gv.setv(gvg, "start", "%d" % seed) else: gv.setv(gvg, "start", seed) # apply all user supplied properties for k,val in gprops.iteritems(): if isinstance(val, PropertyMap): gv.setv(gvg, k, str(val[g])) else: gv.setv(gvg, k, str(val)) # normalize color properties if vcolor != None and not isinstance(vcolor, str): minmax = [float("inf"), -float("inf")] for v in g.vertices(): c = vcolor[v] minmax[0] = min(c,minmax[0]) minmax[1] = max(c,minmax[1]) if minmax[0] == minmax[1]: minmax[1] += 1 if vnorm: vnorm = matplotlib.colors.normalize(vmin=minmax[0], vmax=minmax[1]) if ecolor != None and not isinstance(ecolor, str): minmax = [float("inf"), -float("inf")] for e in g.edges(): c = ecolor[e] minmax[0] = min(c,minmax[0]) minmax[1] = max(c,minmax[1]) if minmax[0] == minmax[1]: minmax[1] += 1 if enorm: enorm = matplotlib.colors.normalize(vmin=minmax[0], vmax=minmax[1]) nodes = [] edges = [] # add nodes for v in g.vertices(): n = gv.node(gvg,str(g.vertex_index[v])) if type(vsize) != tuple: vw = vh = vsize else: vw, vh = vsize if type(vw) == PropertyMap: vw = vw[v] if type(vh) == PropertyMap: vh = vh[v] if type(vw) == str and vw == "in": vw = v.in_degree() if type(vw) == str and vw == "out": vw = v.out_degree() if type(vw) == str and vw == "total": vw = v.in_degree() + v.out_degree() if type(vh) == str and vh == "in": vh = v.in_degree() if type(vh) == str and vh == "out": vh = v.out_degree() if type(vh) == str and vh == "total": vh = v.in_degree() + v.out_degree() gv.setv(n, "width", "%g" % vw) gv.setv(n, "height", "%g" % vh) gv.setv(n, "style", "filled") gv.setv(n, "color", "black") # apply color if vcolor != None: if isinstance(vcolor,str): gv.setv(n, "fillcolor", vcolor) else: color = tuple([int(c*255.0) for c in vcmap(vnorm(vcolor[v]))]) gv.setv(n, "fillcolor", "#%.2x%.2x%.2x%.2x" % color) else: gv.setv(n, "fillcolor", "red") gv.setv(n, "label", "") # user supplied position if pos != None: gv.setv(n, "pos", "%f,%f" % (pos[0][v],pos[1][v])) gv.setv(n, "pin", str(pin)) # apply all user supplied properties for k,val in vprops.iteritems(): if isinstance(val, PropertyMap): gv.setv(n, k, str(val[v])) else: gv.setv(n, k, str(val)) nodes.append(n) for e in g.edges(): ge = gv.edge(nodes[g.vertex_index[e.source()]], nodes[g.vertex_index[e.target()]]) gv.setv(ge, "arrowsize", "0.3") if g.is_directed(): gv.setv(ge, "arrowhead", "vee") # apply color if ecolor != None: if isinstance(ecolor,str): gv.setv(ge, "color", ecolor) else: color = tuple([int(c*255.0) for c in ecmap(enorm(ecolor[e]))]) gv.setv(ge, "color", "#%.2x%.2x%.2x%.2x" % color) # apply weight if eweight != None: if isinstance(eweight, PropertyMap): gv.setv(ge, "weight", str(eweight[e])) else: gv.setv(ge, "weight", str(eweight)) # apply width if ewidth != None: if isinstance(ewidth, PropertyMap): gv.setv(ge, "penwidth", str(ewidth[e])) else: gv.setv(ge, "penwidth", str(ewidth)) # apply all user supplied properties for k,v in eprops.iteritems(): if isinstance(v, PropertyMap): gv.setv(ge, k, str(v[e])) else: gv.setv(ge, k, str(v)) edges.append(ge) gv.layout(gvg, layout) gv.render(gvg, "dot", "/dev/null") # retrieve postitions if pos == None: pos = (g.new_vertex_property("double"), g.new_vertex_property("double")) for n in xrange(0, len(nodes)): p = gv.getv(nodes[n], "pos") p = p.split(",") pos[0][g.vertex(n)] = float(p[0]) pos[1][g.vertex(n)] = float(p[1]) if output_format == "auto": if output == "": output_format = "xlib" else: output_format = output.split(".")[-1] # if using xlib we need to fork the process, otherwise good ol' graphviz # will call exit() when the window is closed if output_format == "xlib" or fork: pid = os.fork() if pid == 0: gv.render(gvg, output_format, output) os._exit(0) # since we forked, it's good to be sure if output_format != "xlib": os.wait() else: gv.render(gvg, output_format, output) if returngv: return pos, gv else: gv.rm(gvg) del gvg return pos
#!/usr/bin/python import sys import gv # create a new empty graph G = gv.digraph('G') # define a simple graph ( A->B ) gv.edge(gv.node(G, 'A'),gv.node(G, 'B')) # compute a directed graph layout gv.layout(G, 'dot') # annotate the graph with the layout information gv.render(G) # do something with the layout n = gv.firstnode(G) while n : print 'node '+gv.nameof(n)+' is at '+gv.getv(n,'pos') e = gv.firstout(n) while e : print 'edge '+gv.nameof(gv.tailof(e))+'->'+gv.nameof(gv.headof(e))+' is at '+gv.getv(e,'pos') e = gv.nextout(n,e) n = gv.nextnode(G,n)
def _getNodesFromDAG(self): # Get the dotfile from the DAG dot = self.dag.get_dot() gvo = gv.readstring(dot) # Bake in the node attributes from 'dot' layout gv.layout(gvo, 'dot') gv.render(gvo) # iterate over node attributes to get/set node positions # see gv.3python.pdf for more info # as well as https://mailman.research.att.com/pipermail/graphviz-interest/2006q1/003182.html n = gv.firstnode(gvo) #store min and max x and y minx = 0 miny = 0 maxx = None maxy = None # store the node label and position as reported by Dot layout nodepos = {} # {<node object>:(x,y)} while gv.ok(n) : # check that the iterator returned by firstnode is ok label = gv.nameof(n) spos = gv.getv(n,'pos').split(',') # list of strings (xpos,ypos) = [float(i) for i in spos] # convert to float node = self.dag.get_node_from_label(label) pos = node.get_position() if pos != None: # Set xpos and ypos if they are already defined in node.get_position() (xpos,ypos) = pos # set min and max values if minx > xpos: minx = xpos if maxx < xpos: maxx = xpos if miny > ypos: miny = ypos if maxy < ypos: maxy = ypos nodepos[node] = (xpos, ypos) #change node before iteration n = gv.nextnode(gvo, n) # Set the position in all nodes and add them to the graph for node, pos in nodepos.iteritems(): node.set_position(pos) label = self.dag.get_label_from_node(node) v_node = v_Node(label) v_node.setPos(*pos) self.graphview.add(v_node) bounding = self.graphview.scene().itemsBoundingRect() #self.graphview.fitInView(bounding, QtCore.Qt.IgnoreAspectRatio) self.graphview.centerOn(bounding.center())
def label(self): return gv.getv(self.handle, b"label")
def layout_graph(edges): """ Take a description of the connectivity of a graph and return a representation of that graph in 2D cartesian space. Input: `edges` An iterable over pairs of 'node_id's that are connected. A 'node_id' is an arbitrary object in this context, with the only restriction that it's uniquely identified by its string representation, that is: (str(node1) == str(node2)) implies (node1 == node2). Output: An iterable yielding triples of the form (`id`, `x`, `y`) where `id` is the string representation of the node_id that this vertex represents, and `x`, `y` are the string representations of the cartesian coordinates of said vertex. It is a bit dirty to return strings rather than the values themselves, but these are meant to be written out to a file anyway, so I'm avoiding redundant conversions. Only the vertices that are connected to some other vertex are listed here (i.e. don't provide vertices linked to themselves), and the vertex order is arbitrary. Nothing should be assumed about the coordinate system in which these vertices are described. Neither scale nor origin are defined. You may need to normalize them and rescale them if you have specific requirements in this regard. `edges` An iterable yielding pairs of the form (`id_a`, `id_b`) where `id_a`, `id_b` are the string representations of the `node_id` of the endpoints of this edge. Not coincidentially, this is the data expected in the graph description referred to in searchview.py '*.history' description files. """ print "Adding edges to graphviz..." graph = gv.strictgraph("graph") for a, b in edges: gv.edge(graph, str(a), str(b)) print "Laying out..." gv.layout(graph, "sfdp") print "Rendering..." gv.render(graph) print "Creating vertices..." vertex_names = set(imap(str, ichain(edges))) return (tuple([name] + gv.getv(gv.findnode(graph, name), "pos").split(",")) for name in vertex_names)
def shape(self): return gv.getv(self.handle, b"shape")
return ok if __name__ == "__main__": name = sys.argv[1] if name[-4:] != '.dot': print "wrong name", name exit name = name[:-4] gr = gv.read(name + '.dot') m = gv.findnode(gr, 'main') gv.setv(m, 'color', 'green') while mark(): pass n = gv.firstnode(gr) while gv.ok(n): if gv.getv(n, 'color') != 'green': gv.setv(n, 'fillcolor', 'red') gv.setv(n, 'style', 'filled') in_degree = 0 e = gv.firstin(n) while gv.ok(e): in_degree += 1 e = gv.nextin(n, e) if in_degree == 1: gv.setv(n, 'shape', 'diamond') n = gv.nextnode(gr, n) gv.write(gr, name + '-new.dot') gv.layout(gr, 'dot') gv.render(gr) gv.render(gr, 'fig', name + '.fig')