是否可以使用TreeLayout添加多个边?

时间:2016-02-05 17:42:12

标签: java graph jung

我要在层次结构中显示类似树级别的图形,因此我使用Jung中包含的TreeLayout,但我不知道是否可以使用此布局在两者之间添加多个边缘节点。如果不可能,你怎么建议我这样做?

谢谢!

    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 个答案:

答案 0 :(得分:0)

JUNG Layout实例确定顶点位置,而不是边缘位置;边缘渲染是根据您使用的边缘形状和连接边数自动确定的。

JUNG Tree对象只能有一条边连接任何一对顶点(否则它不是树)。

因此,如果您想要Graph顶点使用TreeLayout进行布局,但不能直接表示为Tree,那么您可以这样做:

(1)构造一个Tree,它编码你想要的结构关系(来自原始Graph),但没有你想要的平行边。您可以直接自己完成此操作(通过构建一个删除存在的并行边缘的副本,或者如果可行则不添加它们),或者使用MinimumWeightSpanningTree算法从中提取Tree您原来的Graph

(2)为此TreeLayout生成Tree

(3)创建StaticLayout,复制TreeLayout使用的位置。

(4)将此StaticLayout用作原始Graph的布局算法。

您可以在JUNG MinimumSpanningTreeDemo.java中看到此过程,该示例代码是JUNG源代码分发的一部分。如果您只想查看代码,请点击此处:http://jung.sourceforge.net/site/jung-samples/xref/edu/uci/ics/jung/samples/MinimumSpanningTreeDemo.html