Search code examples
nodesgraphvizsubgraph

Force GraphViz force align between subgraph


I use GraphViz with the following dot file:

digraph "Fast-forward"
{
    rankdir=LR;
    subgraph master
    {
        "5c071a6b2c" -> "968bda3251";
    }
    subgraph branch
    {
        "35ee8ce6b6" [color="blue"] [style="filled"];
        "968bda3251" -> "9754d40473" [weight=0];
        "9754d40473" -> "9e59700d33" -> "35ee8ce6b6";
    }
    subgraph c1
    {
        rankdir=LR;
        rank="same";
        "remote/master/HEAD" [shape=box];
        "remote/master/HEAD" -> "35ee8ce6b6" [weight=0];
        oldmh [label="master/HEAD"] [shape=box] [color="red"] [style="filled"];
        newmh [label="master/HEAD"] [shape=box] [color="blue"] [style="filled"];
        oldmh -> "968bda3251" [weight=0];
        newmh -> "35ee8ce6b6" [weight=0];
    }
}

It give me something like that: Bag thing

But I want something like that:

                                                     white
                                                        |
                                                       \/
                     "9754d40473" -> "9e59700d33" -> "35ee8ce6b6";
                     /                                  /\

5c071a6b2c -> 968bda3251

             /\                                         |
              |
            red                                       blue

How can I do that?

For your help, Thanks by advance.


Solution

  • I tend to define all the nodes with special needs (like being in the same rank or having special shapes/colors) first, then define the links. That way, you're assured that the rank=same nodes are correctly grouped, and defined in the right order.

    Without weight=0, all the side links end up on the top. Add weight=0 to the ones you want on the bottom.

    digraph "Fast-forward"
    {
        rankdir=LR;
        subgraph c1 {
            rank="same";
            "968bda3251";
            oldmh [label="master/HEAD"] [shape=box] [color="red"] [style="filled"];
        }
        subgraph c2
        {
            rank="same";
            "remote/master/HEAD" [shape=box];
            "35ee8ce6b6" [color="blue"] [style="filled"];
            newmh [label="master/HEAD"] [shape=box] [color="blue"] [style="filled"];
        }
        "5c071a6b2c" -> "968bda3251" -> "9754d40473" -> "9e59700d33" -> "35ee8ce6b6";
        oldmh -> "968bda3251" [weight=0];
        "remote/master/HEAD" -> "35ee8ce6b6";
        newmh -> "35ee8ce6b6" [weight=0];
    }
    

    The results from dot

    If you really want that jog between 96 and 97, you can do it this way:

    digraph "Fast-forward"
    {
        rankdir=LR;
        subgraph c1 {
            rank=same;
            "968bda3251";
            oldmh [label="master/HEAD"] [shape=box] [color="red"] [style="filled"];
        }
        subgraph c1p5 {
            rank=same;
            "9754d40473";
            inviso [style="invis"];
        }
        subgraph c2
        {
            rank="same";
            "remote/master/HEAD" [shape=box];
            "35ee8ce6b6" [color="blue"] [style="filled"];
            newmh [label="master/HEAD"] [shape=box] [color="blue"] [style="filled"];
        }
        "5c071a6b2c" -> "968bda3251";
        "968bda3251" -> "9754d40473" [weight=0];
        "9754d40473" -> "9e59700d33" -> "35ee8ce6b6";
        oldmh -> "968bda3251" [weight=0];
        "remote/master/HEAD" -> "35ee8ce6b6";
        newmh -> "35ee8ce6b6" [weight=0];
        "968bda3251" -> inviso [style="invis"];
        "9754d40473" -> inviso [style="invis"];
    }
    

    enter image description here