2011-01-12 9 views
28

Welches der Open-Source-Java-Graph-Zeichnungsframeworks für ein Netzwerkdiagramm mit den folgenden Anforderungen? Der Graph wird weniger als 1000 Knoten haben.Vergleichen von Open-Source-Java-Graph-Zeichnungsframeworks (JUNG und Prefuse) zum Zeichnen der Netzwerktopologie

1) weist parallele Kanten
2) gerichteten und ungerichteten Kanten innerhalb eines einzigen Graphen
3) durch Bilder mit Knoten
4) Interaktion mit dem Benutzer dargestellt Knoten und Kanten
5) dynamisch Hinzufügen/Knoten und Kanten Löschen
6) Mehrfachbeschriftung an Knoten und Kanten, verschiedene Ebenen der Beschriftung können von Benutzern ein-/ausgeschaltet werden. (wie Zeichnen in Schichten und Ein-/Ausschalten einer Schicht)
7) verschiedene Layoutalgorithmen zur Darstellung von Stern-, Ring-, Gittertopologien

Ich bewerte JUNG und Prefuse. Das habe ich für jede meiner Anforderungen gefunden.

1) Prefuse kann keine parallelen Kanten anzeigen, während JUNG dies unterstützt. Kann der Code vor der Eingabe manipuliert werden, um parallele Kanten anzuzeigen? Da dies grundlegende Änderungen der Datenebene mit sich bringt, wäre dies meiner Ansicht nach schwieriger, als wenn sich das übliche benutzerdefinierte Rendering ändert.

2) Ich habe keinen Verweis auf kombinierte Graphen (sowohl gerichtete als auch ungerichtete Kanten) sowohl in der Vorsicherung als auch in JUNG gefunden. Weiß jemand etwas anderes?

3) Das scheint einfach mit beiden Prefuse und JUNG

4) Wieder beide prefuse und JUNG bietet Unterstützung für die Interaktion mit dem Benutzer.

5) Sowohl Vorsicherung als auch JUNG unterstützen dies. Wie funktioniert jedes Framework beim Neuzeichnen des Graphen? Ich sah in einem anderen Beitrag, dass Vorfusion nicht gut für dynamische Updates funktioniert (Prefuse Toolkit: dynamically adding nodes and edges)

6) Dies kommt auf die Änderung der Grafik und neu zeichnen es. So wird die Frage gleich wie 5)

7) Sowohl JUNG und Vorsicherung hat mehrere Layout-Algorithmen. Aber wenn ich versuchte, den gleichen Datensatz mit FruchtermanReingoldLayout sowohl in JUNG als auch in Prefuse anzuzeigen, erhalte ich unterschiedliche Darstellungen. Irgendwelche Ideen warum? Irgendwie scheinen die Layout-Algorithmen in Prefuse besser zu sein als in JUNG (Rendering ist auch besser, denke ich), obwohl die meisten Layout-Algorithmen in Prefuse auf der JUNG-Implementierung basieren. Prefuse-Layouts wie ForceDirectedLayout/FruchtermanReingoldLayout und CircleLayout werden direkt Stern-, Kreis- und Netztopologien zugeordnet.

Außerhalb dieser Anforderungen hat Prefuse gute Unterstützung für Ausdrücke und Abfragesprache, aber es sieht so aus, als ob es nicht aktiv entwickelt wurde, wie JUNG. Welcher hat eine bessere Visualisierung? Irgendwelche Vorschläge, welche geeignet sein werden und wie die Mängel überwunden werden können?

Alle anderen Frameworks, die ich verwenden kann?

+7

+1 für diese . Ich mag die Tatsache, dass Sie eine Menge Vorarbeit geleistet haben, um zwei Möglichkeiten zu evaluieren und Ihre Ergebnisse zu präsentieren. Es gibt viel Wert hier für andere außer Ihrer Frage. Dies könnte die beste "erste Frage" für einen neuen Benutzer sein, die ich in zwei Jahren hier gesehen habe. Ich würde es mehr geben, wenn ich könnte. – duffymo

Antwort

3

Vor ein paar Jahren (2007?) Verwende ich prefuse, um Anrufdatensätze zu visualisieren. Ich dachte über prefuse, jung, jgraph und ein paar andere nach und wählte prefuse. Am Anfang ist es ein bisschen schwierig, meinen Kopf um Prefuse zu legen, aber sobald ich mich damit vertraut gemacht habe, ist es wirklich einfach (zu erweitern) und macht Spaß zu benutzen. Ich denke, das gleiche kann für JUNG gesagt werden, aber ich habe es nie versucht.

1) In prefuse ist es sehr einfach, einen eigenen benutzerdefinierten Renderer für das Zeichnen paralleler Kanten hinzuzufügen - Sie können den Standard-EdgeRenderer ableiten und die render() -Methode überschreiben. Es sind keine "grundlegenden Änderungen des Datenniveaus" erforderlich. Dies ist alles im View-Teil, wenn Sie es als MVC-Zeug betrachten möchten.

2) Das ist überhaupt kein Problem. Es gibt mehrere Möglichkeiten, dies zu tun: 1) Sie können zwei Renderer haben - einen für das Zeichnen der gerichteten Kanten und einen für das Zeichnen der ungerichteten Kanten. Sie funktionieren gut und gruppieren die Kanten entsprechend. 2) Setzen Sie ein Flag (fügen Sie eine boolesche Spalte in das Backing-Table-Tupel im Prefuse-Speak ein), um anzugeben, ob die Kante gerichtet ist, und überspringen Sie den Pfeilzeichnungsabschnitt entsprechend im EdgeRender entsprechend diesem Flag.

3) Dies ist super einfach

4) dito

5) Die letzte prefuse Mitteilung ist "prefuse Beta-Version 2007.10.21". Ich habe den vorherigen verwendet, der eine mögliche Wettlaufsituation beim dynamischen Hinzufügen oder Löschen von Knoten hat - es fehlten ein paar synchronisierte Schlüsselwörter, denke ich. Ich löste das, indem ich sicherstellte, dass alle Animationen und Aktionen (Farbe, Größe, Layout) beim Hinzufügen oder Entfernen von Knoten gestoppt wurden - vergessen Sie auch nicht, Ihre Lucene-Indizes zu aktualisieren (wenn Sie die eingebaute Lucene-Suchmaschine verwenden)). Der letzte soll dieses Race Problem lösen, aber ich hatte nie die Chance es auszuprobieren.

6) Da Sie "Mehrfache Beschriftung" erwähnt haben, denke ich, dass es nicht darum geht, den Graphen zu verändern und neu zu zeichnen. Es ist nur eine Frage des Anpassens Ihrer Label/Edge Renderer, nur die relevanten Labels zu zeichnen wirklich ein großes Problem. Ich denke auch nicht, dass dies mit 5 zusammenhängt.

7) Ich bin nicht überrascht, dass Vorfusion und JUNGs Rendering des FruchtermanReingoldLayouts anders sind - es gibt einige Faktoren, die diesen Startknoten beeinflussen könnten, wo jede Implementierung die Berechnung startet, also würde ich mir keine Sorgen machen Zum Thema. Es ist ziemlich einfach, die verschiedenen eingebauten Graphenlayoutalgorithmen in der Prefuse auszuprobieren, so dass Sie weitermachen können, um herauszufinden, welches Ihrem Wunsch am nächsten kommt. Sehen Sie sich das RadialLayout und das BalloonTreeLayout für das Sternenlayout an. ForceDirectedLayout benötigt einige Iterationen, um die Knoten "stabil" zu platzieren. Beachten Sie, dass diese Iterationen nicht angezeigt werden müssen, damit Sie sie im Hintergrund ausführen und das Endergebnis rendern können.

Ich habe JUNG nicht verwendet, daher kann ich nicht viel dazu sagen.

Basierend auf meiner Erfahrung mit Prefuse empfehle ich es aufgrund der sehr gut (IMHO) durchdachte Design und Trennung der Verantwortlichkeit zwischen den Komponenten. Jeffrey Heer (Prefuse-Autor) hat dort wirklich gute Arbeit geleistet.

Dinge zu beachten, wenn Sie prefuse verwenden (das sind die beiden „wunde Daumen“, die ich erinnere mich lebhaft an, wenn sie mit prefuse Arbeits):

1) Es gibt einen Bug, bei dem beim Herauszoomen, die Knotenetiketten werden nicht angemessen herausgezoomt, so dass sie die Begrenzungsbox des Knotens überlaufen, was beim Ziehen des Knotens Font-Zeichnungsartefakte hinterlassen wird, da der Renderer nur innerhalb der Begrenzungsbox des Knotens Inhalte löscht und neu zeichnet. IIRC Dies wird durch einen Fehler in der AWT-Schriftmetrik selbst verursacht. Die Problemumgehung besteht darin, einen ausreichenden Abstand zwischen dem Label und der Bounding-Box des Knotens zu lassen.

