Export JavaScript Charts as image

Martynas Majeris -

Please refer to this tutorial for a way to export the charts as images on SVG-enabled browsers.

Have more questions? Submit a request

Comments

  • Avatar
    Yonghan He

    IE8 does not support SVG tag.how export JavaScript Charts as image in IE8.

  • Avatar
    Tom Bell

    There seems to be an issue with charts that have a chart scrollbar and exporting images using the above tutorial, on IE 9 and 10, which both support SVG.

  • Avatar
    Bettridge Lee

    There is a bug somewhere, possibly in the canvg javascript library, where the Show All text gets rendered as below in the xml when printing a chart

    font-family="Verdana" font-size="11" fill="#000000" text-anchor="start" transform="translate(29 13)" y="5.5"><tspan x="0" y="5.5">Show all</tspan></text>

    note that the opening <text tag is missing.

    This causes ie10 to throw an error and will not export the chart

  • Avatar
    Randy Kline

    I wanted to post a new topic but I don't seem to be able to.  I've seen a lot of people having problems with exporting in IE9.

    We made a couple small adjustments to old export code that we found.  This works in IE9 and IE10.  The code is below

    On another note, does the new export function in v3 support exporting candlesticks?  I've had trouble getting it to work at all.

     

    // Define custom util

    AmCharts.getExport = function (anything) {

    location.href = "#exportImage";

    /*

    ** PRIVATE FUNCTIONS

    */

    }

    stockPanel.addLabel(0, 0, "Powered by MBS Highway", "left", 30, "#053d5d", 0, 1, true);

    chart.validateNow();

    // Word around until somebody found out how to cover that

    function removeImages(svg) {

    var startStr = '<image';
    var stopStr = '</image>';

    var stopStrAlt = '/>';

    var start = svg.indexOf(startStr);

    var stop = svg.indexOf(stopStr);

    var match = '';

    // Recursion

    if (start != -1) {

    var stop = svg.slice(start, start + 1000).indexOf(stopStr);

    if (stop != -1) {

    svg = removeImages(svg.slice(0, start) + svg.slice(start + stop + stopStr.length, svg.length));

    } else {

    stop = svg.slice(start, start + 1000).indexOf(stopStrAlt);

    if (stop != -1) {

    svg = removeImages(svg.slice(0, start) + svg.slice(start + stop + stopStr.length, svg.length));

    }

    }

    }

    return svg;

    };

    // Senseless function to handle any input

    function gatherAnything(anything, inside) {

    switch (String(anything)) {

    case '[object String]':

    if (document.getElementById(anything)) {

    anything = inside ? document.getElementById(anything) : new Array(document.getElementById(anything));

    }

    break;

    case '[object Array]':

    for (var i = 0; i < anything.length; i++) {

    anything[i] = gatherAnything(anything[i], true);

    }

    break;

    case '[object XULElement]':

    anything = inside ? anything : new Array(anything);

    break;

    case '[object HTMLDivElement]':

    anything = inside ? anything : new Array(anything);

    break;

    default:

    anything = new Array();

    for (var i = 0; i < AmCharts.charts.length; i++) {

    anything.push(AmCharts.charts[i].div);

    }

    break;

    }

    return anything;

    }

    /*

    ** varibales VARIABLES!!!

    */

    var chartContainer = gatherAnything(anything);

    var chartImages = [];

    var canvgOptions = {

    ignoreAnimation: true,

    ignoreMouse: true,

    ignoreClear: true,

    ignoreDimensions: true,

    offsetX: 0,

    offsetY: 0

    };

    /*

    ** Loop, generate, offer

    */

    // Loop through given container

    for (var i1 = 0; i1 < chartContainer.length; i1++) {

    var canvas = document.createElement('canvas');

    var context = canvas.getContext('2d');

    var svgs = chartContainer[i1].getElementsByTagName('svg');

    var image = new Image();

    var heightCounter = 0;

    // Set dimensions, background color to the canvas

    canvas.width = chartContainer[i1].offsetWidth;

    canvas.height = chartContainer[i1].offsetHeight;

    context.fillStyle = '#FFFFFF';

    context.fillRect(0, 0, canvas.width, canvas.height);

    // Loop through all svgs within the container

    for (var i2 = 0; i2 < svgs.length; i2++) {

    var wrapper = svgs[i2].parentNode;

    var clone = svgs[i2].cloneNode(true);

    var cloneDiv = document.createElement('div');

    var offsets = {

    x: wrapper.style.left.slice(0, -2) || 0,

    y: wrapper.style.top.slice(0, -2) || 0,

    height: wrapper.offsetHeight,

    width: wrapper.offsetWidth

    };

    // Remove the style and append the clone to the div to receive the full SVG data

    clone.setAttribute('style', '');

    cloneDiv.appendChild(clone);

    innerHTML = removeImages(cloneDiv.innerHTML);

    // without imagery

    // Apply parent offset

    if (offsets.y == 0) {

    offsets.y = heightCounter;

    heightCounter += offsets.height;

    }

    canvgOptions.offsetX = offsets.x;

    canvgOptions.offsetY = offsets.y;

    // Some magic beyond the scenes...

    canvg(canvas, innerHTML, canvgOptions);

    }

    // Get the final data URL and throw that image to the array

    image.src = canvas.toDataURL();

    chartImages.push(image);

    }

    // Return DAT IMAGESS!!!!

     

    return chartImages;

    };

    function exportThis() {

    // Need to pass container to merge all SVGs otherwise we for each AmCharts.charts instance an image

    var items = AmCharts.getExport('chartdiv');

    document.getElementById('button').innerHTML = 'Update Export';

    document.getElementById('not_button').innerHTML = '';

    $("#print-instructions").show();

    for (index in items) {

    document.getElementById('not_button').appendChild(items[index]);

    if (index == 0) {

    stockPanel.clearLabels();

    }

    }

    chart.validateNow();

    return false;

    }

     

    Thanks

  • Avatar
    Bettridge Lee

    I'm still getting invalid xml from the removeImages method within AmCharts.getExport so I changed it to this :

    function removeImages(svg) {

      var stringArray = svg.split('<image');

      if (stringArray.length > 1) {

        var newSvg = stringArray[0];

        for (var i = 1; i < stringArray.length; i++) {

          if (stringArray[i].indexOf('</image>') >= 0) {

            newSvg += stringArray[i].substring(stringArray[i].indexOf('</image>') + 8, stringArray[i].length);

          }

          else {

            newSvg += stringArray[i].substring(stringArray[i].indexOf('/>') + 2, stringArray[i].length);

          }

        }

        return newSvg;

      }

      else {

        return svg;

      }

    };

  • Avatar
    susannamoore

    Besides IE browser, is there any way to export JavaScript charts as image in other browsers, like chrome and firefox?

     

    Related Work I Design: http://www.rasteredge.com/solutions/web-viewing/

     

  • Avatar
    Tube Bot

    Sample:

    amstockchart_3.4.9.free2\samples*_exporting_to_png.html* does not show export button on Chrome, FF

    but: amcharts_3.4.9.free\samples*_exporting_to_png.html* works fine.

    Could you fix this issue or suggest how to avoid wrong behaviour for amstockchart library?

Powered by Zendesk