highcharts-rails 5.0.10 → 5.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.markdown +48 -0
  3. data/app/assets/javascripts/highcharts.js +2395 -1517
  4. data/app/assets/javascripts/highcharts/highcharts-3d.js +212 -116
  5. data/app/assets/javascripts/highcharts/highcharts-more.js +17 -11
  6. data/app/assets/javascripts/highcharts/modules/accessibility.js +29 -16
  7. data/app/assets/javascripts/highcharts/modules/annotations.js +3 -4
  8. data/app/assets/javascripts/highcharts/modules/boost.js +392 -356
  9. data/app/assets/javascripts/highcharts/modules/broken-axis.js +42 -17
  10. data/app/assets/javascripts/highcharts/modules/data.js +6 -6
  11. data/app/assets/javascripts/highcharts/modules/drilldown.js +54 -27
  12. data/app/assets/javascripts/highcharts/modules/exporting.js +125 -102
  13. data/app/assets/javascripts/highcharts/modules/funnel.js +17 -9
  14. data/app/assets/javascripts/highcharts/modules/grid-axis.js +1 -1
  15. data/app/assets/javascripts/highcharts/modules/heatmap.js +12 -2
  16. data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +1 -1
  17. data/app/assets/javascripts/highcharts/modules/offline-exporting.js +12 -4
  18. data/app/assets/javascripts/highcharts/modules/overlapping-datalabels.js +1 -1
  19. data/app/assets/javascripts/highcharts/modules/series-label.js +1 -1
  20. data/app/assets/javascripts/highcharts/modules/solid-gauge.js +2 -2
  21. data/app/assets/javascripts/highcharts/modules/stock.js +182 -101
  22. data/app/assets/javascripts/highcharts/modules/treemap.js +4 -7
  23. data/app/assets/javascripts/highcharts/modules/xrange-series.js +1 -1
  24. data/lib/highcharts/version.rb +1 -1
  25. metadata +1 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.10 (2017-03-31)
2
+ * @license Highcharts JS v5.0.11 (2017-05-04)
3
3
  *
4
4
  * (c) 2009-2017 Torstein Honsi
5
5
  *
@@ -169,17 +169,14 @@
169
169
  length = 0,
170
170
  inBrk,
171
171
  repeat,
172
- brk,
173
172
  min = axis.userMin || axis.min,
174
173
  max = axis.userMax || axis.max,
175
174
  pointRangePadding = pick(axis.pointRangePadding, 0),
176
175
  start,
177
- i,
178
- j;
176
+ i;
179
177
 
180
178
  // Min & max check (#4247)
181
- for (i in breaks) {
182
- brk = breaks[i];
179
+ each(breaks, function(brk) {
183
180
  repeat = brk.repeat || Infinity;
184
181
  if (axis.isInBreak(brk, min)) {
185
182
  min += (brk.to % repeat) - (min % repeat);
@@ -187,11 +184,10 @@
187
184
  if (axis.isInBreak(brk, max)) {
188
185
  max -= (max % repeat) - (brk.from % repeat);
189
186
  }
190
- }
187
+ });
191
188
 
192
189
  // Construct an array holding all breaks in the axis
193
- for (i in breaks) {
194
- brk = breaks[i];
190
+ each(breaks, function(brk) {
195
191
  start = brk.from;
196
192
  repeat = brk.repeat || Infinity;
197
193
 
@@ -202,18 +198,18 @@
202
198
  start += repeat;
203
199
  }
204
200
 
205
- for (j = start; j < max; j += repeat) {
201
+ for (i = start; i < max; i += repeat) {
206
202
  breakArrayT.push({
207
- value: j,
203
+ value: i,
208
204
  move: 'in'
209
205
  });
210
206
  breakArrayT.push({
211
- value: j + (brk.to - brk.from),
207
+ value: i + (brk.to - brk.from),
212
208
  move: 'out',
213
209
  size: brk.breakSize
214
210
  });
215
211
  }
216
- }
212
+ });
217
213
 
218
214
  breakArrayT.sort(function(a, b) {
219
215
  var ret;
@@ -229,8 +225,7 @@
229
225
  inBrk = 0;
230
226
  start = min;
231
227
 
232
- for (i in breakArrayT) {
233
- brk = breakArrayT[i];
228
+ each(breakArrayT, function(brk) {
234
229
  inBrk += (brk.move === 'in' ? 1 : -1);
235
230
 
236
231
  if (inBrk === 1 && brk.move === 'in') {
@@ -244,7 +239,7 @@
244
239
  });
245
240
  length += brk.value - start - (brk.size || 0);
246
241
  }
247
- }
242
+ });
248
243
 
249
244
  axis.breakArray = breakArray;
250
245
 
@@ -256,7 +251,7 @@
256
251
 
257
252
  if (axis.options.staticScale) {
258
253
  axis.transA = axis.options.staticScale;
259
- } else {
254
+ } else if (axis.unitLength) {
260
255
  axis.transA *= (max - axis.min + pointRangePadding) /
261
256
  axis.unitLength;
262
257
  }
@@ -343,6 +338,36 @@
343
338
  });
