Search code examples
graphvizsplinedot

Draw B-tree vertically


Is there a way to draw B-Trees on Graphviz? suggests alternating link, data, link, data, link, ... However, I have, potentially, lots of data in a node such that I can't really space it out horizontally. I am using a vertical node with the arrows from one corner to simulate having the arrows between data.

digraph {
    graph [rankdir=LR, truecolor=true, bgcolor=transparent];
    node [shape=none];
    node1 [label = <
<table>
    <tr><td port="0">Ugargeeon</td></tr>
    <tr><td port="1">103</td></tr>
</table>>];
    node1:0:se -> node2;
    node1:1:se -> node3;
    node2 [label = <
<table>
    <tr><td>Rutorshar</td></tr>
    <tr><td>17</td></tr>
    <tr><td>69</td></tr>
</table>>];
    node3 [label = <
<table>
    <tr><td>Nashmokum</td></tr>
    <tr><td>117</td></tr>
    <tr><td>135</td></tr>
</table>>];
}

Gives.

The result of the digraph.Desired.

The first image is pretty close to what I want as the initial starting point, except, the initial spline is pointing to the south-east. The second image I've edited to show what I think the ideal output should be. That is, roughly symmetrical. Globally setting splines=line works, but with more edges, it becomes easier to tell them apart when they are the default splines. Is there a way to position the arrows between the nodes without affecting the initial spline state?


Solution

  • Close? Major change is to use ports on the head end of the edge - either to West side of entire node or a specific cell. Pick your spline type, Also twiddled with drawing the table, strictly aesthetic.

    //  https://stackoverflow.com/questions/72428350/draw-b-tree-vertically
    digraph {
        graph [rankdir=LR, truecolor=true, bgcolor=transparent];
        splines=false // made a guess, should work fine true or false
        node [shape=none];
        node1 [label = <
    <table>
        <tr><td port="p0">Ugargeeon</td></tr>
        <tr><td port="p1">103</td></tr>
    </table>>];
    
        node1:p0:se -> node2:w;
        //node1:p1:se -> node3:w;  // does not actually touch the node
        node1:p1:se -> node3:p1:w; // looks a bit better?
        
        node2 [label = <
    <table>
        <tr><td port="p0">Rutorshar</td></tr>
        <tr><td port="p1">17</td></tr>
        <tr><td port="p2">69</td></tr>
    </table>>];
    
        node3 [label = <
    <table BORDER="0" CELLBORDER="1" cellspacing="0" >
        <tr><td port="p0">Nashmokum</td></tr>
        <tr><td port="p1">117</td></tr>
        <tr><td port="p2">135</td></tr>
    </table>>];
    }
    

    enter image description here