2010-01-06 16 views
116

En el idioma DOT para GraphViz, intento representar un diagrama de dependencia. Necesito poder tener nodos dentro de un contenedor y poder hacer que los nodos y/o contenedores dependan de otros nodos y/o contenedores.GraphViz - ¿Cómo conectar subgrafos?

Estoy usando subgraph para representar mis contenedores. La vinculación de nodos funciona bien, pero no sé cómo conectar subgrafos.

Dado el siguiente programa, tengo que ser capaz de conectarse cluster_1 y cluster_2 con una flecha, pero nada de lo que he intentado crea nuevos nodos en lugar de conectar los racimos:

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"; 
} 

enter image description here

+2

estoy teniendo el mismo problema, sin embargo, tienen un ejemplo natural donde subgrafos están actuando como nodos, http://www.graphviz.org/content/fdpclust. – nlucaroni

+1

@nlucaroni me pregunto si este problema está resuelto. Este ejemplo me da un gráfico equivocado: los bordes conectan los centros del subgráfico. ¿No sabes cómo hacer que funcione como en el ejemplo? – k102

+1

@ k102, lo sé. Echa un vistazo a esa página otra vez; dice que necesitas usar 'fdp'. El ejemplo vinculado y el que está sobre ambos trabajan (la última línea del ejemplo debe usar los nombres del subgráfico, no la etiqueta, y podría ser conveniente incluir las longitudes de línea para el gráfico); está un poco apretado como está). – nlucaroni

Respuesta

124

El manual de usuario de DOT proporciona el siguiente ejemplo de un gráfico con conglomerados con bordes entre los clústeres

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 clústeres.

enter image description here

+8

Gracias - eso funciona, pero realmente se siente como un hack feo.Estoy ** esperando ** No tengo un escenario en el que tenga un contenedor sin nodos. –

+4

En caso de que alguien esté interesado, esto puede causar problemas de posicionamiento si tiene enlaces etiquetados (bordes). Si bien la cabeza o la cola del borde pueden estar ocultas debajo de un grupo, la etiqueta aún se ubica en el punto medio, lo que significa que algunas etiquetas de borde parecen flotar sobre un grupo en lugar de estar posicionadas por el borde mismo. –

+0

Esta respuesta me ayudó, ahora solo tengo que decidir si puedo usar neato para establecer los clústeres :) –

66

Para facilidad de referencia la solución descrita en la respuesta de HighPerformanceMark, aplicado directamente a la pregunta original, se ve así:

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 'compuesto = true' en la declaración 'gráfico' Es vital. Que produce salidas:

graph with connected clusters

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ñade el compuesto de nivel gráfico atributo' = verdadero '.

En cuanto a la preocupación de que uno quiera conectar un clúster sin nodos dentro de él, mi solución ha sido siempre agregar un nodo a cada clúster, representado con style = plaintext. Utilice este nodo para etiquetar el clúster (en lugar del atributo "etiqueta" integrado del clúster, que se debe establecer en la cadena vacía (en Python, label='""'). Esto significa que ya no añado bordes que conectan clusters directamente, sino funciona en mi situación particular.

+18

Nota: 'graph [fontsize = 10 fontname = "Verdana" compound = true];' es esencial: si pierde ese enlace a cola/lhead no funciona. –

+1

@JonathanHartley, Según su último párrafo, ¿hay alguna forma de centrar ese nodo en el medio del clúster? – Pacerier

+0

también el nombre del clúster no debe comenzar por una letra mayúscula – JCLL

8

Asegúrese de que está utilizando fdp diseño para el archivo. no creo neato admite clústeres.

+2

Yo también he encontrado experimentalmente que el motor 'neato' no admite clusters .. No estoy seguro si esto es un error o no .. –