Search code examples
jung

JUNG - Get position of vertex and save using Graphml


I'm trying to change a layout from CircleLayout to StaticLayout, keeping the positions of the Vertex, to do this im using the following code:

    StaticLayout<VertexType, EdgeType> sLayout = new StaticLayout<VertexType, EdgeType>(graph,
                new Transformer<VertexType, Point2D>() {
                    public Point2D transform(VertexType vertex) {
                        vertex.setX(layout.getX(vertex));
                        vertex.setY(layout.getY(vertex));
                        System.out.println(vertex.toString());
                        System.out.println(vertex.getX());
                        System.out.println(vertex.getY());
                        Point2D p = new Point2D.Double(vertex.getX(), vertex.getY());
                        return p;
                    }
                }, dimension);
        currentVV.setGraphLayout(sLayout);

Where currentVV is a VisualizationViewer and layout is a CircleLayout. setX(double) and setY(double) are methods from my custon Vertex, by default the vertex is initializated with x = 0.0 an y = 0.0. In this stage I used teh println to check if all vertex get their positions correctly and it is working. The next step is to save the graph using the GraphmlWritter:

    GraphMLWriter<VertexType, EdgeType> graphWriter = new GraphMLWriter<VertexType, EdgeType>();
        PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(fileName)));
        graphWriter.addEdgeData("label", null, "0", new Transformer<EdgeType, String>() {
            @Override
            public String transform(EdgeType v) {
                return v.toString();
            }
        });
        graphWriter.addVertexData("x", null, "0", new Transformer<VertexType, String>() {
            public String transform(VertexType v) {
                return Double.toString(v.getX());
            }
        });
        graphWriter.addVertexData("y", null, "0", new Transformer<VertexType, String>() {
            public String transform(VertexType v) {
                return Double.toString(v.getY());
            }
        });
        graphWriter.save(graph, out);

The problems is that while most of the vertexes are being saved sucessfully, some of the vertexes are being saved with the default values to X and Y (0.0), and I have no idea why. If I try to save the graph from directly from the CircleLayout getting the X and Y values from the layout with:

    GraphMLWriter<VertexType, EdgeType> graphWriter = new GraphMLWriter<VertexType, EdgeType>();
        PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(fileName)));
        graphWriter.addEdgeData("label", null, "0", new Transformer<EdgeType, String>() {
            @Override
            public String transform(EdgeType v) {
                return v.toString();
            }
        });
        graphWriter.addVertexData("x", null, "0", new Transformer<VertexType, String>() {
            public String transform(VertexType v) {
                return Double.toString(layout.getX(v));
            }
        });
        graphWriter.addVertexData("y", null, "0", new Transformer<VertexType, String>() {
            public String transform(VertexType v) {
                return Double.toString(layout.getY(v));
            }
        });

While this solution helps I would prefer to save the X and Y values on the vertex as it will be used for future implementations. Anyone knows where I'm missing the position info? Thanks.


Solution

  • I'm not immediately sure where the bug in your code is.

    First question: why are you trying to convert a CircleLayout to a StaticLayout? What does that buy you?

    Assuming that this is actually what you need to do, you don't need to serialize it at all; you can initialize any AbstractLayout subclass with the positions of any other Layout instance, because a Layout is (among other things a Function<V, Point2D>, which means you can pass it to an AbstractLayout instance as an "initializer". Thus, for example:

    CircleLayout<V, E> circleLayout = ...
    ...
    StaticLayout<V, E> staticLayout = new StaticLayout(graph, circleLayout);