Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

writing JUNG graphs to images: can't reliably render complete graph

Tags:

java

image

jung

I've been using JUNG to visualize some simple graphs, and I'd like to write several of them to a PNG file. Unfortunately, the images often appear to render before the graph is finished painting, meaning that I get incomplete graphs -- that is, graphs where only a hanfdul of edges or nodes are drawn -- about half of the time. Rendering to screen works fine, which is part of why I'm so puzzled. As you'll see below, I tried a couple of workarounds, but they didn't help. It may be useful to know that the basicVisualizationServer I'm using won't paint anything useful to the BufferedImage directly -- I just get a black image when I try that.

Thanks!

  public void writeImage(String filename) {
    Layout layout = new CircleLayout<V, E>(jungGraph);
    layout.setSize(innerSize);
    bvs = new BasicVisualizationServer<V,E>(layout);
    float strokeWidth = 8f;
    bvs.getRenderContext().setVertexShapeTransformer(new ConstantTransformer(new Ellipse2D.Float(-24,-24,48,48)));
    bvs.getRenderContext().setArrowDrawPaintTransformer(new ConstantTransformer(Color.black));
    bvs.getRenderContext().setEdgeStrokeTransformer(new ConstantTransformer(new BasicStroke(strokeWidth)));
    bvs.getRenderContext().setEdgeArrowStrokeTransformer(new ConstantTransformer(new BasicStroke(strokeWidth)));
    bvs.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller<E>());
    bvs.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<V>());
    bvs.setPreferredSize(viewSize);
    //int width = bvs.getWidth(); // Always returns zero
    int width = viewFrame.getWidth();
    //int height = bvs.getHeight(); // Always returns zero
    int height = viewFrame.getHeight();

    BufferedImage bim = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    Graphics2D g = bim.createGraphics();
    viewFrame.paintAll(g);

    g.dispose();
    //this.viewFrame.paintComponents(g);
    //try{Thread.sleep(1000);} catch(Exception e) {throw new RuntimeException(e);} // Sleeping doesn't help.
    try {
        File f = new File(filename);
        ImageIO.write(bim,"png",f);
        System.out.println("wrote image for " + jungGraph + " to "+ filename+ ":" + f.toString());
        //try{Thread.sleep(500);} catch(Exception e) {throw new RuntimeException(e);} // Doesn't help
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
like image 268
Chris Avatar asked Oct 25 '22 18:10

Chris


1 Answers

You can also use VisualizationImageServer. It's a subtype of BasicVisualizationServer which adds a getImage method. I have had no trouble with it rendering the graphs properly.

Your code would then be like:

public void writeImage(String filename) {
    Layout layout = new CircleLayout<V, E>(jungGraph);
    layout.setSize(innerSize);
    bvs = new VisualizationImageServer<V,E>(layout);
    // [...]
    BufferedImage image = (BufferedImage)bvs.getImage();
}
like image 159
bashflyng Avatar answered Oct 27 '22 10:10

bashflyng