2) Wenn Sie die integrierten Layouts erweitern, können ein oder zwei "Problembereiche" auftreten, bei denen ein Mitglied der Oberklasse, auf das Sie Zugriff haben möchten, statt der geschützten das private Attribut erhält ist entweder die Bibliothek selbst zu modifizieren oder eine neue Klasse zu erstellen, ohne zu erben (das kann ein bisschen schmerzhaft sein!). Ich denke, Sie können dasselbe für einige andere Java-Bibliotheken sagen. Nicht jeder hat rückblickend den Vorteil? :)

Da Sie diese Frage vor etwa einem Monat gestellt haben (zu der Zeit, als ich das geschrieben habe), würde ich gerne wissen, was Ihre Entscheidung war und wie es für Sie gelaufen ist, wenn Sie mit der Implementierung fortfahren.

2

Ich weiß, dass Sie jung und vorgeben, aber ... Ich hatte gute Erfahrungen mit TomSawyer und yFiles. Die von Ihnen vorgeschlagene Anforderungsliste ist für diese beiden sehr einfach - und sie unterstützen viel mehr.

Lief.

0

Ich würde vorschlagen, auch JGraph auszuwerten.

5

Ich bin einer der Schöpfer und Betreuer von JUNG, also bedenkt das für die Antworten unten.

Zunächst sollte ich jedoch sagen, dass der Autor von Prefuse ein Freund eines Freundes ist (und ja, wir haben uns getroffen) und er hat einen tollen Job gemacht. Ich habe keine Erfahrung mit Prefuse, aber ich habe einige schöne Visualisierungen mit ihm erstellt.

Hier sind die Antworten auf diese Fragen für JUNG. Mehrere von ihnen ((1), (2), (4) in PluggableRendererDemo demonstriert:

  1. Unterstützt (Sie werden das richtige Datenmodell benötigen, alle unterstützen keine parallelen Kanten aus Leistungsgründen)
  2. Unterstützten (auch hier müssen Sie das Modell richtigen Daten)
  3. unterstützt (siehe ImageShaperDemo)
  4. unterstützt (die meisten Demos)
  5. unterstützt (siehe GraphEditorDemo)
  6. nicht direkt unterstützt, obwohl Sie Certa können Ändern Sie Beschriftungen dynamisch und verwenden Sie HTML zum Rendern komplexer Beschriftungen.
  7. JUNGS Layout-Algorithmen sind mehr für allgemeine Netzwerke (mit einigen Ausnahmen für Bäume, etc.). Sie können jedoch sicherlich Ihre eigenen Layout-Algorithmen konstruieren, und viele haben dies getan.

Hoffe, das hilft.

0

Ich mag @ holygeeks Antwort. Hier ist meine Implementierung der Lösung für 2 (beide gerichteten und ungerichteten Kanten), für Prefuse:

public class MyRenderFactory implements RendererFactory 
{ 
    private NodeRenderer nodeRenderer = new NodeRenderer(); 
    private EdgeRenderer defaultEdgeRenderer = new EdgeRenderer(); 
    private EdgeRenderer undirectedEdgeRenderer = new EdgeRenderer(EdgeRenderer.EdgeType.LINE, EdgeRenderer.EdgeArrowType.NONE); 

    public static String directedness = "myEdgeDirectedness"; 

    public enum EdgeDirected 
    { 
     directed, undirected; 

     public static EdgeDirected fromIsDirected(boolean isDirected) 
     { 
      if (isDirected) 
      { 
       return directed; 
      } 
      return undirected; 
     } 
    } 

    @Override 
    public Renderer getRenderer(VisualItem<?> visualItem) 
    { 
     if (visualItem instanceof EdgeItem) 
     { 
      if (visualItem.get(directedness).equals(PrefuseGraphConverter.EdgeDirected.undirected)) 
      { 
       return undirectedEdgeRenderer; 
      } 
      return defaultEdgeRenderer; 
     } 
     return nodeRenderer; 
    } 
} 

... an anderer Stelle, wo der Graph erstellt wird ...

MyRenderFactory.EdgeDirected directedness = 
     MyRenderFactory.EdgeDirected.fromIsDirected(myEdge.isDirected()); 
prefuseEdge.set(MyRenderFactory.directedness, directedness); 
Verwandte Themen