Open piotr-sokolowski opened 4 years ago
I would like to create a simple diagram to describe relationships between AWS accounts and it appears there is no generic box.
How would a generic box look like? If you have icons I'll try to include it.
i’d imagine (LMK if i’m misinterpreting) the desired behavior would be that one could create a cluster-like visual bounding container to represent that some amalgam of resources are physically or logically connected..
the use cases for such a primitive are myriad. the datacenter, subnet, and rack node types are examples that come immediately to my mind
well, if you can link me some nice looking shapes that are free to use Id be happy to include them..
I am also in need for exactly this.
The question for me would be if it really needs to be a png shape? It would be awesome to use all what diagrams offers with the additional shape options of graphviz. Happy to have that only limited to a rectangle with text to start with: https://graphviz.org/doc/info/shapes.html
Is there anything speaking against this? :)
Thanks.
If all you want is a box with text, you can just use the Custom
node class and pass in an empty string as your node image.
from diagrams import Diagram
from diagrams.custom import Custom
with Diagram("\nCustom", show=False) as diag:
Custom_1 = Custom("My\nCustom\ntext #1\n\n\nHELLO", "")
Custom_2 = Custom("My 2nd\nCustom\nstring\n\n\nWORLD!", "")
Custom_1 >> Edge(label="WEEE!!!") >> Custom_2
diag
As a longer term solution, I would suggest adding a Polygon
node class, that behaves similar to the Custom
node class, with the additional option to pass in the following keyword arguments:
Have a look at this Graphviz example: https://www.graphviz.org/Gallery/directed/crazy.html
@steschuser @ludwigm @wolfspyre @craighurley
You can use all of the Graphviz shapes with the Node
class. See code and output below.
https://graphviz.gitlab.io/doc/info/shapes.html
Additionally, all of the Graphviz Node attributes should also be available to you. https://graphviz.gitlab.io/doc/info/attrs.html
from diagrams import Diagram, Node
from diagrams.custom import Custom
shapes = [
"box","polygon","ellipse","oval","circle",
"point","egg","triangle","plaintext","plain",
"diamond","trapezium","parallelogram","house","pentagon",
"hexagon","septagon","octagon","doublecircle","doubleoctagon",
"Mdiamond","Msquare","Mcircle",
"rect","rectangle","square","star","none","underline","cylinder",
"tripleoctagon","invtriangle","invtrapezium","invhouse",
"note","tab","folder","box3d","component","promoter",
"cds","terminator","utr","primersite","restrictionsite",
"fivepoverhang","threepoverhang","noverhang","assembly",
"signature","insulator","ribosite","rnastab","proteasesite",
"proteinstab","rpromoter","rarrow","larrow","lpromoter", ]
num_shapes = len(shapes)
shapes_per_row = 5
num_of_rows = int(num_shapes / shapes_per_row) + (num_shapes % shapes_per_row > 0)
with Diagram("\n\nUsing Graphviz Shapes", show=False) as diag:
for row in range(num_of_rows)[::-1]:
items_in_row = shapes_per_row - (row+1) * shapes_per_row // num_shapes
shapes_i = row * shapes_per_row
node_list = [
'Node('
f'shape="{shapes[shapes_i+item_num]}", '
f'label="\\n"+"{shapes[shapes_i+item_num]}", '
'labelloc="t", '
'style="solid") - Edge(penwidth="0.0")'
for item_num in range(items_in_row)[:-1]
] + ['Node('
f'shape="{shapes[shapes_i+items_in_row-1]}", '
f'label="\\n"+"{shapes[shapes_i+items_in_row-1]}", '
'labelloc="t", '
'style="solid")']
node_row = "-".join(node_list)
eval(node_row)
diag
I for one, really appreciate all your efforts to help out here, (and all the other places where you’ve helped others, with example code even!!!) thank you, @clayms the world needs more contributors like you :)
@mingrammer - assuming you like the implementation as is, the above would be super useful as an example, and perhaps even a test to help ensure no future change unintentionally alters behavior.
@clayms This is fantastic. I was not aware that this is possible. I totally will give this a try :)
Here is how you can add "record" shaped Node
s and have the Edge
s point to specific fields
of each "record" Node
.
See: https://graphviz.gitlab.io/doc/info/shapes.html#record
with Diagram("\nRecord-based Nodes", show=False, direction="TB") as diag:
TB_fields = Node(shape="record", label="{ <t> top |<m> middle |<b> bottom }")
TB_fields2 = Node(shape="record", label="{ <t> top |<m> middle |<b> bottom }")
LR_fields = Node(shape="record", label=" <f0> left|<f1> middle|<f2> right" )
LR_fields2 = Node(shape="record", label=" <f0> left|<f1> middle|<f2> right")
TB_fields >> Edge(tailport="t", headport="b") >> TB_fields2
LR_fields >> Edge(tailport="f2", headport="f0") >> LR_fields2
diag
@mingrammer If some form of the examples above were to be added to the documentation, which document do you prefer:
I can see a case for having certain versions in both.
Regarding the Edge
specific items tailport
and headport
, those may also be called out in edge.md.
With the ability to use all of the Graphviz node shapes, it is also possible to replicate some of the graphs from the Graphviz Gallery.
Let me know any particular preference you have and I can add them and create a pull request.
Thanks,
Do you plan to support more generic node types like for example simple shapes ? This would allow to use diagrams when none of existing specific nodes really match like when creating process or algorithm block diagram