Graphviz (xdot): How to make recursive nodes?

I am currently writing a graph library in Java, and I need a tool to visualize some graphs. I discovered Graph-viz, which happens to be a great, albeit buggy, way to do this.

In my model, Counts are made up of Nodes and Edges . Each Node has a specific number of ports (I / O / IO) and Edges binds those ports together. Some special nodes are called GraphNodes and insert Graph . The ports of these GraphNodes are mapped to some ports on the internal nodes .

I would like to provide some submissions. The first one I am satisfied with is as follows: http://i.stack.imgur.com/ujU71.png

Inputs Ports are green, outputs are red, and inputs are blue.

In this view, GraphNodes are not extended and Nodes are displayed just as easily. In the second version, I would like to create something similar to the following picture: http://i.stack.imgur.com/Cx624.png

The problem is that I cannot create a subgraph (cluster) with fixed areas (it seems not possible). Another solution I tried is to include a graph in node. However, inserting some code into the <td> </td> HTML label does not evaluate the code:

 digraph graph0 { node1 [ label = < <table border="0" cellspacing="0"> <tr> <td cellpadding="0"> <table border="0" cellspacing="0"> <tr> <td bgcolor="palegreen" border="1" port="port2">port2</td> <td bgcolor="palegreen" border="1" port="port3">port3</td> </tr> </table> </td> </tr> <tr> <td cellpadding="0"> <table border="0" cellspacing="0"> <tr> <td cellpadding="0"> <table border="0" cellspacing="0"> <tr> <td bgcolor="skyblue" border="1" port="port5">port5</td> </tr> </table> </td> <td bgcolor="peachpuff" border="1"> subgraph clusterTest { nodeTest } </td> </tr> </table> </td> </tr> <tr> <td cellpadding="0"> <table border="0" cellspacing="0"> <tr> <td bgcolor="lightpink" border="1" port="port4">port4</td> </tr> </table> </td> </tr> </table> > style = "invisible" ] } 

The previous code creates the following schedule: http://i.stack.imgur.com/E9jQ1.png

Finally, the best solution I can come up with is the following: http://i.stack.imgur.com/VzS5g.png

However, I am not satisfied with this because GraphNodes ' Ports are sometimes placed in strange places.

Do you know how I can reach the target schedule? If necessary, request any other information.


EDIT: I still haven't found a solution. A way to deal with this would be to be able to fix the position of the given nodes inside the containing cluster, but this does not seem to be possible with the help of a โ€œpointโ€ layout. Any idea?

+6
source share
1 answer

Using a digraph, you can specify the positions of nodes (relative to each other). This can be used to make certain elements appear above others. Although other nodes may be forced to appear at the same level (ports 101 and 102 in this example)

Fake nesting: This graph does not use the plaintext / semi-html nested nodes because I don't think it is possible (not a function). I'm not sure if their graphviz libraries support, but it might be worth a look at other libraries. I didnโ€™t even use the dot with Java or Python, otherwise I would make a proposal.


nesting


digraph {nodesep = 0.2 ranksep = 0.8 pad = 0.1 node [shape = square] node [style = filled] edge [arrowhead = none]

// rankdir = LR

component_starter [label = <port02 port03 port06 S port07 port08 port04 port05> style = "invisible"]

subgraph cluster_container {label = "I / O with components" color = orange

 //margin = 0 edge [ style="invis"] //edge [ len="0.5" minlen="1" ] node [ height="0.5" width="2" fixedsize=true ]; node [ shape=rectangle style=filled ] { node [ color=palegreen ]; { rank = same port101 -> port102 } } { node [ color=skyblue]; port103 port104 } { node [ height="1.5" width="2" fixedsize=true ]; node [ color=peachpuff]; //notaport } { node [ height="0.5" width="4" fixedsize=true ]; node [ color=lightpink]; output } 

// -

 //subgraph cluster_inner { //label="abstractions" //color="black" //style="invis" component_a [ label = < <table border="0" cellspacing="0"><tr> <td border="1" bgcolor="white" > </td> <td border="1" bgcolor="palegreen" port="port2">port2</td> <td border="1" bgcolor="palegreen" port="port3">port3</td> </tr><tr> <td border="1" bgcolor="skyblue" port="port6">port6</td> <td border="1" bgcolor="peachpuff" rowspan="3" colspan="2">A</td> </tr><tr> <td border="1" bgcolor="skyblue" port="port7">port7</td> </tr><tr> <td border="1" bgcolor="skyblue" port="port8">port8</td> </tr><tr> <td border="1" bgcolor="lightpink" colspan="1" port="port4">port4</td> <td border="1" bgcolor="lightpink" colspan="2" port="port5">port5</td> </tr></table> > style = "invisible" ] component_b [ label = < <table border="0" cellspacing="0"><tr> <td border="1" bgcolor="white" > </td> <td border="1" bgcolor="palegreen" port="port22">port22</td> <td border="1" bgcolor="palegreen" port="port23">port23</td> </tr><tr> <td border="1" bgcolor="skyblue" port="port25">port25</td> <td border="1" bgcolor="peachpuff" colspan="2"> B </td> </tr><tr> <td border="1" bgcolor="lightpink" colspan="3" port="port24">port24</td> </tr></table> > style = "invisible" ] 

// -

  component_c [ label = < <table border="0" cellspacing="0"><tr> <td border="1" bgcolor="white" > </td> <td border="1" bgcolor="palegreen" port="port32">port32</td> <td border="1" bgcolor="palegreen" port="port33">port33</td> </tr><tr> <td border="1" bgcolor="skyblue" port="port35">port35</td> <td border="1" bgcolor="peachpuff" colspan="2"> C </td> </tr><tr> <td border="1" bgcolor="lightpink" colspan="3" port="port34">port34</td> </tr></table> > style = "invisible" ] //} port101 -> port103 port102 -> component_a port102 -> component_b port103 -> port104 component_a -> output; component_b -> output; component_c -> output; edge [ style="" arrowhead="normal" color="#444444"] component_a:port4 -> output; component_c:port34 -> component_a:port3; component_a:port5 -> component_b:port22; port101 -> component_c:port33 

// -

 { rank = same edge [ dir=back ] port104 -> component_a:port8 } } component_starter; component_starter:port5 -> port101; } 

