JUNG Java Universal Network/Graph Framework JUNG jest to biblioteka służąca do modelowania, analizy i wizualizacji danych reprezentowanych w postaci grafów lub sieci. Architektura JUNGa wspiera różnorodność reprezentacji wierzchołków i relacji między nimi, takie jak skierowane, nieskierowane grafy, wielokrotne krawędzie itp. Zdolności tego narzędzia mogą posłużyć do analizy złożonych struktur danych, czy też testowania relacji pomiędzy obiektami. Biblioteka ma zaimplementowane algorytmy grafowe, takie jak dekompozycja, optymalizacja, generowanie grafów losowych, analiza statystyczna, obliczenia długości sieci, przepływu, czy znajdowania najkrótszej ścieżki. JUNG posiada również narzędzia do wizualizacji grafów, które ułatwiają interakcje z analizowanymi strukturami. Użytkownik może zastosować jeden z algorytmów layout, albo stworzyć swój własny layout. Dodatkowo mechanizmy filtracji umożliwiają odróżnienie części grafu, na której detalach Nam zależy. JUNG jest narzędziem ułatwiającym pracę ludziom, którzy korzystają z grafów, sieci i relacji pomiędzy danymi, przy tworzeniu swoich programów. Zaczynamy Aby uruchomić aplikację bazującą na JUNG potrzebne są pakiety Java Development Kit 1.4 albo nowszy http://java.sun.com/javase/ środowisko programistyczne Javy korzystanie na zasadzie Sun's Binary Code License (http://www.java.com/en/download/license.jsp ) Apache Jakarta Commons Collections Cern Colt Scientific Library http://commons.apache.org/collections/ biblioteka z dodatkowymi strukturami danych oraz algorytmami obsługującymi je udostępniania na zasadzie licencji Apache Software License ( http://www.apache.org/licenses/license- 2.0 ) http://dsd.lbl.gov/~hoschek/colt/ bilioteka do naukowych i technicznych obliczeń matematycznych udostępniana na zasadzie open source (oraz częściowo LGPL http://dsd.lbl.gov/~hoschek/colt/license.html )
Xerces - GraphML odczytywanie i zapis GraphML (XML format do reprezentacji grafów) http://xerces.apache.org/xerces2-j/index.html udostępniana na zasadzie Apache Software License ( http://www.apache.org/licenses/license-2.0 ) Biblioteka JUNG jest do pobrania ze strony projektu https://sourceforge.net/projects/jung/ W przewodniku zajmiemy się wersją JUNG'a 1.7.6. JUNG2 jest dopiero w fazie alpha i działanie tej wersji biblioteki bywa niestabilne. Wizualizacja grafów Tworzenie grafów opiera się na następujących etapach. 1. Utwórz graf (tworzymy graf z zależności od naszych potrzeb) Graph g = new DirectedSparseGraph(); 2. Utwórz wierzchołki Vertex v1 = new DirectedSparseVertex()); Vertex v2 = new DirectedSparseVertex()); 3. Utwórz krawędzie DirectedEdge e = (new DirectedSparseEdge(v1, v2)); 4. Dodaj wierzchołki do grafu g.addvertex(v1); g.addvertex(v2); g.addedge(e); 5. Dodaj do grafu layout. Biblioteka posiada parę podstawowych layoutów do prezentacji grafów. SpringLayout MyLayout = new SpringLayout(g); 6. Stwórz PluggableRenderer (it's gone manage the setup of vertex edges, etc...)
PluggableRenderer PR = new PluggableRenderer(); 7. Dodaj layout do VisualizationViewer VisualizationViewer vv = new VisualizationViewer (MyLayout,PR); 8. Dodaj VisualisationViewer do JFrame albo JPanel JFrame jf = new JFrame(); jf.getcontentpane().add(vv); Elementy są dodawane w następujący sposób: Ustawienia grafu Po utworzeniu grafu istnieje możliwość zdefiniowania etykiety dla wierzchołka lub krawędzi. Można również zmieniać kształt i kolory rysowanych obiektów, jak i również obracać cały graf, oraz przesuwać poszczególne wierzchołki. Wszystko to jest możliwe za pomocą JUNG'a.
Etykiety Aby zdefiniować etykietę dla danego wierzchołka najlepiej: Skopiuj do hashmapy wierzchołek i etykietę: mapnamevertex.put(v1,new String("label1")); Stwórz klasę VertexStringerLabel implementując VertexStringer oraz podaj jako parametr hashmapę: import java.util.map; import edu.uci.ics.jung.graph.archetypevertex; import edu.uci.ics.jung.graph.decorators.vertexstringer; /** zarządzanie etykietami dla wierzchołków **/ class VertexStringerDefinitLabel implements VertexStringer protected Map mapnom; private boolean afficherlabel; public VertexStringerDefinitLabel(Map mapnom) this.mapnom = mapnom; public String getlabel(archetypevertex arg0) if(afficherlabel) return (String)mapNom.get(arg0); else return ""; public boolean isafficherlabel() return afficherlabel; public void setafficherlabel(boolean afficherlabel) this.afficherlabel = afficherlabel; Oraz dodaj do PluggableRenderer. PR.setVertexStringer(new VertexStringerDefinitLabel(mapNameVertex));
Wybór koloru Wierzchołek Stwórz klasę VertexPaintFunctionSeedColor implementującą VertexPaintFunction. import java.awt.color; import java.awt.paint; import edu.uci.ics.jung.graph.vertex; import edu.uci.ics.jung.graph.decorators.vertexpaintfunction; import edu.uci.ics.jung.visualization.pickedinfo; /** Wybór koloru dla wierzchołka **/ class VertexPaintFunctionSeedColor implements VertexPaintFunction protected PickedInfo pi; protected boolean seed_coloring; public VertexPaintFunctionSeedColor(PickedInfo plugg) this.pi = plugg; public void setseedcoloring(boolean b) this.seed_coloring = b; public Paint getdrawpaint(vertex v) return Color.BLACK; public Paint getfillpaint(vertex v) if (pi.ispicked(v)) return Color.BLUE; if(seed_coloring) return Color.GREY; Oraz dodaj ją do PluggableRenderer PR.setVertexPaintFunction(new VertexPaintFunctionSeedColor(PR));
Klasa będzie rysowała brzeg wierzchołka na czarno. Gdy zaznaczysz wierzchołek wypełnienie zmieni kolor na niebieski, a jeżeli seed_coloring ma wartość true wierzchołek będzie szary. Aby dodać więcej kryteriów można użyć wartości z userdatum wierzchołka. Krawędzie Stwórz klasę MyEdgePaintfunction implementującą EdgePaintFunction. import java.awt.color; import java.awt.paint; import edu.uci.ics.jung.graph.decorators.edgepaintfunction; import edu.uci.ics.jung.graph.impl.directedsparseedge; import edu.uci.ics.jung.visualization.pickedinfo; public class MyEdgePaintfunction implements EdgePaintFunction protected PickedInfo pi; public MyEdgePaintfunction(PickedInfo plugg) this.pi = plugg; public Paint getdrawpaint(edge e) return Color.BLUE; public Paint getfillpaint(edge e) Color.BLUE; Dodaj ją do PluggableRenderer. PR.setEdgePaintFunction(new MyEdgePaintfunction(PR)); W tym przypadku wszystkie krawędzie będą niebieskie.
Wybierz kształt Wierzchołek Stwórz klasę VertexShapeSizeAspect dziedziczącą po AbstractVertexShapeFunction i implementującą VertexSizeFunction, VertexAspectRatioFunction import java.awt.shape; import edu.uci.ics.jung.graph.vertex; import edu.uci.ics.jung.graph.decorators.abstractvertexshapefunction; import edu.uci.ics.jung.graph.decorators.vertexaspectratiofunction; import edu.uci.ics.jung.graph.decorators.vertexsizefunction; /** Wybór kształtu dla wierzchołka **/ class VertexShapeSizeAspect extends AbstractVertexShapeFunction implements VertexSizeFunction, VertexAspectRatioFunction public VertexShapeSizeAspect() setsizefunction(this); setaspectratiofunction(this); public int getsize(vertex v) return (int)(20); public float getaspectratio(vertex v) return 1.0f; public Shape getshape(vertex v) //wszystkie wierzchołki będą prostokątne return factory.getrectangle(v); Dodaj ją do PluggableRenderer. PR.setVertexShapeFunction(new VertexShapeSizeAspect());
Krawędzie Mamy do wyboru trzy rodzaje krawędzi. Podczas tworzenia PluggableRenderer jest wybierany typ, który potrzebujesz. Jeżeli chcesz zmienić kształt krawędzi podczas działania aplikacji, to musisz zmienić jej wartość. pr.setedgeshapefunction(new EdgeShape.Line()); pr.setedgeshapefunction(new EdgeShape.QuadCurve()); pr.setedgeshapefunction(new EdgeShape.CubicCurve()); ToolTips Jeżeli chcesz zaimplementować ToolTips dla wierzchołków lub krawędzi musisz stwórz klasę MyToolTips dziedziczącą po DefaultToolTipFunction W tym przypadku dodawane są 2 parametery: nazwa i typ do UserDatum wierzchołka. import Tri.BeanPage; import edu.uci.ics.jung.graph.edge; import edu.uci.ics.jung.graph.vertex; import edu.uci.ics.jung.graph.decorators.defaulttooltipfunction; import edu.uci.ics.jung.graph.decorators.numberedgevalue; /** ToolTips podaje informację o wierzchołku lub krawędzi **/ class HitTips extends DefaultToolTipFunction protected NumberEdgeValue edgeweight; private static Properties myprop = new Properties(); public HitTips (NumberEdgeValue EW) this.edgeweight = EW; public String gettooltiptext(vertex v) BeanPage BP_Info=(BeanPage)v.getUserDatum("acceder"); String informations = "Nom : "+BP_Info.getNom()+ " type: "+BP_Info.Type(); return informations; public String gettooltiptext(edge edge) String info = edgeweight.getnumber(edge); return info;
public NumberEdgeValue getedgeweight() return edgeweight; public void setedgeweight(numberedgevalue edgeweight) this.edgeweight = edgeweight; Dodaj do PluggableRenderer. vv.settooltipfunction(new HitTips(edge_weight)); W tym przypadku ToolTips pojawi się, gdy mysz będzie na wierzchołku (pokazując nazwę i typ) lub na krawędzi (pokazując numer) PS: waga krawędzi edgeweight jest przypisywana gdy tworzymy krawędź, np: e1 = new DirectedSparseEdge(v0, v1); edge_weight.setnumber(e1,new Double(4)); Mouse Plug-in JUNG posiada standardową obsługę zdarzeń myszki: ModalGraphMouse gm = new DefaultModalGraphMouse(); vv.setgraphmouse(gm); //affichage pour le choix du mode ( picking ou transforming) JComboBox CB_Mode =((DefaultModalGraphMouse) gm).getmodecombobox(); Teraz można wybierać, poruszać, powiększać, obracać graf itp. Można stworzyć swój własny plug-in i dodać go. Najłatwiej zaimplementować swój plug-in w następujący sposób: Stwórz swój własny plugin, np: public class ClusterGraphMousePlugin extends AbstractGraphMousePlugin implements MouseListener,MouseMotionListener Skopiuj DefaultModalGraphMouse do klasy którą tworzysz (np. MyDefaultModalGraphMouse) oraz dodaj do funkcji loadplugins() swój plugin, oraz dodaj lub usuń we funkcji obsługiwane tryby przez swój plugin (functions : setpickingmode(), settransformingmode()) (jeżeli chcesz aby twój plugin był dostępny tylko w picking mode albo transforming mode )
Hierarchia JUNGa Hierarchia klas i interfejsów grafów JUNGa: Hierarchia klas i interfejsów wierzchołków JUNGa
Linki Więcej informacji nt. JUNGa, oraz szereg przykładowych zastosowań można znaleźć pod następującymi adresami: http://jung.sourceforge.net/doc/manual.html Opis pełnej funkcjonalności biblioteki JUNG. http://jung.sourceforge.net/pmwiki/ JUNG Wiki prezentacje, przykłady, FAQ i How to. http://jung.sourceforge.net/applet/index.html Szereg przykładowych zastosowań JUNGa. http://www.supinfo-projects.com/en/2006/jung%5f2006%5fen/ Prezentacja podstawowej funkcjonalności JUNGa.