#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
}