canvg cannot call a class as a function

1.6k Views Asked by At

For a project I am working on I need to transform a svg to png file. In order to do so I have found multiple guides and explanations online. One of these can be found here: Exporting D3 charts to PDF

In order to transform the svg to a png they use the following code:

let canvas = document.createElement('canvas');
canvg(canvas, svg);
let imgData = canvas.toDataURL('image/png');

But I keep on getting an error when I try to implement this in my own project: "TypeError: Cannot call a class as a function". I have found multiple explanations online where they use the canvg(canvas, svg); notation. I also have read the Github documentation form Canvg and found nothing about this type of notation or an alternative way to do this.

The way I import the package into my project is as follows:

import canvg from "canvg";

This is the full code I am using to convert my d3 svg chart to a pdf:

    exportToPDF() {
      let svg = document.getElementsByClassName("svg")[0].innerHTML;
      var canvas = document.createElement("canvas");

      canvg(canvas, svg);
      let imgData = canvas.toDataURL("image/png");

      var doc = new jsPDF("l", "pt", [1020, 768]);
      doc.addImage(imgData, "PNG", 0, 0, 1020, 768);
      doc.save("svg-png-chart.pdf");
    }
2

There are 2 best solutions below

0
Stephen On BEST ANSWER

I have a found the solution. The fix was also thanks to DDomen. He got me on the right path. canvg.fromString(context, svg) should be used in order to get the transform the svg to a png.

But then the next problem would arise that the dimensions need to be set on the canvas in order to have the imaged being cropped when it is bigger then the default dimensions of a canvas object.

    exportToPDF() {
      let svgElement = document.getElementsByClassName("svg")[0];
      const width = svgElement.getBoundingClientRect().width;
      const height = svgElement.getBoundingClientRect().height;
      let svg = svgElement.innerHTML;
      let canvas = document.createElement("canvas");
      let context = canvas.getContext("2d");
      canvas.width = width;
      canvas.height = height;

      let v = canvg.fromString(context, svg);
      v.start();

      let imgData = canvas.toDataURL("image/png");

      var doc = new jsPDF("l", "pt", [1020, 768]);
      doc.addImage(imgData, "PNG", 0, 0, width, height);
      doc.save("svg-png-chart.pdf");
    }
0
DDomen On

The error is clear, you are calling the class canvg without the new keyword.

Also, you referred to the GitHub Documentation where there is clearly write how to use it:

window.onload = () => {

    const canvas = document.querySelector('canvas');
    const ctx = canvas.getContext('2d');
    
    // ==== HERE YOUR FUNCTION ===
    v = canvg.Canvg.fromString(ctx, '<svg width="600" height="600"><text x="50" y="50">Hello World!</text></svg>');

    // Start SVG rendering with animations and mouse handling.
    v.start();

};

Probably the article you read Exporting D3 charts to PDF was refering to an older API of Canvg

This should do:

exportToPDF() {
      let svg = document.getElementsByClassName("svg")[0].innerHTML;
      let canvas = document.createElement("canvas");
      let context = canvas.getContext('2d')

      let v = canvg.Canvg.fromString(context, svg);
      v.start();

      let imgData = canvas.toDataURL("image/png");

      var doc = new jsPDF("l", "pt", [1020, 768]);
      doc.addImage(imgData, "PNG", 0, 0, 1020, 768);
      doc.save("svg-png-chart.pdf");
}