344
339
  };
345
340
 
341
+
342
+ /**
343
+ * Extend getGraphPath by identifying gaps in the data so that we can draw a gap
344
+ * in the line or area. This was moved from ordinal axis module to broken axis
345
+ * module as of #5045.
346
+ */
347
+ H.Series.prototype.gappedPath = function() {
348
+ var gapSize = this.options.gapSize,
349
+ points = this.points.slice(),
350
+ i = points.length - 1;
351
+
352
+ if (gapSize && i > 0) { // #5008
353
+
354
+ // extension for ordinal breaks
355
+ while (i--) {
356
+ if (points[i + 1].x - points[i].x > this.closestPointRange * gapSize) {
357
+ points.splice( // insert after this one
358
+ i + 1,
359
+ 0, {
360
+ isNull: true
361
+ }
362
+ );
363
+ }
364
+ }
365
+ }
366
+
367
+ // Call base method
368
+ return this.getGraphPath(points);
369
+ };
370
+
346
371
  wrap(H.seriesTypes.column.prototype, 'drawPoints', drawPointsWrapped);
347
372
  wrap(H.Series.prototype, 'drawPoints', drawPointsWrapped);
348
373
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.10 (2017-03-31)
2
+ * @license Highcharts JS v5.0.11 (2017-05-04)
3
3
  * Data module
4
4
  *
5
5
  * (c) 2012-2017 Torstein Honsi
@@ -29,6 +29,7 @@
29
29
  var win = Highcharts.win,
30
30
  doc = win.document,
31
31
  each = Highcharts.each,
32
+ objectEach = Highcharts.objectEach,
32
33
  pick = Highcharts.pick,
33
34
  inArray = Highcharts.inArray,
34
35
  isNumber = Highcharts.isNumber,
@@ -118,7 +119,6 @@
118
119
  // the mapping options.
119
120
  each((options && options.seriesMapping) || [], function(mapping) {
120
121
  var builder = new SeriesBuilder(),
121
- name,
122
122
  numberOfValueColumnsNeeded = individualCounts[seriesIndex] || getValueCount(globalType),
123
123
  seriesArr = (chartOptions && chartOptions.series) || [],
124
124
  series = seriesArr[seriesIndex] || {},
@@ -129,11 +129,11 @@
129
129
  builder.addColumnReader(mapping.x, 'x');
130
130
 
131
131
  // Add all column mappings
132
- for (name in mapping) {
133
- if (mapping.hasOwnProperty(name) && name !== 'x') {
134
- builder.addColumnReader(mapping[name], name);
132
+ objectEach(mapping, function(val, name) {
133
+ if (name !== 'x') {
134
+ builder.addColumnReader(val, name);
135
135
  }
136
- }
136
+ });
137
137
 
138
138
  // Add missing columns
139
139
  for (i = 0; i < numberOfValueColumnsNeeded; i++) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.10 (2017-03-31)
2
+ * @license Highcharts JS v5.0.11 (2017-05-04)
3
3
  * Highcharts Drilldown module
4
4
  *
5
5
  * Author: Torstein Honsi
@@ -30,6 +30,7 @@
30
30
  each = H.each,
31
31
  extend = H.extend,
32
32
  format = H.format,
33
+ objectEach = H.objectEach,
33
34
  pick = H.pick,
34
35
  wrap = H.wrap,
35
36
  Chart = H.Chart,
@@ -133,8 +134,26 @@
133
134
  });
134
135
  };
135
136
 
