diff --git a/diagrams/c4/__init__.py b/diagrams/c4/__init__.py index 62b31717..31973627 100644 --- a/diagrams/c4/__init__.py +++ b/diagrams/c4/__init__.py @@ -37,10 +37,12 @@ def _format_edge_label(description): return f'<{text}>' -def Container(name, type, description, **kwargs): +def Container(name, type="", description="", **kwargs): + type = f"Container: {type}" if type else "Container" node_attributes = { "label": _format_node_label(name, type, description), - "shape": "record", + "labelloc": "c", + "shape": "rect", "width": "2.6", "height": "1.6", "fixedsize": "true", @@ -52,7 +54,8 @@ def Container(name, type, description, **kwargs): return Node(**node_attributes) -def Database(name, type, description, **kwargs): +def Database(name, type="", description="", **kwargs): + type = f"Database: {type}" if type else "Database" node_attributes = { "label": _format_node_label(name, type, description), "shape": "cylinder", @@ -71,7 +74,8 @@ def System(name, description="", external=False, **kwargs): type = "External System" if external else "System" node_attributes = { "label": _format_node_label(name, type, description), - "shape": "record", + "labelloc": "c", + "shape": "rect", "width": "2.6", "height": "1.6", "fixedsize": "true", @@ -86,28 +90,40 @@ def System(name, description="", external=False, **kwargs): return Node(**node_attributes) -def Person(name, description, **kwargs): +def Person(name, description="", external=False, **kwargs): + type = "External Person" if external else "Person" node_attributes = { - "label": _format_node_label(name, "", description), - "shape": "record", + "label": _format_node_label(name, type, description), + "labelloc": "c", + "shape": "rect", "width": "2.6", "height": "1.6", "fixedsize": "true", "style": "rounded,filled", - "fillcolor": "dodgerblue4", + "fillcolor": "gray60" if external else "dodgerblue4", "fontcolor": "white", } + # collapse person 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 SystemBoundary(name, **kwargs): - graph_attributes = {"label": html.escape(name), "bgcolor": "white", "margin": "16", "style": "dashed"} + graph_attributes = { + "label": html.escape(name), + "bgcolor": "white", + "margin": "16", + "style": "dashed", + } graph_attributes.update(kwargs) return Cluster(name, graph_attr=graph_attributes) -def Dependency(label, **kwargs): - edge_attribtues = {"label": _format_edge_label(label), "style": "dashed", "color": "gray60"} +def Dependency(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) diff --git a/tests/test_c4.py b/tests/test_c4.py index fa8d799f..66f25b9f 100644 --- a/tests/test_c4.py +++ b/tests/test_c4.py @@ -28,11 +28,15 @@ class C4Test(unittest.TestCase): person >> container >> database + def test_external_nodes(self): + with Diagram(name=self.name, show=False): + external_person = Person("person", external=True) + external_system = System("external", external=True) + def test_systems(self): with Diagram(name=self.name, show=False): system = System("system", "The internal system.") system_without_description = System("unknown") - external_system = System("external", "The external system.", external=True) system >> system_without_description >> external_system @@ -44,6 +48,13 @@ class C4Test(unittest.TestCase): c1 >> Dependency("depends on") >> c2 c1 << Dependency("is dependend on") << c2 + def test_edge_without_constraint(self): + with Diagram(name=self.name, show=False): + s1 = System("system 1") + s2 = System("system 2") + + s1 >> Dependency(constraint="False") >> s2 + def test_cluster(self): with Diagram(name=self.name, show=False): with SystemBoundary("System"):