Короткий ответ заключается в том, что gvpack
не объявляет ребра между субграфами. Действительно, когда между подграфами есть общие имена узлов, gvpack
переименовывает их, чтобы избежать столкновений. Однако это можно устранить.
Например, если три .dot
файлы 1.dot
:
digraph {
A -> B
A -> C
}
2.dot
:
digraph {
D -> E
E -> F
}
... и 3.dot
:
digraph {
D -> G
G -> A
}
... работает gvpack -u 1.dot 2.dot 3.dot | dot -Tjpg -ogvp1.jpg
дает следующее график gvp1.jpg
:
Как вы можете видеть, gvpack
имеет этикетки для дублированных имен узлов. Тем не менее, мы можем легко обратить повторную маркировку с использованием gvpack -u 1.dot 2.dot 3.dot | sed 's/_gv[0-9]\+//g' | dot -Tjpg -ogvsub.jpg
, который производит следующий график gvsub.jpg
:
Этот подход основан на подграфах, имеющие имена узлов общих, так что может быть необходимо, чтобы вставить дополнительные узлы в подграфе .dot
файлов для этого.
(EDIT: Раствор выше показал граф с узлами объединены, но не с подграфов в кластерах Следующее решение показывает суб-графики в кластерах..)
Указанные .dot
файлы 1.dot
(это так же, как файлы выше, за исключением того, что я дал каждому Digraph имя):
digraph g1 {
A -> B
A -> C
}
2.dot
:
digraph g2 {
D -> E
E -> F
}
... и 3.dot
:
digraph g3 {
D -> G
G -> A
}
... вместе с hdr.dot
:
digraph GMaster {
compound = true;
g1 [style=invisible, height = 0, width = 0, label=""];
g2 [style=invisible, height = 0, width = 0, label=""];
g3 [style=invisible, height = 0, width = 0, label=""];
g1 -> g2 [lhead=clusterg2, ltail=clusterg1];
g1 -> g3 [lhead=clusterg3, ltail=clusterg1]
... и tail.dot
:
}
...мы можем запустить cat 1.dot 2.dot 3.dot | sed 's/digraph \(\w*\) *{/subgraph cluster\1 { \1/' | cat hdr.dot - tail.dot | dot -Tjpg -oclust1.jpg
дать файл clust1.jpg
:
Таким образом, в файле заголовка, я добавил Invisble узел для каждого подграфа, с тем же именем, что и подграфа, используется compound=true
для разрешить края между кластерами. Я указал края для рисования между кластерами, и я установил lhead
и ltail
для каждого из краев между невидимыми узлами, чтобы гарантировать, что правый кластер используется как голова и хвост каждого из этих ребер. Я также добавил соответствующий невидимый узел для каждого подграфа в процессе преобразования каждого подграфа в кластер с использованием sed
.
Ребра между узлами D, G и A показаны, поскольку эти узлы являются общими для кластеров. Кроме того, каждый из них отображается только в одном кластере. Если узлы были уникальны для кластеров, единственными ребрами, которые были бы показаны между кластерами, были бы ребра между невидимыми узлами. Это можно увидеть на следующем графике, где я переименовал узлы в 3.dot
:
Существует один оставшийся недостаток, который я не совсем был в состоянии исправить. Невидимые узлы по-прежнему занимают немного места, поэтому ящики кластера выглядят однобокими, потому что невидимые узлы располагаются рядом с видимыми узлами. Это также означает, что головки краев между кластерами указывают на одну сторону блока кластера, а не на середину. В настоящее время я не вижу, что можно сделать по этому поводу, если мы не готовы смотреть на каждый подграф и находим узел, который уже находится в этом подграфе/кластере, чтобы служить репрезентативным узлом для этого подграфа/кластера (т. Е. один или на который мы рисуем края для этого кластера). Это можно сделать достаточно легко вручную для нескольких подграфов, но было бы утомительно, если бы было много подграфов.
Напротив, подход, который я использовал выше, требует только того, чтобы мы знали имя кластера и можем вставить его в файл hdr.dot
.
Я построил hdr.dot
файл вручную для этого случая, но содержимое файла hdr.dot
может быть извлечен из других .dot
файлов с sed
, awk
, perl
или python
, если есть необходимость. Сценарий также может вставлять края для связывания кластеров в hdr.dot
, если информация о том, какие кластеры должны быть подключены, была доступна где-то.
Спасибо за тщательный ответ Саймон. В моем случае, хотя я хочу рассматривать каждый из подграфов как узлы суперграфа, а не компоненты. Я хочу указать, что ребро существует между 1-> 2 и 1-> 3 и имеют явно выраженные подграфы, связанные с узлами, с соответствующими ребрами между компонентами. – MRocklin
А, я вижу. Я думаю, что присоединение к подграфам может быть достигнуто с помощью аналогичного метода подхода, который я принял в своем ответе. Я подумаю. – Simon
Я отредактировал свой ответ, чтобы показать, как кластеры могут быть связаны по краям. – Simon