GraphViz - Как подключить подграфы?
В DOT
язык для GraphViz
Я пытаюсь представить диаграмму зависимости. Мне нужно иметь возможность размещать узлы внутри контейнера и делать узлы и / или контейнеры зависимыми от других узлов и / или контейнеров.
я использую subgraph
представлять мои контейнеры. Связывание узлов работает просто отлично, но я не могу понять, как соединить подграфы.
Учитывая программу ниже, мне нужно иметь возможность подключиться cluster_1
а также cluster_2
со стрелкой, но все, что я пробовал, создает новые узлы вместо соединения кластеров:
digraph G {
graph [fontsize=10 fontname="Verdana"];
node [shape=record fontsize=10 fontname="Verdana"];
subgraph cluster_0 {
node [style=filled];
"Item 1" "Item 2";
label = "Container A";
color=blue;
}
subgraph cluster_1 {
node [style=filled];
"Item 3" "Item 4";
label = "Container B";
color=blue;
}
subgraph cluster_2 {
node [style=filled];
"Item 5" "Item 6";
label = "Container C";
color=blue;
}
// Renders fine
"Item 1" -> "Item 2";
"Item 2" -> "Item 3";
// Both of these create new nodes
cluster_1 -> cluster_2;
"Container A" -> "Container C";
}
4 ответа
Руководство пользователя DOT дает следующий пример графика с кластерами с ребрами между кластерами
digraph G {
compound=true;
subgraph cluster0 {
a -> b;
a -> c;
b -> d;
c -> d;
}
subgraph cluster1 {
e -> g;
e -> f;
}
b -> f [lhead=cluster1];
d -> e;
c -> g [ltail=cluster0,lhead=cluster1];
c -> e [ltail=cluster0];
d -> h;
}
и ребра между узлами и кластерами.
Для удобства пользования решение, описанное в ответе HighPerformanceMark и примененное непосредственно к исходному вопросу, выглядит следующим образом:
digraph G {
graph [fontsize=10 fontname="Verdana" compound=true];
node [shape=record fontsize=10 fontname="Verdana"];
subgraph cluster_0 {
node [style=filled];
"Item 1" "Item 2";
label = "Container A";
color=blue;
}
subgraph cluster_1 {
node [style=filled];
"Item 3" "Item 4";
label = "Container B";
color=blue;
}
subgraph cluster_2 {
node [style=filled];
"Item 5" "Item 6";
label = "Container C";
color=blue;
}
// Edges between nodes render fine
"Item 1" -> "Item 2";
"Item 2" -> "Item 3";
// Edges that directly connect one cluster to another
"Item 1" -> "Item 3" [ltail=cluster_0 lhead=cluster_1];
"Item 1" -> "Item 5" [ltail=cluster_0 lhead=cluster_2];
}
compound=true
в graph
Декларация имеет жизненно важное значение. Это производит вывод:
Обратите внимание, что я изменил ребра для ссылки на узлы в кластере, добавил атрибуты ltail и lhead для каждого ребра, указав имя кластера, и добавил атрибут уровня графа 'component =true'.
Что касается опасений, что кто-то может захотеть подключить кластер без узлов внутри него, мое решение состояло в том, чтобы всегда добавлять узел в каждый кластер с помощью style = plaintext. Используйте этот узел для маркировки кластера (вместо встроенного в кластер атрибута "label", который должен быть установлен в пустую строку (в Python, label='""'
). Это означает, что я больше не добавляю ребра, которые соединяют кластеры напрямую, но это работает в моей конкретной ситуации.
Убедитесь, что вы используете fdp
макет для файла. Я не думаю neato
поддерживает кластеры.
Убедись в том, чтоcompound=true
в опциях орграфа (ссылка ):
digraph {
compound=true;
subgraph cluster_a {
label="Cluster A";
node1; node3; node5; node7;
}
subgraph cluster_b {
label="Cluster B";
node2; node4; node6; node8;
}
node1 -> node2 [label="1"];
node3 -> node4 [label="2" ltail="cluster_a"];
node5 -> node6 [label="3" lhead="cluster_b"];
node7 -> node8 [label="4" ltail="cluster_a" lhead="cluster_b"];
}