2010-01-06 14 views
116

W języku DOT dla GraphViz, próbuję reprezentować diagram zależności. Muszę być w stanie mieć węzły wewnątrz kontenera i być w stanie uzależnić węzły i/lub kontenery od innych węzłów i/lub kontenerów.GraphViz - jak podłączyć podgrafy?

Używam subgraph do reprezentowania moich kontenerów. Łączenie węzłów działa dobrze, ale nie wiem, jak podłączyć podgrafy.

Biorąc pod uwagę poniżej programu, muszę być w stanie połączyć cluster_1 i cluster_2 ze strzałką, ale nic próbowałem tworzy nowe węzły, zamiast łączenia klastrów:

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

mam ten sam problem, ale oni mają naturalną przykład gdy subgraphs zachowują się jak węzły, http://www.graphviz.org/content/fdpclust. – nlucaroni

+1

@nlucaroni Zastanawiam się, czy ten problem został rozwiązany.Ten przykład daje mi zły wykres: krawędzie łączą centra subgraph.nie wiesz jak sprawiają, że działa tak, jak w przykładzie? – k102

+1

@ k102, Wiem. Sprawdź tę stronę ponownie; mówi, że musisz użyć 'fdp'. Połączony przykład i powyższy obydwa działają (ostatni wiersz w tym przykładzie musi wykorzystywać nazwy podkogafli, a nie etykietę i może być miłe dołączanie długości linii do wykresu); jest trochę ciasno, jak jest). – nlucaroni

Odpowiedz

124

Podręcznik użytkownika DOT podaje następujący przykład wykresu z klastrami z krawędziami między klastrami.

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

i krawędzie między węzłami i klastrami.

enter image description here

+8

Dzięki - to działa, ale to naprawdę wygląda jak brzydkie włamanie.Mam nadzieję, ** Nie mam scenariusza, w którym mam kontener bez węzłów. –

+4

Jeśli ktoś jest zainteresowany, może to spowodować problemy z pozycjonowaniem, jeśli masz oznaczone odnośniki (krawędzie). Podczas gdy głowa lub ogon krawędzi może być ukryty pod klastrem, etykieta jest nadal umieszczona w punkcie środkowym, co oznacza, że ​​niektóre etykiety brzegowe wydają się unosić nad skupiskiem, zamiast być pozycjonowane przez samą krawędź. –

+0

Ta odpowiedź pomogła mi, teraz muszę tylko sprawdzić, czy mogę użyć neato, aby ułożyć klastry :) –

66

Dla ułatwienia rozwiązanie opisane w odpowiedzi HighPerformanceMark za, stosowane bezpośrednio do pierwotnego pytania, wygląda następująco:

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

do „związek = true” w „Graf” deklaracji to istotne. Który wytwarza wyjściowe:

graph with connected clusters

Należy zauważyć, że zmieniono krawędzie odniesienia węzłów w klastrze, dodano ltail i lhead przypisuje każdej krawędzi określenia nazwy klastra i dodano atrybutu związek wykres poziomu” = true ".

Jeśli chodzi o obawy, że ktoś może chcieć podłączyć klaster bez węzłów w środku, moim rozwiązaniem jest zawsze dodanie węzła do każdego klastra, renderowanego za pomocą stylu = tekst jawny. Użyj tego węzła do oznaczenia klastra (zamiast wbudowanego atrybutu "etykieta" klastra, który powinien być ustawiony na pusty ciąg znaków (w języku Python, label='""'). Oznacza to, że nie będę już dodawać krawędzi łączących klastry bezpośrednio, ale to działa w mojej konkretnej sytuacji.

+18

Uwaga: 'graph [fontsize = 10 fontname = "Verdana" compound = true];' jest niezbędna - jeśli przegapisz to, że połączenie z piwem/lenem nie działa. –

+1

@ JonathanHartley, Jak na twój ostatni akapit, czy istnieje sposób centrowania tego węzła w samym środku klastra? – Pacerier

+0

również nazwa klastra nie powinna zaczynać się od dużej litery – JCLL

8

Upewnij używasz fdp układ pliku. nie sądzę neato obsługuje klastry.

+2

Ja też mam empirycznie stwierdziłem, że silnik 'neato' nie obsługuje klastrów .. Nie jestem pewien, czy to błąd, czy nie .. –