2011-01-12 16 views
28

quale dei framework di disegno grafico Java open source da utilizzare per un diagramma di rete con i seguenti requisiti? Il grafico avrà meno di 1000 nodi.confronto di framework di disegno java open source (JUNG e Prefuse) per il disegno della topologia di rete

1) presenta bordi paralleli
2) diretto e bordi non orientati all'interno di un unico grafico
3) i nodi rappresentati dalle immagini
4) l'interazione dell'utente con nodi e bordi
5) aggiungere dinamicamente/eliminazione dei nodi e spigoli
6) etichettatura multipla su nodi e spigoli, diversi livelli di etichettatura possono essere disattivati ​​/ attivati ​​dagli utenti. (come disegnare a strati e spegnere/su un livello)
7) diversi algoritmi di layout per visualizzare le topologie a stella, ad anello, a maglia

Ho valutato JUNG e Prefuse. Questo è quello che ho trovato per ciascuna delle mie esigenze.

1) Prefused non può visualizzare i bordi paralleli mentre JUNG lo supporta. È possibile manipolare il codice di prefusione per visualizzare i bordi paralleli? Dato che questo comporta cambiamenti di livello di dati di base, credo che sarebbe più difficile che il solito rendering personalizzato cambi.

2) Non ho trovato alcun riferimento al grafico combinato (sia diretto che non orientato) sia in prefuse che in JUNG. Qualcuno sa altrimenti?

3) Questo sembra facile sia Prefuse e JUNG

4) Anche in questo caso sia prefusibile e JUNG fornisce il supporto per l'interazione dell'utente.

5) Sia Prefuse che JUNG lo supportano. Come si comporta ogni quadro durante il ridisegno del grafico? Ho visto in un altro post che prefuse non funziona bene per gli aggiornamenti dinamici (Prefuse Toolkit: dynamically adding nodes and edges)

6) Questo si riduce a modificare il grafico e ridisegnarlo. Quindi la domanda diventa la stessa di 5)

7) Sia JUNG che prefuse hanno più algoritmi di layout. Ma quando ho provato a visualizzare lo stesso set di dati utilizzando FruchtermanReingoldLayout in JUNG e Prefuse ottengo diversi display. Qualche idea, perché? In qualche modo gli algoritmi di layout in Prefuse sembrano mostrare un layout migliore rispetto a JUNG (il rendering è anche meglio penso) sebbene la maggior parte degli algoritmi di layout in Prefuse siano basati sull'implementazione di JUNG. I layout prefusi come ForceDirectedLayout/FruchtermanReingoldLayout e CircleLayout vengono mappati direttamente alle topologie a stella, cerchio, mesh.

Al di fuori di questi requisiti, il prefuse ha un buon supporto per espressioni e linguaggio di query, ma sembra che non sia sviluppato attivamente a differenza di JUNG. quale è la visualizzazione migliore? Qualche suggerimento su quale sarà adatto e su come superare le carenze?

Qualsiasi altro quadro che posso utilizzare?

+7

+1 per questo . Mi piace il fatto che hai svolto un sacco di lavoro iniziale valutando due possibilità e presentato le tue scoperte. C'è molto valore qui per gli altri oltre la tua domanda. Questa potrebbe essere la migliore "prima domanda" per un nuovo utente che ho visto in due anni qui. Lo darei di più se potessi. – duffymo

risposta

3

Alcuni anni fa (2007?) Uso prefuse per visualizzare i record dei dati delle chiamate. Ho considerato prefuse, jung, jgraph e pochi altri e ho scelto il prefuse. In un primo momento è un po 'difficile capire come proverli, ma una volta acquisito familiarità con esso è davvero facile (estendere) e divertente da usare. Suppongo che lo stesso si possa dire per JUNG ma non l'ho mai provato.

1) In prefusione è molto semplice aggiungere il proprio renderizzatore personalizzato per disegnare i bordi paralleli: è possibile creare una sottoclasse del EdgeRenderer predefinito e sovrascrivere il metodo render(). Non sono necessarie "modifiche al livello dei dati di base". Questo è tutto nella parte vista se ti piacerebbe pensarlo come una roba MVC.

2) Questo non è proprio un problema. Ci sono più modi per farlo: 1) Puoi avere due renderer - uno per disegnare i bordi diretti e uno per disegnare i bordi non orientati e funzioneranno bene, e raggruppare i bordi in modo appropriato. 2) Metti un flag (aggiungi una colonna booleana nella tupla del backing table in prefuse speak) per indicare se il bordo è diretto e saltare la porzione del disegno della freccia di conseguenza nel EdgeRender in base a quel flag.

3) Questo è super facile

4) idem

