/**
* @license @product.name@ JS v@product.version@ (@product.date@)
* Exporting module
*
* (c) 2010-2011 Torstein Hønsi
*
* License: www.highcharts.com/license
*/
// JSLint options:
/*global Highcharts, document, window, Math, setTimeout */
(function () { // encapsulate
// create shortcuts
var HC = Highcharts,
Chart = HC.Chart,
addEvent = HC.addEvent,
removeEvent = HC.removeEvent,
createElement = HC.createElement,
discardElement = HC.discardElement,
css = HC.css,
merge = HC.merge,
each = HC.each,
extend = HC.extend,
math = Math,
mathMax = math.max,
doc = document,
win = window,
hasTouch = doc.documentElement.ontouchstart !== undefined,
M = 'M',
L = 'L',
DIV = 'div',
HIDDEN = 'hidden',
NONE = 'none',
PREFIX = 'highcharts-',
ABSOLUTE = 'absolute',
PX = 'px',
UNDEFINED,
defaultOptions = HC.getOptions();
// Add language
extend(defaultOptions.lang, {
downloadPNG: 'Download PNG image',
downloadJPEG: 'Download JPEG image',
downloadPDF: 'Download PDF document',
downloadSVG: 'Download SVG vector image',
exportButtonTitle: 'Export to raster or vector image',
printButtonTitle: 'Print the chart'
});
// Buttons and menus are collected in a separate config option set called 'navigation'.
// This can be extended later to add control buttons like zoom and pan right click menus.
defaultOptions.navigation = {
menuStyle: {
border: '1px solid #A0A0A0',
background: '#FFFFFF'
},
menuItemStyle: {
padding: '0 5px',
background: NONE,
color: '#303030',
fontSize: hasTouch ? '14px' : '11px'
},
menuItemHoverStyle: {
background: '#4572A5',
color: '#FFFFFF'
},
buttonOptions: {
align: 'right',
backgroundColor: {
linearGradient: [0, 0, 0, 20],
stops: [
[0.4, '#F7F7F7'],
[0.6, '#E3E3E3']
]
},
borderColor: '#B0B0B0',
borderRadius: 3,
borderWidth: 1,
//enabled: true,
height: 20,
hoverBorderColor: '#909090',
hoverSymbolFill: '#81A7CF',
hoverSymbolStroke: '#4572A5',
symbolFill: '#E0E0E0',
//symbolSize: 12,
symbolStroke: '#A0A0A0',
//symbolStrokeWidth: 1,
symbolX: 11.5,
symbolY: 10.5,
verticalAlign: 'top',
width: 24,
y: 10
}
};
// Add the export related options
defaultOptions.exporting = {
//enabled: true,
//filename: 'chart',
type: 'image/png',
url: 'http://export.highcharts.com/',
width: 800,
buttons: {
exportButton: {
//enabled: true,
symbol: 'exportIcon',
x: -10,
symbolFill: '#A8BF77',
hoverSymbolFill: '#768F3E',
_id: 'exportButton',
_titleKey: 'exportButtonTitle',
menuItems: [{
textKey: 'downloadPNG',
onclick: function () {
this.exportChart();
}
}, {
textKey: 'downloadJPEG',
onclick: function () {
this.exportChart({
type: 'image/jpeg'
});
}
}, {
textKey: 'downloadPDF',
onclick: function () {
this.exportChart({
type: 'application/pdf'
});
}
}, {
textKey: 'downloadSVG',
onclick: function () {
this.exportChart({
type: 'image/svg+xml'
});
}
}
// Enable this block to add "View SVG" to the dropdown menu
/*
,{
text: 'View SVG',
onclick: function () {
var svg = this.getSVG()
.replace(//g, '>');
doc.body.innerHTML = '
' + svg + '
';
}
} // */
]
},
printButton: {
//enabled: true,
symbol: 'printIcon',
x: -36,
symbolFill: '#B5C9DF',
hoverSymbolFill: '#779ABF',
_id: 'printButton',
_titleKey: 'printButtonTitle',
onclick: function () {
this.print();
}
}
}
};
extend(Chart.prototype, {
/**
* Return an SVG representation of the chart
*
* @param additionalOptions {Object} Additional chart options for the generated SVG representation
*/
getSVG: function (additionalOptions) {
var chart = this,
chartCopy,
sandbox,
svg,
seriesOptions,
options = merge(chart.options, additionalOptions); // copy the options and add extra options
// IE compatibility hack for generating SVG content that it doesn't really understand
if (!doc.createElementNS) {
/*jslint unparam: true*//* allow unused parameter ns in function below */
doc.createElementNS = function (ns, tagName) {
var elem = doc.createElement(tagName);
elem.getBBox = function () {
return HC.Renderer.prototype.Element.prototype.getBBox.apply({ element: elem });
};
return elem;
};
/*jslint unparam: false*/
}
// create a sandbox where a new chart will be generated
sandbox = createElement(DIV, null, {
position: ABSOLUTE,
top: '-9999em',
width: chart.chartWidth + PX,
height: chart.chartHeight + PX
}, doc.body);
// override some options
extend(options.chart, {
renderTo: sandbox,
forExport: true
});
options.exporting.enabled = false; // hide buttons in print
options.chart.plotBackgroundImage = null; // the converter doesn't handle images
// prepare for replicating the chart
options.series = [];
each(chart.series, function (serie) {
seriesOptions = merge(serie.options, {
animation: false, // turn off animation
showCheckbox: false,
visible: serie.visible
});
if (!seriesOptions.isInternal) { // used for the navigator series that has its own option set
// remove image markers
if (seriesOptions && seriesOptions.marker && /^url\(/.test(seriesOptions.marker.symbol)) {
seriesOptions.marker.symbol = 'circle';
}
options.series.push(seriesOptions);
}
});
// generate the chart copy
chartCopy = new Highcharts.Chart(options);
// reflect axis extremes in the export
each(['xAxis', 'yAxis'], function (axisType) {
each(chart[axisType], function (axis, i) {
var axisCopy = chartCopy[axisType][i],
extremes = axis.getExtremes(),
userMin = extremes.userMin,
userMax = extremes.userMax;
if (userMin !== UNDEFINED || userMax !== UNDEFINED) {
axisCopy.setExtremes(userMin, userMax, true, false);
}
});
});
// get the SVG from the container's innerHTML
svg = chartCopy.container.innerHTML;
// free up memory
options = null;
chartCopy.destroy();
discardElement(sandbox);
// sanitize
svg = svg
.replace(/zIndex="[^"]+"/g, '')
.replace(/isShadow="[^"]+"/g, '')
.replace(/symbolName="[^"]+"/g, '')
.replace(/jQuery[0-9]+="[^"]+"/g, '')
.replace(/isTracker="[^"]+"/g, '')
.replace(/url\([^#]+#/g, 'url(#')
.replace(/