def _del(self, handle="", node="", edge="", subg=""): """ Deletes items. Finds the item handle by type, if necessary, and removes the item from graph """ head, tail = '', '' if edge: head, tail = edge node, head, tail, subg = map(encode_page, [node, head, tail, subg]) self.changed = 1 if head and tail: item = gv.findedge(gv.findnode(handle, head), gv.findnode(handle, tail)) elif node: item = gv.findnode(handle, node) elif subg: item = gv.findsubg(handle, subg) elif handle: item = handle else: raise ValueError("No graph element or element type specified") if item: gv.rm(item)
def _get(self, handle, node="", edge="", subg=""): """ Gets Graphviz.<Type> items from parent graph (given by handle). """ # Default return value if item is not found head, tail = '', '' if edge: head, tail = edge node, head, tail, subg = map(encode_page, [node, head, tail, subg]) graphvizitem = None if head and tail: item = gv.findedge(gv.findnode(handle, head), gv.findnode(handle, tail)) if item: graphvizitem = GraphvizEdge(self, item) elif node: item = gv.findnode(handle, node) if item: graphvizitem = GraphvizNode(self, item) elif subg: item = gv.findsubg(handle, subg) if item: graphvizitem = GraphvizSubgraph(self, item) else: raise ValueError("No graph element type specified") return graphvizitem
def _setattrs(self, handle="", edge="", node="", subg="", proto="", **attrs): """ Sets attributes for item by handle or by name and type Finds the item handle by type, if necessary, and sets given attributes. """ head, tail = '', '' if edge: head, tail = edge node, head, tail, subg = map(encode_page, [node, head, tail, subg]) self.changed = 1 if proto in ["node", "edge"]: # Gets handle when called from Subraphs.set() if subg: handle = gv.findsubg(self.handle, subg) # Called by self.set() and GraphvizSubgraph.set(), handle known item = getattr(gv, "proto%s" % proto)(handle) # print "item = gv.proto" + proto + "(g)" elif head and tail: item = gv.findedge(gv.findnode(handle, head), gv.findnode(handle, tail)) # print "item = gv.findedge(gv.findnode(g, '" + head + "')," + \ # "gv.findnode(g, '" + tail + "'))" elif node: item = gv.findnode(handle, node) # print "item = gv.findnode(g, '" + node + "')" elif subg: item = gv.findsubg(handle, subg) # print "item = gv.findsubg(g, '" + subg + "')" elif handle: item = handle else: raise ValueError("No graph element or element type specified") for key, elem in attrs.iteritems(): if isinstance(elem, set): for e in elem: key, e = map(encode_page, [key, e]) gv.setv(item, key, e) else: key, elem = map(encode_page, [key, elem]) gv.setv(item, key, elem)
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)
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 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')