33

I have a graph file like this:

digraph {
    "Step1" -> "Step2" -> "Step3";

    subgraph step2detail {
        "Step2" -> "note1";
        "Step2" -> "note2";
        "Step2" -> "note3";
        "Step2" -> "note4";
        rankdir=TB
   }
}

I want the subgraph step2detail to hang off to the right of 'Step2'.

Right now it looks like this:

enter image description here

I want Step1, Step2 and Step3 to all be vertically under each other and in 1 column.

Potherca
  • 13,207
  • 5
  • 76
  • 94
Amandasaurus
  • 58,203
  • 71
  • 188
  • 248

5 Answers5

19

The trick to get the graph you described is to use two subgraphs and link from one to the other. The invisible edges in "details" are what keep the notes aligned.

digraph {
    rankdir="LR";

    subgraph steps {
        rank="same";
        "Step1" -> "Step2" -> "Step3";
    }

    subgraph details {
        rank="same";
        edge[style="invisible",dir="none"];
        "note1" -> "note2" -> "note3" -> "note4";
    }

    "Step2" -> "note1";
    "Step2" -> "note2";
    "Step2" -> "note3";
    "Step2" -> "note4";
}

The result is:

enter image description here

user3313834
  • 7,327
  • 12
  • 56
  • 99
irgeek
  • 191
  • 1
  • 3
  • 2
    I don't know what the original questioner had in mind, but this gives what I imagine wanting based on the description of the question -- and I *think* will help me get what I want for my own graph. :) – lindes Jun 13 '12 at 12:45
  • 1
    Very nice trick, but bit of a shame about the spurious invisible edges. That's zero problem if you're only using the graph to produce an image, which is probably almost always the case, but it would be nice if there was a way to influence the layout this way without changing the structure of the graph. – Ben Jan 13 '22 at 23:21
8

Here's as simple as it gets - just use the group attribute to have graphviz prefer straight edges:

digraph {
    node[group=a, fontname="Arial", fontsize=14];
    "Step1" -> "Step2" -> "Step3";

    node[group=""];
    "Step2" -> "note1";
    "Step2" -> "note2";
    "Step2" -> "note3";
    "Step2" -> "note4";
}

graphviz output

marapet
  • 54,856
  • 12
  • 170
  • 184
7

By grouping the Step nodes into a clustered subgraph, the output is as follows:

digraph {
    subgraph cluster_0 {
        color=invis;
        "Step1" -> "Step2" -> "Step3";
    }

    subgraph cluster_1 {
        color=invis;
        "Step2" -> "note4";
        "Step2" -> "note3";
        "Step2" -> "note2";
        "Step2" -> "note1";
   }
}

color=invis removes the border that would otherwise be drawn around the cluster

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Photodeus
  • 657
  • 1
  • 5
  • 18
3

rankdir doesn't work directly in the subgraph, but if you add another set of curly braces - whatever that's called - rankdir works:

digraph {
    "Step1" -> "Step2" -> "Step3";

    subgraph step2detail {
        {
            "Step2" -> "note1";
            "Step2" -> "note2";
            "Step2" -> "note3";
            "Step2" -> "note4";
            rankdir=TB
            rank=same
        }
   }
}

enter image description here

Jason Kleban
  • 20,024
  • 18
  • 75
  • 125
  • Maybe late but I used this question and the samples at the bottom of this page https://graphs.grevian.org/example to solve a similar issue in a graph I was working on. As a result I think your solution can be done with out subraph and without rankdir. Sorry about formatting. digraph { Step1 -> Step2 -> Step3 Step2 -> note4, note3, note2, note1 {rank=same Step2, note1, note2, note3, note4} } – jj2f1 Oct 07 '20 at 22:33
  • I don't follow what this is saying. The `note*` nodes **aren't** laid out top-to-bottom, so this does not in fact seem to be an example of `rankdir` working in a subgraph. In fact I get exactly the same results if I remove `rankdir=TB`; and I get exactly the same results if I also remove the extra set of braces. Isn't this just showing an example of `rank = same`? It seems to be the only bit of syntax that is actually doing anything here, despite being the only one the answer doesn't talk about. If I'm wrong (very new to graphviz, so quite possible), this could do with more explanation. – Ben Jan 13 '22 at 23:13
-4

Use the command: rankdir=LR;

digraph {
rankdir=LR;

    "Step1" -> "Step2" -> "Step3";

    subgraph step2detail {
        "Step2" -> "note1";
        "Step2" -> "note2";
        "Step2" -> "note3";
        "Step2" -> "note4";
        rankdir=TB
   }

}
Cafeo
  • 3