Merge branch 'master' of https://github.com/mingrammer/diagrams into @cbrown/743-mkdocs-site
@ -0,0 +1,97 @@
|
||||
"""
|
||||
A set of nodes and edges to visualize software architecture using the C4 model.
|
||||
"""
|
||||
import html
|
||||
import textwrap
|
||||
from diagrams import Cluster, Node, Edge
|
||||
|
||||
|
||||
def _format_node_label(name, key, description):
|
||||
"""Create a graphviz label string for a C4 node"""
|
||||
title = f'<font point-size="12"><b>{html.escape(name)}</b></font><br/>'
|
||||
subtitle = f'<font point-size="9">[{html.escape(key)}]<br/></font>' if key else ""
|
||||
text = f'<br/><font point-size="10">{_format_description(description)}</font>' if description else ""
|
||||
return f"<{title}{subtitle}{text}>"
|
||||
|
||||
|
||||
def _format_description(description):
|
||||
"""
|
||||
Formats the description string so it fits into the C4 nodes.
|
||||
|
||||
It line-breaks the description so it fits onto exactly three lines. If there are more
|
||||
than three lines, all further lines are discarded and "..." inserted on the last line to
|
||||
indicate that it was shortened. This will also html-escape the description so it can
|
||||
safely be included in a HTML label.
|
||||
"""
|
||||
wrapper = textwrap.TextWrapper(width=40, max_lines=3)
|
||||
lines = [html.escape(line) for line in wrapper.wrap(description)]
|
||||
lines += [""] * (3 - len(lines)) # fill up with empty lines so it is always three
|
||||
return "<br/>".join(lines)
|
||||
|
||||
|
||||
def _format_edge_label(description):
|
||||
"""Create a graphviz label string for a C4 edge"""
|
||||
wrapper = textwrap.TextWrapper(width=24, max_lines=3)
|
||||
lines = [html.escape(line) for line in wrapper.wrap(description)]
|
||||
text = "<br/>".join(lines)
|
||||
return f'<<font point-size="10">{text}</font>>'
|
||||
|
||||
|
||||
def C4Node(name, technology="", description="", type="Container", **kwargs):
|
||||
key = f"{type}: {technology}" if technology else type
|
||||
node_attributes = {
|
||||
"label": _format_node_label(name, key, description),
|
||||
"labelloc": "c",
|
||||
"shape": "rect",
|
||||
"width": "2.6",
|
||||
"height": "1.6",
|
||||
"fixedsize": "true",
|
||||
"style": "filled",
|
||||
"fillcolor": "dodgerblue3",
|
||||
"fontcolor": "white",
|
||||
}
|
||||
# collapse boxes to a smaller form if they don't have a description
|
||||
if not description:
|
||||
node_attributes.update({"width": "2", "height": "1"})
|
||||
node_attributes.update(kwargs)
|
||||
return Node(**node_attributes)
|
||||
|
||||
|
||||
def Container(name, technology="", description="", **kwargs):
|
||||
return C4Node(name, technology=technology, description=description, type="Container")
|
||||
|
||||
|
||||
def Database(name, technology="", description="", **kwargs):
|
||||
return C4Node(name, technology=technology, description=description, type="Database", shape="cylinder", labelloc="b")
|
||||
|
||||
|
||||
def System(name, description="", external=False, **kwargs):
|
||||
type = "External System" if external else "System"
|
||||
fillcolor = "gray60" if external else "dodgerblue4"
|
||||
return C4Node(name, description=description, type=type, fillcolor=fillcolor)
|
||||
|
||||
|
||||
def Person(name, description="", external=False, **kwargs):
|
||||
type = "External Person" if external else "Person"
|
||||
fillcolor = "gray60" if external else "dodgerblue4"
|
||||
style = "rounded,filled"
|
||||
return C4Node(name, description=description, type=type, fillcolor=fillcolor, style=style)
|
||||
|
||||
|
||||
def SystemBoundary(name, **kwargs):
|
||||
graph_attributes = {
|
||||
"label": html.escape(name),
|
||||
"bgcolor": "white",
|
||||
"margin": "16",
|
||||
"style": "dashed",
|
||||
}
|
||||
graph_attributes.update(kwargs)
|
||||
return Cluster(name, graph_attr=graph_attributes)
|
||||
|
||||
|
||||
def Relationship(label="", **kwargs):
|
||||
edge_attribtues = {"style": "dashed", "color": "gray60"}
|
||||
if label:
|
||||
edge_attribtues.update({"label": _format_edge_label(label)})
|
||||
edge_attribtues.update(kwargs)
|
||||
return Edge(**edge_attribtues)
|
@ -0,0 +1,15 @@
|
||||
# This module is automatically generated by autogen.sh. DO NOT EDIT.
|
||||
|
||||
from . import _Saas
|
||||
|
||||
|
||||
class _Communication(_Saas):
|
||||
_type = "communication"
|
||||
_icon_dir = "resources/saas/communication"
|
||||
|
||||
|
||||
class Twilio(_Communication):
|
||||
_icon = "twilio.png"
|
||||
|
||||
|
||||
# Aliases
|
After Width: | Height: | Size: 141 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 9.5 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 9.4 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 9.8 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 9.8 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 9.4 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 9.5 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 8.3 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 7.8 KiB |
After Width: | Height: | Size: 9.9 KiB |
After Width: | Height: | Size: 7.4 KiB |
After Width: | Height: | Size: 8.0 KiB |