highcharts-rails 5.0.14 → 6.0.0

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.markdown +60 -0
  3. data/Rakefile +54 -5
  4. data/app/assets/images/highcharts/earth.svg +432 -0
  5. data/app/assets/javascripts/highcharts.js +5103 -3147
  6. data/app/assets/javascripts/highcharts/highcharts-3d.js +930 -277
  7. data/app/assets/javascripts/highcharts/highcharts-more.js +1374 -249
  8. data/app/assets/javascripts/highcharts/lib/canvg.js +3073 -0
  9. data/app/assets/javascripts/highcharts/lib/jspdf.js +16624 -0
  10. data/app/assets/javascripts/highcharts/lib/rgbcolor.js +299 -0
  11. data/app/assets/javascripts/highcharts/lib/svg2pdf.js +3488 -0
  12. data/app/assets/javascripts/highcharts/modules/accessibility.js +654 -212
  13. data/app/assets/javascripts/highcharts/modules/annotations.js +1552 -274
  14. data/app/assets/javascripts/highcharts/modules/boost-canvas.js +773 -0
  15. data/app/assets/javascripts/highcharts/modules/boost.js +636 -210
  16. data/app/assets/javascripts/highcharts/modules/broken-axis.js +2 -2
  17. data/app/assets/javascripts/highcharts/modules/bullet.js +364 -0
  18. data/app/assets/javascripts/highcharts/modules/data.js +766 -38
  19. data/app/assets/javascripts/highcharts/modules/drag-panes.js +588 -0
  20. data/app/assets/javascripts/highcharts/modules/drilldown.js +106 -36
  21. data/app/assets/javascripts/highcharts/modules/export-data.js +597 -0
  22. data/app/assets/javascripts/highcharts/modules/exporting.js +424 -162
  23. data/app/assets/javascripts/highcharts/modules/funnel.js +144 -22
  24. data/app/assets/javascripts/highcharts/modules/gantt.js +1154 -0
  25. data/app/assets/javascripts/highcharts/modules/grid-axis.js +1 -1
  26. data/app/assets/javascripts/highcharts/modules/heatmap.js +406 -80
  27. data/app/assets/javascripts/highcharts/modules/histogram-bellcurve.js +513 -0
  28. data/app/assets/javascripts/highcharts/modules/item-series.js +126 -0
  29. data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +31 -13
  30. data/app/assets/javascripts/highcharts/modules/offline-exporting.js +179 -57
  31. data/app/assets/javascripts/highcharts/modules/oldie.js +1378 -0
  32. data/app/assets/javascripts/highcharts/modules/overlapping-datalabels.js +8 -6
  33. data/app/assets/javascripts/highcharts/modules/parallel-coordinates.js +494 -0
  34. data/app/assets/javascripts/highcharts/modules/pareto.js +275 -0
  35. data/app/assets/javascripts/highcharts/modules/sankey.js +641 -0
  36. data/app/assets/javascripts/highcharts/modules/series-label.js +355 -145
  37. data/app/assets/javascripts/highcharts/modules/solid-gauge.js +122 -1
  38. data/app/assets/javascripts/highcharts/modules/static-scale.js +64 -0
  39. data/app/assets/javascripts/highcharts/modules/stock.js +1944 -676
  40. data/app/assets/javascripts/highcharts/modules/streamgraph.js +139 -0
  41. data/app/assets/javascripts/highcharts/modules/sunburst.js +2403 -0
  42. data/app/assets/javascripts/highcharts/modules/tilemap.js +1199 -0
  43. data/app/assets/javascripts/highcharts/modules/treemap.js +538 -134
  44. data/app/assets/javascripts/highcharts/modules/variable-pie.js +490 -0
  45. data/app/assets/javascripts/highcharts/modules/variwide.js +283 -0
  46. data/app/assets/javascripts/highcharts/modules/vector.js +294 -0
  47. data/app/assets/javascripts/highcharts/modules/windbarb.js +490 -0
  48. data/app/assets/javascripts/highcharts/modules/wordcloud.js +681 -0
  49. data/app/assets/javascripts/highcharts/modules/xrange.js +615 -0
  50. data/app/assets/javascripts/highcharts/themes/avocado.js +54 -0
  51. data/app/assets/javascripts/highcharts/themes/dark-blue.js +6 -6
  52. data/app/assets/javascripts/highcharts/themes/dark-green.js +6 -6
  53. data/app/assets/javascripts/highcharts/themes/dark-unica.js +6 -6
  54. data/app/assets/javascripts/highcharts/themes/gray.js +14 -10
  55. data/app/assets/javascripts/highcharts/themes/grid-light.js +6 -6
  56. data/app/assets/javascripts/highcharts/themes/grid.js +7 -5
  57. data/app/assets/javascripts/highcharts/themes/sand-signika.js +8 -7
  58. data/app/assets/javascripts/highcharts/themes/skies.js +15 -9
  59. data/app/assets/javascripts/highcharts/themes/sunset.js +53 -0
  60. data/app/assets/stylesheets/highcharts/highcharts.css +802 -0
  61. data/app/assets/stylesheets/highcharts/highcharts.scss +665 -0
  62. data/lib/highcharts/version.rb +1 -1
  63. metadata +31 -1