The above point file is compressed. Use base64 -d nesting.bz2.base64 |bzcat to view.

 QlpoOTFBWSZTWd/epEIABCzfgHAwWAP/3zgkmAq/7//6UASZm8a7VNrQBQQlSDUaYjTINGjIyZAG ho0aNMgkUZJpEIzUw0TTEzQBoAIwCTUiFT1NppDymGk0Pap6gMmCaAAcwAAAAAAAAAAFSRJoGp6B TyNTyhABoD1DQ0aephLyAcTAhMSQiKogMBLsVaZBYIwUHIGFISYVKCMVkRgLypG2mhHPb5z0hBap yN3HCL2iJVDYvXI6SykmzPN9LCaex+63c7jyTnk18c2KgvDZq6Kkz+WWf4DU4KoQsCQJ1gKpAcwC mp5nGnmlI8wBNtgDi+Hmf0/g/v4PoNaZVrhy5cdWCavJkutPC0t50kljBJLHXrbQUjJMPPDCUKwN NHO8aaiqKTus3tLEpprCW8Gzr68DtvyteHrqa7JJ9J46R4muUMuU39kJYPEgwJWwCSqsgMteezTo ta1rr3va1sccdW/32OJUROFkmUzqeyHn+g96EccgEY5SfJixh2aJgQC0JVmWAtrdagoOkDZAViKA qUpGZ1dXNJikmmsRZmAO16Kq9osW7KzzPZPS9IeLIqXo0cOoNwatry3Mi792YMRvA3oiKxe84ac7 EMGmdrabTaG0qqDpAMJJn5IeAbvMNiSJW8og7y+Ik+CExJBhLDZlKFSFKMBgIIMai57J5pLmgl5R Qm261e797RF6qhy82NQypLEa8ktUVAL2R1hxThWC3pVB0jBThRxVLfHHJeZHv+pMEkxZ3P6KP+ho QWyC9gtIM2cxJK2pIiiIooOPlxE0kkspJPijcgrHRHw6XvMpwy5ldiqlUpWzvymgxr78zAXh4vSW L3jya8Hqc6ekwhhDROybThDBnIdmdlN6ClO8bo7ucxNqSVjHNGd8F8ocW2qmT0bJRujojA9MJqnC TPg09tZlJ5d/am7W8E6GeU3TkyVC0N5nTgeXXn7Sj1UWijm1Q07OKeXiyPbENRSNcNzrnkyxkNeu RgS5GWEXKkpTdIy8NenUhVYpqkbUCushe+cQ15oMcRIrb4GZscDDVmLk3LF7Txk6yFvmky8aoiK5 T+3pVRjVVVUtLRVFFI0q1lrpHlGqNnHKOVIKkktUYAuq2L1bekwQeG68LX3tK64kVNRw2tDb7rLn acBl0J61Ld57HXXHKpXLjoqAo5yyRvQ/YxLdufjNCSaEk4mmYLcZp1ybI1BqDTum20PSm2cId4pU Zx00pZzOJZwnSHjAqXNkWCM4s/+LuSKcKEhv71IhAA== 
+1
source

Source: https://habr.com/ru/post/948314/


All Articles