Ориентация вложенного подграфа Graphviz

#graphviz #dot #subgraph

Вопрос:

Недавно я наткнулся на изображение ниже. Я знаю, что он был создан с помощью graphviz/dot, но исходный код недоступен (потерян во времени).

Желаемый Результат:

Желаемый Результат

Я пытался найти способ перепроектировать исходный код, но горизонтальное упорядочение вложенных подграфов создавало мне трудности. Минимальный, в основном рабочий пример выглядит так в коде

 digraph G {
    A
    B
    subgraph cluster_0 {
        edge [style=invis]
        subgraph cluster_0_0 {
            D -> E -> F
        }
        C -> D -> E -> F -> G
    }

    A -> C
    A -> B
    A -> G
    B -> { D E F }
}
 

Однако это дает мне такой результат:

пример минимума, вертикальный

Добавление newrank=true к внешнему подграфу дает мне горизонтальную ориентацию, которую я ищу:

 digraph G {
    A
    B
    subgraph cluster_0 {
        newrank=true
        edge [style=invis]
        subgraph cluster_0_0 {
            D -> E -> F
        }
        C -> D -> E -> F -> G
    }

    A -> C
    A -> B
    A -> G
    B -> { D E F }
}
 

Но это устанавливает узлы в неправильном порядке:

горизонтально, но не по порядку

Ответ №1:

Я надеюсь, что есть лучшее решение, но вот одно (остальные метки узлов должны быть очевидны):

 digraph G {
   newrank=true
   splines=false  // A->C edge gets wacky without this
   
   node [shape=Mrecord]
   // Mrecords produce this Warning:
   //   flat edge between adjacent nodes one of which has a record shape - replace records with HTML-like labels
   // but Mrecords still seem to work, so maybe ignore warning ??

   // hoped that ordering or weight or group attributes would
   // position C and G as desired, but nope
   // instead, clusters and constraint attribute worked, why?

    A [group=T label="{Measure|4/4}"]
    B [group=T]
    A -> B
    {
      rank=same C F E D G   // declare right-to-left ??
    }
    subgraph clusterCDEFG {
        graph [style=rounded]
    // within a rank, layout tends to be right-to-left
    // so, declare right-to-left ??
    // why do these clusters help position C amp; G ???    
       subgraph clusterG {  peripheries=0
       G 
        }
        subgraph clusterDEF {
      // declare right-to-left
      F
          E [group=T]
      D 
      edge [style=invis]
       //   D -> E -> F
        }
    // why do these clusters help position C amp; G ???
        subgraph clusterC { peripheries=0
       C
        }
    }

    A -> C  [constraint=false]  // why does this impact position within rank ??
    A -> G  [constraint=false]  // why does this impact position within rank ??
    B -> { F E D } // declare right-to-left ??
    edge [style=invis]
//    C -> D  // Mrecord shape has problems
//    F -> G  // Mrecord shape has problems
}
 

Дающий:
введите описание изображения здесь