Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wkhtmltopdf does not render Chart.JS 2.5.0 graph

Using:
WKpdftohml version 0.12.3.2
PHPwkhtmltopdf version 2.2.0
Chart.JS version 2.5.0

I'm trying to print a line graph using the above libraries. I can reproduce a pdf using the shell command: wkhtmltopdf --javascript-delay 5000 " http://netdna.webdesignerdepot.com/uploads7/easily-create-stunning-animated-charts-with-chart-js/chartjs-demo.html" test2.pdf
So there is no problem with WKhtmltopdf.

The problem is when I do it in my app, using the PHPwkhtmltopdf library. I get a blank page.
From my research these are the things I tried:

  • Added 'javascript-delay' => 500 to Chart.JS options;
  • Added animation:{onComplete: function () {window.JSREPORT_READY_TO_START =true} to Chart.JS options;
  • Added <div style="width:800px;height:200;font-size:10px;"> to the parent div of canvas html tag
  • Added ctx.canvas.width = 800;ctx.canvas.height = 200; to javascript initialization of the chart.

Well nothing worked. I love Chart.JS and WKhtmltopdf, but if I cant print I'll have to drop one of them. Is there any solution?

This is my php code for the PHPwkhtmltopdf:

public function imprimir ($request, $response)
{
    // include_once 'config/constants.php';
    // include_once 'resources/auxiliar/helpers.php';

    $folha = $_POST['printit'];
    $variaveis = explode(',', $folha);

    $nomeFicheiro = $variaveis[0];

    $printName = substr($nomeFicheiro, 5);

    if (isset($variaveis[2])) {

        $_SESSION['mesNumero'] = $variaveis[2];
        $_SESSION['mes'] = $variaveis[1];

    } else {

        $mesNumero = 0;
        $mes = '';

    }

    ob_start();
    if ($nomeFicheiro == 'printPpiam') {
        require ('C:/xampp/htdocs/.../'.$nomeFicheiro.'.php');
    } else {
        require ('C:/xampp/htdocs/.../'.$nomeFicheiro.'.php');
    }
    $content = ob_get_clean();

    // You can pass a filename, a HTML string, an URL or an options array to the constructor
    $pdf = new Pdf($content);

    // On some systems you may have to set the path to the wkhtmltopdf executable
    $pdf->binary = 'C:/Program Files/wkhtmltopdf/bin/wkhtmltopdf';

    $pdf -> setOptions(['orientation' => 'Landscape',
                        'javascript-delay' => 500,
                        // 'enable-javascript' => true,
                        // 'no-stop-slow-scripts' => true]
                    ]);

    if (!$pdf->send($printName.'.pdf')) {
        throw new Exception('Could not create PDF: '.$pdf->getError());
    }

    $pdf->send($printName.'.pdf');

}  

# Update 1
Made a php file with the page output. Run it in the browser and the graph rendered. When I do it in the console it renders everything except the graph!
How can it be wkhtmltopdf renders the graphics in this page : http://netdna.webdesignerdepot.com/uploads7/easily-create-stunning-animated-charts-with-chart-js/chartjs-demo.html but not my own?!

like image 550
Luís Alves Avatar asked Mar 02 '17 16:03

Luís Alves


2 Answers

Here's the code that works with wkhtmltopdf version 0.12.5:

chart.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<style>
    .reportGraph {width:900px}
</style>
</head>
<body>

<div class="reportGraph"><canvas id="canvas"></canvas></div>

<script type="text/javascript">
// wkhtmltopdf 0.12.5 crash fix.
// https://github.com/wkhtmltopdf/wkhtmltopdf/issues/3242#issuecomment-518099192
'use strict';
(function(setLineDash) {
    CanvasRenderingContext2D.prototype.setLineDash = function() {
        if(!arguments[0].length){
            arguments[0] = [1,0];
        }
        // Now, call the original method
        return setLineDash.apply(this, arguments);
    };
})(CanvasRenderingContext2D.prototype.setLineDash);
Function.prototype.bind = Function.prototype.bind || function (thisp) {
    var fn = this;
    return function () {
        return fn.apply(thisp, arguments);
    };
};

function drawGraphs() {
    new Chart(
        document.getElementById("canvas"), {
            "responsive": false,
            "type":"line",
            "data":{"labels":["January","February","March","April","May","June","July"],"datasets":[{"label":"My First Dataset","data":[65,59,80,81,56,55,40],"fill":false,"borderColor":"rgb(75, 192, 192)","lineTension":0.1}]},
            "options":{}
        }
    );
}
window.onload = function() {
    drawGraphs();
};
</script>
</body>
</html>

Run:

$ wkhtmltopdf chart.html chart.pdf:

Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
like image 148
temuri Avatar answered Oct 09 '22 05:10

temuri


Found the answer. After I created a separate file, outside the framework, i did some tests again. It rendered the graph in the browser so I tried to use the command tool WKhtmltopdf, and it did not worked, when it did with other examples (see Update #1). So there is something wrong with my php page.
Ran the same tests that I did in the framework, and got the answer for my problem. By introducing a parent div tag width dimensions in the canvas tag it made the graph render in the page.

<div style="width:800px;height:200;">
    <canvas id="myChart" style="width:800px;height:200;"></canvas>
</div>

The proposition was found in this site: Github, so thanks laguiz.

like image 15
Luís Alves Avatar answered Oct 09 '22 03:10

Luís Alves