Воспроизведение определенных макетов графиков обычно может быть достигнуто с помощью:
- Невидимые узлы и ребра
- ранговые ограничения
Вот как я воспроизвел ваш график или хотя бы его часть:
digraph g {
rankdir="LR";
node[shape = circle, fontsize=14];
fontsize=18;
labeljust="l";
edge[style=invis, fontsize=12];
{ rank=same;
0 [style = invis];
01 [style = invis];
02 [style=invis];
0 -> 01 -> 02;
}
subgraph clusterA {
"0A" -> "1A" -> "2A";
"2A" -> "0A" [label=".", constraint=false, style=solid];
label="A";
}
subgraph clusterB {
"0B" -> "1B" -> "2B";
"2B" -> "0B" [label=".", constraint=false, style=solid];
label="B";
}
subgraph clusterC {
"0C" -> "1C" -> "2C";
"2C" -> "0C" [label=".", constraint=false, style=solid];
label="C";
}
0 -> "0A"[style=solid];
01 -> "0B"[style=invis];
02 -> "0C"[style=invis];
// edges between clusters
edge[constraint=false, style=solid];
"0A" -> "1B" [label=a]
"1A" -> "2B" [label=a]
"0B" -> "1C" [label=b]
"1B" -> "2C" [label=b]
}
Это решение не очень интуитивно понятно. Пара моментов для достижения этой цели:
- Я выбрал
rankdir="LR"
, что дало более приятные края, чем TB
, хотя на самом деле оно не соответствует направлению графика
- Невидимые узлы и ребра используются для узлов высшего ранга (0, 01, 02) для выравнивания кластеров влево.
- (Невидимые) верхние узлы имеют одинаковый ранг и связаны невидимыми ребрами - это гарантирует, что кластеры, связанные с каждым узлом, будут отображаться в правильном порядке.
Результат: