Linking 2 subgraphs with dot

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"]
}

image

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:
cluster2clusterForum1

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

image

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)