How to export a graph as PDF

Questions & Answers

Summary

This article describes how the yExport extension package can be used to export a yFiles FLEX graph to a vector graphics file format.

Description

The graph which is displayed on a yFiles FLEX client can easily be exported into a bitmap image format using an ImageExportHandler. Exporting the graph into a vector based file format, though, is not supported. The server side yFiles for Java library, however, offers the posibility to export a graph into vector based formats like SVG, SWF, EPS, EMF and PDF using the extension packages ySVG and yExport. This article shows how to use these extension packages together with a yFiles FLEX client.

Prerequisites

To export the graph, the extension packages use an y.io.IOHandler which writes the image file into an output stream. To do so, these handlers render the graph internally. That means, the graph has to be rendered on the server side, thus we have to use realizers / Graph2D on the server side.

There are two ways to create a Graph2D that can be exported:

  1. Use Java compatible styles / JavaCompatGraphMLIOHandler on the client side and Graph2DRoundtripSupport on the server side. This way the graph created and parsed by the Graph2DRoundtripSupport is already a Graph2D and can be exported. The drawback is that if the built in realizers are not sufficient to display the nodes, a customized realizer has to be created on the client and on the server. See the article Displaying Custom yFiles Java Realizers in yFiles FLEX for more details.

  2. Use normal styles on the client and send the graph as yFiles FLEX GraphML to the server. This way the graph created and parsed by the GraphRoundtripSupport is no Graph2D but uses style beans to store the visual information. Before creating the scalable image it has to be copied to a Graph2D using GraphCopier and a customized GraphCopyFactory. For custom styles customized realizers have to be created to map the styles to.
    This approach is facilitated using yFiles FLEX 1.4 or later as it contains the JavaExportDemo and the ExportStyledGraphServlet using a StyledToGraph2DCopyFactory that demonstrates what's to do on a basic example.

Client side

If we want to create a PDF (or other vector based format) file on the server and save it on the client's local file system, the DownloadHandler is our choice. It displays a download dialog that allows the user to select a download destination. If the user choses a file, the graph is sent to the server and the response is saved to the selected location. The handler's additionalParameters allow to send additional parameters to configure the output. Also, a RoundtripHandler is used as a factory for an output IOHandler, allowing easy configuration. The following code snippet shows a basic configuration.

private function exportPDF():void { // The RoundtripHandler is used as factory for the output IOHandler var roundtrip:RoundtripHandler = new RoundtripHandler(graphCanvas, null, GraphCanvasComponent.OPTION_COPY_ALL); // If using Java compatible styles the OutputIOHandler has to be replaced // by a JavaCompatGraphMLIOHandler. Otherwise this line can be skipped. roundtrip.outputIOHandler = new JavaCompatGraphMLIOHandler(true); var handler:DownloadHandler = new DownloadHandler("http://localhost:8080/yfiles-flex/exportpdf", roundtrip); // configuring, however, can be done using the additional parameters as shown below // these parameters have to be parsed at server side // in this example, the parameter orientation with the value "LANDSCAPE" // or "PORTRAIT" will be sent. var params:Object = new Object(); if (landscape) { params.orientation = "LANDSCAPE"; } else { params.orientation = "PORTRAIT"; } handler.additionalParameters = params; // Display the browser's download dialog and send the request after // the user has chosen a file handler.download(graphCanvas.graph, "export.pdf"); }

Server side

On the server side we need a servlet which reads the GraphML which is sent from the client and uses an export handler (to stay with our example: yext.export.io.PDFOutputHandler) to write the exported file into the response's output stream.

If yFiles Java GraphML is sent to the server, reading is done using Graph2DRoundtripSupport: Graph2DRoundtripSupport support = new Graph2DRoundtripSupport(); Graph2D graph = (Graph2D) support.createRoundtripGraph(); support.readGraph(getGraphInputStream(httpServletRequest), graph); Otherwise a GraphRoundtripSupport is used to read the graph and a GraphCopier to copy it into a Graph2D: GraphRoundtripSupport support = new GraphRoundtripSupport(); LayoutGraph graph = support.createRoundtripGraph(); support.readGraph(getGraphInputStream(httpServletRequest), graph); // Create the Graph2D to copy the LayoutGraph into final Graph2D exportGraph = new Graph2D(); // copy the graph using a GraphCopier and custom GraphCopyFactories. final GraphCopier graphCopier = new GraphCopier( new Graph2DCopyFactory.HierarchicGraph2DCopyFactory( new MyLayoutGraphToGraph2DCopyFactory())); graphCopier.setNodeMapCopying(true); graphCopier.setEdgeMapCopying(true); graphCopier.setDataProviderContentCopying(true); graphCopier.copy(graph, exportGraph);

The class MyLayoutGraphToGraph2DCopyFactory refered to in the example has to lookup the styles assigned to the original graph and create and set appropriate realizer on the export graph. The StyledToGraph2DCopyFactory available from yFiles FLEX 1.4 on shows the basic approach what's to do to copy a StyledLayoutGraph to a Graph2D.

The output can be configured using the parameters which are sent with the request. In our example, we determine the page orientation by evaluating the "orientation" parameter. See the documentation and source code examples of yExport for further configuration options. String orientation = httpServletRequest.getParameter("orientation"); PageFormat pageFormat = new PageFormat(); if ("LANDSCAPE".equals(orientation)) { pageFormat.setOrientation(PageFormat.LANDSCAPE); } else { pageFormat.setOrientation(PageFormat.PORTRAIT); } ... handler.setPageFormat(pageFormat); // handler is a PDFOutputHandler instance

The resulting output can be written into the response. It will be saved by the DownloadHandler into the file chosen by the user as download location. httpServletResponse.setContentType("application/pdf"); httpServletResponse.setHeader("Content-Disposition", "attachment"); httpServletResponse.setStatus(HttpServletResponse.SC_OK); PDFOutputHandler handler = new PDFOutputHandler(); handler.write(graph, httpServletResponse.getOutputStream());

Example code

The example code this article is based on is available as resource attached to this article:

  • PDFExportDemo.mxml: The client side source code.
  • PdfExportServlet.java: The server side source code.
  • snip_web.xml: The servlet mappings to insert into the deployment descriptor (web.xml).

Resources

Categories this article belongs to:
yFiles FLEX > yFiles FLEX Java Server API > Servlets
yFiles FLEX > Input and Output
yFiles FLEX > Using yFiles FLEX with a yFiles Server > Communicating with yFiles Java on the Server
Applies to:
yFiles FLEX: 1.4, 1.5, 1.6, 1.7, 1.8
Keywords:
export - pdf - vector graphics - yExport