2012-05-03 18 views
27

Próbuję wyobrazić następujące dane w formacie dot użyciu GraphViz:Graphviz wyjść bałagan

digraph n { 
node [nodesep=2.0, fontsize=11]; 
graph [ overlap=false]; 
edge[weight=0.2]; 
A -> B [label="I/5"] 
A -> A [label="*/0"] 
A -> C [label="ii/2"] 
A -> H [label="vii/1"] 
B -> D [label="iii/1"] 
B -> E [label="IV/2"] 
B -> F [label="V/2"] 
B -> B [label="vi/2"] 
C -> F [label="V/2"] 
C -> H [label="vii/1"] 
D -> E [label="IV/2"] 
E -> D [label="iii/2"] 
E -> G [label="iv/1"] 
E -> F [label="V/3"] 
F -> B [label="I/4"] 
F -> B [label="vi/1"] 
F -> B [label="*/0"] 
G -> B [label="I/5"] 
H -> B [label="vi/1"] 
} 

uruchamiając następującą komendę: neato -Tpng Chord_NFA.dot > Chord_NFA.png

daje mi ten komunikat:

Chciałbym, aby pasował do formatu A4 i aby żadna krawędź nie zachodziła na siebie lub nie przechodziła przez węzeł. Jest to możliwe (matematycznie), ponieważ zrobiłem to sam za pomocą biro.

+0

Spróbuj użyć 'fdp' zamiast' neato'; trwa dłużej, ale daje lepsze (bardziej odległe) wyniki. Niektóre krawędzie mogą jednak nakładać się na węzły. – Phrogz

+2

'fdp' było jeszcze gorsze. – Rory

Odpowiedz

20

Grałem z nim kilka i got to:

digraph n { 
    node [nodesep=2.0, fontsize=11]; 
    graph [overlap = false]; 
    subgraph cluster_a { 
    style=invisible; 
    A; B; H; 
    } 
    subgraph cluster_b { 
    style=invisible; 
    D; E; G; 
    } 
    subgraph cluster_c { 
    style=invisible; 
    C; F; 
    } 
    A -> B [label="I/5"]; 
    A -> A [label="*/0"]; 
    A -> C [label="ii/2"]; 
    A -> H [label="vii/1"]; 
    B:w -> D [label="iii/1"]; 
    B:nw -> E [minlen=3 label="IV/2"]; 
    B -> F [minlen=2 label="V/2"]; 
    B -> B [label="vi/2"]; 
    C -> F [minlen=2 label="V/2"]; 
    C -> H [label="vii/1"]; 
    D -> E [label="IV/2"]; 
    D -> E [minlen=2 dir=back label="iii/2"]; 
    G -> E [minlen=2 dir=back label="iv/1"]; 
    F -> E [dir=back label="V/3"]; 
    B -> F [minlen=2 dir=back label="I/4"]; 
    B -> F [minlen=2 dir=back label="vi/1"]; 
    B -> F [minlen=2 dir=back label="*/0"]; 
    B -> G [dir=back label="I/5"]; 
    H -> B [label="vi/1"]; 
} 

skompilować z:

dot -Tpng -o Chord_NFA.png Chord_NFA.gv 

Wyjście to jest, bez skrzyżowań linia:

graph

Sztuką jest:

  1. Aby dodać MinLen atrybut zmusić pewną separację, dając więcej odstępów do renderowania bez nakładania i skrzyżowań.

  2. Aby odwrócić logikę niektórych krawędzi (czyniąc je niezaangażowanymi za pomocą dir = wstecz). W ten sposób kropka zawsze widzi acykliczny wykres i może uporządkować krawędzie bez zmieszania.

  3. Ogniskowanie najpierw w niektórych podgraphach i grupowanie ich węzłów w klastrach w celu nadania im pewnej "ochrony" przed zakłóceniami podczas renderowania reszty wykresu.

35

Tutaj jest pewne kroki w kierunku lepszego:

  • nodesep nie jest węzłem atrybut - i to prawdopodobnie nie robi to, czego oczekiwano. Ale nadal jest przydatny w twoim przypadku:

    ... wpływa to na odstępy między pętlami w jednym węźle lub na multiligatory między parą węzłów.

  • Nie sądzę krawędź waga coś zmienia, czy go zmienić na wszystkich krawędziach.
  • Włączenie splines jest często dobrym pomysłem.
  • Dodanie dodatkowej przestrzeni wokół węzłów można zrobić z sep
  • overlap ma więcej wartości niż true/false - często znaleźć scalexy pożytecznego.
  • Gdy dystrybucja węzeł jest ok, można pozycjonuje dostrojenie etykieta za pomocą kombinacji headlabel/taillabel, labeldistance i labelangle (czerwony w przykładzie poniżej, aby je wyróżniać).

Oto zmodyfikowany próbki:

digraph n { 
splines=true; 
sep="+25,25"; 
overlap=scalexy; 
nodesep=0.6; 
node [fontsize=11]; 
//edge[weight=0.2]; 

A -> B [label="I/5"] 
A -> A [label="*/0"] 
A -> C [label="ii/2"] 
A -> H [label="vii/1"] 
B -> D [label="iii/1"] 
B -> E [label="IV/2"] 
B -> F [headlabel="V/2", labeldistance=4, labelangle=-10, labelfontcolor=red] 
B -> B [label="vi/2"] 
C -> F [label="V/2"] 
C -> H [label="vii/1"] 
D -> E [label="IV/2"] 
E -> D [label="iii/2"] 
E -> G [label="iv/1"] 
E -> F [headlabel="V/3", labeldistance=8, labelangle=-7, labelfontcolor=red] 
F -> B [label="I/4"] 
F -> B [label="vi/1"] 
F -> B [label="*/0"] 
G -> B [taillabel="I/5", labeldistance=4, labelangle=15, labelfontcolor=red] 
H -> B [label="vi/1"] 
} 

graphviz output

7

Korzystanie silnik dot mam następujący wyjście bez zmiany dot plik, który powinien pasować na A4. Odtworzenie Marapeta lepiej wykorzystuje przestrzeń.

dot engine output