Search code examples
svgvaadinbatikvaadin-charts

IText, batik and vaadin charts scales wrong on linux


I've been having some trouble getting my charts out to PDF. Recently i posted this: Generating PDF with iText and batik which was solved as suggested with some tweaking to the scales.

I run amy testenviroment on a local glassfishserver on a windows 10 machine, and when I export to PDF I actually get a pretty result now.

Windows result

But when I pushed the results to the RHEL server, the results differed. The charts shown on the website is great, but when I export to pdf, I get this:

Linux result

As you can see, the title is pushed down, for some reason the Y-axis with labels are cropped, and the data-labels are squished together. I've tried playing around with different scales, with and without scaletofit, scaletoabsolute and so on, but no matter what I do, it keeps doing that weird thing.

Does anybody has any idea whats going on - and even better, how to fix it? I've doublechecked that phantomjs is the same version, to make sure the SVG is the right one-.

The code is as follows:

private Image createSvgImage(PdfContentByte contentByte, Chart chart) throws IOException {
    Configuration configuration = chart.getConfiguration();
    configuration.setExporting(false);
    SVGGenerator generator = SVGGenerator.getInstance();
    generator.withHeigth(600);
    generator.withWidth(1200);
    String svg = generator.generate(configuration);
    Image image = drawUnscaledSvg(contentByte, svg);
    image.scaleToFit(800, 370);
    configuration.setExporting(true);
    return image;
}


    private Image drawUnscaledSvg(PdfContentByte contentByte, String svgStr) throws IOException {
    GraphicsNode imageGraphics = buildBatikGraphicsNode(svgStr);

    float width = 1200;
    float height = 600;
    PdfTemplate template = contentByte.createTemplate(width, height);
    Graphics2D graphics = template.createGraphics(width, height);
    try {

        imageGraphics.paint(graphics);
        graphics.translate(-10, -10);

        return new ImgTemplate(template);
    } catch (BadElementException e) {
        throw new RuntimeException("Couldn't generate PDF from SVG", e);
    } finally {
        graphics.dispose();
    }
}


    private GraphicsNode buildBatikGraphicsNode(String svgStr) throws IOException {
      UserAgent agent = new UserAgentAdapter();

        SVGDocument svgdoc = createSVGDocument(svgStr, agent);
        DocumentLoader loader = new DocumentLoader(agent);
        BridgeContext bridgeContext = new BridgeContext(agent, loader);
        bridgeContext.setDynamicState(BridgeContext.STATIC);

        GVTBuilder builder = new GVTBuilder();

        GraphicsNode imageGraphics = builder.build(bridgeContext, svgdoc);
        return imageGraphics;
}


    private SVGDocument createSVGDocument(String svg, UserAgent agent)
        throws IOException {
    SVGDocumentFactory documentFactory = new SAXSVGDocumentFactory(
            agent.getXMLParserClassName(), true);

    SVGDocument svgdoc = documentFactory.createSVGDocument(null,
            new StringReader(svg));
    return svgdoc;
}

UPDATE I've tried reading a SVG file from disk, that I knew was correct, and that is put correctly within the PDF. So the problem lies somewhere within the SVG Generator. Anyone knows about this?


Solution

  • Using an older version of PhantomJS (1.9.8) fixes the problem. I've made a ticket with Vaadin.