Using a digraph, one can specify the positions of nodes (relative to one another). This can be used to force certain elements to appear above others. While other nodes can be forced to appear on the same level ( port 101 and 102 in this example)
Fake nesting: This graph does not use nested plaintext/semi-html nodes because I don't think that is possible (not a feature). I'm not sure if any graphviz libraries support them either, but it may be worth looking into other libraries. I've never even used dot from Java or Python, otherwise I would make a suggestion.
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 device 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 dot file, compressed. Use base64 -d nesting.bz2.base64 |bzcat
to view it.
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==