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

        return cls(tree, config, layout).run()
Ejemplo n.º 2
0
    def build(self, tree, config):
        self.config = config
        self.diagram = Diagram()
        self.instantiate(self.diagram, tree)
        for subgroup in self.diagram.traverse_groups():
            if len(subgroup.nodes) == 0:
                subgroup.group.nodes.remove(subgroup)

        self.bind_edges(self.diagram)
        self.fire_node_event('build_finished')
        return self.diagram
Ejemplo n.º 3
0
    def build(self, tree):
        self.diagram = Diagram()
        self.instantiate(self.diagram, tree)
        for subgroup in self.diagram.traverse_groups():
            if len(subgroup.nodes) == 0:
                subgroup.group.nodes.remove(subgroup)

        self.bind_edges(self.diagram)
        return self.diagram
Ejemplo n.º 4
0
    def test_unknown_image_driver(self):
        from blockdiag.drawer import DiagramDraw
        from blockdiag.elements import Diagram

        with self.assertRaises(RuntimeError):
            DiagramDraw('unknown', Diagram())
Ejemplo n.º 5
0
class DiagramTreeBuilder:
    def build(self, tree, config):
        self.config = config
        self.diagram = Diagram()
        self.instantiate(self.diagram, tree)
        for subgroup in self.diagram.traverse_groups():
            if len(subgroup.nodes) == 0:
                subgroup.group.nodes.remove(subgroup)

        self.bind_edges(self.diagram)
        self.fire_node_event('build_finished')
        return self.diagram

    def fire_node_event(self, event_type):
        for node in self.diagram.nodes:
            if node.drawable:
                fire_node_event(node, event_type)

    def is_related_group(self, group1, group2):
        if group1.is_parent(group2) or group2.is_parent(group1):
            return True
        else:
            return False

    def belong_to(self, node, group):
        if node.group and node.group.level > group.level:
            override = False
        else:
            override = True

        if node.group and node.group != group and override:
            if not self.is_related_group(node.group, group):
                msg = "could not belong to two groups: %s" % node.id
                raise RuntimeError(msg)

            old_group = node.group

            parent = group.parent(old_group.level + 1)
            if parent:
                if parent in old_group.nodes:
                    old_group.nodes.remove(parent)

                index = old_group.nodes.index(node)
                old_group.nodes.insert(index + 1, parent)

            old_group.nodes.remove(node)
            node.group = None

        if node.group is None:
            node.group = group

            if node not in group.nodes:
                group.nodes.append(node)

    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

    def bind_edges(self, group):
        for node in group.nodes:
            if isinstance(node, DiagramNode):
                group.edges += DiagramEdge.find(node)
            else:
                self.bind_edges(node)