import sys, string, cPickle, traceback, os.path from pydot import * # --------------- def layoutDot(D): # --------------- """Performs a JGraph layout on this Dot object. @type D: Dot / Graph @rtype: Dot / Graph """ # Make a bare adjacency-list with same topology as Dot G = Dot2G(D) sizes = Dot2Sizes(D) filename = tempfile.mktemp() f = file(filename, 'w') cPickle.dump(G, f) cPickle.dump(sizes, f) f.close() # Call the Jython portion, which talks to JGraph part2dir = os.path.dirname(traceback.extract_stack()[-1][0]) part2file = os.path.join(part2dir, 'JGLayout2.py') os.spawnlp(os.P_WAIT, 'jython', 'jython', part2file, filename) try: f = file(filename, 'r') coords = cPickle.load(f) f.close() except: print 'Jython portion of layout did not finish properly. Aborting.' return D # Transfer coordinates from coord-list to dot object bb = coords['_bb'] del coords['_bb'] D.set('bb', '%d,%d,%d,%d' % bb) for name, numbers in coords.items(): if isinstance(numbers, tuple): # node node = D.get_node(name) if not node: continue node.set('pos', '%d,%d' % (numbers[0], numbers[1])) node.set('width', '%f' % (float(numbers[2]) / 72.0)) node.set('height', '%f' % (float(numbers[3]) / 72.0)) elif isinstance(numbers, list): # edge points src, tgt = name.split(' -> ') edge = D.get_edge(src, tgt) if not edge: continue posstrs = ['e,%d,%d' % numbers[-1], ' '] del numbers[-1] for pos in numbers: posstrs.extend(['%d,%d' % pos, ' ']) del posstrs[-1] # no final space posstr = ''.join(posstrs) edge.set('pos', posstr) return D # ----------- def Dot2G(D): # ----------- """Returns a simple adjency-list mapping that corresponds to the topology of this Dot object. @type D: Dot / Graph @rtype: {string: [string...]} """ G = {} for node in D.get_node_list(): name = node.get_name() G[name] = [] for edge in D.get_edge_list(): src, dst = edge.get_source(), edge.get_destination() G[src].append(dst) return G # --------------- def Dot2Sizes(D): # --------------- """Gets you a mapping from node-names to (width, height) pairs. @type D: Dot / Graph @rtype: {string: (int, int)} """ sizes = {} for node in D.get_node_list(): name = node.get_name() sizes[name] = map(int, (string.atof(node.width)*72, string.atof(node.height)*72)) return sizes