Exemple #1
0
    def build(cls, tree, config=None, layout=True):
        DiagramNode.clear()
        DiagramEdge.clear()
        NodeGroup.clear()
        Diagram.clear()

        return cls(tree, config, layout).run()
Exemple #2
0
    def compare_child_node_order(self, parent, node1, node2):
        def compare(x, y):
            x = x.duplicate()
            y = y.duplicate()
            while x.node1 == y.node1 and x.node1.group is not None:
                x.node1 = x.node1.group
                y.node1 = y.node1.group

            # cmp x.node1.order and y.node1.order
            if x.node1.order < y.node1.order:
                return -1
            elif x.node1.order == y.node1.order:
                return 0
            else:
                return 1

        edges = (DiagramEdge.find(parent, node1) +
                 DiagramEdge.find(parent, node2))
        edges.sort(key=cmp_to_key(compare))
        if len(edges) == 0:
            return 0
        elif edges[0].node2 == node2:
            return 1
        else:
            return -1
Exemple #3
0
    def run(self):
        for i, group in enumerate(self._groups):
            base = self.diagram.duplicate()
            base.level = group.level - 1

            # bind edges on base diagram (outer the group)
            edges = (DiagramEdge.find(None, group) +
                     DiagramEdge.find(group, None))
            base.edges = self._filter_edges(edges, self.diagram, group.level)

            # bind edges on target group (inner the group)
            subgroups = group.traverse_groups()
            edges = sum([g.edges for g in subgroups], group.edges)
            group.edges = []
            for e in self._filter_edges(edges, group, group.level):
                if isinstance(e.node1, NodeGroup) and e.node1 == e.node2:
                    pass
                else:
                    group.edges.append(e)

            # clear subgroups in the group
            for g in group.nodes:
                if isinstance(g, NodeGroup):
                    g.nodes = []
                    g.edges = []
                    g.separated = True

            # pick up nodes to base diagram
            nodes1 = [e.node1 for e in DiagramEdge.find(None, group)]
            nodes1.sort(key=lambda x: x.order)
            nodes2 = [e.node2 for e in DiagramEdge.find(group, None)]
            nodes2.sort(key=lambda x: x.order)

            nodes = nodes1 + [group] + nodes2
            for i, n in enumerate(nodes):
                n.order = i
                if n not in base.nodes:
                    base.nodes.append(n)
                    n.group = base

            if isinstance(group, Diagram):
                base = group

            DiagramLayoutManager(base).run()
            base.fixiate(True)
            EdgeLayoutManager(base).run()

            yield base
Exemple #4
0
    def run(self):
        if isinstance(self.diagram, Diagram):
            for group in self.diagram.traverse_groups():
                self.__class__(group).run()

        self.edges = DiagramEdge.find_by_level(self.diagram.level)
        self.do_layout()
        self.diagram.fixiate()

        if self.diagram.orientation == 'portrait':
            self.rotate_diagram()
Exemple #5
0
    def instantiate(self, group, tree):
        for stmt in tree.stmts:
            # Translate Node having group attribute to Group
            if isinstance(stmt, parser.Node):
                group_attr = [a for a in stmt.attrs if a.name == 'group']
                if group_attr:
                    group_id = group_attr[-1]
                    stmt.attrs.remove(group_id)

                    if group_id.value != group.id:
                        stmt = parser.Group(group_id.value, [stmt])

            # Instantiate statements
            if isinstance(stmt, parser.Node):
                node = DiagramNode.get(stmt.id)
                node.set_attributes(stmt.attrs)
                self.belong_to(node, group)

            elif isinstance(stmt, parser.Edge):
                from_nodes = [DiagramNode.get(n) for n in stmt.from_nodes]
                to_nodes = [DiagramNode.get(n) for n in stmt.to_nodes]

                for node in from_nodes + to_nodes:
                    self.belong_to(node, group)

                for node1 in from_nodes:
                    for node2 in to_nodes:
                        edge = DiagramEdge.get(node1, node2)
                        edge.set_dir(stmt.edge_type)
                        edge.set_attributes(stmt.attrs)

            elif isinstance(stmt, parser.Group):
                subgroup = NodeGroup.get(stmt.id)
                subgroup.level = group.level + 1
                self.belong_to(subgroup, group)
                self.instantiate(subgroup, stmt)

            elif isinstance(stmt, parser.Attr):
                group.set_attribute(stmt)

            elif isinstance(stmt, parser.Extension):
                if stmt.type == 'class':
                    name = unquote(stmt.name)
                    Diagram.classes[name] = stmt
                elif stmt.type == 'plugin':
                    self.diagram.set_plugin(stmt.name,
                                            stmt.attrs,
                                            config=self.config)

            elif isinstance(stmt, parser.Statements):
                self.instantiate(group, stmt)

        group.update_order()
        return group
