Search code examples
javaswingvector-graphicsjung

Exporting JUNG graphs to hi-res images (preferably vector based)


In one of my projects I use JUNG2 to visualize a very large multiple-parent hierarchy graph, displayed in an applet. I would need to export the whole/parts of the graph to high resolution still images, since screenshots look hideous when printed (especially if the graph has been zoomed out).

The code I use currently is as follows:

public void writeToDisk(File saveToFolder, String filename) {
    //Dimension loDims = getGraphLayout().getSize();
    Dimension vsDims = getSize();

    int width = vsDims.width;
    int height = vsDims.height;
    Color bg = getBackground();

    BufferedImage im = new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
    Graphics2D graphics = im.createGraphics();
    graphics.setColor(bg);
    graphics.fillRect(0,0, width, height);
    paintComponent(graphics);

    try{
       ImageIO.write(im,"png",new File(saveToFolder,filename));
    }catch(Exception e){
        e.printStackTrace();
    }
}

This creates PNG images which are not particularly high resolution. So my questions are as follows:

  1. Is it possible to push up the PNG export resolution to 300 dpi?
  2. Is it possible to export the graph, or any swing component for that matter, to vector based formats such as EPS, PDF or SVG without too much hassle? I have found several libraries (VectorGraphics2D,FreeHEP) for managing vector based images in Java, however I am not sure if using them would mean that I have to "re-draw" each vertex and edge in the graph. That's obviously not very desirable...
  3. Are there any other alternatives which I might have missed?

Thanks in advance,


Solution

  • Thanks for the suggestions but I have managed to get FreeHEP Vector Graphics library working the way I want to. I am sharing the code below in case anyone runs into the same questions.

    The above-named library has a very nice built-in export menu, which handles the export to a bunch of different formats. Code excerpt from the modified ´ModelGraphMouse´ class:

    protected void handlePopup(MouseEvent e) {
            final VisualizationViewer<MyNode, MyEdge> vv = (VisualizationViewer<MyNode, MyEdge>)e.getSource();
            Point2D p = e.getPoint();
            GraphElementAccessor<MyNode, MyEdge> pickSupport = vv.getPickSupport();
            if(pickSupport != null) {
                final MyNode v = pickSupport.getVertex(vv.getGraphLayout(), p.getX(), p.getY());
    
                // if clicked on a vertex -> show info popup
                // else show contexual menu
                if(v != null) {
                    JFrame popup = new JFrame("Node: " + v.getId());
                    popup.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                    ...
                } else{
                    JPopupMenu menu = new JPopupMenu();
                    JMenuItem exportGraphMenuItem = new JMenuItem("Export graph to vector image...");
                    exportGraphMenuItem.addActionListener(new ExportActionListener((WritingVisualizationViewer<V, E>) vv));
                    menu.add(exportGraphMenuItem);
                    menu.show(e.getComponent(), e.getX(), e.getY());
                } 
            }
        }
    

    and the action listener:

        public class ExportActionListener implements ActionListener{
    
        private VisualizationViewer<V, E> wvv;
        public ExportActionListener(VisualizationViewer<V, E> vv) {
            this.wvv = vv;
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            ExportDialog export = new ExportDialog();
            export.showExportDialog(wvv, "Export view as ...", wvv, "export");
        }
    }