GraphViz - Cómo conectar subgrafos?
-
19-09-2019 - |
Pregunta
En el lenguaje DOT
para GraphViz
, estoy tratando de representar un diagrama de dependencia. Tengo que ser capaz de tener nodos dentro de un contenedor y para ser capaz de hacer los nodos y / o contenedores dependiente de otros nodos y / o contenedores.
Estoy usando subgraph
para representar mis contenedores. Nodo de enlace funciona bien, pero no puedo encontrar la manera de conectar subgrafos.
Dado el siguiente programa, tengo que ser capaz de conectar cluster_1
y cluster_2
con una flecha, pero nada de lo que he intentado crea nuevos nodos en lugar de conectar los grupos:
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";
}
Solución
El manual del usuario DOT da el siguiente ejemplo de un gráfico con las agrupaciones con los bordes entre las agrupaciones
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;
}
y bordes entre nodos y clusters.
Otros consejos
Para facilitar la consulta la solución descrita en la respuesta de HighPerformanceMark, aplicado directamente a la pregunta original, tiene el siguiente aspecto:
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];
}
El compound=true
en la declaración graph
es vital. Que produce una salida:
Nota de que he cambiado los bordes para hacer referencia a los nodos dentro de la agrupación, agregó el ltail y atributos lhead a cada borde, especificando el nombre del clúster, y añadido el atributo de nivel gráfico 'compuesto = true'.
En cuanto a la preocupación de que uno podría querer conectar un cluster con ningún nodo dentro de él, mi solución ha sido la de siempre añadir un nodo a cada clúster, rendido con style = texto plano. Utilizar este nodo para etiquetar el cluster (en lugar de una función de de la agrupación "etiqueta" de atributos, que debe ajustarse a la cadena vacía (en Python, label='""'
). Esto significa que ya no soy la adición de bordes que se conectan directamente racimos, pero funciona en mi situación particular.
Asegúrese de que está utilizando el diseño fdp
para el archivo. No creo neato
admite clústeres.