highcharts-rails 4.1.7 → 4.1.8

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Highcharts JS v4.1.7 (2015-06-26)
2
+ * Highcharts JS v4.1.8 (2015-08-20)
3
3
  * Highcharts Broken Axis module
4
4
  *
5
5
  * Author: Stephane Vanraes, Torstein Honsi
@@ -24,16 +24,18 @@
24
24
 
25
25
  extend(Axis.prototype, {
26
26
  isInBreak: function (brk, val) {
27
- var repeat = brk.repeat || Infinity,
27
+ var ret,
28
+ repeat = brk.repeat || Infinity,
28
29
  from = brk.from,
29
30
  length = brk.to - brk.from,
30
31
  test = (val >= from ? (val - from) % repeat : repeat - ((from - val) % repeat));
31
32
 
32
33
  if (!brk.inclusive) {
33
- return (test < length && test !== 0);
34
+ ret = test < length && test !== 0;
34
35
  } else {
35
- return (test <= length);
36
+ ret = test <= length;
36
37
  }
38
+ return ret;
37
39
  },
38
40
 
39
41
  isInAnyBreak: function (val, testKeep) {
@@ -286,6 +288,8 @@
286
288
  points = series.points,
287
289
  yAxis = series.yAxis,
288
290
  breaks = yAxis.breakArray || [],
291
+ threshold = pick(this.options.threshold, yAxis.min),
292
+ eventName,
289
293
  point,
290
294
  brk,
291
295
  i,
@@ -297,12 +301,15 @@
297
301
  y = point.stackY || point.y;
298
302
  for (j = 0; j < breaks.length; j++) {
299
303
  brk = breaks[j];
300
- if (y < brk.from) {
301
- break;
302
- } else if (y > brk.to) {
303
- fireEvent(yAxis, 'pointBreak', {point: point, brk: brk});
304
- } else {
305
- fireEvent(yAxis, 'pointInBreak', {point: point, brk: brk});
304
+ eventName = false;
305
+
306
+ if ((threshold < brk.from && y > brk.to) || (threshold > brk.from && y < brk.from)) {
307
+ eventName = 'pointBreak';
308
+ } else if ((threshold < brk.from && y > brk.from && y < brk.to) || (threshold > brk.from && y > brk.to && y < brk.from)) { // point falls inside the break
309
+ eventName = 'pointInBreak'; // docs
310
+ }
311
+ if (eventName) {
312
+ fireEvent(yAxis, eventName, {point: point, brk: brk});
306
313
  }
307
314
  }
308
315
  }
@@ -2908,7 +2908,7 @@ if (CanvasRenderingContext2D) {
2908
2908
  });
2909
2909
  }
2910
2910
  }/**
2911
- * @license Highcharts JS v4.1.7 (2015-06-26)
2911
+ * @license Highcharts JS v4.1.8 (2015-08-20)
2912
2912
  * CanVGRenderer Extension module
2913
2913
  *
2914
2914
  * (c) 2011-2012 Torstein Honsi, Erik Olsson
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.7 (2015-06-26)
2
+ * @license Highcharts JS v4.1.8 (2015-08-20)
3
3
  * Data module
4
4
  *
5
5
  * (c) 2012-2014 Torstein Honsi
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.7 (2015-06-26)
2
+ * @license Highcharts JS v4.1.8 (2015-08-20)
3
3
  * Exporting module
4
4
  *
5
5
  * (c) 2010-2014 Torstein Honsi
@@ -233,6 +233,13 @@ extend(Chart.prototype, {
233
233
  });
234
234
  },
235
235
 
236
+ /**
237
+ * Return innerHTML of chart. Used as hook for plugins.
238
+ */
239
+ getChartHTML: function () {
240
+ return this.container.innerHTML;
241
+ },
242
+
236
243
  /**
237
244
  * Return an SVG representation of the chart
238
245
  *
@@ -248,7 +255,10 @@ extend(Chart.prototype, {
248
255
  sourceHeight,
249
256
  cssWidth,
250
257
  cssHeight,
251
- options = merge(chart.options, additionalOptions); // copy the options and add extra options
258
+ html,
259
+ options = merge(chart.options, additionalOptions), // copy the options and add extra options
260
+ allowHTML = options.exporting.allowHTML; // docs: experimental, see #2473
261
+
252
262
 
253
263
  // IE compatibility hack for generating SVG content that it doesn't really understand
254
264
  if (!doc.createElementNS) {
@@ -283,7 +293,7 @@ extend(Chart.prototype, {
283
293
  extend(options.chart, {
284
294
  animation: false,
285
295
  renderTo: sandbox,
286
- forExport: true,
296
+ forExport: !allowHTML,
287
297
  width: sourceWidth,
288
298
  height: sourceHeight
289
299
  });
@@ -332,13 +342,26 @@ extend(Chart.prototype, {
332
342
  });
333
343
 
334
344
  // get the SVG from the container's innerHTML
335
- svg = chartCopy.container.innerHTML;
345
+ svg = chartCopy.getChartHTML();
336
346
 
337
347
  // free up memory
338
348
  options = null;
339
349
  chartCopy.destroy();
340
350
  discardElement(sandbox);
341
351
 
352
+ // Move HTML into a foreignObject
353
+ if (allowHTML) {
354
+ html = svg.match(/<\/svg>(.*?$)/);
355
+ if (html) {
356
+ html = '<foreignObject x="0" y="0 width="200" height="200">' +
357
+ '<body xmlns="http://www.w3.org/1999/xhtml">' +
358
+ html[1] +
359
+ '</body>' +
360
+ '</foreignObject>';
361
+ svg = svg.replace('</svg>', html + '</svg>');
362
+ }
363
+ }
364
+
342
365
  // sanitize
343
366
  svg = this.sanitizeSVG(svg);
344
367
 
@@ -530,7 +553,8 @@ extend(Chart.prototype, {
530
553
  onmouseout: function () {
531
554
  css(this, menuItemStyle);
532
555
  },
533
- onclick: function () {
556
+ onclick: function (e) {
557
+ e.stopPropagation();
534
558
  hide();
535
559
  if (item.onclick) {
536
560
  item.onclick.apply(chart, arguments);
@@ -613,8 +637,9 @@ extend(Chart.prototype, {
613
637
  delete attr.states;
614
638
 
615
639
  if (onclick) {
616
- callback = function () {
617
- onclick.apply(chart, arguments);
640
+ callback = function (e) {
641
+ e.stopPropagation();
642
+ onclick.call(chart, e);
618
643
  };
619
644
 
620
645
  } else if (menuItems) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.7 (2015-06-26)
2
+ * @license Highcharts JS v4.1.8 (2015-08-20)
3
3
  *
4
4
  * (c) 2011-2014 Torstein Honsi
5
5
  *
@@ -17,6 +17,7 @@ var UNDEFINED,
17
17
  Legend = Highcharts.Legend,
18
18
  LegendSymbolMixin = Highcharts.LegendSymbolMixin,
19
19
  Series = Highcharts.Series,
20
+ Point = Highcharts.Point,
20
21
 
21
22
  defaultOptions = Highcharts.getOptions(),
22
23
  each = Highcharts.each,
@@ -42,6 +43,8 @@ extend(ColorAxis.prototype, Axis.prototype);
42
43
  extend(ColorAxis.prototype, {
43
44
  defaultColorAxisOptions: {
44
45
  lineWidth: 0,
46
+ minPadding: 0,
47
+ maxPadding: 0,
45
48
  gridLineWidth: 1,
46
49
  tickPixelInterval: 72,
47
50
  startOnTick: true,
@@ -70,7 +73,6 @@ extend(ColorAxis.prototype, {
70
73
  side: horiz ? 2 : 1,
71
74
  reversed: !horiz
72
75
  }, userOptions, {
73
- isX: horiz,
74
76
  opposite: !horiz,
75
77
  showEmpty: false,
76
78
  title: null,
@@ -89,7 +91,6 @@ extend(ColorAxis.prototype, {
89
91
  this.initStops(userOptions);
90
92
 
91
93
  // Override original axis properties
92
- this.isXAxis = true;
93
94
  this.horiz = horiz;
94
95
  this.zoomEnabled = false;
95
96
  },
@@ -392,7 +393,7 @@ extend(ColorAxis.prototype, {
392
393
  });
393
394
 
394
395
  // When updating data classes, destroy old items and make sure new ones are created (#3207)
395
- if (newOptions.dataClasses) {
396
+ if (newOptions.dataClasses && legend.allItems) {
396
397
  each(legend.allItems, function (item) {
397
398
  if (item.isDataClass) {
398
399
  item.legendGroup.destroy();
@@ -531,6 +532,22 @@ wrap(Legend.prototype, 'getAllItems', function (proceed) {
531
532
  });/**
532
533
  * Mixin for maps and heatmaps
533
534
  */
