How to layout nodes once in GraphStream?

浪子不回头ぞ 提交于 2019-12-11 02:58:08

问题


It is possible to activate layout process in GraphStream with Viewer#enableAutoLayout(). Unfortunately, this process will tamper each user interaction like node dragging.

Is is possible to do automatic layout once and then stop?

I have tried to turn autolayout for a second and wait, but this didn't work.

package tests.graphstream;

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import org.graphstream.graph.Graph;
import org.graphstream.graph.implementations.SingleGraph;
import org.graphstream.ui.swingViewer.View;
import org.graphstream.ui.swingViewer.Viewer;

public class Tutorial1_01 {

    private static Graph graph = new SingleGraph("Tutorial 1");

    public static class MyFrame extends JFrame {

        private static final long serialVersionUID = 8394236698316485656L;

        //private Graph graph = new MultiGraph("embedded");
        private Viewer viewer = new Viewer(graph, Viewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD);
        //private Viewer viewer = new Viewer(graph, Viewer.ThreadingModel.GRAPH_IN_SWING_THREAD);
        private View view = viewer.addDefaultView(false);
        private View defaultView  = viewer.getDefaultView();

        public MyFrame() {

             setLayout(new BorderLayout());

             //add( new JScrollPane(defaultView), BorderLayout.CENTER);

             add(defaultView, BorderLayout.CENTER);

             setDefaultCloseOperation(EXIT_ON_CLOSE);

        }

    }

    public static void main(String args[]) {

        SwingUtilities.invokeLater(new Runnable() {

            public void run() {


                MyFrame frame = new MyFrame();


                frame.setSize(320, 240);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                graph.addNode("A");
                graph.addNode("B");
                graph.addNode("C");
                graph.addEdge("AB", "A", "B");
                graph.addEdge("BC", "B", "C");
                graph.addEdge("CA", "C", "A");

                graph.addAttribute("ui.quality");
                graph.addAttribute("ui.antialias");


                frame.viewer.enableAutoLayout();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
                frame.viewer.disableAutoLayout();

                //frame.view.getCamera().resetView();
            }
        });





    }
}

回答1:


One (but surely not the best) solution is to compute the layout inside your run method.

First create an instance of the layout class and plug it to the graph before modifying the graph.

Then compute the layout until some stop condition. A fix amount of iterations is a safe choice in terms of computation but may not give you good results. Instead you can iterate up until the layout stabilizes by itself (which may never happen depending on your graph...)

public void run() {
    MyFrame frame = new MyFrame();

    frame.setSize(320, 240);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);

    // a layout algorithm instance plugged to the graph
    Layout layout = new SpringBox(false);
    graph.addSink(layout);
    layout.addAttributeSink(graph);

    graph.addNode("A");
    graph.addNode("B");
    graph.addNode("C");
    graph.addEdge("AB", "A", "B");
    graph.addEdge("BC", "B", "C");
    graph.addEdge("CA", "C", "A");

    graph.addAttribute("ui.quality");
    graph.addAttribute("ui.antialias");

    // iterate the compute() method a number of times
    while(layout.getStabilization() < 0.9){
        layout.compute();
    }   
}


来源:https://stackoverflow.com/questions/28250584/how-to-layout-nodes-once-in-graphstream

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!