graphviz

How to control the order of nodes in a graph?


I'm trying to force nodes to be in this specific horizontal order: L1 -> L2 -> L3 -> L4 -> L5 -> L6

enter image description here

Once I add the red arrows it gets mangled. What is the best way to force the nodes to be in a specific order?

digraph {
    fontname="monospace";
    splines=false; // Make edges straight

    node [shape=record, fontname="monospace", style=filled, fillcolor=white];

    subgraph cluster_index {
        label = "Index"
        root [label="<A>A|<A_C>|D|<D_F>|G|<G_I>|J|<J_L>|M|<M_O>|P|<P_>"];
        L1 [label="<A>A|<B>B|<C>C"];
        L2 [label="<D>D|<E>E|<F>F"];
        L3 [label="<G>G|<H>H|<I>I"];
        L4 [label="<J>J|<K>K|<L>L"];
        L5 [label="<M>M|<N>N|<O>O"];
        L6 [label="<P>P|<Q>Q|<R>R"];

        {
             rank = same;
             edge[style=invis];
             L1 -> L2 -> L3 -> L4 -> L5 -> L6;
             rankdir = LR;
        }

        root:<A_C> -> L1;
        root:<D_F> -> L2;
        root:<G_I> -> L3;
        root:<J_L> -> L4;
        root:<M_O> -> L5;
        root:<P_> -> L6;

    }

    subgraph cluster_table {
        label = "Table"
        labelloc = "b" // Move lable to bottom

        T1 [label="<G>G|<R>R|<P>P|<D>D"]
        T2 [label="<M>M|<F>F|<A>A|<I>I"]
        T3 [label="<H>H|<N>N|<Q>Q|<L>L"]
        T4 [label="<E>E|<J>J|<O>O|<C>C"]
        T5 [label="<K>K|<B>B"]

        {
            edge [color="red" penwidth=1];
            L1:A -> T2:A;
            L1:B -> T5:B;
            L1:C -> T4:C;
            L2:D -> T1:D;
            L2:E -> T4:E;
            L2:F -> T2:F;
            L3:G -> T1:G;
            L3:H -> T3:H;
            L3:I -> T2:I;
            L4:J -> T4:J;
            L4:K -> T5:K;
            L4:L -> T3:L;
            L5:M -> T2:M;
            L5:N -> T3:N;
            L5:O -> T4:O;
            L6:P -> T1:P;
            L6:Q -> T3:Q;
            L6:R -> T1:R;
        }
    }
}

Solution

  • I hope there is a better solution, but I could not find it. According to the documentation root [ordering=out] should do it. But it does not.
    This seems to work (details of html-labels can be found here: https://www.graphviz.org/doc/info/shapes.html#html

    // from https://stackoverflow.com/questions/79524748/how-to-control-the-order-of-nodes-in-a-graph
    digraph {
        fontname="monospace";
        splines=false; // Make edges straight
    
        node [shape=record, fontname="monospace", style=filled, fillcolor=white];
    
        subgraph cluster_index {
            label = "Index"
            root [label="<A>A|<A_C>|D|<D_F>|G|<G_I>|J|<J_L>|M|<M_O>|P|<P_>"];
        node[shape=plain]
        // converted to one long table, many other ideas failed
            Lx [label=<<table border="0" cellborder="1" cellpadding="5" cellspacing="0">
           <tr>
           <td PORT="A">A</td><td PORT="B">B</td><td PORT="C">C</td><td sides="LR" width="33"></td>
           <td PORT="D">D</td><td PORT="E">E</td><td PORT="F">F</td><td sides="LR" width="33"></td>
           <td PORT="G">G</td><td PORT="H">H</td><td PORT="I">I</td><td sides="LR" width="33"></td>
           <td PORT="J">J</td><td PORT="K">K</td><td PORT="L">L</td><td sides="LR" width="33"></td>
           <td PORT="M">M</td><td PORT="N">N</td><td PORT="O">O</td><td sides="LR" width="33"></td>
           <td PORT="P">P</td><td PORT="Q">Q</td><td PORT="R">R</td></tr>
           </table>>];
    
            root:<A_C> -> Lx:B
            root:<D_F> -> Lx:E
            root:<G_I> -> Lx:H
            root:<J_L> -> Lx:K
            root:<M_O> -> Lx:N
            root:<P_>  -> Lx:Q
    
        }
    
        subgraph cluster_table {
            label = "Table"
            labelloc = "b" // Move lable to bottom
    
            T1 [label="<G>G|<R>R|<P>P|<D>D"]
            T2 [label="<M>M|<F>F|<A>A|<I>I"]
            T3 [label="<H>H|<N>N|<Q>Q|<L>L"]
            T4 [label="<E>E|<J>J|<O>O|<C>C"]
            T5 [label="<K>K|<B>B"]
    
                // pushed down a bit w/ minlen and added north/south ports
                edge [color="red" penwidth=1 minlen=2];  
                Lx:A:s -> T2:A:n
                Lx:B:s -> T5:B:n
                Lx:C:s -> T4:C:n
                Lx:D:s -> T1:D:n
                Lx:E:s -> T4:E:n
                Lx:F:s -> T2:F:n
                Lx:G:s -> T1:G:n
                Lx:H:s -> T3:H:n
                Lx:I:s -> T2:I:n
                Lx:J:s -> T4:J:n
                Lx:K:s -> T5:K:n
                Lx:L:s -> T3:L:n
                Lx:M:s -> T2:M:n
                Lx:N:s -> T3:N:n
                Lx:O:s -> T4:O:n
                Lx:P:s -> T1:P:n
                Lx:Q:s -> T3:Q:n
                Lx:R:s -> T1:R:n
            
        }
    }
    

    Giving:
    enter image description here