def xml(self): """ Return IPFGraph as XML element """ graph = Element("IPFGraph") block_tree = SubElement(graph, "Blocks") for name in sorted(self.__blocks): row, column = self.get_block_cell(name) block_element = SubElement(block_tree, "Block", {"name":name, "grid_row":str(row), "grid_column":str(column)}) block_element.append(self.__blocks[name].xml()) connection_tree = SubElement(graph, "Connections") for connection in sorted(self.connections): oport = connection._oport() iport = connection._iport() oblock = oport._owner_block() iblock = iport._owner_block() oblock_name = self.get_block_name(oblock) iblock_name = self.get_block_name(iblock) oport_name = oblock.get_port_name(oport) iport_name = iblock.get_port_name(iport) conection_element = SubElement(connection_tree, "Connection") con_output = SubElement(conection_element, "ConnectionOutput", {"block" : oblock_name, "port" : oport_name}) con_input = SubElement(conection_element, "ConnectionInput", {"block" : iblock_name, "port" : iport_name}) return graph
def rearrange(self): """ Rearranges graph to layered structure """ block_dict = dict() graph = digraph() for i, block_name in enumerate(self.__blocks): # Add 100 for each block number for make equal length of names # need check if blocks count greater than 900 block_dict[block_name] = str(i + 100) graph.add_node(block_dict[block_name]) for connection in self.connections: out_block_name = self.get_block_name(connection._oport()._owner_block()) in_block_name = self.get_block_name(connection._iport()._owner_block()) try: graph.add_edge( (block_dict[out_block_name], block_dict[in_block_name]) ) except pygraph.classes.exceptions.AdditionError: continue # Export graph to DOT format dot = pygraph.readwrite.dot.write(graph) gvv = pygraphviz.AGraph() gvv.from_string(dot) # Arrange graph in layers gvv.layout('dot') # Parse DOT graph format to get nodes coordinates dot = gvv.to_string() dot = dot.replace('\n', ' ') x_coords = set() y_coords = set() nodes = [] lines = dot.split(";") for line in lines: r = re.compile(r'\s*(?P<node_name>\w+)\s*\[height=".*",\s*pos="(?P<pos_x>[\w\.]+),(?P<pos_y>[\w\.]+)",\s*width=".*"\]') m = r.search(line) if m is not None: x = int(floor(float(m.group('pos_x'))/20)*20) y = int(floor(float(m.group('pos_y'))/20)*20) nodes.append( (m.group('node_name'), x, y) ) x_coords.add(x) y_coords.add(y) xs = sorted(x_coords) ys = sorted(y_coords) row = dict() column = dict() for i, x in enumerate(xs): column[x] = i for i, y in enumerate(ys): row[y] = len(ys) - i - 1 cell_nodes = [] for node, x, y in nodes: cell_nodes.append( (node, row[y], column[x]) ) self._grid_model = self._get_clear_grid_model() for node, row, column in cell_nodes: self._grid_model[row][column] = dict_key_from_value(block_dict, node) self._grid_height = max(self._grid_height, row + 1) self._grid_width = max(self._grid_width, column + 1)