Exemple #6
0
    def instantiate(self, group, tree):
        for stmt in tree.stmts:
            # Translate Node having group attribute to Group
            if isinstance(stmt, parser.Node):
                group_attr = [a for a in stmt.attrs if a.name == 'group']
                if group_attr:
                    group_id = group_attr[-1]
                    stmt.attrs.remove(group_id)

                    if group_id.value != group.id:
                        stmt = parser.Group(group_id.value, [stmt])

            # Instantiate statements
            if isinstance(stmt, parser.Node):
                node = DiagramNode.get(stmt.id)
                node.set_attributes(stmt.attrs)
                self.belong_to(node, group)

            elif isinstance(stmt, parser.Edge):
                from_nodes = [DiagramNode.get(n) for n in stmt.from_nodes]
                to_nodes = [DiagramNode.get(n) for n in stmt.to_nodes]

                for node in from_nodes + to_nodes:
                    self.belong_to(node, group)

                for node1 in from_nodes:
                    for node2 in to_nodes:
                        edge = DiagramEdge.get(node1, node2)
                        edge.set_dir(stmt.edge_type)
                        edge.set_attributes(stmt.attrs)

            elif isinstance(stmt, parser.Group):
                subgroup = NodeGroup.get(stmt.id)
                subgroup.level = group.level + 1
                self.belong_to(subgroup, group)
                self.instantiate(subgroup, stmt)

            elif isinstance(stmt, parser.Attr):
                group.set_attribute(stmt)

            elif isinstance(stmt, parser.Extension):
                if stmt.type == 'class':
                    name = unquote(stmt.name)
                    Diagram.classes[name] = stmt
                elif stmt.type == 'plugin':
                    self.diagram.set_plugin(stmt.name, stmt.attrs,
                                            config=self.config)

            elif isinstance(stmt, parser.Statements):
                self.instantiate(group, stmt)

        group.update_order()
        return group
Exemple #7
0
    def get_parent_node_ypos(self, parent, child):
        heights = []
        for e in DiagramEdge.find(parent, child):
            y = parent.xy.y

            node = e.node1
            while node != parent:
                y += node.xy.y
                node = node.group

            heights.append(y)

        if heights:
            return min(heights)
        else:
            return None
Exemple #8
0
    def _groups(self):
        # Store nodes and edges of subgroups
        nodes = {self.diagram: self.diagram.nodes}
        edges = {self.diagram: self.diagram.edges}
        levels = {self.diagram: self.diagram.level}
        for group in self.diagram.traverse_groups():
            nodes[group] = group.nodes
            edges[group] = group.edges
            levels[group] = group.level

        groups = {}
        orders = {}
        for node in self.diagram.traverse_nodes():
            groups[node] = node.group
            orders[node] = node.order

        for group in self.diagram.traverse_groups():
            yield group

            # Restore nodes, groups and edges
            for g in nodes:
                g.nodes = nodes[g]
                g.edges = edges[g]
                g.level = levels[g]

            for n in groups:
                n.group = groups[n]
                n.order = orders[n]
                n.xy = XY(0, 0)
                n.colwidth = 1
                n.colheight = 1
                n.separated = False

            for edge in DiagramEdge.find_all():
                edge.skipped = False
                edge.crosspoints = []

        yield self.diagram
Exemple #9
0
 def bind_edges(self, group):
     for node in group.nodes:
         if isinstance(node, DiagramNode):
             group.edges += DiagramEdge.find(node)
         else:
             self.bind_edges(node)