@@ -0,0 +1,773 @@
1
+ /**
2
+ * @license Highcharts JS v6.0.0 (2017-10-04)
3
+ * Boost module
4
+ *
5
+ * (c) 2010-2017 Highsoft AS
6
+ * Author: Torstein Honsi
7
+ *
8
+ * License: www.highcharts.com/license
9
+ */
10
+ 'use strict';
11
+ (function(factory) {
12
+ if (typeof module === 'object' && module.exports) {
13
+ module.exports = factory;
14
+ } else {
15
+ factory(Highcharts);
16
+ }
17
+ }(function(Highcharts) {
18
+ (function(H) {
19
+ /**
20
+ * License: www.highcharts.com/license
21
+ * Author: Torstein Honsi, Christer Vasseng
22
+ *
23
+ * This is an experimental Highcharts module that draws long data series on a canvas
24
+ * in order to increase performance of the initial load time and tooltip responsiveness.
25
+ *
26
+ * Compatible with HTML5 canvas compatible browsers (not IE < 9).
27
+ *
28
+ *
29
+ *
30
+ * Development plan
31
+ * - Column range.
32
+ * - Heatmap. Modify the heatmap-canvas demo so that it uses this module.
33
+ * - Treemap.
34
+ * - Check how it works with Highstock and data grouping. Currently it only works when navigator.adaptToUpdatedData
35
+ * is false. It is also recommended to set scrollbar.liveRedraw to false.
36
+ * - Check inverted charts.
37
+ * - Check reversed axes.
38
+ * - Chart callback should be async after last series is drawn. (But not necessarily, we don't do
39
+ that with initial series animation).
40
+ * - Cache full-size image so we don't have to redraw on hide/show and zoom up. But k-d-tree still
41
+ * needs to be built.
42
+ * - Test IE9 and IE10.
43
+ * - Stacking is not perhaps not correct since it doesn't use the translation given in
44
+ * the translate method. If this gets to complicated, a possible way out would be to
45
+ * have a simplified renderCanvas method that simply draws the areaPath on a canvas.
46
+ *
47
+ * If this module is taken in as part of the core
48
+ * - All the loading logic should be merged with core. Update styles in the core.
49
+ * - Most of the method wraps should probably be added directly in parent methods.
50
+ *
51
+ * Notes for boost mode
52
+ * - Area lines are not drawn
53
+ * - Point markers are not drawn on line-type series
54
+ * - Lines are not drawn on scatter charts
55
+ * - Zones and negativeColor don't work
56
+ * - Initial point colors aren't rendered
57
+ * - Columns are always one pixel wide. Don't set the threshold too low.
58
+ *
59
+ * Optimizing tips for users
60
+ * - For scatter plots, use a marker.radius of 1 or less. It results in a rectangle being drawn, which is
61
+ * considerably faster than a circle.
62
+ * - Set extremes (min, max) explicitly on the axes in order for Highcharts to avoid computing extremes.
63
+ * - Set enableMouseTracking to false on the series to improve total rendering time.
64
+ * - The default threshold is set based on one series. If you have multiple, dense series, the combined
65
+ * number of points drawn gets higher, and you may want to set the threshold lower in order to
66
+ * use optimizations.
67
+ */
68
+
69
+
70
+ var win = H.win,
71
+ doc = win.document,
72
+ noop = function() {},
73
+ Color = H.Color,
74
+ Series = H.Series,
75
+ seriesTypes = H.seriesTypes,
76
+ each = H.each,
77
+ extend = H.extend,
78
+ addEvent = H.addEvent,
79
+ fireEvent = H.fireEvent,
80
+ isNumber = H.isNumber,
81
+ merge = H.merge,
82
+ pick = H.pick,
83
+ wrap = H.wrap,
84
+ CHUNK_SIZE = 50000,
85
+ destroyLoadingDiv;
86
+
87
+ function eachAsync(arr, fn, finalFunc, chunkSize, i) {
88
+ i = i || 0;
89
+ chunkSize = chunkSize || CHUNK_SIZE;
90
+
91
+ var threshold = i + chunkSize,
92
+ proceed = true;
93
+
94
+ while (proceed && i < threshold && i < arr.length) {
95
+ proceed = fn(arr[i], i);
96
+ i = i + 1;
97
+ }
98
+ if (proceed) {
99
+ if (i < arr.length) {
100
+ setTimeout(function() {
101
+ eachAsync(arr, fn, finalFunc, chunkSize, i);
102
+ });
103
+ } else if (finalFunc) {
104
+ finalFunc();
105
+ }
106
+ }
107
+ }
108
+
109
+ /*
110
+ * Returns true if the chart is in series boost mode
111
+ * @param chart {Highchart.Chart} - the chart to check
112
+ * @returns {Boolean} - true if the chart is in series boost mode
113
+ */
114
+ function isChartSeriesBoosting(chart) {
115
+ var threshold = (chart.options.boost ? chart.options.boost.seriesThreshold : 0) ||
116
+ chart.options.chart.seriesBoostThreshold ||
117
+ 10;
118
+
119
+ return chart.series.length >= threshold;
120
+ }
121
+
122
+ H.initCanvasBoost = function() {
123
+
124
+ if (H.seriesTypes.heatmap) {
125
+ H.wrap(H.seriesTypes.heatmap.prototype, 'drawPoints', function() {
126
+ var ctx = this.getContext();
127
+ if (ctx) {
128
+
129
+ // draw the columns
130
+ each(this.points, function(point) {
131
+ var plotY = point.plotY,
132
+ shapeArgs,
133
+ pointAttr;
134
+
135
+ if (plotY !== undefined && !isNaN(plotY) && point.y !== null) {
136
+ shapeArgs = point.shapeArgs;
137
+
138
+
139
+ pointAttr = point.series.pointAttribs(point);
140
+
141
+
142
+ ctx.fillStyle = pointAttr.fill;
143
+ ctx.fillRect(shapeArgs.x, shapeArgs.y, shapeArgs.width, shapeArgs.height);
144
+ }
145
+ });
146
+
147
+ this.canvasToSVG();
148
+
149
+ } else {
150
+ this.chart.showLoading('Your browser doesn\'t support HTML5 canvas, <br>please use a modern browser');
151
+
152
+ // Uncomment this to provide low-level (slow) support in oldIE. It will cause script errors on
153
+ // charts with more than a few thousand points.
154
+ // arguments[0].call(this);
155
+ }
156
+ });
157
+ }
158
+
159
+
160
+ /**
161
+ * Override a bunch of methods the same way. If the number of points is below the threshold,
162
+ * run the original method. If not, check for a canvas version or do nothing.
163
+ */
164
+ // each(['translate', 'generatePoints', 'drawTracker', 'drawPoints', 'render'], function (method) {
165
+ // function branch(proceed) {
166
+ // var letItPass = this.options.stacking && (method === 'translate' || method === 'generatePoints');
167
+ // if (((this.processedXData || this.options.data).length < (this.options.boostThreshold || Number.MAX_VALUE) ||
168
+ // letItPass) || !isChartSeriesBoosting(this.chart)) {
169
+
170
+ // // Clear image
171
+ // if (method === 'render' && this.image) {
172
+ // this.image.attr({ href: '' });
173
+ // this.animate = null; // We're zooming in, don't run animation
174
+ // }
175
+
176
+ // proceed.call(this);
177
+
178
+ // // If a canvas version of the method exists, like renderCanvas(), run
179
+ // } else if (this[method + 'Canvas']) {
180
+
181
+ // this[method + 'Canvas']();
182
+ // }
183
+ // }
184
+ // wrap(Series.prototype, method, branch);
185
+
186
+ // // A special case for some types - its translate method is already wrapped
187
+ // if (method === 'translate') {
188
+ // each(['arearange', 'bubble', 'column'], function (type) {
189
+ // if (seriesTypes[type]) {
190
+ // wrap(seriesTypes[type].prototype, method, branch);
191
+ // }
192
+ // });
193
+ // }
194
+ // });
195
+
196
+ H.extend(Series.prototype, {
197
+ directTouch: false,
198
+ pointRange: 0,
199
+ allowDG: false, // No data grouping, let boost handle large data
200
+ hasExtremes: function(checkX) {
201
+ var options = this.options,
202
+ data = options.data,
203
+ xAxis = this.xAxis && this.xAxis.options,
204
+ yAxis = this.yAxis && this.yAxis.options;
205
+ return data.length > (options.boostThreshold || Number.MAX_VALUE) && isNumber(yAxis.min) && isNumber(yAxis.max) &&
206
+ (!checkX || (isNumber(xAxis.min) && isNumber(xAxis.max)));
207
+ },
208
+
209
+ /**
210
+ * If implemented in the core, parts of this can probably be shared with other similar
211
+ * methods in Highcharts.
212
+ */
213
+ destroyGraphics: function() {
214
+ var series = this,
215
+ points = this.points,
216
+ point,
217
+ i;
218
+
219
+ if (points) {
220
+ for (i = 0; i < points.length; i = i + 1) {
221
+ point = points[i];
222
+ if (point && point.graphic) {
223
+ point.graphic = point.graphic.destroy();
224
+ }
225
+ }
226
+ }
227
+
228
+ each(['graph', 'area', 'tracker'], function(prop) {
229
+ if (series[prop]) {
230
+ series[prop] = series[prop].destroy();
231
+ }
232
+ });
233
+ },
234
+
235
+ /**
236
+ * Create a hidden canvas to draw the graph on. The contents is later copied over
237
+ * to an SVG image element.
238
+ */
239
+ getContext: function() {
240
+ var chart = this.chart,
241
+ width = chart.chartWidth,
242
+ height = chart.chartHeight,
243
+ targetGroup = this.group,
244
+ target = this,
245
+ ctx,
246
+ swapXY = function(proceed, x, y, a, b, c, d) {
247
+ proceed.call(this, y, x, a, b, c, d);
248
+ };
249
+
250
+ if (isChartSeriesBoosting(chart)) {
251
+ target = chart;
252
+ targetGroup = chart.seriesGroup;
253
+ }
254
+
255
+ ctx = target.ctx;
256
+
257
+ if (!target.canvas) {
258
+ target.canvas = doc.createElement('canvas');
259
+
260
+ target.image = chart.renderer.image(
261
+ '',
262
+ 0,
263
+ 0,
264
+ width,
265
+ height
266
+ ).add(targetGroup);
267
+
268
+ target.ctx = ctx = target.canvas.getContext('2d');
269
+
270
+ if (chart.inverted) {
271
+ each(['moveTo', 'lineTo', 'rect', 'arc'], function(fn) {
272
+ wrap(ctx, fn, swapXY);
273
+ });
274
+ }
275
+
276
+ target.boostClipRect = chart.renderer.clipRect(
277
+ chart.plotLeft,
278
+ chart.plotTop,
279
+ chart.plotWidth,
280
+ chart.chartHeight
281
+ );
282
+
283
+ target.image.clip(target.boostClipRect);
284
+
285
+ } else if (!(target instanceof H.Chart)) {
286
+ // ctx.clearRect(0, 0, width, height);
287
+ }
288
+
289
+ if (target.canvas.width !== width) {
290
+ target.canvas.width = width;
291
+ }
292
+
293
+ if (target.canvas.height !== height) {
294
+ target.canvas.height = height;
295
+ }
296
+
297
+ target.image.attr({
298
+ x: 0,
299
+ y: 0,
300
+ width: width,
301
+ height: height,
302
+ style: 'pointer-events: none'
303
+ });
304
+
305
+ target.boostClipRect.attr({
306
+ x: 0,
307
+ y: 0,
308
+ width: chart.plotWidth,
309
+ height: chart.chartHeight
310
+ });
311
+
312
+ return ctx;
313
+ },
314
+
315
+ /**
316
+ * Draw the canvas image inside an SVG image
317
+ */
318
+ canvasToSVG: function() {
319
+ if (!isChartSeriesBoosting(this.chart)) {
320
+ this.image.attr({
321
+ href: this.canvas.toDataURL('image/png')
322
+ });
323
+ } else if (this.image) {
324
+ this.image.attr({
325
+ href: ''
326
+ });
327
+ }
328
+ },
329
+
330
+ cvsLineTo: function(ctx, clientX, plotY) {
331
+ ctx.lineTo(clientX, plotY);
332
+ },
333
+
334
+ renderCanvas: function() {
335
+ var series = this,
336
+ options = series.options,
337
+ chart = series.chart,
338
+ xAxis = this.xAxis,
339
+ yAxis = this.yAxis,
340
+ activeBoostSettings = chart.options.boost || {},
341
+ boostSettings = {
342
+ timeRendering: activeBoostSettings.timeRendering || false,
343
+ timeSeriesProcessing: activeBoostSettings.timeSeriesProcessing || false,
344
+ timeSetup: activeBoostSettings.timeSetup || false
345
+ },
346
+ ctx,
347
+ c = 0,
348
+ xData = series.processedXData,
349
+ yData = series.processedYData,
350
+ rawData = options.data,
351
+ xExtremes = xAxis.getExtremes(),
352
+ xMin = xExtremes.min,
353
+ xMax = xExtremes.max,
354
+ yExtremes = yAxis.getExtremes(),
355
+ yMin = yExtremes.min,
356
+ yMax = yExtremes.max,
357
+ pointTaken = {},
358
+ lastClientX,
359
+ sampling = !!series.sampling,
360
+ points,
361
+ r = options.marker && options.marker.radius,
362
+ cvsDrawPoint = this.cvsDrawPoint,
363
+ cvsLineTo = options.lineWidth ? this.cvsLineTo : false,
364
+ cvsMarker = r && r <= 1 ?
365
+ this.cvsMarkerSquare :
366
+ this.cvsMarkerCircle,
367
+ strokeBatch = this.cvsStrokeBatch || 1000,
368
+ enableMouseTracking = options.enableMouseTracking !== false,
369
+ lastPoint,
370
+ threshold = options.threshold,
371
+ yBottom = yAxis.getThreshold(threshold),
372
+ hasThreshold = isNumber(threshold),
373
+ translatedThreshold = yBottom,
374
+ doFill = this.fill,
375
+ isRange = series.pointArrayMap && series.pointArrayMap.join(',') === 'low,high',
376
+ isStacked = !!options.stacking,
377
+ cropStart = series.cropStart || 0,
378
+ loadingOptions = chart.options.loading,
379
+ requireSorting = series.requireSorting,
380
+ wasNull,
381
+ connectNulls = options.connectNulls,
382
+ useRaw = !xData,
383
+ minVal,
384
+ maxVal,
385
+ minI,
386
+ maxI,
387
+ kdIndex,
388
+ sdata = isStacked ? series.data : (xData || rawData),
389
+ fillColor = series.fillOpacity ?
390
+ new Color(series.color).setOpacity(pick(options.fillOpacity, 0.75)).get() :
391
+ series.color,
392
+
393
+ stroke = function() {
394
+ if (doFill) {
395
+ ctx.fillStyle = fillColor;
396
+ ctx.fill();
397
+ } else {
398
+ ctx.strokeStyle = series.color;
399
+ ctx.lineWidth = options.lineWidth;
400
+ ctx.stroke();
401
+ }
402
+ },
403
+
404
+ drawPoint = function(clientX, plotY, yBottom, i) {
405
+ if (c === 0) {
406
+ ctx.beginPath();
407
+
408
+ if (cvsLineTo) {
409
+ ctx.lineJoin = 'round';
410
+ }
411
+ }
412
+
413
+ if (chart.scroller && series.options.className === 'highcharts-navigator-series') {
414
+ plotY += chart.scroller.top;
415
+ if (yBottom) {
416
+ yBottom += chart.scroller.top;
417
+ }
418
+ } else {
419
+ plotY += chart.plotTop;
420
+ }
421
+
422
+ clientX += chart.plotLeft;
423
+
424
+ if (wasNull) {
425
+ ctx.moveTo(clientX, plotY);
426
+ } else {
427
+ if (cvsDrawPoint) {
428
+ cvsDrawPoint(ctx, clientX, plotY, yBottom, lastPoint);
429
+ } else if (cvsLineTo) {
430
+ cvsLineTo(ctx, clientX, plotY);
431
+ } else if (cvsMarker) {
432
+ cvsMarker.call(series, ctx, clientX, plotY, r, i);
433
+ }
434
+ }
435
+
436
+ // We need to stroke the line for every 1000 pixels. It will crash the browser
437
+ // memory use if we stroke too infrequently.
438
+ c = c + 1;
439
+ if (c === strokeBatch) {
440
+ stroke();
441
+ c = 0;
442
+ }
443
+
444
+ // Area charts need to keep track of the last point
445
+ lastPoint = {
446
+ clientX: clientX,
447
+ plotY: plotY,
448
+ yBottom: yBottom
449
+ };
450
+ },
451
+
452
+ addKDPoint = function(clientX, plotY, i) {
453
+ // Avoid more string concatination than required
454
+ kdIndex = clientX + ',' + plotY;
455
+
456
+ // The k-d tree requires series points. Reduce the amount of points, since the time to build the
457
+ // tree increases exponentially.
458
+ if (enableMouseTracking && !pointTaken[kdIndex]) {
459
+ pointTaken[kdIndex] = true;
460
+
461
+ if (chart.inverted) {
462
+ clientX = xAxis.len - clientX;
463
+ plotY = yAxis.len - plotY;
464
+ }
465
+
466
+ points.push({
467
+ clientX: clientX,
468
+ plotX: clientX,
469
+ plotY: plotY,
470
+ i: cropStart + i
471
+ });
472
+ }
473
+ };
474
+
475
+ // If we are zooming out from SVG mode, destroy the graphics
476
+ if (this.points || this.graph) {
477
+ this.destroyGraphics();
478
+ }
479
+
480
+ // The group
481
+ series.plotGroup(
482
+ 'group',
483
+ 'series',
484
+ series.visible ? 'visible' : 'hidden',
485
+ options.zIndex,
486
+ chart.seriesGroup
487
+ );
488
+
489
+ series.markerGroup = series.group;
490
+ // addEvent(series, 'destroy', function () {
491
+ // series.markerGroup = null;
492
+ // });
493
+
494
+ points = this.points = [];
495
+ ctx = this.getContext();
496
+ series.buildKDTree = noop; // Do not start building while drawing
497
+
498
+ // Display a loading indicator
499
+ if (rawData.length > 99999) {
500
+ chart.options.loading = merge(loadingOptions, {
501
+ labelStyle: {
502
+ backgroundColor: H.color('#ffffff').setOpacity(0.75).get(),
503
+ padding: '1em',
504
+ borderRadius: '0.5em'
505
+ },
506
+ style: {
507
+ backgroundColor: 'none',
508
+ opacity: 1
509
+ }
510
+ });
511
+ clearTimeout(destroyLoadingDiv);
512
+ chart.showLoading('Drawing...');
513
+ chart.options.loading = loadingOptions; // reset
514
+ }
515
+
516
+ if (boostSettings.timeRendering) {
517
+ console.time('canvas rendering'); // eslint-disable-line no-console
518
+ }
519
+
520
+ // Loop over the points
521
+ eachAsync(sdata, function(d, i) {
522
+ var x,
523
+ y,
524
+ clientX,
525
+ plotY,
526
+ isNull,
527
+ low,
528
+ isNextInside = false,
529
+ isPrevInside = false,
530
+ nx = false,
531
+ px = false,
532
+ chartDestroyed = typeof chart.index === 'undefined',
533
+ isYInside = true;
534
+
535
+ if (!chartDestroyed) {
536
+ if (useRaw) {
537
+ x = d[0];
538
+ y = d[1];
539
+
540
+ if (sdata[i + 1]) {
541
+ nx = sdata[i + 1][0];
542
+ }
543
+
544
+ if (sdata[i - 1]) {
545
+ px = sdata[i - 1][0];
546
+ }
547
+ } else {
548
+ x = d;
549
+ y = yData[i];
550
+
551
+ if (sdata[i + 1]) {
552
+ nx = sdata[i + 1];
553
+ }
554
+
555
+ if (sdata[i - 1]) {
556
+ px = sdata[i - 1];
557
+ }
558
+ }
559
+
560
+ if (nx && nx >= xMin && nx <= xMax) {
561
+ isNextInside = true;
562
+ }
563
+
564
+ if (px && px >= xMin && px <= xMax) {
565
+ isPrevInside = true;
566
+ }
567
+
568
+ // Resolve low and high for range series
569
+ if (isRange) {
570
+ if (useRaw) {
571
+ y = d.slice(1, 3);
572
+ }
573
+ low = y[0];
574
+ y = y[1];
575
+ } else if (isStacked) {
576
+ x = d.x;
577
+ y = d.stackY;
578
+ low = y - d.y;
579
+ }
580
+
581
+ isNull = y === null;
582
+
583
+ // Optimize for scatter zooming
584
+ if (!requireSorting) {
585
+ isYInside = y >= yMin && y <= yMax;
586
+ }
587
+
588
+ if (!isNull &&
589
+ (
590
+ (x >= xMin && x <= xMax && isYInside) ||
591
+ (isNextInside || isPrevInside)
592
+ )) {
593
+
594
+
595
+ clientX = Math.round(xAxis.toPixels(x, true));
596
+
597
+ if (sampling) {
598
+ if (minI === undefined || clientX === lastClientX) {
599
+ if (!isRange) {
600
+ low = y;
601
+ }
602
+ if (maxI === undefined || y > maxVal) {
603
+ maxVal = y;
604
+ maxI = i;
605
+ }
606
+ if (minI === undefined || low < minVal) {
607
+ minVal = low;
608
+ minI = i;
609
+ }
610
+
611
+ }
612
+ if (clientX !== lastClientX) { // Add points and reset
613
+ if (minI !== undefined) { // then maxI is also a number
614
+ plotY = yAxis.toPixels(maxVal, true);
615
+ yBottom = yAxis.toPixels(minVal, true);
616
+ drawPoint(
617
+ clientX,
618
+ hasThreshold ? Math.min(plotY, translatedThreshold) : plotY,
619
+ hasThreshold ? Math.max(yBottom, translatedThreshold) : yBottom,
620
+ i
621
+ );
622
+ addKDPoint(clientX, plotY, maxI);
623
+ if (yBottom !== plotY) {
624
+ addKDPoint(clientX, yBottom, minI);
625
+ }
626
+ }
627
+
628
+ minI = maxI = undefined;
629
+ lastClientX = clientX;
630
+ }
631
+ } else {
632
+ plotY = Math.round(yAxis.toPixels(y, true));
633
+ drawPoint(clientX, plotY, yBottom, i);
634
+ addKDPoint(clientX, plotY, i);
635
+ }
636
+ }
637
+ wasNull = isNull && !connectNulls;
638
+
639
+ if (i % CHUNK_SIZE === 0) {
640
+ series.canvasToSVG();
641
+ }
642
+ }
643
+
644
+ return !chartDestroyed;
645
+ }, function() {
646
+ var loadingDiv = chart.loadingDiv,
647
+ loadingShown = chart.loadingShown;
648
+ stroke();
649
+ series.canvasToSVG();
650
+
651
+ if (boostSettings.timeRendering) {
652
+ console.timeEnd('canvas rendering'); // eslint-disable-line no-console
653
+ }
654
+
655
+ fireEvent(series, 'renderedCanvas');
656
+
657
+ // Do not use chart.hideLoading, as it runs JS animation and will be blocked by buildKDTree.
658
+ // CSS animation looks good, but then it must be deleted in timeout. If we add the module to core,
659
+ // change hideLoading so we can skip this block.
660
+ if (loadingShown) {
661
+ extend(loadingDiv.style, {
662
+ transition: 'opacity 250ms',
663
+ opacity: 0
664
+ });
665
+ chart.loadingShown = false;
666
+ destroyLoadingDiv = setTimeout(function() {
667
+ if (loadingDiv.parentNode) { // In exporting it is falsy
668
+ loadingDiv.parentNode.removeChild(loadingDiv);
669
+ }
670
+ chart.loadingDiv = chart.loadingSpan = null;
671
+ }, 250);
672
+ }
673
+
674
+ // Pass tests in Pointer.
675
+ // Replace this with a single property, and replace when zooming in
676
+ // below boostThreshold.
677
+ series.directTouch = false;
678
+ series.options.stickyTracking = true;
679
+
680
+ delete series.buildKDTree; // Go back to prototype, ready to build
681
+ series.buildKDTree();
682
+
683
+ // Don't do async on export, the exportChart, getSVGForExport and getSVG methods are not chained for it.
684
+ }, chart.renderer.forExport ? Number.MAX_VALUE : undefined);
685
+ }
686
+ });
687
+
688
+ wrap(Series.prototype, 'setData', function(proceed) {
689
+ if (!this.hasExtremes || !this.hasExtremes(true) || this.type === 'heatmap') {
690
+ proceed.apply(this, Array.prototype.slice.call(arguments, 1));
691
+ }
692
+ });
693
+
694
+ wrap(Series.prototype, 'processData', function(proceed) {
695
+ if (!this.hasExtremes || !this.hasExtremes(true) || this.type === 'heatmap') {
696
+ proceed.apply(this, Array.prototype.slice.call(arguments, 1));
697
+ }
698
+ });
699
+
700
+ seriesTypes.scatter.prototype.cvsMarkerCircle = function(ctx, clientX, plotY, r) {
701
+ ctx.moveTo(clientX, plotY);
702
+ ctx.arc(clientX, plotY, r, 0, 2 * Math.PI, false);
703
+ };
704
+
705
+ // Rect is twice as fast as arc, should be used for small markers
706
+ seriesTypes.scatter.prototype.cvsMarkerSquare = function(ctx, clientX, plotY, r) {
707
+ ctx.rect(clientX - r, plotY - r, r * 2, r * 2);
708
+ };
709
+ seriesTypes.scatter.prototype.fill = true;
710
+
711
+ if (seriesTypes.bubble) {
712
+ seriesTypes.bubble.prototype.cvsMarkerCircle = function(ctx, clientX, plotY, r, i) {
713
+ ctx.moveTo(clientX, plotY);
714
+ ctx.arc(clientX, plotY, this.radii && this.radii[i], 0, 2 * Math.PI, false);
715
+ };
716
+ seriesTypes.bubble.prototype.cvsStrokeBatch = 1;
717
+ }
718
+
719
+ extend(seriesTypes.area.prototype, {
720
+ cvsDrawPoint: function(ctx, clientX, plotY, yBottom, lastPoint) {
721
+ if (lastPoint && clientX !== lastPoint.clientX) {
722
+ ctx.moveTo(lastPoint.clientX, lastPoint.yBottom);
723
+ ctx.lineTo(lastPoint.clientX, lastPoint.plotY);
724
+ ctx.lineTo(clientX, plotY);
725
+ ctx.lineTo(clientX, yBottom);
726
+ }
727
+ },
728
+ fill: true,
729
+ fillOpacity: true,
730
+ sampling: true
731
+ });
732
+
733
+ extend(seriesTypes.column.prototype, {
734
+ cvsDrawPoint: function(ctx, clientX, plotY, yBottom) {
735
+ ctx.rect(clientX - 1, plotY, 1, yBottom - plotY);
736
+ },
737
+ fill: true,
738
+ sampling: true
739
+ });
740
+
741
+ H.Chart.prototype.callbacks.push(function(chart) {
742
+ function canvasToSVG() {
743
+ if (chart.image && chart.canvas) {
744
+ chart.image.attr({
745
+ href: chart.canvas.toDataURL('image/png')
746
+ });
747
+ }
748
+ }
749
+
750
+ function clear() {
751
+ if (chart.image) {
752
+ chart.image.attr({
753
+ href: ''
754
+ });
755
+ }
756
+
757
+ if (chart.canvas) {
758
+ chart.canvas.getContext('2d').clearRect(
759
+ 0,
760
+ 0,
761
+ chart.canvas.width,
762
+ chart.canvas.height
763
+ );
764
+ }
765
+ }
766
+
767
+ addEvent(chart, 'predraw', clear);
768
+ addEvent(chart, 'render', canvasToSVG);
769
+ });
770
+ };
771
+
772
+ }(Highcharts));
773
+ }));