# Make large nodes span multiple ranks

**URL:** <https://forum.graphviz.org/t/make-large-nodes-span-multiple-ranks/1555>\
**Category:** Help\
**Created:** [April 7, 2023, 3:44pm UTC](https://forum.graphviz.org/t/make-large-nodes-span-multiple-ranks/1555 "2023-04-07T15:44:48Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![blloyd](https://avatars.discourse-cdn.com/v4/letter/b/c0e974/32.png) [@blloyd](https://forum.graphviz.org/u/blloyd)\
**Post date:** [April 7, 2023, 3:44pm UTC](https://forum.graphviz.org/t/make-large-nodes-span-multiple-ranks/1555/1 "2023-04-07T15:44:48Z")

</div>

I am creating control flow graphs. Each node contains a block of instructions. Some nodes have many instructions, some have only one. The dot layout puts huge nodes and tiny nodes on the same rank and it makes for sparse graphs that are hard to read. Here is a small example of what I am talking about:  
 ![bad](https://global.discourse-cdn.com/graphviz/original/2X/1/13fd6a537f69a07c1e8097458518660c0cd78aba.svg)

```auto
digraph {
    node [shape=rect];
    C0 [height=4]
    A0 [height=2]
    S->C0 
    C0->E 
    B0->A0
    A0->E
    S->B0
    B0->B1
    B1->B2
    B2->E
}

```

What I would like to be able to do is have a node span multiple ranks so that the space can be utilized better, something more like this:  
 ![better](https://global.discourse-cdn.com/graphviz/original/2X/b/bdf9423f3e0edaccaf41861b539d8fd80c73a94b.svg)  
In practice the height disparities are much more exaggerated. I simulated what I wanted by creating clusters with an invisible multi-rank subgraph inside:

```auto
digraph {
    graph [compound=true]
    node [shape=rect];
    subgraph cluster_C {
        C0 [style=invis]
        C1 [style=invis]
        C2 [style=invis]
        C0->C1 [style=invis]
        C1->C2 [style=invis]
    }
    subgraph cluster_A {
        A0 [style=invis]
        A1 [style=invis]
        A0->A1 [style=invis]
    }
    S->C0 [lhead=cluster_C]
    C2->E [ltail=cluster_C]
    S->B0
    B0->A0 [lhead=cluster_A]
    A1->E [ltail=cluster_A]
    B0->B1
    B1->B2
    B2->E
}

```

The only problem is that I can’t put any content in there. If I add a label to the cluster, it just stretches out the cluster. It doesn’t fill it. Ideally I would want large nodes that are just the size of the contents.

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [April 8, 2023, 3:47pm UTC](https://forum.graphviz.org/t/make-large-nodes-span-multiple-ranks/1555/2 "2023-04-08T15:47:18Z")

</div>

If we were able to place text within the clusters, how would you size the clusters? By eyeball (manually) or programmatically? i.e. how would you determine how many invisible nodes for a given cluster?

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [April 8, 2023, 5:49pm UTC](https://forum.graphviz.org/t/make-large-nodes-span-multiple-ranks/1555/3 "2023-04-08T17:49:07Z")

</div>

Another issue: Graphviz does not do “word wrap” (text wrap) ( a work-around: [Text wrapping in Graphviz?](https://forum.graphviz.org/t/text-wrapping-in-graphviz/753)).  
Do you have a plan for this?

---

<div class="post-metadata">

**Author:** ![blloyd](https://avatars.discourse-cdn.com/v4/letter/b/c0e974/32.png) [@blloyd](https://forum.graphviz.org/u/blloyd)\
**Post date:** [April 8, 2023, 7:10pm UTC](https://forum.graphviz.org/t/make-large-nodes-span-multiple-ranks/1555/4 "2023-04-08T19:10:44Z")

</div>

It isn’t too hard to come up with an estimate of the height of a node based on the number of instructions it contains. Or I could even do a first pass that just creates the nodes and parses the result to get the exact measurements. Then I could create the stand-in longer clusters choosing the number of invisible nodes based on the known long node heights. Assuming that this is done conservatively in such a way that the resulting stand-in clusters are never shorter than the actual long node, I can imagine creating a base layout in .dot format, replacing the stand-in clusters with the actual long nodes, fixing up the edges, and rendering the final graph. I’m just wondering if there are some alternatives that might work better.

I would love to see something like a “rankspan” attribute for nodes that would more or less do the same thing as I would be doing manually above. I’d have to think about it a little more to specify what happens when the long node is larger than the size of internal subgraph. Maybe you could just apportion the excess height proportionally between the spanned ranks.

I’m not sure what you mean about the text-wrapping. I am manually doing text-wrapping.

---

<div class="post-metadata">

**Author:** ![steveroush](https://avatars.discourse-cdn.com/v4/letter/s/a9adbd/32.png) [@steveroush](https://forum.graphviz.org/u/steveroush)\
**Post date:** [April 8, 2023, 9:18pm UTC](https://forum.graphviz.org/t/make-large-nodes-span-multiple-ranks/1555/5 "2023-04-08T21:18:36Z")

</div>

There are several ways to try to build your desired graph.

1. `neato -Goverlap=false -Gmode=hier` // not a fan of this
2. post-process your clusters & replace them with nodes of the same size, then push that through `neato -n` // ugh, lots of things to go wrong
3. use `rankdir=LR` (ranks now vbertical) and `rank=same` // my current favorite

```auto
digraph {
  rankdir=LR
    node [shape=rect];
    C0 [height=4]
    A0 [height=2]
    S->C0 
    C0->E 
    B0->A0
    A0->E
    S->B0
    B0->B1
    B1->B2
    B2->E
    {rank=same S B0 A0 E}
    {rank=same B1 B2}
}

```

Giving:  
 ![tallFlow1](https://global.discourse-cdn.com/graphviz/original/2X/2/29303b9e51b6fc38a445f66027e7d0838bfe6eb9.png)

The issue with #3 is that you will have to determine what nodes go in what (vertical) ranks. Non-trivial, but doable in smallish numbers.

---

<div class="post-metadata">

**Author:** ![magjac](https://sea2.discourse-cdn.com/graphviz/user_avatar/forum.graphviz.org/magjac/32/16_2.png) [@magjac](https://forum.graphviz.org/u/magjac)\
**Post date:** [April 9, 2023, 5:47pm UTC](https://forum.graphviz.org/t/make-large-nodes-span-multiple-ranks/1555/6 "2023-04-09T17:47:29Z")

</div>

You could use `shape=plaintext` instead of invisible nodes within the clusters:

```auto
digraph {
    graph [compound=true]
    node [shape=rect];
    subgraph cluster_C {
        C0 [shape=plaintext]
        C1 [shape=plaintext]
        C2 [shape=plaintext]
        C0->C1 [style=invis]
        C1->C2 [style=invis]
    }
    subgraph cluster_A {
        A0 [shape=plaintext]
        A1 [shape=plaintext]
        A0->A1 [style=invis]
    }
    S->C0 [lhead=cluster_C]
    C2->E [ltail=cluster_C]
    S->B0
    B0->A0 [lhead=cluster_A]
    A1->E [ltail=cluster_A]
    B0->B1
    B1->B2
    B2->E
}

```

![Untitled Graph 99(1)](https://global.discourse-cdn.com/graphviz/original/2X/4/43c772aae5b7169a4a059f26f6bf125bb8bae219.svg)

[Try it yourself here!](http://magjac.com/graphviz-visual-editor/?dot=digraph%20%7B%0A%20%20%20%20graph%20%5Bcompound%3Dtrue%5D%0A%20%20%20%20node%20%5Bshape%3Drect%5D%3B%0A%20%20%20%20subgraph%20cluster_C%20%7B%0A%20%20%20%20%20%20%20%20C0%20%5Bshape%3Dplaintext%5D%0A%20%20%20%20%20%20%20%20C1%20%5Bshape%3Dplaintext%5D%0A%20%20%20%20%20%20%20%20C2%20%5Bshape%3Dplaintext%5D%0A%20%20%20%20%20%20%20%20C0-%3EC1%20%5Bstyle%3Dinvis%5D%0A%20%20%20%20%20%20%20%20C1-%3EC2%20%5Bstyle%3Dinvis%5D%0A%20%20%20%20%7D%0A%20%20%20%20subgraph%20cluster_A%20%7B%0A%20%20%20%20%20%20%20%20A0%20%5Bshape%3Dplaintext%5D%0A%20%20%20%20%20%20%20%20A1%20%5Bshape%3Dplaintext%5D%0A%20%20%20%20%20%20%20%20A0-%3EA1%20%5Bstyle%3Dinvis%5D%0A%20%20%20%20%7D%0A%20%20%20%20S-%3EC0%20%5Blhead%3Dcluster_C%5D%0A%20%20%20%20C2-%3EE%20%5Bltail%3Dcluster_C%5D%0A%20%20%20%20S-%3EB0%0A%20%20%20%20B0-%3EA0%20%5Blhead%3Dcluster_A%5D%0A%20%20%20%20A1-%3EE%20%5Bltail%3Dcluster_A%5D%0A%20%20%20%20B0-%3EB1%0A%20%20%20%20B1-%3EB2%0A%20%20%20%20B2-%3EE%0A%7D)

You can also use `shape=plain` (See [Node Shapes | Graphviz](https://graphviz.org/doc/info/shapes.html)) or experiment with the node attributes `width`, `height` and `margin` to get the size of the cluster that you want.

---

<div class="post-metadata">

**Author:** ![blloyd](https://avatars.discourse-cdn.com/v4/letter/b/c0e974/32.png) [@blloyd](https://forum.graphviz.org/u/blloyd)\
**Post date:** [April 13, 2023, 2:28am UTC](https://forum.graphviz.org/t/make-large-nodes-span-multiple-ranks/1555/7 "2023-04-13T02:28:24Z")

</div>

Thanks for the hints.

The rankdir flip is an interesting idea. It won’t work in general, but clever. It is desirable to keep edges coming out of the tops and bottoms and I can use ports for that, but I would like to keep edges from going upwards (except for backedges). I’ll experiment with the multipass approach to see what I can get out of that.
