2013-05-27 5 views
8

Ich habe eine Grafik, die sich im Laufe der Zeit ändert (normalerweise werden neue Knoten hinzugefügt). Ich muss das Diagramm mehrmals regenerieren und möchte, dass alle Knoten dort bleiben, wo sie waren. Dies funktioniert teilweise, wenn graphviz mit dem fdp -algorithmus verwendet wird, das pin -flag gesetzt wird und die Positionen mit dem pos -argument spezifiziert werden.GrafikViz erzwingen Knotenpositionen zu erhalten

In den meisten Fällen funktioniert das ziemlich gut. Aber besonders wenn neue Knoten hinzugefügt werden, ändert sich das Layout manchmal drastisch - was ich vermeiden muss. Gibt es eine Option zu Kraft diese fixierten Positionen tatsächlich? Es könnte zu einer hässlichen Grafik führen, das wäre in Ordnung - aber sie müssen nur bleiben.

Antwort

14

Graphviz macht es nicht leicht Neins in der gleichen Position zu halten:

  • Hinzufügen/Entfernen eines Knotens ein völlig anderes Layout führen kann.
  • Das Hinzufügen/Entfernen eines Knotens kann die Dimension der zu ändernden Begrenzungsbox ändern.

Die folgenden Werke, wenn alle Knoten bekannt sind, wenn die Diagramme zu erstellen:

  • erstellen Graph alle möglichen Knoten enthält, und lassen Sie es graphviz legen. Sie können nodes[pin=true]; am Anfang des Diagramms hinzufügen (dann müssen Sie es später nicht mehr hinzufügen).
  • -Layout der Graph:

    fdp -Tdot input.gv -o input.pos.gv 
    

    Sie haben nun einen Punkt Datei, die alle Knoten enthält. Sie können dies als Basisdatei für alle zu erstellenden Diagramme verwenden:

  • Erstellen Sie für jedes Diagramm eine Kopie von input.pos.gv und blenden Sie die nicht benötigten Knoten und Kanten aus, indem Sie ihren Attributen style=invis hinzufügen. Dies stellt sicher, dass sie nicht angezeigt werden, aber auch die Stelle, die sie im Layout verwenden, wird nicht abgeschnitten entfernt (zum Beispiel, wenn ganz oben in der Grafik).
  • Legen Sie sie heraus so etwas wie dies mit (neato und Option -n2 sind die wichtigen Teile):

    neato -n2 -Tpng input.pos.v1.gv -o output.v1.png 
    

Beispiel:

input.gv:

digraph g{ 
    node[pin=true]; 
    a -> b; 
    a -> c; 
    b -> d; 
    b -> e; 
    b -> f; 
    c -> g; 
} 

input.pos.modified.gv:

digraph g { 
    node [label="\N", pin=true]; 
    graph [bb="0,0,187,207"]; 
    a [pos="60.846,70.555", width="0.75", height="0.5", style=invis]; 
    b [pos="94.351,128.04", width="0.75", height="0.5"]; 
    c [pos="76.868,18.459", width="0.75", height="0.5"]; 
    d [pos="119.08,188.8", width="0.75", height="0.5",style=invis]; 
    e [pos="157.97,106.75", width="0.75", height="0.5"]; 
    f [pos="27.319,158.05", width="0.75", height="0.5"]; 
    g [pos="160.1,20.585", width="0.75", height="0.5"]; 
    a -> b [pos="e,84.434,111.03 70.717,87.493 73.42,92.13 76.411,97.263 79.332,102.27", style=invis]; 
    a -> c [pos="e,71.34,36.433 66.27,52.918 66.934,50.759 67.624,48.514 68.32,46.252", style=invis]; 
    b -> d [pos="e,111.86,171.05 101.5,145.62 103.54,150.61 105.8,156.17 108.01,161.59", style=invis]; 
    b -> e [pos="e,133.72,114.86 118.76,119.87 120.45,119.31 122.17,118.73 123.89,118.16"]; 
    b -> f [pos="e,49.99,147.9 71.657,138.2 67.726,139.96 63.572,141.82 59.447,143.67"]; 
    c -> g [pos="e,133.07,19.895 104.12,19.155 110.07,19.307 116.47,19.471 122.74,19.631"]; 
} 

Eingabe.png ohne Änderungen:

output.png

verborgenen Knoten:

output with invisible nodes

+0

Vielen Dank für Ihre Antwort! Leider kenne ich nicht alle Knoten gleich zu Beginn. Einige Hintergrundinformationen: Ich visualisiere ein physikalisches Netzwerk, das sich jederzeit ändern kann (neue, bisher unbekannte Knoten werden hinzugefügt, Verbindungen ändern sich, ...). Und da der Endbenutzer Knoten verschieben und ein eigenes Layout erstellen kann, sollte er sich nicht vollständig ändern, sobald ein Update durchgeführt wurde. Das kann mit graphviz also nicht erreicht werden? Und wenn nicht, gibt es eine Alternative? Ich habe seit Ewigkeiten gesucht ... – Remo

+0

Ich dachte auch daran, Untergraphen zu erstellen oder separate Graphen zu erstellen und sie zu kombinieren. Wäre das eine Möglichkeit? Ich habe nicht die Forderung, dass die neuen Knoten gut passen ... sie können außerhalb aller vorhandenen Knoten positioniert werden und die Verbindungen können sich überlappen, wenn sie es brauchen. – Remo

+0

Mit 'pin' und' pos' können Sie versuchen, einen Standardwert (oder zufällige) 'pos'-Werte für einen neuen Knoten hinzuzufügen. Ich denke, ich erinnere mich irgendwo gelesen zu haben, dass, um feste Knotenpositionen zu haben, alle Knoten _must_ ein 'pos'-Attribut haben müssen (weiß nicht über die Kanten). – marapet

Verwandte Themen