PageRenderTime 28ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/ajax/libs/highcharts/4.1.9.1/modules/offline-exporting.src.js

https://gitlab.com/Mirros/cdnjs
JavaScript | 277 lines | 204 code | 20 blank | 53 comment | 33 complexity | 45dec4b2964a0e95d20e44f57d059ad8 MD5 | raw file
  1. /**
  2. * @license Highcharts JS v4.1.9 (2015-10-07)
  3. * Client side exporting module
  4. *
  5. * (c) 2015 Torstein Honsi / Oystein Moseng
  6. *
  7. * License: www.highcharts.com/license
  8. */
  9. // JSLint options:
  10. /*global Highcharts, HighchartsAdapter, document, window, Blob, MSBlobBuilder */
  11. (function (Highcharts) {
  12. // Dummy object so we can reuse our canvas-tools.js without errors
  13. Highcharts.CanVGRenderer = {};
  14. /**
  15. * Add a new method to the Chart object to perform a local download
  16. */
  17. Highcharts.Chart.prototype.exportChartLocal = function (exportingOptions, chartOptions) {
  18. var chart = this,
  19. options = Highcharts.merge(chart.options.exporting, exportingOptions),
  20. webKit = navigator.userAgent.indexOf('WebKit') > -1 && navigator.userAgent.indexOf("Chrome") < 0, // Webkit and not chrome
  21. scale = options.scale || 2,
  22. chartCopyContainer,
  23. domurl = window.URL || window.webkitURL || window,
  24. images,
  25. imagesEmbedded = 0,
  26. el,
  27. i,
  28. l,
  29. fallbackToExportServer = function () {
  30. if (options.fallbackToExportServer === false) {
  31. throw 'Fallback to export server disabled';
  32. }
  33. chart.exportChart(options);
  34. },
  35. // Get data:URL from image URL
  36. // Pass in callbacks to handle results. finallyCallback is always called at the end of the process. Supplying this callback is optional.
  37. // All callbacks receive two arguments: imageURL, and callbackArgs. callbackArgs is used only by callbacks and can contain whatever.
  38. imageToDataUrl = function (imageURL, callbackArgs, successCallback, taintedCallback, noCanvasSupportCallback, failedLoadCallback, finallyCallback) {
  39. var img = new Image();
  40. if (!webKit) {
  41. img.crossOrigin = 'Anonymous'; // For some reason Safari chokes on this attribute
  42. }
  43. img.onload = function () {
  44. var canvas = document.createElement('canvas'),
  45. ctx = canvas.getContext && canvas.getContext('2d'),
  46. dataURL;
  47. if (!ctx) {
  48. noCanvasSupportCallback(imageURL, callbackArgs);
  49. } else {
  50. canvas.height = img.height * scale;
  51. canvas.width = img.width * scale;
  52. ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
  53. // Now we try to get the contents of the canvas.
  54. try {
  55. dataURL = canvas.toDataURL();
  56. successCallback(dataURL, callbackArgs);
  57. } catch (e) {
  58. // Failed - either tainted canvas or something else went horribly wrong
  59. if (e.name === 'SecurityError' || e.name === 'SECURITY_ERR' || e.message === 'SecurityError') {
  60. taintedCallback(imageURL, callbackArgs);
  61. } else {
  62. throw e;
  63. }
  64. }
  65. }
  66. if (finallyCallback) {
  67. finallyCallback(imageURL, callbackArgs);
  68. }
  69. };
  70. img.onerror = function () {
  71. failedLoadCallback(imageURL, callbackArgs);
  72. if (finallyCallback) {
  73. finallyCallback(imageURL, callbackArgs);
  74. }
  75. };
  76. img.src = imageURL;
  77. },
  78. // Get blob URL from SVG code. Falls back to normal data URI.
  79. svgToDataUrl = function (svg) {
  80. try {
  81. // Safari requires data URI since it doesn't allow navigation to blob URLs
  82. // Firefox has an issue with Blobs and internal references, leading to gradients not working using Blobs (#4550)
  83. if (!webKit && navigator.userAgent.toLowerCase().indexOf('firefox') < 0) {
  84. return domurl.createObjectURL(new Blob([svg], { type: 'image/svg+xml;charset-utf-16'}));
  85. }
  86. } catch (e) {
  87. // Ignore
  88. }
  89. return 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg);
  90. },
  91. // Download contents by dataURL/blob
  92. download = function (dataURL, extension) {
  93. var a = document.createElement('a'),
  94. filename = (options.filename || 'chart') + '.' + extension,
  95. windowRef;
  96. // IE specific blob implementation
  97. if (navigator.msSaveOrOpenBlob) {
  98. navigator.msSaveOrOpenBlob(dataURL, filename);
  99. return;
  100. }
  101. // Try HTML5 download attr if supported
  102. if (typeof a.download !== 'undefined') {
  103. a.href = dataURL;
  104. a.download = filename; // HTML5 download attribute
  105. a.target = '_blank';
  106. document.body.appendChild(a);
  107. a.click();
  108. document.body.removeChild(a);
  109. } else {
  110. // No download attr, just opening data URI
  111. try {
  112. windowRef = window.open(dataURL, 'chart');
  113. if (typeof windowRef === 'undefined' || windowRef === null) {
  114. throw 1;
  115. }
  116. } catch (e) {
  117. // window.open failed, trying location.href
  118. window.location.href = dataURL;
  119. }
  120. }
  121. },
  122. // Get data URL to an image of the chart and call download on it
  123. initiateDownload = function () {
  124. var svgurl,
  125. blob,
  126. svg = chart.sanitizeSVG(chartCopyContainer.innerHTML); // SVG of chart copy
  127. // Initiate download depending on file type
  128. if (options && options.type === 'image/svg+xml') {
  129. // SVG download. In this case, we want to use Microsoft specific Blob if available
  130. try {
  131. if (navigator.msSaveOrOpenBlob) {
  132. blob = new MSBlobBuilder();
  133. blob.append(svg);
  134. svgurl = blob.getBlob('image/svg+xml');
  135. } else {
  136. svgurl = svgToDataUrl(svg);
  137. }
  138. download(svgurl, 'svg');
  139. } catch (e) {
  140. fallbackToExportServer();
  141. }
  142. } else {
  143. // PNG download - create bitmap from SVG
  144. // First, try to get PNG by rendering on canvas
  145. svgurl = svgToDataUrl(svg);
  146. imageToDataUrl(svgurl, { /* args */ }, function (imageURL) {
  147. // Success
  148. try {
  149. download(imageURL, 'png');
  150. } catch (e) {
  151. fallbackToExportServer();
  152. }
  153. }, function () {
  154. // Failed due to tainted canvas
  155. // Create new and untainted canvas
  156. var canvas = document.createElement('canvas'),
  157. ctx = canvas.getContext('2d'),
  158. imageWidth = svg.match(/^<svg[^>]*width\s*=\s*\"?(\d+)\"?[^>]*>/)[1] * scale,
  159. imageHeight = svg.match(/^<svg[^>]*height\s*=\s*\"?(\d+)\"?[^>]*>/)[1] * scale,
  160. downloadWithCanVG = function () {
  161. ctx.drawSvg(svg, 0, 0, imageWidth, imageHeight);
  162. try {
  163. download(navigator.msSaveOrOpenBlob ? canvas.msToBlob() : canvas.toDataURL('image/png'), 'png');
  164. } catch (e) {
  165. fallbackToExportServer();
  166. }
  167. };
  168. canvas.width = imageWidth;
  169. canvas.height = imageHeight;
  170. if (window.canvg) {
  171. // Use preloaded canvg
  172. downloadWithCanVG();
  173. } else {
  174. // Must load canVG first
  175. chart.showLoading();
  176. HighchartsAdapter.getScript(Highcharts.getOptions().global.canvasToolsURL, function () {
  177. chart.hideLoading();
  178. downloadWithCanVG();
  179. });
  180. }
  181. },
  182. // No canvas support
  183. fallbackToExportServer,
  184. // Failed to load image
  185. fallbackToExportServer,
  186. // Finally
  187. function () {
  188. try {
  189. domurl.revokeObjectURL(svgurl);
  190. } catch (e) {
  191. // Ignore
  192. }
  193. });
  194. }
  195. };
  196. // Hook into getSVG to get a copy of the chart copy's container
  197. Highcharts.wrap(Highcharts.Chart.prototype, 'getChartHTML', function (proceed) {
  198. chartCopyContainer = this.container.cloneNode(true);
  199. return proceed.apply(this, Array.prototype.slice.call(arguments, 1));
  200. });
  201. // Trigger hook to get chart copy
  202. chart.getSVGForExport(options, chartOptions);
  203. images = chartCopyContainer.getElementsByTagName('image');
  204. try {
  205. // If there are no images to embed, just go ahead and start the download process
  206. if (!images.length) {
  207. initiateDownload();
  208. }
  209. // Success handler, we converted image to base64!
  210. function embeddedSuccess(imageURL, callbackArgs) {
  211. ++imagesEmbedded;
  212. // Change image href in chart copy
  213. callbackArgs.imageElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', imageURL);
  214. // Start download when done with the last image
  215. if (imagesEmbedded === images.length) {
  216. initiateDownload();
  217. }
  218. }
  219. // Go through the images we want to embed
  220. for (i = 0, l = images.length; i < l; ++i) {
  221. el = images[i];
  222. imageToDataUrl(el.getAttributeNS('http://www.w3.org/1999/xlink', 'href'), { imageElement: el },
  223. embeddedSuccess,
  224. // Tainted canvas
  225. fallbackToExportServer,
  226. // No canvas support
  227. fallbackToExportServer,
  228. // Failed to load source
  229. fallbackToExportServer
  230. );
  231. }
  232. } catch (e) {
  233. fallbackToExportServer();
  234. }
  235. };
  236. // Extend the default options to use the local exporter logic
  237. Highcharts.getOptions().exporting.buttons.contextButton.menuItems = [{
  238. textKey: 'printChart',
  239. onclick: function () {
  240. this.print();
  241. }
  242. }, {
  243. separator: true
  244. }, {
  245. textKey: 'downloadPNG',
  246. onclick: function () {
  247. this.exportChartLocal();
  248. }
  249. }, {
  250. textKey: 'downloadSVG',
  251. onclick: function () {
  252. this.exportChartLocal({
  253. type: 'image/svg+xml'
  254. });
  255. }
  256. }];
  257. }(Highcharts));