136
- Chart.prototype.addSeriesAsDrilldown = function(point, ddOptions) {
137
- this.addSingleSeriesAsDrilldown(point, ddOptions);
137
+ /**
138
+ * Add a series to the chart as drilldown from a specific point in the parent
139
+ * series. This method is used for async drilldown, when clicking a point in a
140
+ * series should result in loading and displaying a more high-resolution series.
141
+ * When not async, the setup is simpler using the {@link
142
+ * https://api.highcharts.com/highcharts/drilldown.series|drilldown.series}
143
+ * options structure.
144
+ *
145
+ * @memberOf Highcharts.Chart
146
+ * @function #addSeriesAsDrilldown
147
+ *
148
+ * @param {Highcharts.Point} point
149
+ * The point from which the drilldown will start.
150
+ * @param {SeriesOptions} options
151
+ * The series options for the new, detailed series.
152
+ *
153
+ * @sample highcharts/drilldown/async/ Async drilldown
154
+ */
155
+ Chart.prototype.addSeriesAsDrilldown = function(point, options) {
156
+ this.addSingleSeriesAsDrilldown(point, options);
138
157
  this.applyDrilldown();
139
158
  };
140
159
  Chart.prototype.addSingleSeriesAsDrilldown = function(point, ddOptions) {
@@ -299,6 +318,13 @@
299
318
  }
300
319
  };
301
320
 
321
+ /**
322
+ * When the chart is drilled down to a child series, calling `chart.drillUp()`
323
+ * will drill up to the parent series.
324
+ *
325
+ * @memberOf Highcharts.Chart
326
+ * @name #drillUp
327
+ */
302
328
  Chart.prototype.drillUp = function() {
303
329
  var chart = this,
304
330
  drilldownLevels = chart.drilldownLevels,
@@ -511,6 +537,9 @@
511
537
  ColumnSeries.prototype.animateDrillupFrom = function(level) {
512
538
  var animationOptions = this.chart.options.drilldown.animation,
513
539
  group = this.group,
540
+ // For 3d column series all columns are added to one group
541
+ // so we should not delete the whole group. #5297
542
+ removeGroup = group !== this.chart.seriesGroup,
514
543
  series = this;
515
544
 
516
545
  // Cancel mouse events on the series group (#2787)
@@ -520,14 +549,16 @@
520
549
  }
521
550
  });
522
551
 
552
+ if (removeGroup) {
553
+ delete this.group;
554
+ }
523
555
 
524
- delete this.group;
525
556
  each(this.points, function(point) {
526
557
  var graphic = point.graphic,
527
558
  animateTo = level.shapeArgs,
528
559
  complete = function() {
529
560
  graphic.destroy();
530
- if (group) {
561
+ if (group && removeGroup) {
531
562
  group = group.destroy();
532
563
  }
533
564
  };
@@ -640,15 +671,11 @@
640
671
  * Drill down to a given category. This is the same as clicking on an axis label.
641
672
  */
642
673
  H.Axis.prototype.drilldownCategory = function(x, e) {
643
- var key,
644
- point,
645
- ddPointsX = this.getDDPoints(x);
646
- for (key in ddPointsX) {
647
- point = ddPointsX[key];
674
+ objectEach(this.getDDPoints(x), function(point) {
648
675
  if (point && point.series && point.series.visible && point.doDrilldown) { // #3197
649
676
  point.doDrilldown(true, x, e);
650
677
  }
651
- }
678
+ });
652
679
  this.chart.applyDrilldown();
653
680
  };
654
681
 
@@ -787,26 +814,26 @@
787
814
  });
788
815
 
789
816
  // Mark the trackers with a pointer
790
- var type,
791
- drawTrackerWrapper = function(proceed) {
792
- proceed.call(this);
793
- each(this.points, function(point) {
794
- if (point.drilldown && point.graphic) {
795
- point.graphic.addClass('highcharts-drilldown-point');
817
+ var drawTrackerWrapper = function(proceed) {
818
+ proceed.call(this);
819
+ each(this.points, function(point) {
820
+ if (point.drilldown && point.graphic) {
821
+ point.graphic.addClass('highcharts-drilldown-point');
796
822
 
797
823
 
798
- point.graphic.css({
799
- cursor: 'pointer'
800
- });
824
+ point.graphic.css({
825
+ cursor: 'pointer'
826
+ });
801
827
 
802
- }
803
- });
804
- };
805
- for (type in seriesTypes) {
806
- if (seriesTypes[type].prototype.supportsDrilldown) {
807
- wrap(seriesTypes[type].prototype, 'drawTracker', drawTrackerWrapper);
828
+ }
829
+ });
830
+ };
831
+
832
+ objectEach(seriesTypes, function(seriesType) {
833
+ if (seriesType.prototype.supportsDrilldown) {
834
+ wrap(seriesType.prototype, 'drawTracker', drawTrackerWrapper);
808
835
  }
809
- }
836
+ });
810
837
 
811
838
  }(Highcharts));