5) L'ultimo rilascio Prefuse è "Prefuse versione beta 2007/10/21". Ho usato quello precedente, che ha una possibile condizione di competizione durante l'aggiunta o l'eliminazione dinamica dei nodi: mancavano alcune parole chiave sincronizzate, immagino. Ho risolto questo problema assicurandoti di interrompere tutte le animazioni e le azioni (colore, dimensioni, layout) quando aggiungi o rimuovi i nodi - inoltre non dimenticare di aggiornare anche i tuoi indici di lucene (se usi il suo motore di ricerca lucene integrato). L'ultimo dovrebbe risolvere questo problema di razza, ma non ho mai avuto la possibilità di provarlo.

6) Dato che hai menzionato "etichettatura multipla", penso che non si tratta di "modificare il grafico e ridisegnarlo" - è solo una questione di personalizzare i renderer di etichette/bordi per disegnare solo le etichette pertinenti, quindi questo non è davvero un grosso problema. Inoltre non penso che questo sia collegato a 5 affatto.

7) Non mi sorprende che il rendering di prefused e JUNG del FruchtermanReingoldLayout siano diversi - ci sono alcuni fattori che potrebbero influenzare questo uno di loro il nodo di partenza in cui ogni implementazione avvia il calcolo quindi non mi preoccuperei molto su questo problema. È abbastanza facile provare i diversi algoritmi di layout grafico predefiniti in prefuse in modo da poter andare avanti e verificare quale è il più vicino a ciò che vorresti avere. Controlla RadialLayout e BalloonTreeLayout per il layout a stella. ForceDirectedLayout richiede alcune iterazioni per il posizionamento dei nodi "stabile". Nota che queste iterazioni non sono necessarie per essere mostrate in modo da poterle eseguire in background e rendere il risultato finale.

Non ho usato JUNG quindi non posso commentare molto su di esso.

Sulla base della mia esperienza con prefuse lo consiglio vivamente grazie al ben congegnato design (IMHO) e alla separazione della resposabilità tra i componenti. Jeffrey Heer (autore di prefissi) ha fatto davvero un buon lavoro lì.

cose da guardare fuori per se si utilizza Prefuse (questi sono i due "mal-pollici" che ho un vivo ricordo quando si lavora con Prefuse):

1) C'è un bug per cui quando lo zoom out, le etichette dei nodi non vengono rimpiccioliti in modo appropriato in modo tale da far traboccare il riquadro di delimitazione del nodo che lascerà le risorse del disegno del font quando il nodo si sposta perché il renderer solo cancella e ridisegna le cose all'interno del riquadro di delimitazione del nodo. IIRC è causato da un bug nella metrica del font AWT stesso. La soluzione è lasciare ampio margine tra l'etichetta e il riquadro di delimitazione del nodo.

2) Quando si estendono i layout incorporati, è possibile che si verifichi uno o due "problemi di scoping" in cui un membro della superclasse a cui si desidera accedere riceve l'attributo privato anziché protetto, quindi la soluzione è quello di modificare la libreria stessa o creare una nuova classe senza ereditare (che può essere un po 'doloroso!). Immagino si possa dire lo stesso per alcune altre librerie java. Non tutti hanno il beneficio del senno di poi no? :)

Dato che hai fatto questa domanda circa un mese fa (al momento della stesura di questo) vorrei sapere qual è stata la tua decisione e come è andata a finire se hai seguito l'implementazione.

2

So che hai specificato jung e prefuse ma ... Ho avuto una buona esperienza con TomSawyer e yFiles. La lista dei requisiti che hai proposto è molto basilare per questi due - e supportano molto di più.

Ran.

5

Sono uno dei creatori e manutentori di JUNG, quindi tenetelo a mente per le risposte di seguito.

Prima, però, dovrei dire che l'autore di Prefuse è amico di un amico (e sì, ci siamo incontrati) e ha fatto un ottimo lavoro. Non ho esperienza con Prefuse, ma ho visto alcune belle visualizzazioni create con esso.

Ecco le risposte a queste domande per JUNG. Molti di loro ((1), (2), (4) sono illustrati in PluggableRendererDemo:

  1. supportati (è necessario il modello di dati a destra, non tutti sostenere bordi paralleli per motivi di prestazioni)
  2. supportati (ancora una volta, è necessario il modello di dati a destra)
  3. supportati (vedi ImageShaperDemo)
  4. supportati (la maggior parte delle demo)
  5. supportati (vedi GraphEditorDemo)
  6. non direttamente supportati, anche se è possibile cERTA modifica le etichette in modo dinamico e utilizza HTML per il rendering di etichette complesse.
  7. Gli algoritmi di layout di JUNG sono più utili per le reti generali (con poche eccezioni per gli alberi, ecc.). Puoi certamente costruire i tuoi algoritmi di layout, tuttavia, e molti lo hanno fatto.

Spero che questo aiuti.

0

Mi piace la risposta di @ holygeek. Ecco il mio attuazione alla soluzione di 2 (entrambi diretti e bordi non orientati), per 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; 
    } 
} 

... altrove, in cui viene creato il grafico ...

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