Search code examples
graphvizgraph-visualization

Lost x y edge when using rank=same


I'm trying to visualize doubly linked lists using GraphViz. An example:

digraph List {
    rankdir=LR;
    node [shape=record];
    0 [label="{<prev> | <length> 2 | <tone> 1 | <next>}"];
    1 [label="{<prev> | <length> 1 | <tone> A | <next>}"];
    0:<next>:c -> 1:n [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false, arrowsize=1.2];
    1:<prev>:c -> 0:s [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false, arrowsize=1.2];
}

Result

The result is fine except for one thing; the height of the elements. With each consecutive element added the height decreases, I want all elements to be on the same height. But when I add

{rank=same; 0; 1;}

a GraphViz error occurs (Error: lost 1 0 edge). Now, the only fix I could find for this error is to replace the record shaped nodes with plaintext nodes and using HTML labels to create the record shape. I tried this, but it produces the same error.

The code using HTML labels:

digraph List {
    rankdir=LR;
    node [shape=plaintext];
    0 [label=<
    <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
        <TR>
            <TD PORT="prev">     </TD>
            <TD PORT="length">2</TD>
            <TD PORT="note">1</TD>
            <TD PORT="next">     </TD>
        </TR>
    </TABLE>>];
    1 [label=<
    <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
        <TR>
            <TD PORT="prev">     </TD>
            <TD PORT="length">1</TD>
            <TD PORT="note">A</TD>
            <TD PORT="next">     </TD>
        </TR>
    </TABLE>>];
    0:next:c -> 1:n [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false, arrowsize=0.8];
    1:prev:c -> 0:s [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false, arrowsize=0.8];
}

Result

I would appreciate any suggestions on how to solve this issue.

A previous attempt looked like this:

digraph List { 
    rankdir=LR;
    node [shape=record];
    0 [label="{<prev> | <firstName> Wolfgang Amadeus | <lastName> Mozart | <instrument> Klavier | <next>}"];
    1 [label="{<prev> | <length> 1 | <tone> A | <next>}"];
    0:<next>:c -> 1:<prev> [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false, arrowsize=0.8];
    1:<prev>:c -> 0 [arrowhead=vee, arrowtail=dot, dir=both, tailclip=false, arrowsize=0.8];
}

Result

Here there is no clear distinction between the two arrows. Getting two distinct arrows between the nodes would also solve my problem.


Solution

  • You can align the nodes using a strong ("heavy") link, an invisible edge, between the last element of the first and the first element of the second node.

    Add this line as the last one to your HTML-like code (which gives you much more flexibility than record shapes)

    0:next:e -> 1:prev:w[ weight = 100, style = invis ];
    

    and you get

    enter image description here

    which is what I think you want.