812
839
  }));
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.10 (2017-03-31)
2
+ * @license Highcharts JS v5.0.11 (2017-05-04)
3
3
  * Exporting module
4
4
  *
5
5
  * (c) 2010-2017 Torstein Honsi
@@ -38,6 +38,7 @@
38
38
  merge = H.merge,
39
39
  pick = H.pick,
40
40
  each = H.each,
41
+ objectEach = H.objectEach,
41
42
  extend = H.extend,
42
43
  isTouchDevice = H.isTouchDevice,
43
44
  win = H.win,
@@ -122,75 +123,47 @@
122
123
  symbol: 'menu',
123
124
  _titleKey: 'contextButtonTitle',
124
125
  menuItems: [{
125
- textKey: 'printChart',
126
- onclick: function() {
127
- this.print();
128
- }
129
- }, {
130
- separator: true
131
- }, {
132
- textKey: 'downloadPNG',
133
- onclick: function() {
134
- this.exportChart();
135
- }
136
- }, {
137
- textKey: 'downloadJPEG',
138
- onclick: function() {
139
- this.exportChart({
140
- type: 'image/jpeg'
141
- });
142
- }
143
- }, {
144
- textKey: 'downloadPDF',
145
- onclick: function() {
146
- this.exportChart({
147
- type: 'application/pdf'
148
- });
149
- }
150
- }, {
151
- textKey: 'downloadSVG',
152
- onclick: function() {
153
- this.exportChart({
154
- type: 'image/svg+xml'
155
- });
156
- }
126
+ textKey: 'printChart',
127
+ onclick: function() {
128
+ this.print();
157
129
  }
158
- // Enable this block to add "View SVG" to the dropdown menu
159
- /*
160
- ,{
161
-
162
- text: 'View SVG Image',
163
- onclick: function () {
164
- var div = doc.createElement('div');
165
- div.innerHTML = this.getSVGForExport();
166
-
167
- this.renderTo.parentNode.appendChild(div);
168
- }
169
- }, {
170
-
171
- text: 'View SVG Source',
172
- onclick: function () {
173
- var pre = doc.createElement('pre');
174
- pre.innerHTML = this.getSVGForExport()
175
- .replace(/</g, '\n&lt;')
176
- .replace(/>/g, '&gt;');
177
-
178
- this.renderTo.parentNode.appendChild(pre);
179
- }
130
+ }, {
131
+ separator: true
132
+ }, {
133
+ textKey: 'downloadPNG',
134
+ onclick: function() {
135
+ this.exportChart();
136
+ }
137
+ }, {
138
+ textKey: 'downloadJPEG',
139
+ onclick: function() {
140
+ this.exportChart({
141
+ type: 'image/jpeg'
142
+ });
143
+ }
144
+ }, {
145
+ textKey: 'downloadPDF',
146
+ onclick: function() {
147
+ this.exportChart({
148
+ type: 'application/pdf'
149
+ });
150
+ }
151
+ }, {
152
+ textKey: 'downloadSVG',
153
+ onclick: function() {
154
+ this.exportChart({
155
+ type: 'image/svg+xml'
156
+ });
180
157
  }
181
- // */
182
- ]
158
+ }]
183
159
  }
184
160
  }
185
161
  };
186
162
 
187
163
  // Add the H.post utility
188
164
  H.post = function(url, data, formAttributes) {
189
- var name,
190
- form;
191
-
192
165
  // create the form
193
- form = createElement('form', merge({
166
+ var form = createElement('form', merge({
194
167
  method: 'post',
195
168
  action: url,
196
169
  enctype: 'multipart/form-data'
@@ -199,13 +172,13 @@
199
172
  }, doc.body);
200
173
 
201
174
  // add the data
202
- for (name in data) {
175
+ objectEach(data, function(val, name) {
203
176
  createElement('input', {
204
177
  type: 'hidden',
205
178
  name: name,
206
- value: data[name]
179
+ value: val
207
180
  }, null, form);
208
- }
181
+ });
209
182
 
210
183
  // submit
211
184
  form.submit();
@@ -214,7 +187,7 @@
214
187
  discardElement(form);
215
188
  };
216
189
 
217
- extend(Chart.prototype, {
190
+ extend(Chart.prototype, /** @lends Highcharts.Chart.prototype */ {
218
191
 
219
192
  /**
220
193
  * A collection of fixes on the produced SVG to account for expando properties,
@@ -290,13 +263,17 @@
290
263
  /**
291
264
  * Return an SVG representation of the chart.
292
265
  *
293
- * @param additionalOptions {Object} Additional chart options for the
294
- * generated SVG representation. For collections like `xAxis`, `yAxis` or
295
- * `series`, the additional options is either merged in to the orininal
296
- * item of the same `id`, or to the first item if a commin id is not
297
- * found.
266
+ * @param chartOptions {Options}
267
+ * Additional chart options for the generated SVG representation.
268
+ * For collections like `xAxis`, `yAxis` or `series`, the additional
269
+ * options is either merged in to the orininal item of the same
270
+ * `id`, or to the first item if a common id is not found.
271
+ * @return {String}
272
+ * The SVG representation of the rendered chart.
273
+ * @sample highcharts/members/chart-getsvg/
274
+ * View the SVG from a button
298
275
  */
299
- getSVG: function(additionalOptions) {
276
+ getSVG: function(chartOptions) {
300
277
  var chart = this,
301
278
  chartCopy,
302
279
  sandbox,
@@ -306,7 +283,7 @@
306
283
  sourceHeight,
307
284
  cssWidth,
308
285
  cssHeight,
309
- options = merge(chart.options, additionalOptions); // copy the options and add extra options
286
+ options = merge(chart.options, chartOptions); // copy the options and add extra options
310
287
 
311
288
 
312
289
  // IE compatibility hack for generating SVG content that it doesn't really understand
@@ -374,11 +351,11 @@
374
351
  chartCopy = new H.Chart(options, chart.callback);
375
352
 
376
353
  // Axis options and series options (#2022, #3900, #5982)
377
- if (additionalOptions) {
354
+ if (chartOptions) {
378
355
  each(['xAxis', 'yAxis', 'series'], function(coll) {
379
356
  var collOptions = {};
380
- if (additionalOptions[coll]) {
381
- collOptions[coll] = additionalOptions[coll];
357
+ if (chartOptions[coll]) {
358
+ collOptions[coll] = chartOptions[coll];
382
359
  chartCopy.update(collOptions);
383
360
  }
384
361
  });
@@ -431,30 +408,61 @@
431
408
  },
432
409
 
433
410
  /**
434
- * Submit the SVG representation of the chart to the server
435
- * @param {Object} options Exporting options. Possible members are url, type, width and formAttributes.
436
- * @param {Object} chartOptions Additional chart options for the SVG representation of the chart
411
+ * Exporting module required. Submit an SVG version of the chart to a server
412
+ * along with some parameters for conversion.
413
+ * @param {Object} exportingOptions
414
+ * Exporting options in addition to those defined in {@link
415
+ * https://api.highcharts.com/highcharts/exporting|exporting}.
416
+ * @param {String} exportingOptions.filename
417
+ * The file name for the export without extension.
418
+ * @param {String} exportingOptions.url
419
+ * The URL for the server module to do the conversion.
420
+ * @param {Number} exportingOptions.width
421
+ * The width of the PNG or JPG image generated on the server.
422
+ * @param {String} exportingOptions.type
423
+ * The MIME type of the converted image.
424
+ * @param {Number} exportingOptions.sourceWidth
425
+ * The pixel width of the source (in-page) chart.
426
+ * @param {Number} exportingOptions.sourceHeight
427
+ * The pixel height of the source (in-page) chart.
428
+ * @param {Options} chartOptions
429
+ * Additional chart options for the exported chart. For example a
430
+ * different background color can be added here, or `dataLabels`
431
+ * for export only.
432
+ *
433
+ * @sample highcharts/members/chart-exportchart/
434
+ * Export with no options
435
+ * @sample highcharts/members/chart-exportchart-filename/
436
+ * PDF type and custom filename
437
+ * @sample highcharts/members/chart-exportchart-custom-background/
438
+ * Different chart background in export
437
439
  */
438
- exportChart: function(options, chartOptions) {
440
+ exportChart: function(exportingOptions, chartOptions) {
439
441
 
440
- var svg = this.getSVGForExport(options, chartOptions);
442
+ var svg = this.getSVGForExport(exportingOptions, chartOptions);
441
443
 
442
444
  // merge the options
443
- options = merge(this.options.exporting, options);
445
+ exportingOptions = merge(this.options.exporting, exportingOptions);
444
446
 
445
447
  // do the post
446
- H.post(options.url, {
447
- filename: options.filename || 'chart',
448
- type: options.type,
449
- width: options.width || 0, // IE8 fails to post undefined correctly, so use 0
450
- scale: options.scale,
448
+ H.post(exportingOptions.url, {
449
+ filename: exportingOptions.filename || 'chart',
450
+ type: exportingOptions.type,
451
+ width: exportingOptions.width || 0, // IE8 fails to post undefined correctly, so use 0
452
+ scale: exportingOptions.scale,
451
453
  svg: svg
452
- }, options.formAttributes);
454
+ }, exportingOptions.formAttributes);
453
455
 
454
456
  },
455
457
 
456
458
  /**
457
- * Print the chart
459
+ * Exporting module required. Clears away other elements in the page and
460
+ * prints the chart as it is displayed. By default, when the exporting
461
+ * module is enabled, a context button with a drop down menu in the upper
462
+ * right corner accesses this function.
463
+ *
464
+ * @sample highcharts/members/chart-print/
465
+ * Print from a HTML button
458
466
  */
459
467
  print: function() {
460
468
 
@@ -855,28 +863,28 @@
855
863
 
856
864
  // Add the buttons on chart load
857
865
  Chart.prototype.renderExporting = function() {
858
- var n,
859
- exportingOptions = this.options.exporting,
866
+ var chart = this,
867
+ exportingOptions = chart.options.exporting,
860
868
  buttons = exportingOptions.buttons,
861
- isDirty = this.isDirtyExporting || !this.exportSVGElements;
869
+ isDirty = chart.isDirtyExporting || !chart.exportSVGElements;
862
870
 
863
- this.buttonOffset = 0;
864
- if (this.isDirtyExporting) {
865
- this.destroyExport();
871
+ chart.buttonOffset = 0;
872
+ if (chart.isDirtyExporting) {
873
+ chart.destroyExport();
866
874
  }
867
875
 
868
876
  if (isDirty && exportingOptions.enabled !== false) {
869
- this.exportEvents = [];
877
+ chart.exportEvents = [];
870
878
 
871
- for (n in buttons) {
872
- this.addButton(buttons[n]);
873
- }
879
+ objectEach(buttons, function(button) {
880
+ chart.addButton(button);
881
+ });
874
882
 
875
- this.isDirtyExporting = false;
883
+ chart.isDirtyExporting = false;
876
884
  }
877
885
 
878
886
  // Destroy the export elements at chart destroy
879
- addEvent(this, 'destroy', this.destroyExport);
887
+ addEvent(chart, 'destroy', chart.destroyExport);
880
888
  };
881
889
 
882
890
  Chart.prototype.callbacks.push(function(chart) {
@@ -908,14 +916,29 @@
908
916
  // testing of export
909
917
  /*
910
918
  if (!chart.renderer.forExport) {
911
- var button = doc.createElement('button');
912
- button.innerHTML = 'View exported SVG';
919
+ var button;
920
+
921
+ // View SVG Image
922
+ button = doc.createElement('button');
923
+ button.innerHTML = 'View SVG Image';
913
924
  chart.renderTo.parentNode.appendChild(button);
914
925
  button.onclick = function () {
915
926
  var div = doc.createElement('div');
916
927
  div.innerHTML = chart.getSVGForExport();
917
928
  chart.renderTo.parentNode.appendChild(div);
918
929
  };
930
+
931
+ // View SVG Source
932
+ button = doc.createElement('button');
933
+ button.innerHTML = 'View SVG Source';
934
+ chart.renderTo.parentNode.appendChild(button);
935
+ button.onclick = function () {
936
+ var pre = doc.createElement('pre');
937
+ pre.innerHTML = chart.getSVGForExport()
938
+ .replace(/</g, '\n&lt;')
939
+ .replace(/>/g, '&gt;');
940
+ chart.renderTo.parentNode.appendChild(pre);
941
+ };
919
942
  }
920
943
  // */
921
944
  });