Search code examples
graphviz

Order cluster nodes in graphviz


I have the following (simplified) graph which is generated by the following .dot:

enter image description here

digraph Configurations {

  subgraph cluster_1 {
    s_0_0 [shape=circle,style=filled,fixedsize=true,width=0.5,label="0",fillcolor=yellowgreen]
    s_0_1 [shape=circle,style=filled,fixedsize=true,width=0.5,label="1",fillcolor=yellowgreen]
  }
  subgraph cluster_2 {
    s_1_0 [shape=circle,style=filled,fixedsize=true,width=0.5,label="0",fillcolor=yellowgreen]
    s_1_1 [shape=circle,style=filled,fixedsize=true,width=0.5,label="1",fillcolor=white]
  }
  subgraph cluster_3 {
    s_2_0 [shape=circle,style=filled,fixedsize=true,width=0.5,label="0",fillcolor=white]
    s_2_1 [shape=circle,style=filled,fixedsize=true,width=0.5,label="1",fillcolor=yellowgreen]
  }
  subgraph cluster_4 {
    s_3_0 [shape=circle,style=filled,fixedsize=true,width=0.5,label="0",fillcolor=white]
    s_3_1 [shape=circle,style=filled,fixedsize=true,width=0.5,label="1",fillcolor=white]
  }

  s_0_1 -> s_1_1
  s_0_0 -> s_2_0
  s_2_1 -> s_3_1
  s_1_0 -> s_3_0
}

I would like to be able to be able to enforce ordering inside the subgraphs so that the nodes of each subgraph are displayed in ascending order (each cluster should have nodes placed (0, 1), never (1, 0)). As I understand it, rankdir, which was my first attempt, is not supported in subgraphs, so what is a proper way to do this? I am looking for a solution which gives me a reasonably similar layout (which would then include more intersecting arrows) and is scalable, since the real graphs will be huge.


Solution

  • Turns out this could be solved by adding invisible edges inside and forcing same rank inside the graphs, like so:

    
    subgraph cluster_1 {
        {rank=same; s_0_0 s_0_1}
        s_0_0 -> s_0_1 [style=invis]
        s_0_0 [shape=circle, style=filled, fixedsize=true,
            width=0.5, label="0", fillcolor=yellowgreen]
        s_0_1 [shape=circle, style=filled, fixedsize=true, 
            width=0.5, label="1", fillcolor=yellowgreen]
    }