highcharts-rails 5.0.14 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }));