Browse Source

Merge branch 'feature/add_icons_to_cluster_labels' of https://github.com/givanovexpe/diagrams into givanovexpe-feature/add_icons_to_cluster_labels

pull/407/head
Dan Aharon-Shalom 4 years ago
parent
commit
b9f53a87d0
2 changed files with 55 additions and 4 deletions
  1. +31
    -3
      diagrams/__init__.py
  2. +24
    -1
      docs/guides/cluster.md

+ 31
- 3
diagrams/__init__.py View File

@@ -36,6 +36,10 @@ def getcluster():
def setcluster(cluster): def setcluster(cluster):
__cluster.set(cluster) __cluster.set(cluster)


def new_init(cls, init):
def reset_init(*args, **kwargs):
cls.__init__ = init
return reset_init


class Diagram: class Diagram:
__directions = ("TB", "BT", "LR", "RL") __directions = ("TB", "BT", "LR", "RL")
@@ -211,8 +215,13 @@ class Cluster:
# Cluster direction does not work now. Graphviz couldn't render # Cluster direction does not work now. Graphviz couldn't render
# correctly for a subgraph that has a different rank direction. # correctly for a subgraph that has a different rank direction.
def __init__( def __init__(
self, label: str = "cluster", direction: str = "LR", graph_attr: dict = {},
):
self,
label: str = "cluster",
direction: str = "LR",
graph_attr: dict = {},
icon: object = None,
icon_size: int = 30
):
"""Cluster represents a cluster context. """Cluster represents a cluster context.


:param label: Cluster label. :param label: Cluster label.
@@ -221,13 +230,24 @@ class Cluster:
""" """
self.label = label self.label = label
self.name = "cluster_" + self.label self.name = "cluster_" + self.label
self.icon = icon
self.icon_size = icon_size


self.dot = Digraph(self.name) self.dot = Digraph(self.name)


# Set attributes. # Set attributes.
for k, v in self._default_graph_attrs.items(): for k, v in self._default_graph_attrs.items():
self.dot.graph_attr[k] = v self.dot.graph_attr[k] = v
self.dot.graph_attr["label"] = self.label

# if an icon is set, try to find and instantiate a Node without calling __init__()
# then find it's icon by calling _load_icon()
if self.icon:
_node = self.icon(_no_init=True)
if isinstance(_node,Node):
self.icon_label = '<<TABLE border="0"><TR><TD fixedsize="true" width="' + str(self.icon_size) +'" height="' + str(self.icon_size) +'"><IMG SRC="' + _node._load_icon() + '"></IMG></TD><TD>' + self.label + '</TD></TR></TABLE>>'
self.dot.graph_attr["label"] = self.icon_label
else:
self.dot.graph_attr["label"] = self.label


if not self._validate_direction(direction): if not self._validate_direction(direction):
raise ValueError(f'"{direction}" is not a valid direction') raise ValueError(f'"{direction}" is not a valid direction')
@@ -284,6 +304,14 @@ class Node:


_height = 1.9 _height = 1.9


def __new__(cls, *args, **kwargs):
instance = object.__new__(cls)
lazy = kwargs.pop('_no_init', False)
if not lazy:
return instance
cls.__init__ = new_init(cls, cls.__init__)
return instance

def __init__(self, label: str = "", **attrs: Dict): def __init__(self, label: str = "", **attrs: Dict):
"""Node represents a system component. """Node represents a system component.




+ 24
- 1
docs/guides/cluster.md View File

@@ -66,6 +66,29 @@ with Diagram("Event Processing", show=False):
handlers >> dw handlers >> dw
``` ```


## Clusters with icons in the label

You can add a Node icon before the cluster label (and specify its size as well). You need to import the used Node class first.

```python
from diagrams import Cluster, Diagram
from diagrams.aws.compute import ECS
from diagrams.aws.database import RDS, Aurora
from diagrams.aws.network import Route53, VPC

with Diagram("Simple Web Service with DB Cluster", show=False):
dns = Route53("dns")
web = ECS("service")

with Cluster(label='VPC',icon=VPC):
with Cluster("DB Cluster",icon=Aurora,icon_size=30):
db_master = RDS("master")
db_master - [RDS("slave1"),
RDS("slave2")]

dns >> web >> db_master
```

![event processing diagram](/img/event_processing_diagram.png) ![event processing diagram](/img/event_processing_diagram.png)


> There is no depth limit of nesting. Feel free to create nested clusters as deep as you want.
> There is no depth limit of nesting. Feel free to create nested clusters as deep as you want.

Loading…
Cancel
Save