2
votes

I'm trying to take a chart created by flot and render it to PDF using wkhtmltopdf.

To do that I grab the HTML within the div containing the chart and pass it back to the server.

I find that in the PDF I only get the axes showing and not the actual chart.

When seen in the browser the chart looks like this :

enter image description here

But the same image when rendered by wkhtmltopdf looks like this: enter image description here

I've included the flot/examples/examples.css in both templates .

The HTML passed to wkhtmltopdf looks like this :

<body>
  <h2>Incidents per 100 Workers</h2>
  <p>This is the test output</p>
        <div id="content">
                <div class="demo-container">
                        <div id="placeholder" class="demo-placeholder">
            <canvas height="450" width="850" style="direction: ltr; position: absolute; left: 0px; top: 0px; width: 850px; height: 450px;" class="flot-base"></canvas><div style="position: absolute; top: 0px; left: 0px; bottom: 0px; right: 0px; font-size: smaller; color: rgb(84, 84, 84);" class="flot-text"><div style="position: absolute; top: 0px; left: 0px; bottom: 0px; right: 0px; display: block;" class="flot-x-axis flot-x1-axis xAxis x1Axis"><div class="flot-tick-label tickLabel" style="position: absolute; max-width: 106px; top: 431px; left: 23px; text-align: center;">0</div><div class="flot-tick-label tickLabel" style="position: absolute; max-width: 106px; top: 431px; left: 144px; text-align: center;">2</div><div class="flot-tick-label tickLabel" style="position: absolute; max-width: 106px; top: 431px; left: 265px; text-align: center;">4</div><div class="flot-tick-label tickLabel" style="position: absolute; max-width: 106px; top: 431px; left: 386px; text-align: center;">6</div><div class="flot-tick-label tickLabel" style="position: absolute; max-width: 106px; top: 431px; left: 507px; text-align: center;">8</div><div class="flot-tick-label tickLabel" style="position: absolute; max-width: 106px; top: 431px; left: 624px; text-align: center;">10</div><div class="flot-tick-label tickLabel" style="position: absolute; max-width: 106px; top: 431px; left: 745px; text-align: center;">12</div></div><div style="position: absolute; top: 0px; left: 0px; bottom: 0px; right: 0px; display: block;" class="flot-y-axis flot-y1-axis yAxis y1Axis"><div class="flot-tick-label tickLabel" style="position: absolute; top: 418px; left: 2px; text-align: right;">-1.5</div><div class="flot-tick-label tickLabel" style="position: absolute; top: 348px; left: 2px; text-align: right;">-1.0</div><div class="flot-tick-label tickLabel" style="position: absolute; top: 279px; left: 2px; text-align: right;">-0.5</div><div class="flot-tick-label tickLabel" style="position: absolute; top: 209px; left: 6px; text-align: right;">0.0</div><div class="flot-tick-label tickLabel" style="position: absolute; top: 140px; left: 6px; text-align: right;">0.5</div><div class="flot-tick-label tickLabel" style="position: absolute; top: 70px; left: 6px; text-align: right;">1.0</div><div class="flot-tick-label tickLabel" style="position: absolute; top: 1px; left: 6px; text-align: right;">1.5</div></div></div><canvas height="450" width="850" style="direction: ltr; position: absolute; left: 0px; top: 0px; width: 850px; height: 450px;" class="flot-overlay"></canvas>
            </div>
                </div>
        </div>
</body>
</html>

Anyone got any ideas what might cause this ?

Thanks


ANSWER !

As mentioned by Ryley below it's not good enough to squirt the HTML back to the server as the canvas on which most of the chart is 'written' is then lost .

Instead I did this :

//fplotChart is the value returned by calling 
//the fPlot .plot() function
var fplotChartCanvas = fplotChart.getCanvas();
valueToSubmitToServer = fplotChartCanvas.toDataURL();

And once the value was back on the server I then used 'valueToSubmitToServer' as a 'src' in an IMG element

<img id="chart1" src="{{ pdf_inject_canvas_url }}">

This worked just fine except that the original background colouration was lost - for my purposes that was just fine as I didn't want it anyway.

2

2 Answers

2
votes

Flot uses a canvas element to render the graph itself, and positioned html divs to display the labels. I would guess the version of wkhtmltopdf you are using does not support canvas elements. I have used a statically linked version of wkhtmltopdf 0.10.0 rc2 to successfully capture flot graphs into a pdf, so it is definitely possible. You'll have to track down a version that works for your platform.

1
votes

I've had this same issue a number of times. It's caused by some missing dependencies that wkhtmltopdf uses to render canvas spaces (I imagine because they're graphics-accelerated content). I can't recall exactly what is missing, but wkhtmltopdf will probably be writing some useful debug info to stdout or to the logs of whatever is calling it. It might be something to do with the X server environment or QT dependencies, but as I said the best thing is to check the logs.

Parsing the canvas out to a dataURL is fine, except that if you need to support legacy IE versions (<= IE8)