535
+ var colorPointMixin = {
536
+ /**
537
+ * Set the visibility of a single point
538
+ */
539
+ setVisible: function (vis) {
540
+ var point = this,
541
+ method = vis ? 'show' : 'hide';
542
+
543
+ // Show and hide associated elements
544
+ each(['graphic', 'dataLabel'], function (key) {
545
+ if (point[key]) {
546
+ point[key][method]();
547
+ }
548
+ });
549
+ }
550
+ };
534
551
  var colorSeriesMixin = {
535
552
 
536
553
  pointAttrToOptions: { // mapping between SVG attributes and the corresponding options
@@ -560,7 +577,8 @@ var colorSeriesMixin = {
560
577
  var value = point[colorKey],
561
578
  color;
562
579
 
563
- color = value === null ? nullColor : (colorAxis && value !== undefined) ? colorAxis.toColor(value, point) : point.color || series.color;
580
+ color = point.options.color ||
581
+ (value === null ? nullColor : (colorAxis && value !== undefined) ? colorAxis.toColor(value, point) : point.color || series.color);
564
582
 
565
583
  if (color) {
566
584
  point.color = color;
@@ -606,6 +624,7 @@ seriesTypes.heatmap = extendClass(seriesTypes.scatter, merge(colorSeriesMixin, {
606
624
  type: 'heatmap',
607
625
  pointArrayMap: ['y', 'value'],
608
626
  hasPointSpecificOptions: true,
627
+ pointClass: extendClass(Point, colorPointMixin),
609
628
  supportsDrilldown: true,
610
629
  getExtremesFromAll: true,
611
630
  directTouch: true,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.7 (2015-06-26)
2
+ * @license Highcharts JS v4.1.8 (2015-08-20)
3
3
  * Plugin for displaying a message when there is no data visible in chart.
4
4
  *
5
5
  * (c) 2010-2014 Highsoft AS
@@ -0,0 +1,276 @@
1
+ /**
2
+ * @license Highcharts JS v4.1.8 (2015-08-20)
3
+ * Client side exporting module
4
+ *
5
+ * (c) 2015 Torstein Honsi / Oystein Moseng
6
+ *
7
+ * License: www.highcharts.com/license
8
+ */
9
+
10
+ // JSLint options:
11
+ /*global Highcharts, HighchartsAdapter, document, window, Blob, MSBlobBuilder */
12
+
13
+ (function (Highcharts) {
14
+
15
+ // Dummy object so we can reuse our canvas-tools.js without errors
16
+ Highcharts.CanVGRenderer = {};
17
+
18
+ /**
19
+ * Add a new method to the Chart object to perform a local download
20
+ */
21
+ Highcharts.Chart.prototype.exportChartLocal = function (exportingOptions, chartOptions) {
22
+ var chart = this,
23
+ options = Highcharts.merge(chart.options.exporting, exportingOptions),
24
+ webKit = navigator.userAgent.indexOf('WebKit') > -1 && navigator.userAgent.indexOf("Chrome") < 0, // Webkit and not chrome
25
+ scale = options.scale || 2,
26
+ chartCopyContainer,
27
+ domurl = window.URL || window.webkitURL || window,
28
+ images,
29
+ imagesEmbedded = 0,
30
+ el,
31
+ i,
32
+ l,
33
+ fallbackToExportServer = function () {
34
+ if (options.fallbackToExportServer === false) {
35
+ throw 'Fallback to export server disabled';
36
+ }
37
+ chart.exportChart(options);
38
+ },
39
+ // Get data:URL from image URL
40
+ // Pass in callbacks to handle results. finallyCallback is always called at the end of the process. Supplying this callback is optional.
41
+ // All callbacks receive two arguments: imageURL, and callbackArgs. callbackArgs is used only by callbacks and can contain whatever.
42
+ imageToDataUrl = function (imageURL, callbackArgs, successCallback, taintedCallback, noCanvasSupportCallback, failedLoadCallback, finallyCallback) {
43
+ var img = new Image();
44
+ if (!webKit) {
45
+ img.crossOrigin = 'Anonymous'; // For some reason Safari chokes on this attribute
46
+ }
47
+ img.onload = function () {
48
+ var canvas = document.createElement('canvas'),
49
+ ctx = canvas.getContext && canvas.getContext('2d'),
50
+ dataURL;
51
+
52
+ if (!ctx) {
53
+ noCanvasSupportCallback(imageURL, callbackArgs);
54
+ } else {
55
+ canvas.height = img.height * scale;
56
+ canvas.width = img.width * scale;
57
+ ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
58
+
59
+ // Now we try to get the contents of the canvas.
60
+ try {
61
+ dataURL = canvas.toDataURL();
62
+ successCallback(dataURL, callbackArgs);
63
+ } catch (e) {
64
+ // Failed - either tainted canvas or something else went horribly wrong
65
+ if (e.name === 'SecurityError' || e.name === 'SECURITY_ERR' || e.message === 'SecurityError') {
66
+ taintedCallback(imageURL, callbackArgs);
67
+ } else {
68
+ throw e;
69
+ }
70
+ }
71
+ }
72
+ if (finallyCallback) {
73
+ finallyCallback(imageURL, callbackArgs);
74
+ }
75
+ };
76
+ img.onerror = function () {
77
+ failedLoadCallback(imageURL, callbackArgs);
78
+ if (finallyCallback) {
79
+ finallyCallback(imageURL, callbackArgs);
80
+ }
81
+ };
82
+ img.src = imageURL;
83
+ },
84
+ // Get blob URL from SVG code. Falls back to normal data URI.
85
+ svgToDataUrl = function (svg) {
86
+ try {
87
+ // Safari requires data URI since it doesn't allow navigation to blob URLs
88
+ if (!webKit) {
89
+ return domurl.createObjectURL(new Blob([svg], { type: 'image/svg+xml;charset-utf-16'}));
90
+ }
91
+ } catch (e) {
92
+ // Ignore
93
+ }
94
+ return 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg);
95
+ },
96
+ // Download contents by dataURL/blob
97
+ download = function (dataURL, extension) {
98
+ var a = document.createElement('a'),
99
+ filename = (options.filename || 'chart') + '.' + extension,
100
+ windowRef;
101
+
102
+ // IE specific blob implementation
103
+ if (navigator.msSaveOrOpenBlob) {
104
+ navigator.msSaveOrOpenBlob(dataURL, filename);
105
+ return;
106
+ }
107
+
108
+ // Try HTML5 download attr if supported
109
+ if (typeof a.download !== 'undefined') {
110
+ a.href = dataURL;
111
+ a.download = filename; // HTML5 download attribute
112
+ a.target = '_blank';
113
+ document.body.appendChild(a);
114
+ a.click();
115
+ document.body.removeChild(a);
116
+ } else {
117
+ // No download attr, just opening data URI
118
+ try {
119
+ windowRef = window.open(dataURL, 'chart');
120
+ if (typeof windowRef === 'undefined' || windowRef === null) {
121
+ throw 1;
122
+ }
123
+ } catch (e) {
124
+ // window.open failed, trying location.href
125
+ window.location.href = dataURL;
126
+ }
127
+ }
128
+ },
129
+ // Get data URL to an image of the chart and call download on it
130
+ initiateDownload = function () {
131
+ var svgurl,
132
+ blob,
133
+ svg = chart.sanitizeSVG(chartCopyContainer.innerHTML); // SVG of chart copy
134
+
135
+ // Initiate download depending on file type
136
+ if (options && options.type === 'image/svg+xml') {
137
+ // SVG download. In this case, we want to use Microsoft specific Blob if available
138
+ try {
139
+ if (navigator.msSaveOrOpenBlob) {
140
+ blob = new MSBlobBuilder();
141
+ blob.append(svg);
142
+ svgurl = blob.getBlob('image/svg+xml');
143
+ } else {
144
+ svgurl = svgToDataUrl(svg);
145
+ }
146
+ download(svgurl, 'svg');
147
+ } catch (e) {
148
+ fallbackToExportServer();
149
+ }
150
+ } else {
151
+ // PNG download - create bitmap from SVG
152
+
153
+ // First, try to get PNG by rendering on canvas
154
+ svgurl = svgToDataUrl(svg);
155
+ imageToDataUrl(svgurl, { /* args */ }, function (imageURL) {
156
+ // Success
157
+ try {
158
+ download(imageURL, 'png');
159
+ } catch (e) {
160
+ fallbackToExportServer();
161
+ }
162
+ }, function () {
163
+ // Failed due to tainted canvas
164
+ // Create new and untainted canvas
165
+ var canvas = document.createElement('canvas'),
166
+ ctx = canvas.getContext('2d'),
167
+ imageWidth = svg.match(/^<svg[^>]*width\s*=\s*\"?(\d+)\"?[^>]*>/)[1] * scale,
168
+ imageHeight = svg.match(/^<svg[^>]*height\s*=\s*\"?(\d+)\"?[^>]*>/)[1] * scale,
169
+ downloadWithCanVG = function () {
170
+ ctx.drawSvg(svg, 0, 0, imageWidth, imageHeight);
171
+ try {
172
+ download(navigator.msSaveOrOpenBlob ? canvas.msToBlob() : canvas.toDataURL('image/png'), 'png');
173
+ } catch (e) {
174
+ fallbackToExportServer();
175
+ }
176
+ };
177
+
178
+ canvas.width = imageWidth;
179
+ canvas.height = imageHeight;
180
+ if (window.canvg) {
181
+ // Use preloaded canvg
182
+ downloadWithCanVG();
183
+ } else {
184
+ // Must load canVG first
185
+ chart.showLoading();
186
+ HighchartsAdapter.getScript(Highcharts.getOptions().global.canvasToolsURL, function () {
187
+ chart.hideLoading();
188
+ downloadWithCanVG();
189
+ });
190
+ }
191
+ },
192
+ // No canvas support
193
+ fallbackToExportServer,
194
+ // Failed to load image
195
+ fallbackToExportServer,
196
+ // Finally
197
+ function () {
198
+ try {
199
+ domurl.revokeObjectURL(svgurl);
200
+ } catch (e) {
201
+ // Ignore
202
+ }
203
+ });
204
+ }
205
+ };
206
+
207
+ // Hook into getSVG to get a copy of the chart copy's container
208
+ Highcharts.wrap(Highcharts.Chart.prototype, 'getChartHTML', function (proceed) {
209
+ chartCopyContainer = this.container.cloneNode(true);
210
+ return proceed.apply(this, Array.prototype.slice.call(arguments, 1));
211
+ });
212
+
213
+ // Trigger hook to get chart copy
214
+ chart.getSVGForExport(options, chartOptions);
215
+ images = chartCopyContainer.getElementsByTagName('image');
216
+
217
+ try {
218
+ // If there are no images to embed, just go ahead and start the download process
219
+ if (!images.length) {
220
+ initiateDownload();
221
+ }
222
+
223
+ // Success handler, we converted image to base64!
224
+ function embeddedSuccess(imageURL, callbackArgs) {
225
+ ++imagesEmbedded;
226
+
227
+ // Change image href in chart copy
228
+ callbackArgs.imageElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', imageURL);
229
+
230
+ // Start download when done with the last image
231
+ if (imagesEmbedded === images.length) {
232
+ initiateDownload();
233
+ }
234
+ }
235
+
236
+ // Go through the images we want to embed
237
+ for (i = 0, l = images.length; i < l; ++i) {
238
+ el = images[i];
239
+ imageToDataUrl(el.getAttributeNS('http://www.w3.org/1999/xlink', 'href'), { imageElement: el },
240
+ embeddedSuccess,
241
+ // Tainted canvas
242
+ fallbackToExportServer,
243
+ // No canvas support
244
+ fallbackToExportServer,
245
+ // Failed to load source
246
+ fallbackToExportServer
247
+ );
248
+ }
249
+ } catch (e) {
250
+ fallbackToExportServer();
251
+ }
252
+ };
253
+
254
+ // Extend the default options to use the local exporter logic
255
+ Highcharts.getOptions().exporting.buttons.contextButton.menuItems = [{
256
+ textKey: 'printChart',
257
+ onclick: function () {
258
+ this.print();
259
+ }
260
+ }, {
261
+ separator: true
262
+ }, {
263
+ textKey: 'downloadPNG',
264
+ onclick: function () {
265
+ this.exportChartLocal();
266
+ }
267
+ }, {
268
+ textKey: 'downloadSVG',
269
+ onclick: function () {
270
+ this.exportChartLocal({
271
+ type: 'image/svg+xml'
272
+ });
273
+ }
274
+ }];
275
+
276
+ }(Highcharts));