dse
June 18, 2023, 4:36am
1
Hello,
Below are the code with corresponding image.
I need to link two subgraphs (“cluster_A1” and “cluster_B1”, arrow tail starting on the subgraph’s border)
Please advise me on the best way to do this.
I tried adding invisible nodes, but it does not give me the output I want (here I made the dots visible just for clarity) :
The invisible node should be right below the subgraph labels (A1 and B1), not at the bottom
Or if possible, right beside the labels, left or right
I want to minimize the space taken by the invisible node
Thank you.
digraph G {
rankdir=LR
splines=ortho
edge [fontsize=12]
subgraph "cluster_A1" {
"A1_invis"[shape=point style=invisx pin=true]
"A3"[shape=rectangle, style="rounded,filled", fillcolor=khaki]
label = "A1"
style = "filled, rounded"
fillcolor = "lightgray"
subgraph "cluster_A2" {
label = "A2"
style = "filled, rounded"
fillcolor = "lightblue"
"A4"[shape=rectangle, style="rounded,filled", fillcolor=khaki]
}
}
subgraph "cluster_B1" {
"B1_invis"[shape=point style=invisx pin=true]
label = "B1"
style = "filled, rounded"
fillcolor = "lightgray"
subgraph "cluster_B2" {
label = "B2"
style = "filled, rounded"
fillcolor = "lightblue"
"B3"[shape=rectangle, style="rounded,filled", fillcolor=khaki]
"B4"[shape=rectangle, style="rounded,filled", fillcolor=khaki]
}
}
A1_invis->B1_invis[xlabel="\E", style="solid"]
}
A bit of a challenge, but by putting the invisible nodes inside clusters of their own, we get dot to place them at the top of the surrounding clusters. [Nope, not documented, I made a guess].
Wasn’t sure what to do with the edge xlabel/label. What do you really want?
Removed:
pin doesn’t hurt, but ignored by dot
Added:
compound
peripheries
lhead & ltail
margin
minlen to push B1 to the right
Look up any of these attributes here: Attributes | Graphviz
So:
digraph G {
rankdir=LR
splines=ortho // ortho is buggy, but OK for this use
compound=true // allow edges that seem to be to/from clusters
edge [fontsize=12]
subgraph "cluster_A1" {
subgraph clusterI1{
peripheries=0 // no surrounding box
margin=0 // reduce vertical space
"A1_invis"[shape=point style=invis ] // pin ignored by dot pin=true]
}
"A3"[shape=rectangle, style="rounded,filled", fillcolor=khaki]
label = "A1"
style = "filled, rounded"
fillcolor = "lightgray"
subgraph "cluster_A2" {
label = "A2"
style = "filled, rounded"
fillcolor = "lightblue"
"A4"[shape=rectangle, style="rounded,filled", fillcolor=khaki]
}
}
subgraph "cluster_B1" {
subgraph clusterI2{
peripheries=0 // no surrounding box
margin=0 // reduce vertical space
"B1_invis"[shape=point style=invis] // ignored pin=true]
}
label = "B1"
style = "filled, rounded"
fillcolor = "lightgray"
subgraph "cluster_B2" {
label = "B2"
style = "filled, rounded"
fillcolor = "lightblue"
"B3"[shape=rectangle, style="rounded,filled", fillcolor=khaki]
"B4"[shape=rectangle, style="rounded,filled", fillcolor=khaki]
}
}
// added lhead & ltail to appear cluster-to-cluster
// what label/xlabel do you really want, if any?
A1_invis->B1_invis [XXXXXxlabel="\E", style="solid"
minlen=2 // push cluster_B1 to the right (down a rank)
ltail=cluster_A1 lhead=cluster_B1 ]
}
Giving:
dse
June 24, 2023, 9:10pm
3
Thank you for the answer !
However sometimes the invisible nodes a set in between nodes, and not at the top or bottom like they should
Do you know why the arrow from A1_invis to B1_invis in the graph below doesn’t start/end at the border of the subgraphs ?
graph
I also tried recreating this using tables:
code
digraph test {
rankdir=LR
// splines="polyline"
ranksep=1.2
node [label="\N", fontsize=15, shape=plaintext];
atbl [label=<
<TABLE BGCOLOR="lightgray" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" PORT="a1">
<TR><TD BORDER="0" >title</TD></TR>
<TR>
<TD BORDER="0">
<TABLE BGCOLOR="lightblue" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" PORT="a2">
<TR><TD BORDER="0" PORT="f1">A</TD></TR>
<TR><TD BGCOLOR="khaki" STYLE="ROUNDED" PORT="l1" WIDTH="50">a</TD></TR>
</TABLE>
</TD>
</TR>
<TR>
<TD BORDER="0">
<TABLE BGCOLOR="lightblue" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">A</TD></TR>
<TR><TD BGCOLOR="khaki" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >a</TD></TR>
</TABLE>
</TD>
</TR>
</TABLE>
>, ];
btbl [label=<
<TABLE BGCOLOR="lightgray" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">title</TD></TR>
<TR>
<TD BORDER="0">
<TABLE BGCOLOR="lightblue" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">B</TD></TR>
<TR><TD BGCOLOR="khaki" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >b</TD></TR>
</TABLE>
</TD>
</TR>
<TR>
<TD BORDER="0">
<TABLE BGCOLOR="lightblue" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">B</TD></TR>
<TR><TD BGCOLOR="khaki" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" PORT="b1">b</TD></TR>
</TABLE>
</TD>
</TR>
</TABLE>
>, ];
ctbl [label=<
<TABLE BGCOLOR="lightgray" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">title</TD></TR>
<TR>
<TD BORDER="0">
<TABLE BGCOLOR="lightblue" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">C</TD></TR>
<TR><TD BGCOLOR="khaki" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >c</TD></TR>
</TABLE>
</TD>
</TR>
<TR>
<TD BORDER="0">
<TABLE BGCOLOR="lightblue" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">C</TD></TR>
<TR><TD BGCOLOR="khaki" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" PORT="c1">c</TD></TR>
</TABLE>
</TD>
</TR>
</TABLE>
>, ];
dtbl [label=<
<TABLE BGCOLOR="lightgray" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">title</TD></TR>
<TR>
<TD BORDER="0">
<TABLE BGCOLOR="lightblue" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">D</TD></TR>
<TR><TD BGCOLOR="khaki" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >d</TD></TR>
</TABLE>
</TD>
</TR>
<TR>
<TD BORDER="0">
<TABLE BGCOLOR="lightblue" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">D</TD></TR>
<TR><TD BGCOLOR="khaki" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" PORT="d1">d</TD></TR>
</TABLE>
</TD>
</TR>
</TABLE>
>, ];
etbl [label=<
<TABLE BGCOLOR="lightgray" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">title</TD></TR>
<TR>
<TD BORDER="0">
<TABLE BGCOLOR="lightblue" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">E</TD></TR>
<TR><TD BGCOLOR="khaki" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >e</TD></TR>
</TABLE>
</TD>
</TR>
<TR>
<TD BORDER="0">
<TABLE BGCOLOR="lightblue" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">E</TD></TR>
<TR><TD BGCOLOR="khaki" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" PORT="e1">e</TD></TR>
</TABLE>
</TD>
</TR>
</TABLE>
>, ];
ftbl [label=<
<TABLE BGCOLOR="lightgray" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50">
<TR><TD BORDER="0">title</TD></TR>
<TR>
<TD BORDER="0">
<TABLE BGCOLOR="lightblue" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" PORT="f0">
<TR><TD BORDER="0">F</TD></TR>
<TR><TD BGCOLOR="khaki" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >f</TD></TR>
</TABLE>
</TD>
</TR>
<TR>
<TD BORDER="0">
<TABLE BGCOLOR="lightblue" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">F</TD></TR>
<TR><TD BGCOLOR="khaki" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" PORT="f1">f</TD></TR>
</TABLE>
</TD>
</TR>
</TABLE>
>, ];
gtbl [label=<
<TABLE BGCOLOR="lightgray" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">title</TD></TR>
<TR>
<TD BORDER="0">
<TABLE BGCOLOR="lightblue" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">G</TD></TR>
<TR><TD BGCOLOR="khaki" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >g</TD></TR>
</TABLE>
</TD>
</TR>
<TR>
<TD BORDER="0">
<TABLE BGCOLOR="lightblue" STYLE="ROUNDED" CELLSPACING="5" WIDTH="50" >
<TR><TD BORDER="0">G</TD></TR>
<TR><TD BGCOLOR="khaki" STYLE="ROUNDED" PORT="g1" CELLSPACING="5" WIDTH="50" >g</TD></TR>
</TABLE>
</TD>
</TR>
</TABLE>
>, ];
atbl:a1->btbl:b1[xlabel="A-b"]
atbl:a1->ctbl:c1[xlabel="A-c"]
atbl:a1->dtbl:d1[xlabel="A-d"]
btbl:b1->dtbl:d1[xlabel="b-d"]
atbl:a1->etbl:e1[xlabel="A-e"]
etbl:e1->ctbl:c1[xlabel="e-c"]
atbl:a1->ftbl:f0[xlabel="A-F"]
btbl:b1->ftbl:f1[xlabel="b-f"]
atbl:a1->gtbl:g1[xlabel="A-g"]
}
img
But splines=“ortho” doesn’t work with ports.
Is there another way to get this output but with orthogonal lines ?
(with or without tables, and if possible without invisible nodes)
Thank you !
Please include the failing version of your input.
(Unfortunately, ortho does not work with ports, currently a lost cause. So ortho & tables are quite unlikely)