Можно ли добавить несколько ребер с помощью TreeLayout?

Мне нужно отобразить граф как уровень дерева в иерархии, поэтому я использую TreeLayout, включенный в Jung, но я не знаю, возможно ли использовать этот макет для добавления нескольких ребер между узлами. И если это невозможно, как вы рекомендуете мне это сделать?

Спасибо!

    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);}}

person Tamara Andrea Vejar Ferrada    schedule 05.02.2016    source источник


Ответы (1)


Экземпляры 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

person Joshua O'Madadhain    schedule 07.02.2016
comment
Я попытался сделать то, что вы сказали мне, но у меня все еще есть проблемы с визуализацией нескольких ребер (они не появляются), и я не могу найти проблему. Вот мой код. Спасибо за помощь! - person Tamara Andrea Vejar Ferrada; 08.02.2016
comment
Не глядя на ваш код (и не имея возможности увидеть результат), вы можете ошибиться в двух местах: (а) граф, который вы пытаетесь визуализировать (визуализировать), не имеет параллельных ребер, или (b) вы используете Line EdgeShape, из-за чего края отображаются друг над другом. Проверь это. - person Joshua O'Madadhain; 08.02.2016