def _layout(self):

        self._initialize()

        # order the nodes
        ordered_nodes = CFGUtils.quasi_topological_sort_nodes(self.graph)

        # conver the graph to an acylic graph
        acyclic_graph = self._to_acyclic_graph(self.graph, ordered_nodes=ordered_nodes)

        # assign row and column to each node
        self._assign_grid_locations(self.graph, acyclic_graph, ordered_nodes=ordered_nodes)

        # edge routing
        edge_router = EdgeRouter(self.graph, self._cols, self._rows, self._locations, self._max_col, self._max_row)
        self.edges = edge_router.edges
        self._vertical_edges = edge_router.vertical_edges
        self._horizontal_edges = edge_router.horizontal_edges

        # determine the maximum index for each grid
        self._set_max_grid_edge_id()

        # determine row and column sizes
        self._make_grids()

        # calculate coordinates of nodes
        self._calculate_coordinates()
    def _to_acyclic_graph(self, graph, ordered_nodes=None):
        """
        Convert a given DiGraph into an acyclic graph.

        :param networkx.DiGraph graph: The graph to convert.
        :param list ordered_nodes:     A list of nodes sorted in a topological order.
        :return:                       The converted acyclic graph.
        """

        if ordered_nodes is None:
            # take the quasi-topological order of the graph
            ordered_nodes = CFGUtils.quasi_topological_sort_nodes(graph)

        acyclic_graph = networkx.DiGraph()

        # add each node and its edge into the graph
        visited = set()
        for node in ordered_nodes:
            visited.add(node)
            acyclic_graph.add_node(node)
            for successor in graph.successors(node):
                if successor not in visited:
                    acyclic_graph.add_edge(node, successor)

        return acyclic_graph
Beispiel #3
0
    def sort_nodes(self, nodes=None):
        sorted_nodes = CFGUtils.quasi_topological_sort_nodes(self.cfg.graph)

        if nodes is not None:
            sorted_nodes = [n for n in sorted_nodes if n in set(nodes)]

        return sorted_nodes
    def _assign_grid_locations(self, graph, acyclic_graph, ordered_nodes=None):
        """
        Assign locations to each node in the graph in a bottom-up manner.

        :param networkx.DiGraph graph:          The original graph.
        :param networkx.DiGraph acyclic_graph:  The acyclic graph to work on.
        :param list ordered_nodes:      A list of nodes sorted in a topological order.
        :return:                        None
        """

        if ordered_nodes is None:
            # take the quasi-topological order of the graph
            ordered_nodes = CFGUtils.quasi_topological_sort_nodes(acyclic_graph)

        self._assign_rows(graph, acyclic_graph, ordered_nodes)
        self._assign_columns(acyclic_graph)