C3: PDF generation by wkhtmltopdf fails with c3 0.3.0

Created on 10 Sep 2014  ·  17Comments  ·  Source: c3js/c3

When using wkhtmltopdf to generate PDF documents from html with c3 charts, the latest version of c3 (0.3.0) makes wkhtmltopdf announce error "Warning: undefined:0 TypeError: 'undefined' is not a function". The resulting PDF shows blank space instead of a chart.

An older version of c3 used to generate the chart swimmingly. I've reproduced this with pie and bar chart types.

Full html, css & javascript package with wkhtmltopdf is at
http://burgan.whitevector.com/images/bug_report.zip

Full output of wkhtmltopdf:
shark@virshark:~/bug_report$ sh generate_pdf.sh
Loading pages (1/6)
Warning: undefined:0 TypeError: 'undefined' is not a function
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done

Most helpful comment

I suspect this is because wkhtmltopdf uses QtWebKit which has problems with Function.prototype.bind, a method used throughout the new version of c3. I had to tackle a similar issue myself when I wrote a phantomjs exporter. The solution is to add this little polyfill:

Function.prototype.bind = Function.prototype.bind || function (thisp) {
  var fn = this;
  return function () {
    return fn.apply(thisp, arguments);
  };
};

I'm not familiar with wkhtmltopdf but you'll need to run that code within the context of the page being rendered (just include it in the page before the c3 js files and it'll work)

All 17 comments

I suspect this is because wkhtmltopdf uses QtWebKit which has problems with Function.prototype.bind, a method used throughout the new version of c3. I had to tackle a similar issue myself when I wrote a phantomjs exporter. The solution is to add this little polyfill:

Function.prototype.bind = Function.prototype.bind || function (thisp) {
  var fn = this;
  return function () {
    return fn.apply(thisp, arguments);
  };
};

I'm not familiar with wkhtmltopdf but you'll need to run that code within the context of the page being rendered (just include it in the page before the c3 js files and it'll work)

Thank you! Inserting those 6 lines before other Javascripts solved the issue.

Thanks! This issue looks solved, so please let me close.

@yuvii
dwight-schrute-thank-you-cry-on-the-office

@yuvii you're awesome!
slothsome

I encountered the same issue but with vega / wkhtmltopdf. The solution by @yuvii worked like a charm. Thanks a lot!

@yuvii you are king!

@yuvii Thank you!!!!!

For googlers, @yuvii solved my generation issue with fullcalendar. I spent hours searching for a solution.
Thank you.

Awesome @yuvii . I got into the same issue when Google Maps API changed

Thanks a lot, this totally solved my django pdfkit issue!

Thank you @yuvii . I spent hours searching for a solution:
Drawing on canvas with Fabric.js > Html > wkhtmltopdf > .pdf file
Html in the browser was correct, but output .pdf file had blank canvas.

Looks like fabric.js has the same issue

I suspect this is because wkhtmltopdf uses QtWebKit which has problems with Function.prototype.bind, a method used throughout the new version of c3. I had to tackle a similar issue myself when I wrote a phantomjs exporter. The solution is to add this little polyfill:

Function.prototype.bind = Function.prototype.bind || function (thisp) {
  var fn = this;
  return function () {
    return fn.apply(thisp, arguments);
  };
};

I'm not familiar with wkhtmltopdf but you'll need to run that code within the context of the page being rendered (just include it in the page before the c3 js files and it'll work)

Thanks a lot, saved my day. Its worked for me with C3js. It's important to set the chart container width.

These comments are amazing. I don't code anymore, I left that world, but every now and then I visit this page, and watch in awe as a solution I found for a niche problem has helped _so many people_ for 5 years and going. It's crazy.

I suspect this is because wkhtmltopdf uses QtWebKit which has problems with Function.prototype.bind, a method used throughout the new version of c3. I had to tackle a similar issue myself when I wrote a phantomjs exporter. The solution is to add this little polyfill:

Function.prototype.bind = Function.prototype.bind || function (thisp) {
  var fn = this;
  return function () {
    return fn.apply(thisp, arguments);
  };
};

I'm not familiar with wkhtmltopdf but you'll need to run that code within the context of the page being rendered (just include it in the page before the c3 js files and it'll work)

Holly Molly, You will forever have a special place in my heart. Highchart graph were working properly on web browser but were not converted properly to PDF with Wkhtmltopdf. If someone is having the same problem simply add create that function before to call your highchart script. Finally found a solution after 4 hour. Also to be able to debug your problem with Wkhtmltopdf and Highchart dont forget to add those argument "wkhtmltopdf.exe --javascript-delay 10000 --no-stop-slow-scripts --enable-javascript --debug-javascript"

I suspect this is because wkhtmltopdf uses QtWebKit which has problems with Function.prototype.bind, a method used throughout the new version of c3. I had to tackle a similar issue myself when I wrote a phantomjs exporter. The solution is to add this little polyfill:

Function.prototype.bind = Function.prototype.bind || function (thisp) {
  var fn = this;
  return function () {
    return fn.apply(thisp, arguments);
  };
};

I'm not familiar with wkhtmltopdf but you'll need to run that code within the context of the page being rendered (just include it in the page before the c3 js files and it'll work)

Thank you very much I just plugged in above 6 lines and it works with the hight chart, was debugging it for almost 3 - 4 hrs.

I suspect this is because wkhtmltopdf uses QtWebKit which has problems with Function.prototype.bind, a method used throughout the new version of c3. I had to tackle a similar issue myself when I wrote a phantomjs exporter. The solution is to add this little polyfill:

Function.prototype.bind = Function.prototype.bind || function (thisp) {
  var fn = this;
  return function () {
    return fn.apply(thisp, arguments);
  };
};

I'm not familiar with wkhtmltopdf but you'll need to run that code within the context of the page being rendered (just include it in the page before the c3 js files and it'll work)

Saved my day. Was struggling for days together :+1:

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Zerim picture Zerim  ·  3Comments

u119102 picture u119102  ·  3Comments

jstone-ponderosa picture jstone-ponderosa  ·  3Comments

laurentdebricon picture laurentdebricon  ·  3Comments

MarcusJT picture MarcusJT  ·  4Comments