Search code examples
javagraphstream

graphstream using "always-on" autolayout


I was playing around with graphstream with a small compiler I'm writing to create an Abstract-Syntax-Tree visualization, like this:

     // ASTNode is the root to to the AST tree. Given that node, this just displays
     // the AST on-screen.
     public static void visualize(ASTNode ast) throws IOException, URISyntaxException {
        Path file = Path.of(VisualizeAbstractSyntaxTree.class.getResource("graph.css").toURI());
        String css = Files.readString(file);
        System.setProperty("org.graphstream.ui.renderer", "org.graphstream.ui.j2dviewer.J2DGraphRenderer");
        Graph graph = new SingleGraph("AST");
        graph.addAttribute("ui.stylesheet", css);
        construct(ast, "0", graph);  // construct the tree from the AST root node.
        Viewer viewer = graph.display();
    }

Running the program shows the auto positioning magic. However, when a node is dragged by the mouse the other nodes remain stationary. Is there an easy way to get the other nodes to react (also pulled) if a node is dragged with the mouse?

This must be supported, but I cannot seem to find any examples or API references to this?


Solution

  • I don't know the code behind your function but usually it's automatic with the default viewer. You can try to force the activation of the autolayout with :

    viewer.enableAutoLayout();
    

    You can find some documentation in the website.

    If the autolayout works but just stop suddenly, it's perhaps the parameter of the layout algorithm that doesn't suit you. Layout algorithms are written to stop when they reach their stabilization point, but you can change this.

    You just have to define a new instance of the layout algorithm that you prefer and use it :

    SpringBox l = new SpringBox();
    

    Then you can define the parameter, like the force or the stabilization point. The convention is that the value 0 means that the process controlling the layout will not stop the layout (will therefore not consider the stabilization limit). In other words the layout will compute endlessly. :

    l.setStabilizationLimit(0);
    

    But please keep in mind that if you want to use your instance of layout algorithm, you are going to create your viewer before the display. And that implies to build your own ui. Here an easy example, you can find more on the official github :

    SpringBox l = new SpringBox(); // The layout algorithm
    l.setStabilizationLimit(0);
    
    Viewer viewer = new Viewer(graph, Viewer.ThreadingModel.GRAPH_IN_GUI_THREAD);
    viewer.enableAutoLayout(l); // Add the layout algorithm to the viewer
    
    // Build your UI
    add(viewer.addDefaultView(false), BorderLayout.CENTER); // Your class should extends JFrame
    setSize(800, 600);
    setVisible(true);