sam140
sam140

Reputation: 249

Unable to export D3 chart Properly

I am trying to export the d3 chart as png image on button click.Also,i have mentioned below the function which i am using here:

$(function() {
  $('#btnSave').click(function(){
    html2canvas($('#test'), 
    {
      onrendered: function (canvas) {
        var a = document.createElement('a');
        // toDataURL defaults to png, so we need to request a jpeg, then convert for file download.
        a.href = canvas.toDataURL();
        a.download = 'somefilename.jpg';
        a.click();
      }
    });
  });

});

When i am clicking on export button i am not getting the chart properly.Also i have mentioned the screen shot which i am getting after export.

Chart

After Export

Upvotes: 0

Views: 879

Answers (1)

Shashank
Shashank

Reputation: 5670

I would suggest not to use html2Canvas here because capturing any SVG images would create taint on the canvas and this library does not allow that (unless you force allowTaint: true which isn't a good option either). Here's the issue you can go through: SVG Taint on canvas

Here's an approach to capture the SVG:

JS FIDDLE

Relevant code to capture image without any special library:

var svgString = new XMLSerializer().serializeToString(d3.select('body svg#custom_id').node()),
    blob = new Blob([svgString], {type: "image/svg+xml;charset=utf-8"}),
  url = window.URL.createObjectURL(blob);

var img = d3.select('body').append('img').classed('exportImg', true).node();
img.onload = function () {
    var canvas = document.createElement('canvas'),
    ctx = canvas.getContext('2d');
    canvas.width = w + m[1] + m[3];
    canvas.height = h + m[0] + m[2];
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
   // $('body').append(canvas);
    d3.select('img.exportImg').remove();

    // create link
    var a = document.createElement('a');
    a.href = canvas.toDataURL();
    a.download = 'somefilename';
    a.click();
};
img.src = url;

And by adding style to the paths, I meant, NOT using CSS (I'm sorry I wasn't clear there). Here is what I was talking about:

 .enter().append("svg:path")
 .attr("d", path).style('fill', 'none').style('stroke', 'steelblue').style('stroke-opacity', 0.7).style('stroke-width', 1.5);

Added the same to foreground and background. You can do the styling to the axes too in a similar fashion. CSS properties aren't captured while creating the SVG string.

Hope this helps. (And I've used sample base64 code for the image as those images weren't available, you can change that) :)

Upvotes: 1

Related Questions