@Override public void writeOutput(VisualizerInput input, OutputStream outstream) { this.input = input; AnnisResult result = input.getResult(); List<AbstractImageGraphicsItem> layouts = new LinkedList<AbstractImageGraphicsItem>(); double width = 0; double maxheight = 0; for (DirectedGraph<AnnisNode, Edge> g : graphtools.getSyntaxGraphs(input)) { if (g.getEdgeCount() > 0 && g.getVertexCount() > 0) { ConstituentLayouter<AbstractImageGraphicsItem> cl = new ConstituentLayouter<AbstractImageGraphicsItem>(g, backend, labeler, styler, input); AbstractImageGraphicsItem item = cl.createLayout( new LayoutOptions( VerticalOrientation.TOP_ROOT, AnnisGraphTools.detectLayoutDirection(result.getGraph()))); Rectangle2D treeSize = item.getBounds(); maxheight = Math.max(maxheight, treeSize.getHeight()); width += treeSize.getWidth(); layouts.add(item); } } BufferedImage image = new BufferedImage( (int) (width + (layouts.size() - 1) * TREE_DISTANCE + 2 * SIDE_MARGIN), (int) (maxheight + 2 * TOP_MARGIN), BufferedImage.TYPE_INT_ARGB); Graphics2D canvas = createCanvas(image); double xOffset = SIDE_MARGIN; for (AbstractImageGraphicsItem item : layouts) { AffineTransform t = canvas.getTransform(); Rectangle2D bounds = item.getBounds(); canvas.translate(xOffset, TOP_MARGIN + maxheight - bounds.getHeight()); renderTree(item, canvas); xOffset += bounds.getWidth() + TREE_DISTANCE; canvas.setTransform(t); } try { ImageIO.write(image, "png", outstream); } catch (IOException e) { throw new RuntimeException(e); } }