2012-05-03 11 views
27

Ich versuche, die folgenden Daten in Punktformat GraphViz sichtbar zu machen:Graphviz gibt ein Chaos

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

Ausführen des folgenden Befehl ein: neato -Tpng Chord_NFA.dot > Chord_NFA.png

gibt mir diese Ausgabe:

Ich möchte es auf A4 passen und für keine der Kanten zu überlappen oder über einen Knoten. Dies ist (mathematisch) möglich, weil ich es selbst mit einem Kugelschreiber gemacht habe.

+0

Verwenden Sie 'fdp' anstelle von' neato'; Es dauert länger, erzeugt aber bessere Ergebnisse. Einige Kanten können jedoch immer noch Knoten überlappen. – Phrogz

+2

'fdp' war noch schlimmer. – Rory

Antwort

20

ich mit ihm gespielt wenige und bekam diese:

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

Compile mit:

dot -Tpng -o Chord_NFA.png Chord_NFA.gv 

Der Ausgang ist dies, ohne Linienkreuzungen:

graph

Der Trick ist:

  1. das MinLen Attribut hinzuzufügen gewisse Trennung zu zwingen, ohne Überlappungen und Kreuzungen für das Rendern mehr Abstand zu geben.

  2. Um die Logik einiger Kanten zu invertieren (nicht invertiert mit dir = zurück). Auf diese Weise sieht dot immer einen azyklischen Graphen und kann die Kanten ordnen, ohne sich zu verwirren.

  3. Fokussierung in einigen Teilgraphen zuerst und Gruppierung ihrer Knoten in Clustern, um ihnen etwas "Schutz" vor Interferenzen zu geben, wenn der Rest des Graphen gerendert wird.

35

Hier ist ein paar Schritte in eine bessere Richtung:

  • nodesep ist kein Knoten-Attribut - und tut es wahrscheinlich nicht, was Sie erwartet. Aber es ist immer noch in Ihrem Fall nützlich:

    ... Dies betrifft den Abstand zwischen Schleifen auf einem einzelnen Knoten oder mehrere zwischen einem Paar von Knoten.

  • Ich glaube nicht, Rand Gewicht etwas ändert, wenn Sie es für alle Kanten ändern.
  • Aktivieren splines ist oft eine gute Idee.
  • zusätzlichen Raum um die Knoten hinzufügen kann mit sep
  • overlap hat mehr Werte als wahr/falsch getan werden - finde ich oft scalexy nützlich.
  • Sobald die Knotenverteilung in Ordnung ist, können Sie Feinabstimmung Label positionieren durch eine Kombination aus headlabel/taillabel Verwendung labeldistance und labelangle (rot im Beispiel unten, um sie abheben).

Hier ist das modifizierte Beispiel:

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

Mit dem Punktmotor ich die folgende Ausgabe bekam den Punkt Datei ohne Änderung, die auf A4 passen sollte. Marapets Wiedergabe nutzt den Raum besser aus.

dot engine output