How to export a graph as PDF
Questions & AnswersSummary
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:
- Use
Java compatible styles / on the client side andJavaCompatGraphMLIOHandler
Graph2DRoundtripSupport
on the server side. This way the graph created and parsed by theGraph2DRoundtripSupport
is already aGraph2D
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. - 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 noGraph2D
but uses style beans to store the visual information. Before creating the scalable image it has to be copied to aGraph2D
using GraphCopier and a customizedGraphCopyFactory
. 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 theJavaExportDemo
and theExportStyledGraphServlet
using aStyledToGraph2DCopyFactory
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 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).