3

I have an IgniteUI igDataChart that I would like to save to disk as an image. You cannot right click on the chart and save the image, because it uses several canvases. The chart does however have an export image method which will get the entire chart image and return it into a javascript variable.

I would like to automatically save this file to the user's download folder on a button click. If this were a server side image I could simply direct the user to the appropriate url, but it is not.

How can the user download this client side generated png image of the chart on a button click? I need a crossbrowser solution.

JSFIDDLE

$(function () {
    $("#exportBtn").click(function(){
       //returns an image DOM element;
       var pngImage = $("#chart").igDataChart("exportImage");
       //now i need to download the image
    });
});
Brino
  • 2,442
  • 1
  • 21
  • 36

2 Answers2

2

This solution offers better browser support and can be assigned to a button. http://jsfiddle.net/koo2hv5t/7/

  1. Check blob support (you can add a message for old browsers or a server side fallback)
  2. Wait till animation end
  3. Copy the chart to dataURL format with igDataChart
  4. Convert to a blob with Util.dataURLToBlob from https://github.com/ebidel/filer.js
  5. Save the blob to a file with saveAs from https://github.com/eligrey/FileSaver.js

    //check support
    try {
        var isFileSaverSupported = !! new Blob;
    } catch (e) {}
    
    setTimeout(function () {
        //add data to url
        function downloadCanvas(link, canv, filename) {
            if (isFileSaverSupported) {
                saveAs(Util.dataURLToBlob(canv.src), filename);
            }
        }
        $("#exportBtn").click(function () {
            downloadCanvas(this, $("#chart").igDataChart("exportImage", 800, 600), 'test.png');
        });
    }, 1000); //wait till animation end
    
kb_
  • 131
  • 8
  • this works great. You could have just updated your first answer, rather than submit a new one. – Brino Jun 04 '15 at 21:15
  • i'll do some testing to make sure it works in all cases, then mark it as the answer – Brino Jun 04 '15 at 21:26
  • Filesaver.js has decent browser support. Util.dataURLToBlob is only supported on Chrome, but it also appears to work on IE, so this appears to be as good as I will get for a cross-browser solution, until HTML 5 is fully supported in IE. Thanks for the good information and effort. – Brino Jun 10 '15 at 02:38
1

You can proceed the following way:

  1. Wait till animation end
  2. Copy all canvas in the last one
  3. Assign the data to an url (not a button)

    setTimeout(function () {
        var c = $("#chart canvas"); //get handle to all canvas
        var ctx = c[c.length - 1].getContext('2d');
        for (i = 0; i < c.length - 1; i++) { //add all canvas to the last one
            ctx.drawImage(c[i], 0, 0);
        }
        for (i = 0; i < c.length - 1; i++) { //remove the duplicates
            c[i].remove();
        }
        //add data to url
        function downloadCanvas(link, canv, filename) {
            link.href = canv.toDataURL();
            link.download = filename;
        }
        $("#dl1").click(function () {
            downloadCanvas(this, c[2], 'test.png');
        });
    
    }, 1000); //wait till animation end
    

http://jsfiddle.net/koo2hv5t/1/

kb_
  • 131
  • 8
  • Good point about waiting for the animation to end. Is there a way to use this with the exportImage method? – Brino Jun 04 '15 at 03:13
  • This works great, but not in IE, and not on a button click. The download attribute is fairly new and not supported in IE yet: http://www.w3schools.com/jsref/prop_anchor_download.asp – Brino Jun 04 '15 at 13:07
  • Yeah, like I said it's only for urls and IE has a lot of limitations when it comes to HTML5 features... This is probably what you need https://github.com/eligrey/FileSaver.js – kb_ Jun 04 '15 at 13:56
  • Ok. Thanks for all your help so far, I'll take a look at that. – Brino Jun 04 '15 at 14:31