0
votes

I've to display a graph like a tree level in hierarchy so I use the TreeLayout included in Jung, but I don't know if it's possible use this layout to add multiple edges between nodes. And if it's not possible, how you recommend me to do that?

Thanks!

    public class Visualizacion extends JApplet {
/**
 * the graph
 */
Graph<String,String> graph;
Forest<String,String> tree;

Funciones f=new Funciones();

/**
 * the visual component and renderer for the graph
 */
VisualizationViewer<String,String> vv;
String root;
Layout<String,String> layout;
Layout<String,String> layout2; ;

public Visualizacion(org.graphstream.graph.Graph grafito) {

    graph= new DirectedSparseMultigraph<String, String>();
    createTree(grafito);

    MinimumSpanningForest2<String,String> prim = 
        new MinimumSpanningForest2<String,String>(graph,
            new DelegateForest<String,String>(), DelegateTree.<String,String>getFactory(),
            new ConstantTransformer(1.0));

    tree = prim.getForest();

    layout = new TreeLayout<String,String>(tree,100,100);
    layout2 = new StaticLayout<String,String>(graph, layout);

    Transformer<String,Paint>vertexPaint= new Transformer<String,Paint>(){
        public Paint transform(String i){
            Node node=grafito.getNode(i);
            if(node.hasAttribute("ExcedeCaudal")){
                return Color.RED;}
            else{
                return Color.lightGray;}
        }
    };

    vv =  new VisualizationViewer<String,String>(layout2, new Dimension(800,600));
    vv.addGraphMouseListener(new TestGraphMouseListener<String>());
    vv.setBackground(Color.white);
    vv.getRenderContext().setEdgeShapeTransformer(new EdgeShape.Line());
    vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
    vv.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller());
    vv.getRenderContext().setVertexShapeTransformer(new ClusterVertexShapeFunction());
    vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint);
    // add a listener for ToolTips
    vv.setVertexToolTipTransformer(new ToStringLabeller());
    vv.getRenderContext().setArrowFillPaintTransformer(new ConstantTransformer(Color.lightGray));
    vv.getRenderContext().setEdgeLabelTransformer(new EdgeLabelTransformer<String>());

    Container content = getContentPane();
    final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv);
    content.add(panel);

    final DefaultModalGraphMouse graphMouse = new DefaultModalGraphMouse();
    vv.setGraphMouse(graphMouse);

    //ver cual nodo se selecciona
    final PickedState<String> pickedState=vv.getPickedVertexState();
    pickedState.addItemListener(new ItemListener(){

        @Override
        public void itemStateChanged(ItemEvent e){
            Object subject=e.getItem();
            if(subject instanceof String){
                String vertice=(String)subject;
                if(pickedState.isPicked(vertice)){
                    System.out.println("Vertice "+vertice+" está seleccionado");
                }
                else{
                    System.out.println("Vertice "+vertice+"no está seleccionado");
                }
            }

        }
    });
}private void createTree(org.graphstream.graph.Graph grafito) {

for(Node node:grafito){
     graph.addVertex(node.getId());
}
int count=0;
for (Edge edge: grafito.getEachEdge()){
     String padre=edge.getNode0().getId();
     String hijo=edge.getNode1().getId();
     String caudal=(edge.getAttribute("Caudal"));

     graph.addEdge(caudal+"-"+count, padre,hijo,EdgeType.DIRECTED);  
     System.out.println("intento agregar "+edge.getAttribute("Caudal")+" cuyo padre es "+padre+" e hijo "+hijo);

     count++;
}}private class EdgeLabelTransformer<V>implements Transformer<V,String>{
    public String transform(V v){
        return v.toString().split("-")[0];
    }
}

class ClusterVertexShapeFunction<V> extends EllipseVertexShapeTransformer<V> {

    ClusterVertexShapeFunction() {
        setSizeTransformer(new ClusterVertexSizeFunction<V>(20));
    }
    @SuppressWarnings("unchecked")
    @Override
    public Shape transform(V v) {
        if(v instanceof Graph) {
            int size = ((Graph)v).getVertexCount();
            if (size < 8) {   
                int sides = Math.max(size, 3);
                return factory.getRegularPolygon(v, sides);
            }
            else {
                return factory.getRegularStar(v, size);
            }
        }
        return super.transform(v);
    }
}

class ClusterVertexSizeFunction<V> implements Transformer<V,Integer> {
    int size;
    public ClusterVertexSizeFunction(Integer size) {
        this.size = size;
    }

    public Integer transform(V v) {
        if(v instanceof Graph) {
            return 30;
        }
        return size;
    }
}

static class TestGraphMouseListener<V> implements GraphMouseListener<V> {

        public void graphClicked(V v, MouseEvent me) {
                if(me.getClickCount()==2){
                    System.err.println("Vertex "+v+" fui doble click");
                }
            System.err.println("Vertex "+v+" was clicked at ("+me.getX()+","+me.getY()+")");
        }
        public void graphPressed(V v, MouseEvent me) {
            System.err.println("Vertex "+v+" was pressed at ("+me.getX()+","+me.getY()+")");
        }
        public void graphReleased(V v, MouseEvent me) {
            System.err.println("Vertex "+v+" was released at ("+me.getX()+","+me.getY()+")");
        }
}



public void execute(org.graphstream.graph.Graph grafito){

    JFrame frame = new JFrame();
    Container content = frame.getContentPane();
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

    content.add(new Visualizacion(grafito));
    frame.pack();
    frame.setVisible(true);}}
1

1 Answers

0
votes

JUNG Layout instances determine vertex positions, not edge positions; edge rendering is determined automatically based on the edge shape that you use and the number of connecting edges.

JUNG Tree objects, however, can only have one edge connecting any pair of vertices (otherwise it's not a tree).

So if you want a Graph whose vertices are laid out using TreeLayout, but which is not directly representable as a Tree, this is what you can do:

(1) Construct a Tree which encodes the structural relationships that you want (from your original Graph), but doesn't have the parallel edges you want. You can do this either directly yourself (by constructing a copy that removing parallel edges where they exist, or just not adding them initially if that's feasible), or by using the MinimumWeightSpanningTree algorithm to extract a Tree from your original Graph.

(2) Generate a TreeLayout for this Tree.

(3) Create a StaticLayout which copies the positions used by the TreeLayout.

(4) Use this StaticLayout as a layout algorithm for your original Graph.

You can see this process demonstrated in the JUNG MinimumSpanningTreeDemo.java, in the provided sample code that's part of the JUNG source distribution. If you just want to see the code, it's here: http://jung.sourceforge.net/site/jung-samples/xref/edu/uci/ics/jung/samples/MinimumSpanningTreeDemo.html