corrade-nucleus-nucleons – Blame information for rev 20

Subversion Repositories:
Rev:
Rev Author Line No. Line
20 office 1 /**
2 * @license Highcharts JS v5.0.12 (2017-05-24)
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: Christer Vasseng, Torstein Honsi
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 WebGL compatible browsers (not IE < 11).
27 *
28 * Development plan
29 * - Column range.
30 * - Check how it works with Highstock and data grouping. Currently it only works when navigator.adaptToUpdatedData
31 * is false. It is also recommended to set scrollbar.liveRedraw to false.
32 * - Check inverted charts.
33 * - Chart callback should be async after last series is drawn. (But not necessarily, we don't do
34 that with initial series animation).
35 *
36 * If this module is taken in as part of the core
37 * - All the loading logic should be merged with core. Update styles in the core.
38 * - Most of the method wraps should probably be added directly in parent methods.
39 *
40 * Notes for boost mode
41 * - Area lines are not drawn
42 * - Lines are not drawn on scatter charts
43 * - Zones and negativeColor don't work
44 * - Columns are always one pixel wide. Don't set the threshold too low.
45 * - Disable animations
46 * - Marker shapes are not supported: markers will always be circles
47 *
48 * Optimizing tips for users
49 * - Set extremes (min, max) explicitly on the axes in order for Highcharts to avoid computing extremes.
50 * - Set enableMouseTracking to false on the series to improve total rendering time.
51 * - The default threshold is set based on one series. If you have multiple, dense series, the combined
52 * number of points drawn gets higher, and you may want to set the threshold lower in order to
53 * use optimizations.
54 * - If drawing large scatter charts, it's beneficial to set the marker radius to a value
55 * less than 1. This is to add additional spacing to make the chart more readable.
56 * - If the value increments on both the X and Y axis aren't small, consider setting
57 * useGPUTranslations to true on the boost settings object. If you do this and
58 * the increments are small (e.g. datetime axis with small time increments)
59 * it may cause rendering issues due to floating point rounding errors,
60 * so your millage may vary.
61 *
62 * Settings
63 * There are two ways of setting the boost threshold:
64 * - Per. series: boost based on number of points in individual series
65 * - Per. chart: boost based on the number of series
66 *
67 * To set the series boost threshold, set seriesBoostThreshold on the chart object.
68 * To set the series-specific threshold, set boostThreshold on the series object.
69 *
70 * In addition, the following can be set in the boost object:
71 * {
72 * //Wether or not to use alpha blending
73 * useAlpha: boolean - default: true
74 * //Set to true to perform translations on the GPU.
75 * //Much faster, but may cause rendering issues
76 * //when using values far from 0 due to floating point
77 * //rounding issues
78 * useGPUTranslations: boolean - default: false
79 * //Use pre-allocated buffers, much faster,
80 * //but may cause rendering issues with some data sets
81 * usePreallocated: boolean - default: false
82 * //Output rendering time in console
83 * timeRendering: boolean - default: false
84 * //Output processing time in console
85 * timeSeriesProcessing: boolean - default: false
86 * //Output setup time in console
87 * timeSetup: boolean - default: false
88 * }
89 */
90  
91 /**
92 * Set the series threshold for when the boost should kick in globally.
93 *
94 * Setting to e.g. 20 will cause the whole chart to enter boost mode
95 * if there are 20 or more series active. When the chart is in boost mode,
96 * every series in it will be rendered to a common canvas. This offers
97 * a significant speed improvment in charts with a very high
98 * amount of series.
99 *
100 * Note: only available when including the boost module.
101 *
102 * @default null
103 * @apioption boost.seriesThreshold
104 */
105  
106 /**
107 * Set the point threshold for when a series should enter boost mode.
108 *
109 * Setting it to e.g. 2000 will cause the series to enter boost mode
110 * when there are 2000 or more points in the series.
111 *
112 * Note: only available when including the boost module.
113 *
114 * @default 5000
115 * @apioption series.boostThreshold
116 */
117  
118 /* global Float32Array */
119  
120  
121 var win = H.win,
122 doc = win.document,
123 noop = function() {},
124 Color = H.Color,
125 Series = H.Series,
126 seriesTypes = H.seriesTypes,
127 each = H.each,
128 extend = H.extend,
129 addEvent = H.addEvent,
130 fireEvent = H.fireEvent,
131 grep = H.grep,
132 isNumber = H.isNumber,
133 merge = H.merge,
134 pick = H.pick,
135 wrap = H.wrap,
136 plotOptions = H.getOptions().plotOptions,
137 CHUNK_SIZE = 50000,
138 index;
139  
140 // Register color names since GL can't render those directly.
141 Color.prototype.names = {
142 aliceblue: '#f0f8ff',
143 antiquewhite: '#faebd7',
144 aqua: '#00ffff',
145 aquamarine: '#7fffd4',
146 azure: '#f0ffff',
147 beige: '#f5f5dc',
148 bisque: '#ffe4c4',
149 black: '#000000',
150 blanchedalmond: '#ffebcd',
151 blue: '#0000ff',
152 blueviolet: '#8a2be2',
153 brown: '#a52a2a',
154 burlywood: '#deb887',
155 cadetblue: '#5f9ea0',
156 chartreuse: '#7fff00',
157 chocolate: '#d2691e',
158 coral: '#ff7f50',
159 cornflowerblue: '#6495ed',
160 cornsilk: '#fff8dc',
161 crimson: '#dc143c',
162 cyan: '#00ffff',
163 darkblue: '#00008b',
164 darkcyan: '#008b8b',
165 darkgoldenrod: '#b8860b',
166 darkgray: '#a9a9a9',
167 darkgreen: '#006400',
168 darkkhaki: '#bdb76b',
169 darkmagenta: '#8b008b',
170 darkolivegreen: '#556b2f',
171 darkorange: '#ff8c00',
172 darkorchid: '#9932cc',
173 darkred: '#8b0000',
174 darksalmon: '#e9967a',
175 darkseagreen: '#8fbc8f',
176 darkslateblue: '#483d8b',
177 darkslategray: '#2f4f4f',
178 darkturquoise: '#00ced1',
179 darkviolet: '#9400d3',
180 deeppink: '#ff1493',
181 deepskyblue: '#00bfff',
182 dimgray: '#696969',
183 dodgerblue: '#1e90ff',
184 feldspar: '#d19275',
185 firebrick: '#b22222',
186 floralwhite: '#fffaf0',
187 forestgreen: '#228b22',
188 fuchsia: '#ff00ff',
189 gainsboro: '#dcdcdc',
190 ghostwhite: '#f8f8ff',
191 gold: '#ffd700',
192 goldenrod: '#daa520',
193 gray: '#808080',
194 green: '#008000',
195 greenyellow: '#adff2f',
196 honeydew: '#f0fff0',
197 hotpink: '#ff69b4',
198 indianred: '#cd5c5c',
199 indigo: '#4b0082',
200 ivory: '#fffff0',
201 khaki: '#f0e68c',
202 lavender: '#e6e6fa',
203 lavenderblush: '#fff0f5',
204 lawngreen: '#7cfc00',
205 lemonchiffon: '#fffacd',
206 lightblue: '#add8e6',
207 lightcoral: '#f08080',
208 lightcyan: '#e0ffff',
209 lightgoldenrodyellow: '#fafad2',
210 lightgrey: '#d3d3d3',
211 lightgreen: '#90ee90',
212 lightpink: '#ffb6c1',
213 lightsalmon: '#ffa07a',
214 lightseagreen: '#20b2aa',
215 lightskyblue: '#87cefa',
216 lightslateblue: '#8470ff',
217 lightslategray: '#778899',
218 lightsteelblue: '#b0c4de',
219 lightyellow: '#ffffe0',
220 lime: '#00ff00',
221 limegreen: '#32cd32',
222 linen: '#faf0e6',
223 magenta: '#ff00ff',
224 maroon: '#800000',
225 mediumaquamarine: '#66cdaa',
226 mediumblue: '#0000cd',
227 mediumorchid: '#ba55d3',
228 mediumpurple: '#9370d8',
229 mediumseagreen: '#3cb371',
230 mediumslateblue: '#7b68ee',
231 mediumspringgreen: '#00fa9a',
232 mediumturquoise: '#48d1cc',
233 mediumvioletred: '#c71585',
234 midnightblue: '#191970',
235 mintcream: '#f5fffa',
236 mistyrose: '#ffe4e1',
237 moccasin: '#ffe4b5',
238 navajowhite: '#ffdead',
239 navy: '#000080',
240 oldlace: '#fdf5e6',
241 olive: '#808000',
242 olivedrab: '#6b8e23',
243 orange: '#ffa500',
244 orangered: '#ff4500',
245 orchid: '#da70d6',
246 palegoldenrod: '#eee8aa',
247 palegreen: '#98fb98',
248 paleturquoise: '#afeeee',
249 palevioletred: '#d87093',
250 papayawhip: '#ffefd5',
251 peachpuff: '#ffdab9',
252 peru: '#cd853f',
253 pink: '#ffc0cb',
254 plum: '#dda0dd',
255 powderblue: '#b0e0e6',
256 purple: '#800080',
257 red: '#ff0000',
258 rosybrown: '#bc8f8f',
259 royalblue: '#4169e1',
260 saddlebrown: '#8b4513',
261 salmon: '#fa8072',
262 sandybrown: '#f4a460',
263 seagreen: '#2e8b57',
264 seashell: '#fff5ee',
265 sienna: '#a0522d',
266 silver: '#c0c0c0',
267 skyblue: '#87ceeb',
268 slateblue: '#6a5acd',
269 slategray: '#708090',
270 snow: '#fffafa',
271 springgreen: '#00ff7f',
272 steelblue: '#4682b4',
273 tan: '#d2b48c',
274 teal: '#008080',
275 thistle: '#d8bfd8',
276 tomato: '#ff6347',
277 turquoise: '#40e0d0',
278 violet: '#ee82ee',
279 violetred: '#d02090',
280 wheat: '#f5deb3',
281 white: '#ffffff',
282 whitesmoke: '#f5f5f5',
283 yellow: '#ffff00',
284 yellowgreen: '#9acd32'
285 };
286  
287 /**
288 * Tolerant max() funciton
289 * @return {number} max value
290 */
291 function patientMax() {
292 var args = Array.prototype.slice.call(arguments),
293 r = -Number.MAX_VALUE;
294  
295 each(args, function(t) {
296 if (typeof t !== 'undefined' && typeof t.length !== 'undefined') {
297 //r = r < t.length ? t.length : r;
298 if (t.length > 0) {
299 r = t.length;
300 return true;
301 }
302 }
303 });
304  
305 return r;
306 }
307  
308 /*
309 * Returns true if we should force chart series boosting
310 */
311 function shouldForceChartSeriesBoosting(chart) {
312 // If there are more than five series currently boosting,
313 // we should boost the whole chart to avoid running out of webgl contexts.
314 var sboostCount = 0,
315 series;
316  
317 if (chart.series.length > 1) {
318 for (var i = 0; i < chart.series.length; i++) {
319 series = chart.series[i];
320 if (patientMax(
321 series.processedXData,
322 series.options.data,
323 series.points
324 ) >= (series.options.boostThreshold || Number.MAX_VALUE)) {
325 sboostCount++;
326 }
327 }
328 }
329  
330 return sboostCount > 5;
331 }
332  
333 /*
334 * Returns true if the chart is in series boost mode
335 * @param chart {Highchart.Chart} - the chart to check
336 * @returns {Boolean} - true if the chart is in series boost mode
337 */
338 function isChartSeriesBoosting(chart) {
339 return shouldForceChartSeriesBoosting(chart) || chart.series.length >= pick(
340 chart.options.boost && chart.options.boost.seriesThreshold,
341 50
342 );
343 }
344  
345 /*
346 * Returns true if the series is in boost mode
347 * @param series {Highchart.Series} - the series to check
348 * @returns {boolean} - true if the series is in boost mode
349 */
350 function isSeriesBoosting(series) {
351 return isChartSeriesBoosting(series.chart) ||
352 patientMax(
353 series.processedXData,
354 series.options.data,
355 series.points
356 ) >= (series.options.boostThreshold || Number.MAX_VALUE);
357 }
358  
359 ////////////////////////////////////////////////////////////////////////////////
360 // START OF WEBGL ABSTRACTIONS
361  
362 /*
363 * A static shader mimicing axis translation functions found in parts/Axis
364 * @param gl {WebGLContext} - the context in which the shader is active
365 */
366 function GLShader(gl) {
367 var vertShade = [
368 /* eslint-disable */
369 '#version 100',
370 'precision highp float;',
371  
372 'attribute vec4 aVertexPosition;',
373 'attribute vec4 aColor;',
374  
375 'varying highp vec2 position;',
376 'varying highp vec4 vColor;',
377  
378 'uniform mat4 uPMatrix;',
379 'uniform float pSize;',
380  
381 'uniform float translatedThreshold;',
382 'uniform bool hasThreshold;',
383  
384 'uniform bool skipTranslation;',
385  
386 'uniform float xAxisTrans;',
387 'uniform float xAxisMin;',
388 'uniform float xAxisMinPad;',
389 'uniform float xAxisPointRange;',
390 'uniform float xAxisLen;',
391 'uniform bool xAxisPostTranslate;',
392 'uniform float xAxisOrdinalSlope;',
393 'uniform float xAxisOrdinalOffset;',
394 'uniform float xAxisPos;',
395 'uniform bool xAxisCVSCoord;',
396  
397 'uniform float yAxisTrans;',
398 'uniform float yAxisMin;',
399 'uniform float yAxisMinPad;',
400 'uniform float yAxisPointRange;',
401 'uniform float yAxisLen;',
402 'uniform bool yAxisPostTranslate;',
403 'uniform float yAxisOrdinalSlope;',
404 'uniform float yAxisOrdinalOffset;',
405 'uniform float yAxisPos;',
406 'uniform bool yAxisCVSCoord;',
407  
408 'uniform bool isBubble;',
409 'uniform bool bubbleSizeByArea;',
410 'uniform float bubbleZMin;',
411 'uniform float bubbleZMax;',
412 'uniform float bubbleZThreshold;',
413 'uniform float bubbleMinSize;',
414 'uniform float bubbleMaxSize;',
415 'uniform bool bubbleSizeAbs;',
416 'uniform bool isInverted;',
417  
418 'float bubbleRadius(){',
419 'float value = aVertexPosition.w;',
420 'float zMax = bubbleZMax;',
421 'float zMin = bubbleZMin;',
422 'float radius = 0.0;',
423 'float pos = 0.0;',
424 'float zRange = zMax - zMin;',
425  
426 'if (bubbleSizeAbs){',
427 'value = value - bubbleZThreshold;',
428 'zMax = max(zMax - bubbleZThreshold, zMin - bubbleZThreshold);',
429 'zMin = 0.0;',
430 '}',
431  
432 'if (value < zMin){',
433 'radius = bubbleZMin / 2.0 - 1.0;',
434 '} else {',
435 'pos = zRange > 0.0 ? (value - zMin) / zRange : 0.5;',
436 'if (bubbleSizeByArea && pos > 0.0){',
437 'pos = sqrt(pos);',
438 '}',
439 'radius = ceil(bubbleMinSize + pos * (bubbleMaxSize - bubbleMinSize)) / 2.0;',
440 '}',
441  
442 'return radius * 2.0;',
443 '}',
444  
445 'float translate(float val,',
446 'float pointPlacement,',
447 'float localA,',
448 'float localMin,',
449 'float minPixelPadding,',
450 'float pointRange,',
451 'float len,',
452 'bool cvsCoord',
453 '){',
454  
455 'float sign = 1.0;',
456 'float cvsOffset = 0.0;',
457  
458 'if (cvsCoord) {',
459 'sign *= -1.0;',
460 'cvsOffset = len;',
461 '}',
462  
463 'return sign * (val - localMin) * localA + cvsOffset + ',
464 '(sign * minPixelPadding);', //' + localA * pointPlacement * pointRange;',
465 '}',
466  
467 'float xToPixels(float value){',
468 'if (skipTranslation){',
469 'return value;// + xAxisPos;',
470 '}',
471  
472 'return translate(value, 0.0, xAxisTrans, xAxisMin, xAxisMinPad, xAxisPointRange, xAxisLen, xAxisCVSCoord);// + xAxisPos;',
473 '}',
474  
475 'float yToPixels(float value, float checkTreshold){',
476 'float v;',
477 'if (skipTranslation){',
478 'v = value;// + yAxisPos;',
479 '} else {',
480 'v = translate(value, 0.0, yAxisTrans, yAxisMin, yAxisMinPad, yAxisPointRange, yAxisLen, yAxisCVSCoord);// + yAxisPos;',
481 '}',
482 'if (checkTreshold > 0.0 && hasThreshold) {',
483 'v = min(v, translatedThreshold);',
484 '}',
485 'return v;',
486 '}',
487  
488 'void main(void) {',
489 'if (isBubble){',
490 'gl_PointSize = bubbleRadius();',
491 '} else {',
492 'gl_PointSize = pSize;',
493 '}',
494 //'gl_PointSize = 10.0;',
495 'vColor = aColor;',
496  
497 'if (isInverted) {',
498 'gl_Position = uPMatrix * vec4(xToPixels(aVertexPosition.y) + yAxisPos, yToPixels(aVertexPosition.x, aVertexPosition.z) + xAxisPos, 0.0, 1.0);',
499 '} else {',
500 'gl_Position = uPMatrix * vec4(xToPixels(aVertexPosition.x) + xAxisPos, yToPixels(aVertexPosition.y, aVertexPosition.z) + yAxisPos, 0.0, 1.0);',
501 '}',
502 //'gl_Position = uPMatrix * vec4(aVertexPosition.x, aVertexPosition.y, 0.0, 1.0);',
503 '}'
504 /* eslint-enable */
505 ].join('\n'),
506 //Fragment shader source
507 fragShade = [
508 /* eslint-disable */
509 'precision highp float;',
510 'uniform vec4 fillColor;',
511 'varying highp vec2 position;',
512 'varying highp vec4 vColor;',
513 'uniform sampler2D uSampler;',
514 'uniform bool isCircle;',
515 'uniform bool hasColor;',
516  
517 // 'vec4 toColor(float value, vec2 point) {',
518 // 'return vec4(0.0, 0.0, 0.0, 0.0);',
519 // '}',
520  
521 'void main(void) {',
522 'vec4 col = fillColor;',
523  
524 'if (hasColor) {',
525 'col = vColor;',
526 '}',
527  
528 'if (isCircle) {',
529 'gl_FragColor = col * texture2D(uSampler, gl_PointCoord.st);',
530 '} else {',
531 'gl_FragColor = col;',
532 '}',
533 '}'
534 /* eslint-enable */
535 ].join('\n'),
536 uLocations = {},
537 //The shader program
538 shaderProgram,
539 //Uniform handle to the perspective matrix
540 pUniform,
541 //Uniform for point size
542 psUniform,
543 //Uniform for fill color
544 fillColorUniform,
545 //Uniform for isBubble
546 isBubbleUniform,
547 //Uniform for bubble abs sizing
548 bubbleSizeAbsUniform,
549 bubbleSizeAreaUniform,
550 //Skip translation uniform
551 skipTranslationUniform,
552 //Set to 1 if circle
553 isCircleUniform,
554 //Uniform for invertion
555 isInverted,
556 //Texture uniform
557 uSamplerUniform;
558  
559 /* String to shader program
560 * @param {string} str - the program source
561 * @param {string} type - the program type: either `vertex` or `fragment`
562 * @returns {bool|shader}
563 */
564 function stringToProgram(str, type) {
565 var t = type === 'vertex' ? gl.VERTEX_SHADER : gl.FRAGMENT_SHADER,
566 shader = gl.createShader(t);
567  
568 gl.shaderSource(shader, str);
569 gl.compileShader(shader);
570  
571 if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
572 //console.error('shader error:', gl.getShaderInfoLog(shader));
573 return false;
574 }
575 return shader;
576 }
577  
578 /*
579 * Create the shader.
580 * Loads the shader program statically defined above
581 */
582 function createShader() {
583 var v = stringToProgram(vertShade, 'vertex'),
584 f = stringToProgram(fragShade, 'fragment');
585  
586 if (!v || !f) {
587 shaderProgram = false;
588 //console.error('error creating shader program');
589 return false;
590 }
591  
592 function uloc(n) {
593 return gl.getUniformLocation(shaderProgram, n);
594 }
595  
596 shaderProgram = gl.createProgram();
597  
598 gl.attachShader(shaderProgram, v);
599 gl.attachShader(shaderProgram, f);
600 gl.linkProgram(shaderProgram);
601  
602 gl.useProgram(shaderProgram);
603  
604 gl.bindAttribLocation(shaderProgram, 0, 'aVertexPosition');
605  
606 pUniform = uloc('uPMatrix');
607 psUniform = uloc('pSize');
608 fillColorUniform = uloc('fillColor');
609 isBubbleUniform = uloc('isBubble');
610 bubbleSizeAbsUniform = uloc('bubbleSizeAbs');
611 bubbleSizeAreaUniform = uloc('bubbleSizeByArea');
612 uSamplerUniform = uloc('uSampler');
613 skipTranslationUniform = uloc('skipTranslation');
614 isCircleUniform = uloc('isCircle');
615 isInverted = uloc('isInverted');
616  
617 return true;
618 }
619  
620 /*
621 * Destroy the shader
622 */
623 function destroy() {
624 if (gl && shaderProgram) {
625 gl.deleteProgram(shaderProgram);
626 }
627 }
628  
629 /*
630 * Bind the shader.
631 * This makes the shader the active one until another one is bound,
632 * or until 0 is bound.
633 */
634 function bind() {
635 gl.useProgram(shaderProgram);
636 }
637  
638 /*
639 * Set a uniform value.
640 * This uses a hash map to cache uniform locations.
641 * @param name {string} - the name of the uniform to set
642 * @param val {float} - the value to set
643 */
644 function setUniform(name, val) {
645 var u = uLocations[name] = uLocations[name] ||
646 gl.getUniformLocation(shaderProgram, name);
647 gl.uniform1f(u, val);
648 }
649  
650 /*
651 * Set the active texture
652 * @param texture - the texture
653 */
654 function setTexture() {
655 gl.uniform1i(uSamplerUniform, 0);
656 }
657  
658 /*
659 * Set if inversion state
660 * @flag is the state
661 */
662 function setInverted(flag) {
663 gl.uniform1i(isInverted, flag);
664 }
665  
666 ////////////////////////////////////////////////////////////////////////////
667  
668 /*
669 * Enable/disable circle drawing
670 */
671 function setDrawAsCircle(flag) {
672 gl.uniform1i(isCircleUniform, flag ? 1 : 0);
673 }
674  
675 /*
676 * Flush
677 */
678 function reset() {
679 gl.uniform1i(isBubbleUniform, 0);
680 gl.uniform1i(isCircleUniform, 0);
681 }
682  
683 /*
684 * Set bubble uniforms
685 * @param series {Highcharts.Series} - the series to use
686 */
687 function setBubbleUniforms(series, zCalcMin, zCalcMax) {
688 var seriesOptions = series.options,
689 zMin = Number.MAX_VALUE,
690 zMax = -Number.MAX_VALUE;
691  
692 if (series.type === 'bubble') {
693 zMin = pick(seriesOptions.zMin, Math.min(
694 zMin,
695 Math.max(
696 zCalcMin,
697 seriesOptions.displayNegative === false ?
698 seriesOptions.zThreshold : -Number.MAX_VALUE
699 )
700 ));
701  
702 zMax = pick(seriesOptions.zMax, Math.max(zMax, zCalcMax));
703  
704 gl.uniform1i(isBubbleUniform, 1);
705 gl.uniform1i(isCircleUniform, 1);
706 gl.uniform1i(bubbleSizeAreaUniform, series.options.sizeBy !== 'width');
707 gl.uniform1i(bubbleSizeAbsUniform, series.options.sizeByAbsoluteValue);
708  
709 setUniform('bubbleZMin', zMin);
710 setUniform('bubbleZMax', zMax);
711 setUniform('bubbleZThreshold', series.options.zThreshold);
712 setUniform('bubbleMinSize', series.minPxSize);
713 setUniform('bubbleMaxSize', series.maxPxSize);
714 }
715 }
716  
717 /*
718 * Set the Color uniform.
719 * @param color {Array<float>} - an array with RGBA values
720 */
721 function setColor(color) {
722 gl.uniform4f(
723 fillColorUniform,
724 color[0] / 255.0,
725 color[1] / 255.0,
726 color[2] / 255.0,
727 color[3]
728 );
729 }
730  
731 /*
732 * Set skip translation
733 */
734 function setSkipTranslation(flag) {
735 gl.uniform1i(skipTranslationUniform, flag === true ? 1 : 0);
736 }
737  
738 /*
739 * Set the perspective matrix
740 * @param m {Matrix4x4} - the matrix
741 */
742 function setPMatrix(m) {
743 gl.uniformMatrix4fv(pUniform, false, m);
744 }
745  
746 /*
747 * Set the point size.
748 * @param p {float} - point size
749 */
750 function setPointSize(p) {
751 gl.uniform1f(psUniform, p);
752 }
753  
754 /*
755 * Get the shader program handle
756 * @returns {GLInt} - the handle for the program
757 */
758 function getProgram() {
759 return shaderProgram;
760 }
761  
762 if (gl) {
763 createShader();
764 }
765  
766 return {
767 psUniform: function() {
768 return psUniform;
769 },
770 pUniform: function() {
771 return pUniform;
772 },
773 fillColorUniform: function() {
774 return fillColorUniform;
775 },
776 setBubbleUniforms: setBubbleUniforms,
777 bind: bind,
778 program: getProgram,
779 create: createShader,
780 setUniform: setUniform,
781 setPMatrix: setPMatrix,
782 setColor: setColor,
783 setPointSize: setPointSize,
784 setSkipTranslation: setSkipTranslation,
785 setTexture: setTexture,
786 setDrawAsCircle: setDrawAsCircle,
787 reset: reset,
788 setInverted: setInverted,
789 destroy: destroy
790 };
791 }
792  
793 /*
794 * Vertex Buffer abstraction
795 * A vertex buffer is a set of vertices which are passed to the GPU
796 * in a single call.
797 * @param gl {WebGLContext} - the context in which to create the buffer
798 * @param shader {GLShader} - the shader to use
799 */
800 function GLVertexBuffer(gl, shader, dataComponents /*, type */ ) {
801 var buffer = false,
802 vertAttribute = false,
803 components = dataComponents || 2,
804 preAllocated = false,
805 iterator = 0,
806 data;
807  
808 // type = type || 'float';
809  
810 function destroy() {
811 if (buffer) {
812 gl.deleteBuffer(buffer);
813 }
814 }
815  
816 /*
817 * Build the buffer
818 * @param dataIn {Array<float>} - a 0 padded array of indices
819 * @param attrib {String} - the name of the Attribute to bind the buffer to
820 * @param dataComponents {Integer} - the number of components per. indice
821 */
822 function build(dataIn, attrib, dataComponents) {
823  
824 data = dataIn || [];
825  
826 if ((!data || data.length === 0) && !preAllocated) {
827 //console.error('trying to render empty vbuffer');
828 buffer = false;
829 return false;
830 }
831  
832 components = dataComponents || components;
833  
834 if (buffer) {
835 gl.deleteBuffer(buffer);
836 }
837  
838 buffer = gl.createBuffer();
839 gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
840 gl.bufferData(
841 gl.ARRAY_BUFFER,
842 preAllocated || new Float32Array(data),
843 gl.STATIC_DRAW
844 );
845  
846 // gl.bindAttribLocation(shader.program(), 0, 'aVertexPosition');
847 vertAttribute = gl.getAttribLocation(shader.program(), attrib);
848 gl.enableVertexAttribArray(vertAttribute);
849  
850 return true;
851 }
852  
853 /*
854 * Bind the buffer
855 */
856 function bind() {
857 if (!buffer) {
858 return false;
859 }
860  
861 // gl.bindAttribLocation(shader.program(), 0, 'aVertexPosition');
862 //gl.enableVertexAttribArray(vertAttribute);
863 //gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
864 gl.vertexAttribPointer(vertAttribute, components, gl.FLOAT, false, 0, 0);
865 //gl.enableVertexAttribArray(vertAttribute);
866 }
867  
868 /*
869 * Render the buffer
870 * @param from {Integer} - the start indice
871 * @param to {Integer} - the end indice
872 * @param drawMode {String} - the draw mode
873 */
874 function render(from, to, drawMode) {
875 var length = preAllocated ? preAllocated.length : data.length;
876  
877 if (!buffer) {
878 return false;
879 }
880  
881 if (!length) {
882 return false;
883 }
884  
885 if (!from || from > length || from < 0) {
886 < 0) { from = 0;
887 < 0) { }
888  
889 < 0) { if (!to || to > length) {
890 < 0) { to = length;
891 < 0) { }
892  
893 < 0) { drawMode = drawMode || 'points';
894  
895 < 0) { gl.drawArrays(
896 < 0) { gl[drawMode.toUpperCase()],
897 < 0) { from / components,
898 < 0) { (to - from) / components
899 < 0) { );
900  
901 < 0) { return true;
902 < 0) { }
903  
904 < 0) { function push(x, y, a, b) {
905 < 0) { if (preAllocated) { // && iterator <= preAllocated.length - 4) {
906 < 0) {<= preAllocated.length - 4) { preAllocated[++iterator] = x;
907 < 0) {<= preAllocated.length - 4) { preAllocated[++iterator] = y;
908 < 0) {<= preAllocated.length - 4) { preAllocated[++iterator] = a;
909 < 0) {<= preAllocated.length - 4) { preAllocated[++iterator] = b;
910 < 0) {<= preAllocated.length - 4) { }
911 < 0) {<= preAllocated.length - 4) { }
912  
913 < 0) {<= preAllocated.length - 4) { /*
914 < 0) {<= preAllocated.length - 4) { * Note about pre-allocated buffers:
915 < 0) {<= preAllocated.length - 4) { * - This is slower for charts with many series
916 < 0) {<= preAllocated.length - 4) { */
917 < 0) {<= preAllocated.length - 4) { function allocate(size) {
918 < 0) {<= preAllocated.length - 4) { size *= 4;
919 < 0) {<= preAllocated.length - 4) { iterator = -1;
920  
921 < 0) {<= preAllocated.length - 4) { //if (!preAllocated || (preAllocated && preAllocated.length !== size)) {
922 < 0) {<= preAllocated.length - 4) { preAllocated = new Float32Array(size);
923 < 0) {<= preAllocated.length - 4) { //}
924 < 0) {<= preAllocated.length - 4) { }
925  
926 < 0) {<= preAllocated.length - 4) { ////////////////////////////////////////////////////////////////////////////
927 < 0) {<= preAllocated.length - 4) { return {
928 < 0) {<= preAllocated.length - 4) { destroy: destroy,
929 < 0) {<= preAllocated.length - 4) { bind: bind,
930 < 0) {<= preAllocated.length - 4) { data: data,
931 < 0) {<= preAllocated.length - 4) { build: build,
932 < 0) {<= preAllocated.length - 4) { render: render,
933 < 0) {<= preAllocated.length - 4) { allocate: allocate,
934 < 0) {<= preAllocated.length - 4) { push: push
935 < 0) {<= preAllocated.length - 4) { };
936 < 0) {<= preAllocated.length - 4) { }
937  
938 < 0) {<= preAllocated.length - 4) { /* Main renderer. Used to render series.
939 < 0) {<= preAllocated.length - 4) { * Notes to self:
940 < 0) {<= preAllocated.length - 4) { * - May be able to build a point map by rendering to a separate canvas
941 < 0) {<= preAllocated.length - 4) { * and encoding values in the color data.
942 < 0) {<= preAllocated.length - 4) { * - Need to figure out a way to transform the data quicker
943 < 0) {<= preAllocated.length - 4) { */
944 < 0) {<= preAllocated.length - 4) { function GLRenderer(postRenderCallback) {
945 < 0) {<= preAllocated.length - 4) { var // Shader
946 < 0) {<= preAllocated.length - 4) { shader = false,
947 < 0) {<= preAllocated.length - 4) { // Vertex buffers - keyed on shader attribute name
948 < 0) {<= preAllocated.length - 4) { vbuffer = false,
949 < 0) {<= preAllocated.length - 4) { // Opengl context
950 < 0) {<= preAllocated.length - 4) { gl = false,
951 < 0) {<= preAllocated.length - 4) { // Width of our viewport in pixels
952 < 0) {<= preAllocated.length - 4) { width = 0,
953 < 0) {<= preAllocated.length - 4) { // Height of our viewport in pixels
954 < 0) {<= preAllocated.length - 4) { height = 0,
955 < 0) {<= preAllocated.length - 4) { // The data to render - array of coordinates
956 < 0) {<= preAllocated.length - 4) { data = false,
957 < 0) {<= preAllocated.length - 4) { // The marker data
958 < 0) {<= preAllocated.length - 4) { markerData = false,
959 < 0) {<= preAllocated.length - 4) { // Is the texture ready?
960 < 0) {<= preAllocated.length - 4) { textureIsReady = false,
961 < 0) {<= preAllocated.length - 4) { // Exports
962 < 0) {<= preAllocated.length - 4) { exports = {},
963 < 0) {<= preAllocated.length - 4) { // Is it inited?
964 < 0) {<= preAllocated.length - 4) { isInited = false,
965 < 0) {<= preAllocated.length - 4) { // The series stack
966 < 0) {<= preAllocated.length - 4) { series = [],
967 < 0) {<= preAllocated.length - 4) { // Texture for circles
968 < 0) {<= preAllocated.length - 4) { circleTexture = doc.createElement('canvas'),
969 < 0) {<= preAllocated.length - 4) { // Context for circle texture
970 < 0) {<= preAllocated.length - 4) { circleCtx = circleTexture.getContext('2d'),
971 < 0) {<= preAllocated.length - 4) { // Handle for the circle texture
972 < 0) {<= preAllocated.length - 4) { circleTextureHandle,
973 < 0) {<= preAllocated.length - 4) { // Things to draw as "rectangles" (i.e lines)
974 < 0) {<= preAllocated.length - 4) { asBar = {
975 < 0) {<= preAllocated.length - 4) { 'column': true,
976 < 0) {<= preAllocated.length - 4) { 'area': true
977 < 0) {<= preAllocated.length - 4) { },
978 < 0) {<= preAllocated.length - 4) { asCircle = {
979 < 0) {<= preAllocated.length - 4) { 'scatter': true,
980 < 0) {<= preAllocated.length - 4) { 'bubble': true
981 < 0) {<= preAllocated.length - 4) { },
982 < 0) {<= preAllocated.length - 4) { //Render settings
983 < 0) {<= preAllocated.length - 4) { settings = {
984 < 0) {<= preAllocated.length - 4) { pointSize: 1,
985 < 0) {<= preAllocated.length - 4) { lineWidth: 3,
986 < 0) {<= preAllocated.length - 4) { fillColor: '#AA00AA',
987 < 0) {<= preAllocated.length - 4) { useAlpha: true,
988 < 0) {<= preAllocated.length - 4) { usePreallocated: false,
989 < 0) {<= preAllocated.length - 4) { useGPUTranslations: false,
990 < 0) {<= preAllocated.length - 4) { timeRendering: false,
991 < 0) {<= preAllocated.length - 4) { timeSeriesProcessing: false,
992 < 0) {<= preAllocated.length - 4) { timeSetup: false
993 < 0) {<= preAllocated.length - 4) { };
994  
995 < 0) {<= preAllocated.length - 4) { ////////////////////////////////////////////////////////////////////////////
996  
997 < 0) {<= preAllocated.length - 4) { function setOptions(options) {
998 < 0) {<= preAllocated.length - 4) { merge(true, settings, options);
999 < 0) {<= preAllocated.length - 4) { }
1000  
1001 < 0) {<= preAllocated.length - 4) { function seriesPointCount(series) {
1002 < 0) {<= preAllocated.length - 4) { var isStacked,
1003 < 0) {<= preAllocated.length - 4) { xData,
1004 < 0) {<= preAllocated.length - 4) { s;
1005  
1006 < 0) {<= preAllocated.length - 4) { if (isSeriesBoosting(series)) {
1007 < 0) {<= preAllocated.length - 4) { isStacked = !!series.options.stacking;
1008 < 0) {<= preAllocated.length - 4) { xData = series.xData || series.options.xData || series.processedXData;
1009 < 0) {<= preAllocated.length - 4) { s = (isStacked ? series.data : (xData || series.options.data)).length;
1010  
1011 < 0) {<= preAllocated.length - 4) { if (series.type === 'treemap') {
1012 < 0) {<= preAllocated.length - 4) { s *= 12;
1013 < 0) {<= preAllocated.length - 4) { } else if (series.type === 'heatmap') {
1014 < 0) {<= preAllocated.length - 4) { s *= 6;
1015 < 0) {<= preAllocated.length - 4) { } else if (asBar[series.type]) {
1016 < 0) {<= preAllocated.length - 4) { s *= 2;
1017 < 0) {<= preAllocated.length - 4) { }
1018  
1019 < 0) {<= preAllocated.length - 4) { return s;
1020 < 0) {<= preAllocated.length - 4) { }
1021  
1022 < 0) {<= preAllocated.length - 4) { return 0;
1023 < 0) {<= preAllocated.length - 4) { }
1024  
1025 < 0) {<= preAllocated.length - 4) { /* Allocate a float buffer to fit all series */
1026 < 0) {<= preAllocated.length - 4) { function allocateBuffer(chart) {
1027 < 0) {<= preAllocated.length - 4) { var s = 0;
1028  
1029 < 0) {<= preAllocated.length - 4) { if (!settings.usePreallocated) {
1030 < 0) {<= preAllocated.length - 4) { return;
1031 < 0) {<= preAllocated.length - 4) { }
1032  
1033 < 0) {<= preAllocated.length - 4) { each(chart.series, function(series) {
1034 < 0) {<= preAllocated.length - 4) { if (isSeriesBoosting(series)) {
1035 < 0) {<= preAllocated.length - 4) { s += seriesPointCount(series);
1036 < 0) {<= preAllocated.length - 4) { }
1037 < 0) {<= preAllocated.length - 4) { });
1038  
1039 < 0) {<= preAllocated.length - 4) { vbuffer.allocate(s);
1040 < 0) {<= preAllocated.length - 4) { }
1041  
1042 < 0) {<= preAllocated.length - 4) { function allocateBufferForSingleSeries(series) {
1043 < 0) {<= preAllocated.length - 4) { var s = 0;
1044  
1045 < 0) {<= preAllocated.length - 4) { if (!settings.usePreallocated) {
1046 < 0) {<= preAllocated.length - 4) { return;
1047 < 0) {<= preAllocated.length - 4) { }
1048  
1049 < 0) {<= preAllocated.length - 4) { if (isSeriesBoosting(series)) {
1050 < 0) {<= preAllocated.length - 4) { s = seriesPointCount(series);
1051 < 0) {<= preAllocated.length - 4) { }
1052  
1053 < 0) {<= preAllocated.length - 4) { vbuffer.allocate(s);
1054 < 0) {<= preAllocated.length - 4) { }
1055  
1056 < 0) {<= preAllocated.length - 4) { /*
1057 < 0) {<= preAllocated.length - 4) { * Returns an orthographic perspective matrix
1058 < 0) {<= preAllocated.length - 4) { * @param {number} width - the width of the viewport in pixels
1059 < 0) {<= preAllocated.length - 4) { * @param {number} height - the height of the viewport in pixels
1060 < 0) {<= preAllocated.length - 4) { */
1061 < 0) {<= preAllocated.length - 4) { function orthoMatrix(width, height) {
1062 < 0) {<= preAllocated.length - 4) { var near = 0,
1063 < 0) {<= preAllocated.length - 4) { far = 1;
1064  
1065 < 0) {<= preAllocated.length - 4) { return [
1066 < 0) {<= preAllocated.length - 4) { 2 / width, 0, 0, 0,
1067 < 0) {<= preAllocated.length - 4) { 0, -(2 / height), 0, 0,
1068 < 0) {<= preAllocated.length - 4) { 0, 0, -2 / (far - near), 0, -1, 1, -(far + near) / (far - near), 1
1069 < 0) {<= preAllocated.length - 4) { ];
1070 < 0) {<= preAllocated.length - 4) { }
1071  
1072 < 0) {<= preAllocated.length - 4) { /*
1073 < 0) {<= preAllocated.length - 4) { * Clear the depth and color buffer
1074 < 0) {<= preAllocated.length - 4) { */
1075 < 0) {<= preAllocated.length - 4) { function clear() {
1076 < 0) {<= preAllocated.length - 4) { gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
1077 < 0) {<= preAllocated.length - 4) { }
1078  
1079 < 0) {<= preAllocated.length - 4) { /*
1080 < 0) {<= preAllocated.length - 4) { * Get the WebGL context
1081 < 0) {<= preAllocated.length - 4) { * @returns {WebGLContext} - the context
1082 < 0) {<= preAllocated.length - 4) { */
1083 < 0) {<= preAllocated.length - 4) { function getGL() {
1084 < 0) {<= preAllocated.length - 4) { return gl;
1085 < 0) {<= preAllocated.length - 4) { }
1086  
1087 < 0) {<= preAllocated.length - 4) { /*
1088 < 0) {<= preAllocated.length - 4) { * Push data for a single series
1089 < 0) {<= preAllocated.length - 4) { * This calculates additional vertices and transforms the data to be
1090 < 0) {<= preAllocated.length - 4) { * aligned correctly in memory
1091 < 0) {<= preAllocated.length - 4) { */
1092 < 0) {<= preAllocated.length - 4) { function pushSeriesData(series, inst) {
1093 < 0) {<= preAllocated.length - 4) { var isRange = series.pointArrayMap &&
1094 < 0) {<= preAllocated.length - 4) { series.pointArrayMap.join(',') === 'low,high',
1095 < 0) {<= preAllocated.length - 4) { chart = series.chart,
1096 < 0) {<= preAllocated.length - 4) { options = series.options,
1097 < 0) {<= preAllocated.length - 4) { isStacked = !!options.stacking,
1098 < 0) {<= preAllocated.length - 4) { rawData = options.data,
1099 < 0) {<= preAllocated.length - 4) { xExtremes = series.xAxis.getExtremes(),
1100 < 0) {<= preAllocated.length - 4) { xMin = xExtremes.min,
1101 < 0) {<= preAllocated.length - 4) { xMax = xExtremes.max,
1102 < 0) {<= preAllocated.length - 4) { yExtremes = series.yAxis.getExtremes(),
1103 < 0) {<= preAllocated.length - 4) { yMin = yExtremes.min,
1104 < 0) {<= preAllocated.length - 4) { yMax = yExtremes.max,
1105 < 0) {<= preAllocated.length - 4) { xData = series.xData || options.xData || series.processedXData,
1106 < 0) {<= preAllocated.length - 4) { yData = series.yData || options.yData || series.processedYData,
1107 < 0) {<= preAllocated.length - 4) { zData = series.zData || options.zData || series.processedZData,
1108 < 0) {<= preAllocated.length - 4) { yAxis = series.yAxis,
1109 < 0) {<= preAllocated.length - 4) { xAxis = series.xAxis,
1110 < 0) {<= preAllocated.length - 4) { useRaw = !xData || xData.length === 0,
1111 < 0) {<= preAllocated.length - 4) { // threshold = options.threshold,
1112 < 0) {<= preAllocated.length - 4) { // yBottom = chart.yAxis[0].getThreshold(threshold),
1113 < 0) {<= preAllocated.length - 4) { // hasThreshold = isNumber(threshold),
1114 < 0) {<= preAllocated.length - 4) { // colorByPoint = series.options.colorByPoint,
1115 < 0) {<= preAllocated.length - 4) { // This is required for color by point, so make sure this is
1116 < 0) {<= preAllocated.length - 4) { // uncommented if enabling that
1117 < 0) {<= preAllocated.length - 4) { // colorIndex = 0,
1118 < 0) {<= preAllocated.length - 4) { // Required for color axis support
1119 < 0) {<= preAllocated.length - 4) { // caxis,
1120 < 0) {<= preAllocated.length - 4) { // connectNulls = options.connectNulls,
1121 < 0) {<= preAllocated.length - 4) { // For some reason eslint doesn't pick up that this is actually used
1122 < 0) {<= preAllocated.length - 4) { maxVal, //eslint-disable-line no-unused-vars
1123 < 0) {<= preAllocated.length - 4) { points = series.points || false,
1124 < 0) {<= preAllocated.length - 4) { lastX = false,
1125 < 0) {<= preAllocated.length - 4) { minVal,
1126 < 0) {<= preAllocated.length - 4) { color,
1127 < 0) {<= preAllocated.length - 4) { scolor,
1128 < 0) {<= preAllocated.length - 4) { sdata = isStacked ? series.data : (xData || rawData),
1129 < 0) {<= preAllocated.length - 4) { closestLeft = {
1130 < 0) {<= preAllocated.length - 4) { x: Number.MIN_VALUE,
1131 < 0) {<= preAllocated.length - 4) { y: 0
1132 < 0) {<= preAllocated.length - 4) { },
1133 < 0) {<= preAllocated.length - 4) { closestRight = {
1134 < 0) {<= preAllocated.length - 4) { x: Number.MIN_VALUE,
1135 < 0) {<= preAllocated.length - 4) { y: 0
1136 < 0) {<= preAllocated.length - 4) { };
1137  
1138 < 0) {<= preAllocated.length - 4) { if (options.boostData && options.boostData.length > 0) {
1139 < 0) {<= preAllocated.length - 4) { return;
1140 < 0) {<= preAllocated.length - 4) { }
1141  
1142 < 0) {<= preAllocated.length - 4) { series.closestPointRangePx = Number.MAX_VALUE;
1143  
1144 < 0) {<= preAllocated.length - 4) { // Push color to color buffer - need to do this per. vertex
1145 < 0) {<= preAllocated.length - 4) { function pushColor(color) {
1146 < 0) {<= preAllocated.length - 4) { if (color) {
1147 < 0) {<= preAllocated.length - 4) { inst.colorData.push(color[0]);
1148 < 0) {<= preAllocated.length - 4) { inst.colorData.push(color[1]);
1149 < 0) {<= preAllocated.length - 4) { inst.colorData.push(color[2]);
1150 < 0) {<= preAllocated.length - 4) { inst.colorData.push(color[3]);
1151 < 0) {<= preAllocated.length - 4) { }
1152 < 0) {<= preAllocated.length - 4) { }
1153  
1154 < 0) {<= preAllocated.length - 4) { //Push a vertice to the data buffer
1155 < 0) {<= preAllocated.length - 4) { function vertice(x, y, checkTreshold, pointSize, color) {
1156 < 0) {<= preAllocated.length - 4) { pushColor(color);
1157 < 0) {<= preAllocated.length - 4) { if (settings.usePreallocated) {
1158 < 0) {<= preAllocated.length - 4) { vbuffer.push(x, y, checkTreshold ? 1 : 0, pointSize || 1);
1159 < 0) {<= preAllocated.length - 4) { } else {
1160 < 0) {<= preAllocated.length - 4) { data.push(x);
1161 < 0) {<= preAllocated.length - 4) { data.push(y);
1162 < 0) {<= preAllocated.length - 4) { data.push(checkTreshold ? 1 : 0);
1163 < 0) {<= preAllocated.length - 4) { data.push(pointSize || 1);
1164 < 0) {<= preAllocated.length - 4) { }
1165 < 0) {<= preAllocated.length - 4) { }
1166  
1167 < 0) {<= preAllocated.length - 4) { // Push a rectangle to the data buffer
1168 < 0) {<= preAllocated.length - 4) { function pushRect(x, y, w, h, color) {
1169 < 0) {<= preAllocated.length - 4) { pushColor(color);
1170 < 0) {<= preAllocated.length - 4) { vertice(x + w, y);
1171 < 0) {<= preAllocated.length - 4) { pushColor(color);
1172 < 0) {<= preAllocated.length - 4) { vertice(x, y);
1173 < 0) {<= preAllocated.length - 4) { pushColor(color);
1174 < 0) {<= preAllocated.length - 4) { vertice(x, y + h);
1175  
1176 < 0) {<= preAllocated.length - 4) { pushColor(color);
1177 < 0) {<= preAllocated.length - 4) { vertice(x, y + h);
1178 < 0) {<= preAllocated.length - 4) { pushColor(color);
1179 < 0) {<= preAllocated.length - 4) { vertice(x + w, y + h);
1180 < 0) {<= preAllocated.length - 4) { pushColor(color);
1181 < 0) {<= preAllocated.length - 4) { vertice(x + w, y);
1182 < 0) {<= preAllocated.length - 4) { }
1183  
1184 < 0) {<= preAllocated.length - 4) { // Special case for point shapes
1185 < 0) {<= preAllocated.length - 4) { if (points && points.length > 0) {
1186  
1187 < 0) {<= preAllocated.length - 4) { // If we're doing points, we assume that the points are already
1188 < 0) {<= preAllocated.length - 4) { // translated, so we skip the shader translation.
1189 < 0) {<= preAllocated.length - 4) { inst.skipTranslation = true;
1190 < 0) {<= preAllocated.length - 4) { // Force triangle draw mode
1191 < 0) {<= preAllocated.length - 4) { inst.drawMode = 'triangles';
1192  
1193 < 0) {<= preAllocated.length - 4) { // We don't have a z component in the shader, so we need to sort.
1194 < 0) {<= preAllocated.length - 4) { if (points[0].node && points[0].node.levelDynamic) {
1195 < 0) {<= preAllocated.length - 4) { points.sort(function(a, b) {
1196 < 0) {<= preAllocated.length - 4) { if (a.node) {
1197 < 0) {<= preAllocated.length - 4) { if (a.node.levelDynamic > b.node.levelDynamic) {
1198 < 0) {<= preAllocated.length - 4) { return 1;
1199 < 0) {<= preAllocated.length - 4) { } else if (a.node.levelDynamic < b.node.levelDynamic) {
1200 < 0) {<= preAllocated.length - 4) { return -1;
1201 < 0) {<= preAllocated.length - 4) { }
1202 < 0) {<= preAllocated.length - 4) { }
1203 < 0) {<= preAllocated.length - 4) { return 0;
1204 < 0) {<= preAllocated.length - 4) { });
1205 < 0) {<= preAllocated.length - 4) { }
1206  
1207 < 0) {<= preAllocated.length - 4) { each(points, function(point) {
1208 < 0) {<= preAllocated.length - 4) { var plotY = point.plotY,
1209 < 0) {<= preAllocated.length - 4) { shapeArgs,
1210 < 0) {<= preAllocated.length - 4) { swidth,
1211 < 0) {<= preAllocated.length - 4) { pointAttr;
1212  
1213 < 0) {<= preAllocated.length - 4) { if (plotY !== undefined && !isNaN(plotY) && point.y !== null) {
1214 < 0) {<= preAllocated.length - 4) { shapeArgs = point.shapeArgs;
1215  
1216  
1217 < 0) {<= preAllocated.length - 4) { pointAttr = point.series.colorAttribs(point);
1218  
1219 < 0) {<= preAllocated.length - 4) { swidth = pointAttr['stroke-width'] || 0;
1220  
1221 < 0) {<= preAllocated.length - 4) { // Handle point colors
1222 < 0) {<= preAllocated.length - 4) { color = H.color(pointAttr.fill).rgba;
1223 < 0) {<= preAllocated.length - 4) { color[0] /= 255.0;
1224 < 0) {<= preAllocated.length - 4) { color[1] /= 255.0;
1225 < 0) {<= preAllocated.length - 4) { color[2] /= 255.0;
1226  
1227 < 0) {<= preAllocated.length - 4) { // So there are two ways of doing this. Either we can
1228 < 0) {<= preAllocated.length - 4) { // create a rectangle of two triangles, or we can do a
1229 < 0) {<= preAllocated.length - 4) { // point and use point size. Latter is faster, but
1230 < 0) {<= preAllocated.length - 4) { // only supports squares. So we're doing triangles.
1231 < 0) {<= preAllocated.length - 4) { // We could also use one color per. vertice to get
1232 < 0) {<= preAllocated.length - 4) { // better color interpolation.
1233  
1234 < 0) {<= preAllocated.length - 4) { // If there's stroking, we do an additional rect
1235 < 0) {<= preAllocated.length - 4) { //if (pointAttr.stroke !== 'none' && swidth && swidth > 0) {
1236 < 0) {<= preAllocated.length - 4) { if (series.type === 'treemap') {
1237 < 0) {<= preAllocated.length - 4) { swidth = swidth || 1;
1238 < 0) {<= preAllocated.length - 4) { scolor = H.color(pointAttr.stroke).rgba;
1239  
1240 < 0) {<= preAllocated.length - 4) { scolor[0] /= 255.0;
1241 < 0) {<= preAllocated.length - 4) { scolor[1] /= 255.0;
1242 < 0) {<= preAllocated.length - 4) { scolor[2] /= 255.0;
1243  
1244 < 0) {<= preAllocated.length - 4) { pushRect(
1245 < 0) {<= preAllocated.length - 4) { shapeArgs.x,
1246 < 0) {<= preAllocated.length - 4) { shapeArgs.y,
1247 < 0) {<= preAllocated.length - 4) { shapeArgs.width,
1248 < 0) {<= preAllocated.length - 4) { shapeArgs.height,
1249 < 0) {<= preAllocated.length - 4) { scolor
1250 < 0) {<= preAllocated.length - 4) { );
1251  
1252 < 0) {<= preAllocated.length - 4) { swidth /= 2;
1253 < 0) {<= preAllocated.length - 4) { }
1254 < 0) {<= preAllocated.length - 4) { // } else {
1255 < 0) {<= preAllocated.length - 4) { // swidth = 0;
1256 < 0) {<= preAllocated.length - 4) { // }
1257  
1258 < 0) {<= preAllocated.length - 4) { pushRect(
1259 < 0) {<= preAllocated.length - 4) { shapeArgs.x + swidth,
1260 < 0) {<= preAllocated.length - 4) { shapeArgs.y + swidth,
1261 < 0) {<= preAllocated.length - 4) { shapeArgs.width - (swidth * 2),
1262 < 0) {<= preAllocated.length - 4) { shapeArgs.height - (swidth * 2),
1263 < 0) {<= preAllocated.length - 4) { color
1264 < 0) {<= preAllocated.length - 4) { );
1265 < 0) {<= preAllocated.length - 4) { }
1266 < 0) {<= preAllocated.length - 4) { });
1267  
1268 < 0) {<= preAllocated.length - 4) { return;
1269 < 0) {<= preAllocated.length - 4) { }
1270  
1271 < 0) {<= preAllocated.length - 4) { // Extract color axis
1272 < 0) {<= preAllocated.length - 4) { // each(chart.axes || [], function (a) {
1273 < 0) {<= preAllocated.length - 4) { // if (H.ColorAxis && a instanceof H.ColorAxis) {
1274 < 0) {<= preAllocated.length - 4) { // caxis = a;
1275 < 0) {<= preAllocated.length - 4) { // }
1276 < 0) {<= preAllocated.length - 4) { // });
1277  
1278 < 0) {<= preAllocated.length - 4) { each(sdata, function(d, i) {
1279 < 0) {<= preAllocated.length - 4) { var x,
1280 < 0) {<= preAllocated.length - 4) { y,
1281 < 0) {<= preAllocated.length - 4) { z,
1282 < 0) {<= preAllocated.length - 4) { px = false,
1283 < 0) {<= preAllocated.length - 4) { nx = false,
1284 < 0) {<= preAllocated.length - 4) { // This is in fact used.
1285 < 0) {<= preAllocated.length - 4) { low, //eslint-disable-line no-unused-vars
1286 < 0) {<= preAllocated.length - 4) { chartDestroyed = typeof chart.index === 'undefined',
1287 < 0) {<= preAllocated.length - 4) { nextInside = false,
1288 < 0) {<= preAllocated.length - 4) { prevInside = false,
1289 < 0) {<= preAllocated.length - 4) { pcolor = false,
1290 < 0) {<= preAllocated.length - 4) { drawAsBar = asBar[series.type],
1291 < 0) {<= preAllocated.length - 4) { isXInside = false,
1292 < 0) {<= preAllocated.length - 4) { isYInside = true;
1293  
1294 < 0) {<= preAllocated.length - 4) { if (chartDestroyed) {
1295 < 0) {<= preAllocated.length - 4) { return false;
1296 < 0) {<= preAllocated.length - 4) { }
1297  
1298 < 0) {<= preAllocated.length - 4) { // Uncomment this to enable color by point.
1299 < 0) {<= preAllocated.length - 4) { // This currently left disabled as the charts look really ugly
1300 < 0) {<= preAllocated.length - 4) { // when enabled and there's a lot of points.
1301 < 0) {<= preAllocated.length - 4) { // Leaving in for the future (tm).
1302 < 0) {<= preAllocated.length - 4) { // if (colorByPoint) {
1303 < 0) {<= preAllocated.length - 4) { // colorIndex = ++colorIndex % series.chart.options.colors.length;
1304 < 0) {<= preAllocated.length - 4) { // pcolor = toRGBAFast(series.chart.options.colors[colorIndex]);
1305 < 0) {<= preAllocated.length - 4) { // pcolor[0] /= 255.0;
1306 < 0) {<= preAllocated.length - 4) { // pcolor[1] /= 255.0;
1307 < 0) {<= preAllocated.length - 4) { // pcolor[2] /= 255.0;
1308 < 0) {<= preAllocated.length - 4) { // }
1309  
1310 < 0) {<= preAllocated.length - 4) { if (useRaw) {
1311 < 0) {<= preAllocated.length - 4) { x = d[0];
1312 < 0) {<= preAllocated.length - 4) { y = d[1];
1313  
1314 < 0) {<= preAllocated.length - 4) { if (sdata[i + 1]) {
1315 < 0) {<= preAllocated.length - 4) { nx = sdata[i + 1][0];
1316 < 0) {<= preAllocated.length - 4) { }
1317  
1318 < 0) {<= preAllocated.length - 4) { if (sdata[i - 1]) {
1319 < 0) {<= preAllocated.length - 4) { px = sdata[i - 1][0];
1320 < 0) {<= preAllocated.length - 4) { }
1321  
1322 < 0) {<= preAllocated.length - 4) { if (d.length >= 3) {
1323 < 0) {<= preAllocated.length - 4) { z = d[2];
1324  
1325 < 0) {<= preAllocated.length - 4) { if (d[2] > inst.zMax) {
1326 < 0) {<= preAllocated.length - 4) { inst.zMax = d[2];
1327 < 0) {<= preAllocated.length - 4) { }
1328  
1329 < 0) {<= preAllocated.length - 4) { if (d[2] < inst.zMin) {
1330 < 0) {<= preAllocated.length - 4) { inst.zMin = d[2];
1331 < 0) {<= preAllocated.length - 4) { }
1332 < 0) {<= preAllocated.length - 4) { }
1333  
1334 < 0) {<= preAllocated.length - 4) { } else {
1335 < 0) {<= preAllocated.length - 4) { x = d;
1336 < 0) {<= preAllocated.length - 4) { y = yData[i];
1337  
1338 < 0) {<= preAllocated.length - 4) { if (sdata[i + 1]) {
1339 < 0) {<= preAllocated.length - 4) { nx = sdata[i + 1];
1340 < 0) {<= preAllocated.length - 4) { }
1341  
1342 < 0) {<= preAllocated.length - 4) { if (sdata[i - 1]) {
1343 < 0) {<= preAllocated.length - 4) { px = sdata[i - 1];
1344 < 0) {<= preAllocated.length - 4) { }
1345  
1346 < 0) {<= preAllocated.length - 4) { if (zData && zData.length) {
1347 < 0) {<= preAllocated.length - 4) { z = zData[i];
1348  
1349 < 0) {<= preAllocated.length - 4) { if (zData[i] > inst.zMax) {
1350 < 0) {<= preAllocated.length - 4) { inst.zMax = zData[i];
1351 < 0) {<= preAllocated.length - 4) { }
1352  
1353 < 0) {<= preAllocated.length - 4) { if (zData[i] < inst.zMin) {
1354 < 0) {<= preAllocated.length - 4) { inst.zMin = zData[i];
1355 < 0) {<= preAllocated.length - 4) { }
1356 < 0) {<= preAllocated.length - 4) { }
1357 < 0) {<= preAllocated.length - 4) { }
1358  
1359 < 0) {<= preAllocated.length - 4) { if (nx && nx >= xMin && nx <= xMax) {
1360 < 0) {<= preAllocated.length - 4) { nextInside = true;
1361 < 0) {<= preAllocated.length - 4) { }
1362  
1363 < 0) {<= preAllocated.length - 4) { if (px && px >= xMin && px <= xMax) {
1364 < 0) {<= preAllocated.length - 4) { prevInside = true;
1365 < 0) {<= preAllocated.length - 4) { }
1366  
1367 < 0) {<= preAllocated.length - 4) { if (isRange) {
1368 < 0) {<= preAllocated.length - 4) { if (useRaw) {
1369 < 0) {<= preAllocated.length - 4) { y = d.slice(1, 3);
1370 < 0) {<= preAllocated.length - 4) { }
1371  
1372 < 0) {<= preAllocated.length - 4) { low = y[0];
1373 < 0) {<= preAllocated.length - 4) { y = y[1];
1374  
1375 < 0) {<= preAllocated.length - 4) { } else if (isStacked) {
1376 < 0) {<= preAllocated.length - 4) { x = d.x;
1377 < 0) {<= preAllocated.length - 4) { y = d.stackY;
1378 < 0) {<= preAllocated.length - 4) { low = y - d.y;
1379 < 0) {<= preAllocated.length - 4) { }
1380  
1381 < 0) {<= preAllocated.length - 4) { if (!series.requireSorting) {
1382 < 0) {<= preAllocated.length - 4) { isYInside = y >= yMin && y <= yMax;
1383 < 0) {<= preAllocated.length - 4) { }
1384  
1385 < 0) {<= preAllocated.length - 4) { if (x > xMax && closestRight.x < xMax) {
1386 < 0) {<= preAllocated.length - 4) { closestRight.x = x;
1387 < 0) {<= preAllocated.length - 4) { closestRight.y = y;
1388 < 0) {<= preAllocated.length - 4) { }
1389  
1390 < 0) {<= preAllocated.length - 4) { if (x < xMin && closestLeft.x < xMin) {
1391 < 0) {<= preAllocated.length - 4) { closestLeft.x = x;
1392 < 0) {<= preAllocated.length - 4) { closestLeft.y = y;
1393 < 0) {<= preAllocated.length - 4) { }
1394  
1395 < 0) {<= preAllocated.length - 4) { if (y !== 0 && (!y || !isYInside)) {
1396 < 0) {<= preAllocated.length - 4) { return;
1397 < 0) {<= preAllocated.length - 4) { }
1398  
1399 < 0) {<= preAllocated.length - 4) { if (x >= xMin && x <= xMax) {
1400 < 0) {<= preAllocated.length - 4) { isXInside = true;
1401 < 0) {<= preAllocated.length - 4) { }
1402  
1403 < 0) {<= preAllocated.length - 4) { if (!isXInside && !nextInside && !prevInside) {
1404 < 0) {<= preAllocated.length - 4) { return;
1405 < 0) {<= preAllocated.length - 4) { }
1406  
1407 < 0) {<= preAllocated.length - 4) { // Skip translations - temporary floating point fix
1408 < 0) {<= preAllocated.length - 4) { if (!settings.useGPUTranslations) {
1409 < 0) {<= preAllocated.length - 4) { inst.skipTranslation = true;
1410 < 0) {<= preAllocated.length - 4) { x = xAxis.toPixels(x, true);
1411 < 0) {<= preAllocated.length - 4) { y = yAxis.toPixels(y, true);
1412 < 0) {<= preAllocated.length - 4) { }
1413  
1414 < 0) {<= preAllocated.length - 4) { if (drawAsBar) {
1415  
1416 < 0) {<= preAllocated.length - 4) { maxVal = y;
1417 < 0) {<= preAllocated.length - 4) { minVal = 0;
1418  
1419 < 0) {<= preAllocated.length - 4) { if (y < 0) {
1420 < 0) {<= preAllocated.length - 4) { minVal = y;
1421 < 0) {<= preAllocated.length - 4) { y = 0;
1422 < 0) {<= preAllocated.length - 4) { }
1423  
1424 < 0) {<= preAllocated.length - 4) { if (!settings.useGPUTranslations) {
1425 < 0) {<= preAllocated.length - 4) { minVal = yAxis.toPixels(minVal, true);
1426 < 0) {<= preAllocated.length - 4) { }
1427  
1428 < 0) {<= preAllocated.length - 4) { // Need to add an extra point here
1429 < 0) {<= preAllocated.length - 4) { vertice(x, minVal, 0, 0, pcolor);
1430 < 0) {<= preAllocated.length - 4) { }
1431  
1432 < 0) {<= preAllocated.length - 4) { // No markers on out of bounds things.
1433 < 0) {<= preAllocated.length - 4) { // Out of bound things are shown if and only if the next
1434 < 0) {<= preAllocated.length - 4) { // or previous point is inside the rect.
1435 < 0) {<= preAllocated.length - 4) { if (inst.hasMarkers) { // && isXInside) {
1436 < 0) {<= preAllocated.length - 4) { // x = H.correctFloat(
1437 < 0) {<= preAllocated.length - 4) { // Math.min(Math.max(-1e5, xAxis.translate(
1438 < 0) {<= preAllocated.length - 4) { // x,
1439 < 0) {<= preAllocated.length - 4) { // 0,
1440 < 0) {<= preAllocated.length - 4) { // 0,
1441 < 0) {<= preAllocated.length - 4) { // 0,
1442 < 0) {<= preAllocated.length - 4) { // 1,
1443 < 0) {<= preAllocated.length - 4) { // 0.5,
1444 < 0) {<= preAllocated.length - 4) { // false
1445 < 0) {<= preAllocated.length - 4) { // )), 1e5)
1446 < 0) {<= preAllocated.length - 4) { // );
1447  
1448 < 0) {<= preAllocated.length - 4) { if (lastX !== false) {
1449 < 0) {<= preAllocated.length - 4) { series.closestPointRangePx = Math.min(
1450 < 0) {<= preAllocated.length - 4) { series.closestPointRangePx,
1451 < 0) {<= preAllocated.length - 4) { Math.abs(x - lastX)
1452 < 0) {<= preAllocated.length - 4) { );
1453 < 0) {<= preAllocated.length - 4) { }
1454 < 0) {<= preAllocated.length - 4) { }
1455  
1456 < 0) {<= preAllocated.length - 4) { vertice(
1457 < 0) {<= preAllocated.length - 4) { x,
1458 < 0) {<= preAllocated.length - 4) { y,
1459 < 0) {<= preAllocated.length - 4) { 0,
1460 < 0) {<= preAllocated.length - 4) { series.type === 'bubble' ? (z || 1) : 2,
1461 < 0) {<= preAllocated.length - 4) { pcolor
1462 < 0) {<= preAllocated.length - 4) { );
1463  
1464 < 0) {<= preAllocated.length - 4) { // Uncomment this to support color axis.
1465 < 0) {<= preAllocated.length - 4) { // if (caxis) {
1466 < 0) {<= preAllocated.length - 4) { // color = H.color(caxis.toColor(y)).rgba;
1467  
1468 < 0) {<= preAllocated.length - 4) { // inst.colorData.push(color[0] / 255.0);
1469 < 0) {<= preAllocated.length - 4) { // inst.colorData.push(color[1] / 255.0);
1470 < 0) {<= preAllocated.length - 4) { // inst.colorData.push(color[2] / 255.0);
1471 < 0) {<= preAllocated.length - 4) { // inst.colorData.push(color[3]);
1472 < 0) {<= preAllocated.length - 4) { // }
1473  
1474 < 0) {<= preAllocated.length - 4) { lastX = x;
1475  
1476 < 0) {<= preAllocated.length - 4) { //return true;
1477 < 0) {<= preAllocated.length - 4) { });
1478  
1479 < 0) {<= preAllocated.length - 4) { function pushSupplementPoint(point) {
1480 < 0) {<= preAllocated.length - 4) { if (!settings.useGPUTranslations) {
1481 < 0) {<= preAllocated.length - 4) { inst.skipTranslation = true;
1482 < 0) {<= preAllocated.length - 4) { point.x = xAxis.toPixels(point.x, true);
1483 < 0) {<= preAllocated.length - 4) { point.y = yAxis.toPixels(point.y, true);
1484 < 0) {<= preAllocated.length - 4) { }
1485  
1486 < 0) {<= preAllocated.length - 4) { // We should only do this for lines, and we should ignore markers
1487 < 0) {<= preAllocated.length - 4) { // since there's no point here that would have a marker.
1488  
1489 < 0) {<= preAllocated.length - 4) { vertice(
1490 < 0) {<= preAllocated.length - 4) { point.x,
1491 < 0) {<= preAllocated.length - 4) { point.y,
1492 < 0) {<= preAllocated.length - 4) { 0,
1493 < 0) {<= preAllocated.length - 4) { 2
1494 < 0) {<= preAllocated.length - 4) { );
1495 < 0) {<= preAllocated.length - 4) { }
1496  
1497 < 0) {<= preAllocated.length - 4) { if (!lastX) {
1498 < 0) {<= preAllocated.length - 4) { // There are no points within the selected range
1499 < 0) {<= preAllocated.length - 4) { pushSupplementPoint(closestLeft);
1500 < 0) {<= preAllocated.length - 4) { pushSupplementPoint(closestRight);
1501 < 0) {<= preAllocated.length - 4) { }
1502 < 0) {<= preAllocated.length - 4) { }
1503  
1504 < 0) {<= preAllocated.length - 4) { /*
1505 < 0) {<= preAllocated.length - 4) { * Push a series to the renderer
1506 < 0) {<= preAllocated.length - 4) { * If we render the series immediatly, we don't have to loop later
1507 < 0) {<= preAllocated.length - 4) { * @param s {Highchart.Series} - the series to push
1508 < 0) {<= preAllocated.length - 4) { */
1509 < 0) {<= preAllocated.length - 4) { function pushSeries(s) {
1510 < 0) {<= preAllocated.length - 4) { if (series.length > 0) {
1511 < 0) {<= preAllocated.length - 4) { series[series.length - 1].to = data.length;
1512 < 0) {<= preAllocated.length - 4) { if (series[series.length - 1].hasMarkers) {
1513 < 0) {<= preAllocated.length - 4) { series[series.length - 1].markerTo = markerData.length;
1514 < 0) {<= preAllocated.length - 4) { }
1515 < 0) {<= preAllocated.length - 4) { }
1516  
1517 < 0) {<= preAllocated.length - 4) { if (settings.timeSeriesProcessing) {
1518 < 0) {<= preAllocated.length - 4) { console.time('building ' + s.type + ' series'); //eslint-disable-line no-console
1519 < 0) {<= preAllocated.length - 4) { }
1520  
1521 < 0) {<= preAllocated.length - 4) { series.push({
1522 < 0) {<= preAllocated.length - 4) { from: data.length,
1523 < 0) {<= preAllocated.length - 4) { markerFrom: markerData.length,
1524 < 0) {<= preAllocated.length - 4) { // Push RGBA values to this array to use per. point coloring.
1525 < 0) {<= preAllocated.length - 4) { // It should be 0-padded, so each component should be pushed in
1526 < 0) {<= preAllocated.length - 4) { // succession.
1527 < 0) {<= preAllocated.length - 4) { colorData: [],
1528 < 0) {<= preAllocated.length - 4) { series: s,
1529 < 0) {<= preAllocated.length - 4) { zMin: Number.MAX_VALUE,
1530 < 0) {<= preAllocated.length - 4) { zMax: -Number.MAX_VALUE,
1531 < 0) {<= preAllocated.length - 4) { hasMarkers: s.options.marker ? s.options.marker.enabled !== false : false,
1532 < 0) {<= preAllocated.length - 4) { showMarksers: true,
1533 < 0) {<= preAllocated.length - 4) { drawMode: ({
1534 < 0) {<= preAllocated.length - 4) { 'area': 'lines',
1535 < 0) {<= preAllocated.length - 4) { 'arearange': 'lines',
1536 < 0) {<= preAllocated.length - 4) { 'areaspline': 'line_strip',
1537 < 0) {<= preAllocated.length - 4) { 'column': 'lines',
1538 < 0) {<= preAllocated.length - 4) { 'line': 'line_strip',
1539 < 0) {<= preAllocated.length - 4) { 'scatter': 'points',
1540 < 0) {<= preAllocated.length - 4) { 'heatmap': 'triangles',
1541 < 0) {<= preAllocated.length - 4) { 'treemap': 'triangles',
1542 < 0) {<= preAllocated.length - 4) { 'bubble': 'points'
1543 < 0) {<= preAllocated.length - 4) { })[s.type] || 'line_strip'
1544 < 0) {<= preAllocated.length - 4) { });
1545  
1546 < 0) {<= preAllocated.length - 4) { // Add the series data to our buffer(s)
1547 < 0) {<= preAllocated.length - 4) { pushSeriesData(s, series[series.length - 1]);
1548  
1549 < 0) {<= preAllocated.length - 4) { if (settings.timeSeriesProcessing) {
1550 < 0) {<= preAllocated.length - 4) { console.timeEnd('building ' + s.type + ' series'); //eslint-disable-line no-console
1551 < 0) {<= preAllocated.length - 4) { }
1552 < 0) {<= preAllocated.length - 4) { }
1553  
1554 < 0) {<= preAllocated.length - 4) { /*
1555 < 0) {<= preAllocated.length - 4) { * Flush the renderer.
1556 < 0) {<= preAllocated.length - 4) { * This removes pushed series and vertices.
1557 < 0) {<= preAllocated.length - 4) { * Should be called after clearing and before rendering
1558 < 0) {<= preAllocated.length - 4) { */
1559 < 0) {<= preAllocated.length - 4) { function flush() {
1560 < 0) {<= preAllocated.length - 4) { series = [];
1561 < 0) {<= preAllocated.length - 4) { exports.data = data = [];
1562 < 0) {<= preAllocated.length - 4) { markerData = [];
1563 < 0) {<= preAllocated.length - 4) { }
1564  
1565 < 0) {<= preAllocated.length - 4) { /*
1566 < 0) {<= preAllocated.length - 4) { * Pass x-axis to shader
1567 < 0) {<= preAllocated.length - 4) { * @param axis {Highcharts.Axis} - the x-axis
1568 < 0) {<= preAllocated.length - 4) { */
1569 < 0) {<= preAllocated.length - 4) { function setXAxis(axis) {
1570 < 0) {<= preAllocated.length - 4) { if (!shader) {
1571 < 0) {<= preAllocated.length - 4) { return;
1572 < 0) {<= preAllocated.length - 4) { }
1573  
1574 < 0) {<= preAllocated.length - 4) { shader.setUniform('xAxisTrans', axis.transA);
1575 < 0) {<= preAllocated.length - 4) { shader.setUniform('xAxisMin', axis.min);
1576 < 0) {<= preAllocated.length - 4) { shader.setUniform('xAxisMinPad', axis.minPixelPadding);
1577 < 0) {<= preAllocated.length - 4) { shader.setUniform('xAxisPointRange', axis.pointRange);
1578 < 0) {<= preAllocated.length - 4) { shader.setUniform('xAxisLen', axis.len);
1579 < 0) {<= preAllocated.length - 4) { shader.setUniform('xAxisPos', axis.pos);
1580 < 0) {<= preAllocated.length - 4) { shader.setUniform('xAxisCVSCoord', !axis.horiz);
1581 < 0) {<= preAllocated.length - 4) { }
1582  
1583 < 0) {<= preAllocated.length - 4) { /*
1584 < 0) {<= preAllocated.length - 4) { * Pass y-axis to shader
1585 < 0) {<= preAllocated.length - 4) { * @param axis {Highcharts.Axis} - the y-axis
1586 < 0) {<= preAllocated.length - 4) { */
1587 < 0) {<= preAllocated.length - 4) { function setYAxis(axis) {
1588 < 0) {<= preAllocated.length - 4) { if (!shader) {
1589 < 0) {<= preAllocated.length - 4) { return;
1590 < 0) {<= preAllocated.length - 4) { }
1591  
1592 < 0) {<= preAllocated.length - 4) { shader.setUniform('yAxisTrans', axis.transA);
1593 < 0) {<= preAllocated.length - 4) { shader.setUniform('yAxisMin', axis.min);
1594 < 0) {<= preAllocated.length - 4) { shader.setUniform('yAxisMinPad', axis.minPixelPadding);
1595 < 0) {<= preAllocated.length - 4) { shader.setUniform('yAxisPointRange', axis.pointRange);
1596 < 0) {<= preAllocated.length - 4) { shader.setUniform('yAxisLen', axis.len);
1597 < 0) {<= preAllocated.length - 4) { shader.setUniform('yAxisPos', axis.pos);
1598 < 0) {<= preAllocated.length - 4) { shader.setUniform('yAxisCVSCoord', !axis.horiz);
1599 < 0) {<= preAllocated.length - 4) { }
1600  
1601 < 0) {<= preAllocated.length - 4) { /*
1602 < 0) {<= preAllocated.length - 4) { * Set the translation threshold
1603 < 0) {<= preAllocated.length - 4) { * @param has {boolean} - has threshold flag
1604 < 0) {<= preAllocated.length - 4) { * @param translation {Float} - the threshold
1605 < 0) {<= preAllocated.length - 4) { */
1606 < 0) {<= preAllocated.length - 4) { function setThreshold(has, translation) {
1607 < 0) {<= preAllocated.length - 4) { shader.setUniform('hasThreshold', has);
1608 < 0) {<= preAllocated.length - 4) { shader.setUniform('translatedThreshold', translation);
1609 < 0) {<= preAllocated.length - 4) { }
1610  
1611 < 0) {<= preAllocated.length - 4) { /*
1612 < 0) {<= preAllocated.length - 4) { * Render the data
1613 < 0) {<= preAllocated.length - 4) { * This renders all pushed series.
1614 < 0) {<= preAllocated.length - 4) { */
1615 < 0) {<= preAllocated.length - 4) { function render(chart) {
1616  
1617 < 0) {<= preAllocated.length - 4) { if (chart) {
1618 < 0) {<= preAllocated.length - 4) { if (!chart.chartHeight || !chart.chartWidth) {
1619 < 0) {<= preAllocated.length - 4) { //chart.setChartSize();
1620 < 0) {<= preAllocated.length - 4) { }
1621  
1622 < 0) {<= preAllocated.length - 4) { width = chart.chartWidth || 800;
1623 < 0) {<= preAllocated.length - 4) { height = chart.chartHeight || 400;
1624 < 0) {<= preAllocated.length - 4) { } else {
1625 < 0) {<= preAllocated.length - 4) { return false;
1626 < 0) {<= preAllocated.length - 4) { }
1627  
1628 < 0) {<= preAllocated.length - 4) { if (!gl || !width || !height) {
1629 < 0) {<= preAllocated.length - 4) { return false;
1630 < 0) {<= preAllocated.length - 4) { }
1631  
1632 < 0) {<= preAllocated.length - 4) { if (settings.timeRendering) {
1633 < 0) {<= preAllocated.length - 4) { console.time('gl rendering'); //eslint-disable-line no-console
1634 < 0) {<= preAllocated.length - 4) { }
1635  
1636 < 0) {<= preAllocated.length - 4) { shader.bind();
1637  
1638 < 0) {<= preAllocated.length - 4) { gl.viewport(0, 0, width, height);
1639 < 0) {<= preAllocated.length - 4) { shader.setPMatrix(orthoMatrix(width, height));
1640  
1641 < 0) {<= preAllocated.length - 4) { if (settings.lineWidth > 1 && !H.isMS) {
1642 < 0) {<= preAllocated.length - 4) { gl.lineWidth(settings.lineWidth);
1643 < 0) {<= preAllocated.length - 4) { }
1644  
1645 < 0) {<= preAllocated.length - 4) { vbuffer.build(exports.data, 'aVertexPosition', 4);
1646 < 0) {<= preAllocated.length - 4) { vbuffer.bind();
1647  
1648 < 0) {<= preAllocated.length - 4) { if (textureIsReady) {
1649 < 0) {<= preAllocated.length - 4) { gl.bindTexture(gl.TEXTURE_2D, circleTextureHandle);
1650 < 0) {<= preAllocated.length - 4) { shader.setTexture(circleTextureHandle);
1651 < 0) {<= preAllocated.length - 4) { }
1652  
1653 < 0) {<= preAllocated.length - 4) { shader.setInverted(chart.options.chart ? chart.options.chart.inverted : false);
1654  
1655 < 0) {<= preAllocated.length - 4) { // Render the series
1656 < 0) {<= preAllocated.length - 4) { each(series, function(s, si) {
1657 < 0) {<= preAllocated.length - 4) { var options = s.series.options,
1658 < 0) {<= preAllocated.length - 4) { threshold = options.threshold,
1659 < 0) {<= preAllocated.length - 4) { hasThreshold = isNumber(threshold),
1660 < 0) {<= preAllocated.length - 4) { yBottom = s.series.yAxis.getThreshold(threshold),
1661 < 0) {<= preAllocated.length - 4) { translatedThreshold = yBottom,
1662 < 0) {<= preAllocated.length - 4) { cbuffer,
1663 < 0) {<= preAllocated.length - 4) { showMarkers = pick(
1664 < 0) {<= preAllocated.length - 4) { options.marker ? options.marker.enabled : null,
1665 < 0) {<= preAllocated.length - 4) { s.series.xAxis.isRadial ? true : null,
1666 < 0) {<= preAllocated.length - 4) { s.series.closestPointRangePx >
1667 < 0) {<= preAllocated.length - 4) { 2 * ((
1668 < 0) {<= preAllocated.length - 4) { options.marker ?
1669 < 0) {<= preAllocated.length - 4) { options.marker.radius :
1670 < 0) {<= preAllocated.length - 4) { 10
1671 < 0) {<= preAllocated.length - 4) { ) || 10)
1672 < 0) {<= preAllocated.length - 4) { ),
1673 < 0) {<= preAllocated.length - 4) { fillColor = s.series.fillOpacity ?
1674 < 0) {<= preAllocated.length - 4) { new Color(s.series.color).setOpacity(
1675 < 0) {<= preAllocated.length - 4) { pick(options.fillOpacity, 0.85)
1676 < 0) {<= preAllocated.length - 4) { ).get() :
1677 < 0) {<= preAllocated.length - 4) { s.series.color,
1678 < 0) {<= preAllocated.length - 4) { color;
1679  
1680 < 0) {<= preAllocated.length - 4) { vbuffer.bind();
1681  
1682 < 0) {<= preAllocated.length - 4) { if (options.colorByPoint) {
1683 < 0) {<= preAllocated.length - 4) { fillColor = s.series.chart.options.colors[si];
1684 < 0) {<= preAllocated.length - 4) { }
1685  
1686 < 0) {<= preAllocated.length - 4) { color = H.color(fillColor).rgba;
1687  
1688 < 0) {<= preAllocated.length - 4) { if (!settings.useAlpha) {
1689 < 0) {<= preAllocated.length - 4) { color[3] = 1.0;
1690 < 0) {<= preAllocated.length - 4) { }
1691  
1692 < 0) {<= preAllocated.length - 4) { //Blending
1693 < 0) {<= preAllocated.length - 4) { if (options.boostBlending === 'add') {
1694 < 0) {<= preAllocated.length - 4) { gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
1695 < 0) {<= preAllocated.length - 4) { gl.blendEquation(gl.FUNC_ADD);
1696  
1697 < 0) {<= preAllocated.length - 4) { } else if (options.boostBlending === 'mult') {
1698 < 0) {<= preAllocated.length - 4) { gl.blendFunc(gl.DST_COLOR, gl.ZERO);
1699  
1700 < 0) {<= preAllocated.length - 4) { } else if (options.boostBlending === 'darken') {
1701 < 0) {<= preAllocated.length - 4) { gl.blendFunc(gl.ONE, gl.ONE);
1702 < 0) {<= preAllocated.length - 4) { gl.blendEquation(gl.FUNC_MIN);
1703  
1704 < 0) {<= preAllocated.length - 4) { } else {
1705 < 0) {<= preAllocated.length - 4) { //gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);//, gl.ONE, gl.ZERO);
1706 < 0) {<= preAllocated.length - 4) { //gl.blendEquation(gl.FUNC_ADD);
1707 < 0) {<= preAllocated.length - 4) { gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
1708 < 0) {<= preAllocated.length - 4) { }
1709  
1710 < 0) {<= preAllocated.length - 4) { shader.reset();
1711  
1712 < 0) {<= preAllocated.length - 4) { // If there are entries in the colorData buffer, build and bind it.
1713 < 0) {<= preAllocated.length - 4) { if (s.colorData.length > 0) {
1714 < 0) {<= preAllocated.length - 4) { shader.setUniform('hasColor', 1.0);
1715 < 0) {<= preAllocated.length - 4) { cbuffer = GLVertexBuffer(gl, shader); //eslint-disable-line new-cap
1716 < 0) {<= preAllocated.length - 4) { cbuffer.build(s.colorData, 'aColor', 4);
1717 < 0) {<= preAllocated.length - 4) { cbuffer.bind();
1718 < 0) {<= preAllocated.length - 4) { }
1719  
1720 < 0) {<= preAllocated.length - 4) { // Set series specific uniforms
1721 < 0) {<= preAllocated.length - 4) { shader.setColor(color);
1722 < 0) {<= preAllocated.length - 4) { setXAxis(s.series.xAxis);
1723 < 0) {<= preAllocated.length - 4) { setYAxis(s.series.yAxis);
1724 < 0) {<= preAllocated.length - 4) { setThreshold(hasThreshold, translatedThreshold);
1725  
1726 < 0) {<= preAllocated.length - 4) { if (s.drawMode === 'points') {
1727 < 0) {<= preAllocated.length - 4) { if (options.marker && options.marker.radius) {
1728 < 0) {<= preAllocated.length - 4) { shader.setPointSize(options.marker.radius * 2.0);
1729 < 0) {<= preAllocated.length - 4) { } else {
1730 < 0) {<= preAllocated.length - 4) { shader.setPointSize(1);
1731 < 0) {<= preAllocated.length - 4) { }
1732 < 0) {<= preAllocated.length - 4) { }
1733  
1734 < 0) {<= preAllocated.length - 4) { // If set to true, the toPixels translations in the shader
1735 < 0) {<= preAllocated.length - 4) { // is skipped, i.e it's assumed that the value is a pixel coord.
1736 < 0) {<= preAllocated.length - 4) { shader.setSkipTranslation(s.skipTranslation);
1737  
1738 < 0) {<= preAllocated.length - 4) { if (s.series.type === 'bubble') {
1739 < 0) {<= preAllocated.length - 4) { shader.setBubbleUniforms(s.series, s.zMin, s.zMax);
1740 < 0) {<= preAllocated.length - 4) { }
1741  
1742 < 0) {<= preAllocated.length - 4) { shader.setDrawAsCircle((asCircle[s.series.type] && textureIsReady) || false);
1743  
1744 < 0) {<= preAllocated.length - 4) { // Do the actual rendering
1745 < 0) {<= preAllocated.length - 4) { vbuffer.render(s.from, s.to, s.drawMode);
1746  
1747 < 0) {<= preAllocated.length - 4) { if (s.hasMarkers && showMarkers) {
1748 < 0) {<= preAllocated.length - 4) { if (options.marker && options.marker.radius) {
1749 < 0) {<= preAllocated.length - 4) { shader.setPointSize(options.marker.radius * 2.0);
1750 < 0) {<= preAllocated.length - 4) { } else {
1751 < 0) {<= preAllocated.length - 4) { shader.setPointSize(10);
1752 < 0) {<= preAllocated.length - 4) { }
1753 < 0) {<= preAllocated.length - 4) { shader.setDrawAsCircle(true);
1754 < 0) {<= preAllocated.length - 4) { vbuffer.render(s.from, s.to, 'POINTS');
1755 < 0) {<= preAllocated.length - 4) { }
1756 < 0) {<= preAllocated.length - 4) { });
1757  
1758 < 0) {<= preAllocated.length - 4) { vbuffer.destroy();
1759  
1760 < 0) {<= preAllocated.length - 4) { if (settings.timeRendering) {
1761 < 0) {<= preAllocated.length - 4) { console.timeEnd('gl rendering'); //eslint-disable-line no-console
1762 < 0) {<= preAllocated.length - 4) { }
1763  
1764 < 0) {<= preAllocated.length - 4) { flush();
1765  
1766 < 0) {<= preAllocated.length - 4) { if (postRenderCallback) {
1767 < 0) {<= preAllocated.length - 4) { postRenderCallback();
1768 < 0) {<= preAllocated.length - 4) { }
1769 < 0) {<= preAllocated.length - 4) { }
1770  
1771 < 0) {<= preAllocated.length - 4) { /*
1772 < 0) {<= preAllocated.length - 4) { * Render the data when ready
1773 < 0) {<= preAllocated.length - 4) { */
1774 < 0) {<= preAllocated.length - 4) { function renderWhenReady(chart) {
1775 < 0) {<= preAllocated.length - 4) { clear();
1776  
1777 < 0) {<= preAllocated.length - 4) { if (chart.renderer.forExport) {
1778 < 0) {<= preAllocated.length - 4) { return render(chart);
1779 < 0) {<= preAllocated.length - 4) { }
1780  
1781 < 0) {<= preAllocated.length - 4) { if (isInited) {
1782 < 0) {<= preAllocated.length - 4) { render(chart);
1783 < 0) {<= preAllocated.length - 4) { } else {
1784 < 0) {<= preAllocated.length - 4) { setTimeout(function() {
1785 < 0) {<= preAllocated.length - 4) { renderWhenReady(chart);
1786 < 0) {<= preAllocated.length - 4) { }, 1);
1787 < 0) {<= preAllocated.length - 4) { }
1788 < 0) {<= preAllocated.length - 4) { }
1789  
1790 < 0) {<= preAllocated.length - 4) { /*
1791 < 0) {<= preAllocated.length - 4) { * Set the viewport size in pixels
1792 < 0) {<= preAllocated.length - 4) { * Creates an orthographic perspective matrix and applies it.
1793 < 0) {<= preAllocated.length - 4) { * @param w {Integer} - the width of the viewport
1794 < 0) {<= preAllocated.length - 4) { * @param h {Integer} - the height of the viewport
1795 < 0) {<= preAllocated.length - 4) { */
1796 < 0) {<= preAllocated.length - 4) { function setSize(w, h) {
1797 < 0) {<= preAllocated.length - 4) { // Skip if there's no change
1798 < 0) {<= preAllocated.length - 4) { if (width === w && h === h) {
1799 < 0) {<= preAllocated.length - 4) { return;
1800 < 0) {<= preAllocated.length - 4) { }
1801  
1802 < 0) {<= preAllocated.length - 4) { width = w;
1803 < 0) {<= preAllocated.length - 4) { height = h;
1804  
1805 < 0) {<= preAllocated.length - 4) { shader.bind();
1806 < 0) {<= preAllocated.length - 4) { shader.setPMatrix(orthoMatrix(width, height));
1807 < 0) {<= preAllocated.length - 4) { }
1808  
1809 < 0) {<= preAllocated.length - 4) { /*
1810 < 0) {<= preAllocated.length - 4) { * Init OpenGL
1811 < 0) {<= preAllocated.length - 4) { * @param canvas {HTMLCanvas} - the canvas to render to
1812 < 0) {<= preAllocated.length - 4) { */
1813 < 0) {<= preAllocated.length - 4) { function init(canvas, noFlush) {
1814 < 0) {<= preAllocated.length - 4) { var i = 0,
1815 < 0) {<= preAllocated.length - 4) { contexts = [
1816 < 0) {<= preAllocated.length - 4) { 'webgl',
1817 < 0) {<= preAllocated.length - 4) { 'experimental-webgl',
1818 < 0) {<= preAllocated.length - 4) { 'moz-webgl',
1819 < 0) {<= preAllocated.length - 4) { 'webkit-3d'
1820 < 0) {<= preAllocated.length - 4) { ];
1821  
1822 < 0) {<= preAllocated.length - 4) { isInited = false;
1823  
1824 < 0) {<= preAllocated.length - 4) { if (!canvas) {
1825 < 0) {<= preAllocated.length - 4) { return false;
1826 < 0) {<= preAllocated.length - 4) { }
1827  
1828 < 0) {<= preAllocated.length - 4) { if (settings.timeSetup) {
1829 < 0) {<= preAllocated.length - 4) { console.time('gl setup'); //eslint-disable-line no-console
1830 < 0) {<= preAllocated.length - 4) { }
1831  
1832 < 0) {<= preAllocated.length - 4) { for (; i < contexts.length; i++) {
1833 < 0) {<= preAllocated.length - 4) { gl = canvas.getContext(contexts[i]);
1834 < 0) {<= preAllocated.length - 4) { if (gl) {
1835 < 0) {<= preAllocated.length - 4) { break;
1836 < 0) {<= preAllocated.length - 4) { }
1837 < 0) {<= preAllocated.length - 4) { }
1838  
1839 < 0) {<= preAllocated.length - 4) { if (gl) {
1840 < 0) {<= preAllocated.length - 4) { if (!noFlush) {
1841 < 0) {<= preAllocated.length - 4) { flush();
1842 < 0) {<= preAllocated.length - 4) { }
1843 < 0) {<= preAllocated.length - 4) { } else {
1844 < 0) {<= preAllocated.length - 4) { return false;
1845 < 0) {<= preAllocated.length - 4) { }
1846  
1847 < 0) {<= preAllocated.length - 4) { gl.enable(gl.BLEND);
1848 < 0) {<= preAllocated.length - 4) { // gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
1849 < 0) {<= preAllocated.length - 4) { gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
1850 < 0) {<= preAllocated.length - 4) { gl.disable(gl.DEPTH_TEST);
1851 < 0) {<= preAllocated.length - 4) { gl.depthMask(gl.FALSE);
1852  
1853 < 0) {<= preAllocated.length - 4) { shader = GLShader(gl); //eslint-disable-line new-cap
1854 < 0) {<= preAllocated.length - 4) { vbuffer = GLVertexBuffer(gl, shader); //eslint-disable-line new-cap
1855  
1856 < 0) {<= preAllocated.length - 4) { textureIsReady = false;
1857  
1858 < 0) {<= preAllocated.length - 4) { // Set up the circle texture used for bubbles
1859 < 0) {<= preAllocated.length - 4) { circleTextureHandle = gl.createTexture();
1860  
1861 < 0) {<= preAllocated.length - 4) { // Draw the circle
1862 < 0) {<= preAllocated.length - 4) { circleTexture.width = 512;
1863 < 0) {<= preAllocated.length - 4) { circleTexture.height = 512;
1864  
1865 < 0) {<= preAllocated.length - 4) { circleCtx.fillStyle = '#FFF';
1866 < 0) {<= preAllocated.length - 4) { circleCtx.beginPath();
1867 < 0) {<= preAllocated.length - 4) { circleCtx.arc(256, 256, 256, 0, 2 * Math.PI);
1868 < 0) {<= preAllocated.length - 4) { circleCtx.fill();
1869  
1870 < 0) {<= preAllocated.length - 4) { try {
1871  
1872 < 0) {<= preAllocated.length - 4) { gl.bindTexture(gl.TEXTURE_2D, circleTextureHandle);
1873  
1874 < 0) {<= preAllocated.length - 4) { gl.texImage2D(
1875 < 0) {<= preAllocated.length - 4) { gl.TEXTURE_2D,
1876 < 0) {<= preAllocated.length - 4) { 0,
1877 < 0) {<= preAllocated.length - 4) { gl.RGBA,
1878 < 0) {<= preAllocated.length - 4) { gl.RGBA,
1879 < 0) {<= preAllocated.length - 4) { gl.UNSIGNED_BYTE,
1880 < 0) {<= preAllocated.length - 4) { circleTexture
1881 < 0) {<= preAllocated.length - 4) { );
1882  
1883 < 0) {<= preAllocated.length - 4) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
1884 < 0) {<= preAllocated.length - 4) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
1885 < 0) {<= preAllocated.length - 4) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
1886 < 0) {<= preAllocated.length - 4) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
1887  
1888 < 0) {<= preAllocated.length - 4) { gl.generateMipmap(gl.TEXTURE_2D);
1889  
1890 < 0) {<= preAllocated.length - 4) { gl.bindTexture(gl.TEXTURE_2D, null);
1891  
1892 < 0) {<= preAllocated.length - 4) { textureIsReady = true;
1893 < 0) {<= preAllocated.length - 4) { } catch (e) {}
1894  
1895 < 0) {<= preAllocated.length - 4) { isInited = true;
1896  
1897 < 0) {<= preAllocated.length - 4) { if (settings.timeSetup) {
1898 < 0) {<= preAllocated.length - 4) { console.timeEnd('gl setup'); //eslint-disable-line no-console
1899 < 0) {<= preAllocated.length - 4) { }
1900  
1901 < 0) {<= preAllocated.length - 4) { return true;
1902 < 0) {<= preAllocated.length - 4) { }
1903  
1904 < 0) {<= preAllocated.length - 4) { /*
1905 < 0) {<= preAllocated.length - 4) { * Check if we have a valid OGL context
1906 < 0) {<= preAllocated.length - 4) { * @returns {Boolean} - true if the context is valid
1907 < 0) {<= preAllocated.length - 4) { */
1908 < 0) {<= preAllocated.length - 4) { function valid() {
1909 < 0) {<= preAllocated.length - 4) { return gl !== false;
1910 < 0) {<= preAllocated.length - 4) { }
1911  
1912 < 0) {<= preAllocated.length - 4) { /*
1913 < 0) {<= preAllocated.length - 4) { * Check if the renderer has been initialized
1914 < 0) {<= preAllocated.length - 4) { * @returns {Boolean} - true if it has, false if not
1915 < 0) {<= preAllocated.length - 4) { */
1916 < 0) {<= preAllocated.length - 4) { function inited() {
1917 < 0) {<= preAllocated.length - 4) { return isInited;
1918 < 0) {<= preAllocated.length - 4) { }
1919  
1920 < 0) {<= preAllocated.length - 4) { function destroy() {
1921 < 0) {<= preAllocated.length - 4) { vbuffer.destroy();
1922 < 0) {<= preAllocated.length - 4) { shader.destroy();
1923 < 0) {<= preAllocated.length - 4) { if (gl) {
1924 < 0) {<= preAllocated.length - 4) { //gl.deleteTexture(circleTextureHandle);
1925 < 0) {<= preAllocated.length - 4) { }
1926 < 0) {<= preAllocated.length - 4) { }
1927  
1928 < 0) {<= preAllocated.length - 4) { ////////////////////////////////////////////////////////////////////////////
1929 < 0) {<= preAllocated.length - 4) { exports = {
1930 < 0) {<= preAllocated.length - 4) { allocateBufferForSingleSeries: allocateBufferForSingleSeries,
1931 < 0) {<= preAllocated.length - 4) { pushSeries: pushSeries,
1932 < 0) {<= preAllocated.length - 4) { setSize: setSize,
1933 < 0) {<= preAllocated.length - 4) { inited: inited,
1934 < 0) {<= preAllocated.length - 4) { setThreshold: setThreshold,
1935 < 0) {<= preAllocated.length - 4) { init: init,
1936 < 0) {<= preAllocated.length - 4) { render: renderWhenReady,
1937 < 0) {<= preAllocated.length - 4) { settings: settings,
1938 < 0) {<= preAllocated.length - 4) { valid: valid,
1939 < 0) {<= preAllocated.length - 4) { clear: clear,
1940 < 0) {<= preAllocated.length - 4) { flush: flush,
1941 < 0) {<= preAllocated.length - 4) { setXAxis: setXAxis,
1942 < 0) {<= preAllocated.length - 4) { setYAxis: setYAxis,
1943 < 0) {<= preAllocated.length - 4) { data: data,
1944 < 0) {<= preAllocated.length - 4) { gl: getGL,
1945 < 0) {<= preAllocated.length - 4) { allocateBuffer: allocateBuffer,
1946 < 0) {<= preAllocated.length - 4) { destroy: destroy,
1947 < 0) {<= preAllocated.length - 4) { setOptions: setOptions
1948 < 0) {<= preAllocated.length - 4) { };
1949  
1950 < 0) {<= preAllocated.length - 4) { return exports;
1951 < 0) {<= preAllocated.length - 4) { }
1952  
1953 < 0) {<= preAllocated.length - 4) { // END OF WEBGL ABSTRACTIONS
1954 < 0) {<= preAllocated.length - 4) { ////////////////////////////////////////////////////////////////////////////////
1955  
1956 < 0) {<= preAllocated.length - 4) { /*
1957 < 0) {<= preAllocated.length - 4) { * Create a canvas + context and attach it to the target
1958 < 0) {<= preAllocated.length - 4) { * @param target {Highcharts.Chart|Highcharts.Series} - the canvas target
1959 < 0) {<= preAllocated.length - 4) { * @param chart {Highcharts.Chart} - the chart
1960 < 0) {<= preAllocated.length - 4) { */
1961 < 0) {<= preAllocated.length - 4) { function createAndAttachRenderer(chart, series) {
1962 < 0) {<= preAllocated.length - 4) { var width = chart.chartWidth,
1963 < 0) {<= preAllocated.length - 4) { height = chart.chartHeight,
1964 < 0) {<= preAllocated.length - 4) { target = chart,
1965 < 0) {<= preAllocated.length - 4) { targetGroup = chart.seriesGroup || series.group,
1966 < 0) {<= preAllocated.length - 4) { swapXY = function(proceed, x, y, a, b, c, d) {
1967 < 0) {<= preAllocated.length - 4) { proceed.call(series, y, x, a, b, c, d);
1968 < 0) {<= preAllocated.length - 4) { };
1969  
1970 < 0) {<= preAllocated.length - 4) { if (isChartSeriesBoosting(chart)) {
1971 < 0) {<= preAllocated.length - 4) { target = chart;
1972 < 0) {<= preAllocated.length - 4) { } else {
1973 < 0) {<= preAllocated.length - 4) { target = series;
1974 < 0) {<= preAllocated.length - 4) { }
1975  
1976 < 0) {<= preAllocated.length - 4) { if (target.ogl) {
1977 < 0) {<= preAllocated.length - 4) { //target.ogl.destroy();
1978 < 0) {<= preAllocated.length - 4) { }
1979  
1980 < 0) {<= preAllocated.length - 4) { if (!target.image) {
1981 < 0) {<= preAllocated.length - 4) { target.canvas = doc.createElement('canvas');
1982  
1983 < 0) {<= preAllocated.length - 4) { target.image = chart.renderer.image(
1984 < 0) {<= preAllocated.length - 4) { '',
1985 < 0) {<= preAllocated.length - 4) { 0,
1986 < 0) {<= preAllocated.length - 4) { 0,
1987 < 0) {<= preAllocated.length - 4) { width,
1988 < 0) {<= preAllocated.length - 4) { height
1989 < 0) {<= preAllocated.length - 4) { ).add(targetGroup);
1990  
1991 < 0) {<= preAllocated.length - 4) { target.boostClipRect = chart.renderer.clipRect(
1992 < 0) {<= preAllocated.length - 4) { chart.plotLeft,
1993 < 0) {<= preAllocated.length - 4) { chart.plotTop,
1994 < 0) {<= preAllocated.length - 4) { chart.plotWidth,
1995 < 0) {<= preAllocated.length - 4) { chart.chartHeight
1996 < 0) {<= preAllocated.length - 4) { );
1997  
1998 < 0) {<= preAllocated.length - 4) { target.image.clip(target.boostClipRect);
1999  
2000 < 0) {<= preAllocated.length - 4) { if (target.inverted) {
2001 < 0) {<= preAllocated.length - 4) { each(['moveTo', 'lineTo', 'rect', 'arc'], function(fn) {
2002 < 0) {<= preAllocated.length - 4) { wrap(false, fn, swapXY);
2003 < 0) {<= preAllocated.length - 4) { });
2004 < 0) {<= preAllocated.length - 4) { }
2005  
2006 < 0) {<= preAllocated.length - 4) { if (target instanceof H.Chart) {
2007 < 0) {<= preAllocated.length - 4) { target.markerGroup = target.renderer.g().add(targetGroup);
2008  
2009 < 0) {<= preAllocated.length - 4) { target.markerGroup.translate(series.xAxis.pos, series.yAxis.pos);
2010 < 0) {<= preAllocated.length - 4) { }
2011 < 0) {<= preAllocated.length - 4) { }
2012  
2013 < 0) {<= preAllocated.length - 4) { target.canvas.width = width;
2014 < 0) {<= preAllocated.length - 4) { target.canvas.height = height;
2015  
2016 < 0) {<= preAllocated.length - 4) { target.image.attr({
2017 < 0) {<= preAllocated.length - 4) { x: 0,
2018 < 0) {<= preAllocated.length - 4) { y: 0,
2019 < 0) {<= preAllocated.length - 4) { width: width,
2020 < 0) {<= preAllocated.length - 4) { height: height,
2021 < 0) {<= preAllocated.length - 4) { style: 'pointer-events: none'
2022 < 0) {<= preAllocated.length - 4) { });
2023  
2024 < 0) {<= preAllocated.length - 4) { target.boostClipRect.attr({
2025 < 0) {<= preAllocated.length - 4) { x: chart.plotLeft,
2026 < 0) {<= preAllocated.length - 4) { y: chart.plotTop,
2027 < 0) {<= preAllocated.length - 4) { width: chart.plotWidth,
2028 < 0) {<= preAllocated.length - 4) { height: chart.chartHeight
2029 < 0) {<= preAllocated.length - 4) { });
2030  
2031 < 0) {<= preAllocated.length - 4) { if (!target.ogl) {
2032  
2033  
2034 < 0) {<= preAllocated.length - 4) { target.ogl = GLRenderer(function() { // eslint-disable-line new-cap
2035 < 0) {<= preAllocated.length - 4) { target.image.attr({
2036 < 0) {<= preAllocated.length - 4) { href: target.canvas.toDataURL('image/png')
2037 < 0) {<= preAllocated.length - 4) { });
2038 < 0) {<= preAllocated.length - 4) { }); //eslint-disable-line new-cap
2039  
2040 < 0) {<= preAllocated.length - 4) { target.ogl.init(target.canvas);
2041 < 0) {<= preAllocated.length - 4) { // target.ogl.clear();
2042 < 0) {<= preAllocated.length - 4) { target.ogl.setOptions(chart.options.boost || {});
2043  
2044 < 0) {<= preAllocated.length - 4) { if (target instanceof H.Chart) {
2045 < 0) {<= preAllocated.length - 4) { target.ogl.allocateBuffer(chart);
2046 < 0) {<= preAllocated.length - 4) { }
2047 < 0) {<= preAllocated.length - 4) { }
2048  
2049 < 0) {<= preAllocated.length - 4) { target.ogl.setSize(width, height);
2050  
2051 < 0) {<= preAllocated.length - 4) { return target.ogl;
2052 < 0) {<= preAllocated.length - 4) { }
2053  
2054 < 0) {<= preAllocated.length - 4) { /*
2055 < 0) {<= preAllocated.length - 4) { * Performs the actual render if the renderer is
2056 < 0) {<= preAllocated.length - 4) { * attached to the series.
2057 < 0) {<= preAllocated.length - 4) { * @param renderer {OGLRenderer} - the renderer
2058 < 0) {<= preAllocated.length - 4) { * @param series {Highcharts.Series} - the series
2059 < 0) {<= preAllocated.length - 4) { */
2060 < 0) {<= preAllocated.length - 4) { function renderIfNotSeriesBoosting(renderer, series, chart) {
2061 < 0) {<= preAllocated.length - 4) { if (renderer &&
2062 < 0) {<= preAllocated.length - 4) { series.image &&
2063 < 0) {<= preAllocated.length - 4) { series.canvas &&
2064 < 0) {<= preAllocated.length - 4) { !isChartSeriesBoosting(chart || series.chart)
2065 < 0) {<= preAllocated.length - 4) { ) {
2066 < 0) {<= preAllocated.length - 4) { renderer.render(chart || series.chart);
2067 < 0) {<= preAllocated.length - 4) { }
2068 < 0) {<= preAllocated.length - 4) { }
2069  
2070 < 0) {<= preAllocated.length - 4) { function allocateIfNotSeriesBoosting(renderer, series) {
2071 < 0) {<= preAllocated.length - 4) { if (renderer &&
2072 < 0) {<= preAllocated.length - 4) { series.image &&
2073 < 0) {<= preAllocated.length - 4) { series.canvas &&
2074 < 0) {<= preAllocated.length - 4) { !isChartSeriesBoosting(series.chart)
2075 < 0) {<= preAllocated.length - 4) { ) {
2076 < 0) {<= preAllocated.length - 4) { renderer.allocateBufferForSingleSeries(series);
2077 < 0) {<= preAllocated.length - 4) { }
2078 < 0) {<= preAllocated.length - 4) { }
2079  
2080 < 0) {<= preAllocated.length - 4) { /*
2081 < 0) {<= preAllocated.length - 4) { * An "async" foreach loop.
2082 < 0) {<= preAllocated.length - 4) { * Uses a setTimeout to keep the loop from blocking the UI thread
2083 < 0) {<= preAllocated.length - 4) { * @param arr {Array} - the array to loop through
2084 < 0) {<= preAllocated.length - 4) { * @param fn {Function} - the callback to call for each item
2085 < 0) {<= preAllocated.length - 4) { * @param finalFunc {Function} - the callback to call when done
2086 < 0) {<= preAllocated.length - 4) { * @param chunkSize {Number} - the number of iterations per. timeout
2087 < 0) {<= preAllocated.length - 4) { * @param i {Number} - the current index
2088 < 0) {<= preAllocated.length - 4) { * @param noTimeout {Boolean} - set to true to skip timeouts
2089 < 0) {<= preAllocated.length - 4) { */
2090 < 0) {<= preAllocated.length - 4) { function eachAsync(arr, fn, finalFunc, chunkSize, i, noTimeout) {
2091 < 0) {<= preAllocated.length - 4) { i = i || 0;
2092 < 0) {<= preAllocated.length - 4) { chunkSize = chunkSize || CHUNK_SIZE;
2093  
2094 < 0) {<= preAllocated.length - 4) { var threshold = i + chunkSize,
2095 < 0) {<= preAllocated.length - 4) { proceed = true;
2096  
2097 < 0) {<= preAllocated.length - 4) { while (proceed && i < threshold && i < arr.length) {
2098 < 0) {<= preAllocated.length - 4) { proceed = fn(arr[i], i);
2099 < 0) {<= preAllocated.length - 4) { ++i;
2100 < 0) {<= preAllocated.length - 4) { }
2101 < 0) {<= preAllocated.length - 4) { if (proceed) {
2102 < 0) {<= preAllocated.length - 4) { if (i < arr.length) {
2103  
2104 < 0) {<= preAllocated.length - 4) { if (noTimeout) {
2105 < 0) {<= preAllocated.length - 4) { eachAsync(arr, fn, finalFunc, chunkSize, i, noTimeout);
2106 < 0) {<= preAllocated.length - 4) { } else if (win.requestAnimationFrame) {
2107 < 0) {<= preAllocated.length - 4) { //If available, do requestAnimationFrame - shaves off a few ms
2108 < 0) {<= preAllocated.length - 4) { win.requestAnimationFrame(function() {
2109 < 0) {<= preAllocated.length - 4) { eachAsync(arr, fn, finalFunc, chunkSize, i);
2110 < 0) {<= preAllocated.length - 4) { });
2111 < 0) {<= preAllocated.length - 4) { } else {
2112 < 0) {<= preAllocated.length - 4) { setTimeout(function() {
2113 < 0) {<= preAllocated.length - 4) { eachAsync(arr, fn, finalFunc, chunkSize, i);
2114 < 0) {<= preAllocated.length - 4) { });
2115 < 0) {<= preAllocated.length - 4) { }
2116  
2117 < 0) {<= preAllocated.length - 4) { } else if (finalFunc) {
2118 < 0) {<= preAllocated.length - 4) { finalFunc();
2119 < 0) {<= preAllocated.length - 4) { }
2120 < 0) {<= preAllocated.length - 4) { }
2121 < 0) {<= preAllocated.length - 4) { }
2122  
2123 < 0) {<= preAllocated.length - 4) { ////////////////////////////////////////////////////////////////////////////////
2124 < 0) {<= preAllocated.length - 4) { // Following is the parts of the boost that's common between OGL/Legacy
2125  
2126 < 0) {<= preAllocated.length - 4) { /**
2127 < 0) {<= preAllocated.length - 4) { * Return a full Point object based on the index.
2128 < 0) {<= preAllocated.length - 4) { * The boost module uses stripped point objects for performance reasons.
2129 < 0) {<= preAllocated.length - 4) { * @param {Number} boostPoint A stripped-down point object
2130 < 0) {<= preAllocated.length - 4) { * @returns {Object} A Point object as per http://api.highcharts.com/highcharts#Point
2131 < 0) {<= preAllocated.length - 4) { */
2132 < 0) {<= preAllocated.length - 4) { Series.prototype.getPoint = function(boostPoint) {
2133 < 0) {<= preAllocated.length - 4) { var point = boostPoint,
2134 < 0) {<= preAllocated.length - 4) { xData = this.xData || this.options.xData || this.processedXData || false;
2135  
2136 < 0) {<= preAllocated.length - 4) { if (boostPoint && !(boostPoint instanceof this.pointClass)) {
2137 < 0) {<= preAllocated.length - 4) { point = (new this.pointClass()).init( // eslint-disable-line new-cap
2138 < 0) {<= preAllocated.length - 4) { this,
2139 < 0) {<= preAllocated.length - 4) { this.options.data[boostPoint.i],
2140 < 0) {<= preAllocated.length - 4) { xData ? xData[boostPoint.i] : undefined
2141 < 0) {<= preAllocated.length - 4) { );
2142  
2143 < 0) {<= preAllocated.length - 4) { point.category = point.x;
2144  
2145 < 0) {<= preAllocated.length - 4) { point.dist = boostPoint.dist;
2146 < 0) {<= preAllocated.length - 4) { point.distX = boostPoint.distX;
2147 < 0) {<= preAllocated.length - 4) { point.plotX = boostPoint.plotX;
2148 < 0) {<= preAllocated.length - 4) { point.plotY = boostPoint.plotY;
2149 < 0) {<= preAllocated.length - 4) { point.index = boostPoint.i;
2150 < 0) {<= preAllocated.length - 4) { }
2151  
2152 < 0) {<= preAllocated.length - 4) { return point;
2153 < 0) {<= preAllocated.length - 4) { };
2154  
2155 < 0) {<= preAllocated.length - 4) { /**
2156 < 0) {<= preAllocated.length - 4) { * Return a point instance from the k-d-tree
2157 < 0) {<= preAllocated.length - 4) { */
2158 < 0) {<= preAllocated.length - 4) { wrap(Series.prototype, 'searchPoint', function(proceed) {
2159 < 0) {<= preAllocated.length - 4) { return this.getPoint(
2160 < 0) {<= preAllocated.length - 4) { proceed.apply(this, [].slice.call(arguments, 1))
2161 < 0) {<= preAllocated.length - 4) { );
2162 < 0) {<= preAllocated.length - 4) { });
2163  
2164 < 0) {<= preAllocated.length - 4) { /**
2165 < 0) {<= preAllocated.length - 4) { * Extend series.destroy to also remove the fake k-d-tree points (#5137).
2166 < 0) {<= preAllocated.length - 4) { * Normally this is handled by Series.destroy that calls Point.destroy,
2167 < 0) {<= preAllocated.length - 4) { * but the fake search points are not registered like that.
2168 < 0) {<= preAllocated.length - 4) { */
2169 < 0) {<= preAllocated.length - 4) { wrap(Series.prototype, 'destroy', function(proceed) {
2170 < 0) {<= preAllocated.length - 4) { var series = this,
2171 < 0) {<= preAllocated.length - 4) { chart = series.chart;
2172  
2173 < 0) {<= preAllocated.length - 4) { if (chart.markerGroup === series.markerGroup) {
2174 < 0) {<= preAllocated.length - 4) { series.markerGroup = null;
2175 < 0) {<= preAllocated.length - 4) { }
2176  
2177 < 0) {<= preAllocated.length - 4) { if (chart.hoverPoints) {
2178 < 0) {<= preAllocated.length - 4) { chart.hoverPoints = grep(chart.hoverPoints, function(point) {
2179 < 0) {<= preAllocated.length - 4) { return point.series === series;
2180 < 0) {<= preAllocated.length - 4) { });
2181 < 0) {<= preAllocated.length - 4) { }
2182  
2183 < 0) {<= preAllocated.length - 4) { if (chart.hoverPoint && chart.hoverPoint.series === series) {
2184 < 0) {<= preAllocated.length - 4) { chart.hoverPoint = null;
2185 < 0) {<= preAllocated.length - 4) { }
2186  
2187 < 0) {<= preAllocated.length - 4) { proceed.call(this);
2188 < 0) {<= preAllocated.length - 4) { });
2189  
2190 < 0) {<= preAllocated.length - 4) { /**
2191 < 0) {<= preAllocated.length - 4) { * Do not compute extremes when min and max are set.
2192 < 0) {<= preAllocated.length - 4) { * If we use this in the core, we can add the hook
2193 < 0) {<= preAllocated.length - 4) { * to hasExtremes to the methods directly.
2194 < 0) {<= preAllocated.length - 4) { */
2195 < 0) {<= preAllocated.length - 4) { wrap(Series.prototype, 'getExtremes', function(proceed) {
2196 < 0) {<= preAllocated.length - 4) { if (!isSeriesBoosting(this) || (!this.hasExtremes || !this.hasExtremes())) {
2197 < 0) {<= preAllocated.length - 4) { return proceed.apply(this, Array.prototype.slice.call(arguments, 1));
2198 < 0) {<= preAllocated.length - 4) { }
2199 < 0) {<= preAllocated.length - 4) { });
2200  
2201 < 0) {<= preAllocated.length - 4) { // Set default options
2202 < 0) {<= preAllocated.length - 4) { each([
2203 < 0) {<= preAllocated.length - 4) { 'area',
2204 < 0) {<= preAllocated.length - 4) { 'arearange',
2205 < 0) {<= preAllocated.length - 4) { 'column',
2206 < 0) {<= preAllocated.length - 4) { 'line',
2207 < 0) {<= preAllocated.length - 4) { 'scatter',
2208 < 0) {<= preAllocated.length - 4) { 'heatmap',
2209 < 0) {<= preAllocated.length - 4) { 'bubble',
2210 < 0) {<= preAllocated.length - 4) { 'treemap',
2211 < 0) {<= preAllocated.length - 4) { 'heatmap'
2212 < 0) {<= preAllocated.length - 4) { ],
2213 < 0) {<= preAllocated.length - 4) { function(type) {
2214 < 0) {<= preAllocated.length - 4) { if (plotOptions[type]) {
2215 < 0) {<= preAllocated.length - 4) { plotOptions[type].boostThreshold = 5000;
2216 < 0) {<= preAllocated.length - 4) { plotOptions[type].boostData = [];
2217 < 0) {<= preAllocated.length - 4) { }
2218 < 0) {<= preAllocated.length - 4) { }
2219 < 0) {<= preAllocated.length - 4) { );
2220  
2221 < 0) {<= preAllocated.length - 4) { /**
2222 < 0) {<= preAllocated.length - 4) { * Override a bunch of methods the same way. If the number of points is
2223 < 0) {<= preAllocated.length - 4) { * below the threshold, run the original method. If not, check for a
2224 < 0) {<= preAllocated.length - 4) { * canvas version or do nothing.
2225 < 0) {<= preAllocated.length - 4) { *
2226 < 0) {<= preAllocated.length - 4) { * Note that we're not overriding any of these for heatmaps.
2227 < 0) {<= preAllocated.length - 4) { */
2228 < 0) {<= preAllocated.length - 4) { each([
2229 < 0) {<= preAllocated.length - 4) { 'translate',
2230 < 0) {<= preAllocated.length - 4) { 'generatePoints',
2231 < 0) {<= preAllocated.length - 4) { 'drawTracker',
2232 < 0) {<= preAllocated.length - 4) { 'drawPoints',
2233 < 0) {<= preAllocated.length - 4) { 'render'
2234 < 0) {<= preAllocated.length - 4) { ], function(method) {
2235 < 0) {<= preAllocated.length - 4) { function branch(proceed) {
2236 < 0) {<= preAllocated.length - 4) { var letItPass = this.options.stacking &&
2237 < 0) {<= preAllocated.length - 4) { (method === 'translate' || method === 'generatePoints');
2238  
2239 < 0) {<= preAllocated.length - 4) { if (!isSeriesBoosting(this) ||
2240 < 0) {<= preAllocated.length - 4) { letItPass ||
2241 < 0) {<= preAllocated.length - 4) { this.type === 'heatmap' ||
2242 < 0) {<= preAllocated.length - 4) { this.type === 'treemap'
2243 < 0) {<= preAllocated.length - 4) { ) {
2244  
2245 < 0) {<= preAllocated.length - 4) { // Clear image
2246 < 0) {<= preAllocated.length - 4) { if (method === 'render' && this.image && !isChartSeriesBoosting(this.chart)) {
2247 < 0) {<= preAllocated.length - 4) { this.image.attr({
2248 < 0) {<= preAllocated.length - 4) { href: ''
2249 < 0) {<= preAllocated.length - 4) { });
2250 < 0) {<= preAllocated.length - 4) { this.animate = null; // We're zooming in, don't run animation
2251 < 0) {<= preAllocated.length - 4) { }
2252  
2253 < 0) {<= preAllocated.length - 4) { proceed.call(this);
2254  
2255 < 0) {<= preAllocated.length - 4) { // If a canvas version of the method exists, like renderCanvas(), run
2256 < 0) {<= preAllocated.length - 4) { } else if (this[method + 'Canvas']) {
2257 < 0) {<= preAllocated.length - 4) { this[method + 'Canvas']();
2258 < 0) {<= preAllocated.length - 4) { }
2259 < 0) {<= preAllocated.length - 4) { }
2260  
2261 < 0) {<= preAllocated.length - 4) { wrap(Series.prototype, method, branch);
2262  
2263 < 0) {<= preAllocated.length - 4) { // A special case for some types - their translate method is already wrapped
2264 < 0) {<= preAllocated.length - 4) { if (method === 'translate') {
2265 < 0) {<= preAllocated.length - 4) { if (seriesTypes.column) {
2266 < 0) {<= preAllocated.length - 4) { wrap(seriesTypes.column.prototype, method, branch);
2267 < 0) {<= preAllocated.length - 4) { }
2268  
2269 < 0) {<= preAllocated.length - 4) { if (seriesTypes.arearange) {
2270 < 0) {<= preAllocated.length - 4) { wrap(seriesTypes.arearange.prototype, method, branch);
2271 < 0) {<= preAllocated.length - 4) { }
2272  
2273 < 0) {<= preAllocated.length - 4) { if (seriesTypes.treemap) {
2274 < 0) {<= preAllocated.length - 4) { wrap(seriesTypes.treemap.prototype, method, branch);
2275 < 0) {<= preAllocated.length - 4) { }
2276 < 0) {<= preAllocated.length - 4) { }
2277 < 0) {<= preAllocated.length - 4) { });
2278  
2279 < 0) {<= preAllocated.length - 4) { /*
2280 < 0) {<= preAllocated.length - 4) { * Returns true if the current browser supports webgl
2281 < 0) {<= preAllocated.length - 4) { */
2282 < 0) {<= preAllocated.length - 4) { function hasWebGLSupport() {
2283 < 0) {<= preAllocated.length - 4) { var i = 0,
2284 < 0) {<= preAllocated.length - 4) { canvas,
2285 < 0) {<= preAllocated.length - 4) { contexts = ['webgl', 'experimental-webgl', 'moz-webgl', 'webkit-3d'],
2286 < 0) {<= preAllocated.length - 4) { context = false;
2287  
2288 < 0) {<= preAllocated.length - 4) { if (typeof win.WebGLRenderingContext !== 'undefined') {
2289 < 0) {<= preAllocated.length - 4) { canvas = doc.createElement('canvas');
2290  
2291 < 0) {<= preAllocated.length - 4) { for (; i < contexts.length; i++) {
2292 < 0) {<= preAllocated.length - 4) { try {
2293 < 0) {<= preAllocated.length - 4) { context = canvas.getContext(contexts[i]);
2294 < 0) {<= preAllocated.length - 4) { if (typeof context !== 'undefined' && context !== null) {
2295 < 0) {<= preAllocated.length - 4) { return true;
2296 < 0) {<= preAllocated.length - 4) { }
2297 < 0) {<= preAllocated.length - 4) { } catch (e) {
2298  
2299 < 0) {<= preAllocated.length - 4) { }
2300 < 0) {<= preAllocated.length - 4) { }
2301 < 0) {<= preAllocated.length - 4) { }
2302  
2303 < 0) {<= preAllocated.length - 4) { return false;
2304 < 0) {<= preAllocated.length - 4) { }
2305  
2306 < 0) {<= preAllocated.length - 4) { /* Used for treemap|heatmap.drawPoints */
2307 < 0) {<= preAllocated.length - 4) { function pointDrawHandler(proceed) {
2308 < 0) {<= preAllocated.length - 4) { if (!isSeriesBoosting(this)) {
2309 < 0) {<= preAllocated.length - 4) { return proceed.call(this);
2310 < 0) {<= preAllocated.length - 4) { }
2311  
2312 < 0) {<= preAllocated.length - 4) { //Make sure we have a valid OGL context
2313 < 0) {<= preAllocated.length - 4) { var renderer = createAndAttachRenderer(this.chart, this);
2314  
2315 < 0) {<= preAllocated.length - 4) { if (renderer) {
2316 < 0) {<= preAllocated.length - 4) { allocateIfNotSeriesBoosting(renderer, this);
2317 < 0) {<= preAllocated.length - 4) { renderer.pushSeries(this);
2318 < 0) {<= preAllocated.length - 4) { }
2319  
2320 < 0) {<= preAllocated.length - 4) { renderIfNotSeriesBoosting(renderer, this);
2321 < 0) {<= preAllocated.length - 4) { }
2322  
2323  
2324  
2325 < 0) {<= preAllocated.length - 4) { ////////////////////////////////////////////////////////////////////////////////
2326 < 0) {<= preAllocated.length - 4) { // We're wrapped in a closure, so just return if there's no webgl support
2327  
2328 < 0) {<= preAllocated.length - 4) { if (!hasWebGLSupport()) {
2329 < 0) {<= preAllocated.length - 4) { if (typeof H.initCanvasBoost !== 'undefined') {
2330 < 0) {<= preAllocated.length - 4) { // Fallback to canvas boost
2331 < 0) {<= preAllocated.length - 4) { H.initCanvasBoost();
2332 < 0) {<= preAllocated.length - 4) { } else {
2333 < 0) {<= preAllocated.length - 4) { H.error(26);
2334 < 0) {<= preAllocated.length - 4) { }
2335 < 0) {<= preAllocated.length - 4) { } else {
2336  
2337 < 0) {<= preAllocated.length - 4) { ////////////////////////////////////////////////////////////////////////////
2338 < 0) {<= preAllocated.length - 4) { // GL-SPECIFIC WRAPPINGS FOLLOWS
2339  
2340 < 0) {<= preAllocated.length - 4) { /** If the series is a heatmap or treemap, or if the series is not boosting
2341 < 0) {<= preAllocated.length - 4) { * do the default behaviour. Otherwise, process if the series has no
2342 < 0) {<= preAllocated.length - 4) { * extremes.
2343 < 0) {<= preAllocated.length - 4) { */
2344 < 0) {<= preAllocated.length - 4) { wrap(Series.prototype, 'processData', function(proceed) {
2345 < 0) {<= preAllocated.length - 4) { // If this is a heatmap, do default behaviour
2346 < 0) {<= preAllocated.length - 4) { if (!isSeriesBoosting(this) ||
2347 < 0) {<= preAllocated.length - 4) { this.type === 'heatmap' ||
2348 < 0) {<= preAllocated.length - 4) { this.type === 'treemap') {
2349 < 0) {<= preAllocated.length - 4) { proceed.apply(this, Array.prototype.slice.call(arguments, 1));
2350 < 0) {<= preAllocated.length - 4) { }
2351  
2352 < 0) {<= preAllocated.length - 4) { if (!this.hasExtremes || !this.hasExtremes(true)) {
2353 < 0) {<= preAllocated.length - 4) { proceed.apply(this, Array.prototype.slice.call(arguments, 1));
2354 < 0) {<= preAllocated.length - 4) { }
2355 < 0) {<= preAllocated.length - 4) { });
2356  
2357 < 0) {<= preAllocated.length - 4) { H.extend(Series.prototype, {
2358 < 0) {<= preAllocated.length - 4) { pointRange: 0,
2359 < 0) {<= preAllocated.length - 4) { directTouch: false,
2360 < 0) {<= preAllocated.length - 4) { allowDG: false, // No data grouping, let boost handle large data
2361 < 0) {<= preAllocated.length - 4) { hasExtremes: function(checkX) {
2362 < 0) {<= preAllocated.length - 4) { var options = this.options,
2363 < 0) {<= preAllocated.length - 4) { data = options.data,
2364 < 0) {<= preAllocated.length - 4) { xAxis = this.xAxis && this.xAxis.options,
2365 < 0) {<= preAllocated.length - 4) { yAxis = this.yAxis && this.yAxis.options;
2366  
2367 < 0) {<= preAllocated.length - 4) { return data.length > (options.boostThreshold || Number.MAX_VALUE) &&
2368 < 0) {<= preAllocated.length - 4) { isNumber(yAxis.min) && isNumber(yAxis.max) &&
2369 < 0) {<= preAllocated.length - 4) { (!checkX || (isNumber(xAxis.min) && isNumber(xAxis.max)));
2370 < 0) {<= preAllocated.length - 4) { },
2371  
2372 < 0) {<= preAllocated.length - 4) { /**
2373 < 0) {<= preAllocated.length - 4) { * If implemented in the core, parts of this can probably be
2374 < 0) {<= preAllocated.length - 4) { * shared with other similar methods in Highcharts.
2375 < 0) {<= preAllocated.length - 4) { */
2376 < 0) {<= preAllocated.length - 4) { destroyGraphics: function() {
2377 < 0) {<= preAllocated.length - 4) { var series = this,
2378 < 0) {<= preAllocated.length - 4) { points = this.points,
2379 < 0) {<= preAllocated.length - 4) { point,
2380 < 0) {<= preAllocated.length - 4) { i;
2381  
2382 < 0) {<= preAllocated.length - 4) { if (points) {
2383 < 0) {<= preAllocated.length - 4) { for (i = 0; i < points.length; i = i + 1) {
2384 < 0) {<= preAllocated.length - 4) { point = points[i];
2385 < 0) {<= preAllocated.length - 4) { if (point && point.graphic) {
2386 < 0) {<= preAllocated.length - 4) { point.graphic = point.graphic.destroy();
2387 < 0) {<= preAllocated.length - 4) { }
2388 < 0) {<= preAllocated.length - 4) { }
2389 < 0) {<= preAllocated.length - 4) { }
2390  
2391 < 0) {<= preAllocated.length - 4) { each(['graph', 'area', 'tracker'], function(prop) {
2392 < 0) {<= preAllocated.length - 4) { if (series[prop]) {
2393 < 0) {<= preAllocated.length - 4) { series[prop] = series[prop].destroy();
2394 < 0) {<= preAllocated.length - 4) { }
2395 < 0) {<= preAllocated.length - 4) { });
2396 < 0) {<= preAllocated.length - 4) { },
2397  
2398 < 0) {<= preAllocated.length - 4) { renderCanvas: function() {
2399 < 0) {<= preAllocated.length - 4) { var series = this,
2400 < 0) {<= preAllocated.length - 4) { options = series.options || {},
2401 < 0) {<= preAllocated.length - 4) { renderer = false,
2402 < 0) {<= preAllocated.length - 4) { chart = series.chart,
2403 < 0) {<= preAllocated.length - 4) { xAxis = this.xAxis,
2404 < 0) {<= preAllocated.length - 4) { yAxis = this.yAxis,
2405 < 0) {<= preAllocated.length - 4) { //ctx,
2406 < 0) {<= preAllocated.length - 4) { //c = 0,
2407 < 0) {<= preAllocated.length - 4) { xData = options.xData || series.processedXData,
2408 < 0) {<= preAllocated.length - 4) { yData = options.yData || series.processedYData,
2409  
2410 < 0) {<= preAllocated.length - 4) { rawData = options.data,
2411 < 0) {<= preAllocated.length - 4) { xExtremes = xAxis.getExtremes(),
2412 < 0) {<= preAllocated.length - 4) { xMin = xExtremes.min,
2413 < 0) {<= preAllocated.length - 4) { xMax = xExtremes.max,
2414 < 0) {<= preAllocated.length - 4) { yExtremes = yAxis.getExtremes(),
2415 < 0) {<= preAllocated.length - 4) { yMin = yExtremes.min,
2416 < 0) {<= preAllocated.length - 4) { yMax = yExtremes.max,
2417 < 0) {<= preAllocated.length - 4) { pointTaken = {},
2418 < 0) {<= preAllocated.length - 4) { lastClientX,
2419 < 0) {<= preAllocated.length - 4) { sampling = !!series.sampling,
2420 < 0) {<= preAllocated.length - 4) { points,
2421 < 0) {<= preAllocated.length - 4) { enableMouseTracking = options.enableMouseTracking !== false,
2422 < 0) {<= preAllocated.length - 4) { threshold = options.threshold,
2423 < 0) {<= preAllocated.length - 4) { yBottom = yAxis.getThreshold(threshold),
2424 < 0) {<= preAllocated.length - 4) { isRange = series.pointArrayMap &&
2425 < 0) {<= preAllocated.length - 4) { series.pointArrayMap.join(',') === 'low,high',
2426 < 0) {<= preAllocated.length - 4) { isStacked = !!options.stacking,
2427 < 0) {<= preAllocated.length - 4) { cropStart = series.cropStart || 0,
2428 < 0) {<= preAllocated.length - 4) { requireSorting = series.requireSorting,
2429 < 0) {<= preAllocated.length - 4) { useRaw = !xData,
2430 < 0) {<= preAllocated.length - 4) { minVal,
2431 < 0) {<= preAllocated.length - 4) { maxVal,
2432 < 0) {<= preAllocated.length - 4) { minI,
2433 < 0) {<= preAllocated.length - 4) { maxI,
2434  
2435 < 0) {<= preAllocated.length - 4) { addKDPoint = function(clientX, plotY, i) {
2436 < 0) {<= preAllocated.length - 4) { //Shaves off about 60ms compared to repeated concatination
2437 < 0) {<= preAllocated.length - 4) { index = clientX + ',' + plotY;
2438  
2439 < 0) {<= preAllocated.length - 4) { // The k-d tree requires series points.
2440 < 0) {<= preAllocated.length - 4) { // Reduce the amount of points, since the time to build the
2441 < 0) {<= preAllocated.length - 4) { // tree increases exponentially.
2442 < 0) {<= preAllocated.length - 4) { if (enableMouseTracking && !pointTaken[index]) {
2443 < 0) {<= preAllocated.length - 4) { pointTaken[index] = true;
2444  
2445 < 0) {<= preAllocated.length - 4) { if (chart.inverted) {
2446 < 0) {<= preAllocated.length - 4) { clientX = xAxis.len - clientX;
2447 < 0) {<= preAllocated.length - 4) { plotY = yAxis.len - plotY;
2448 < 0) {<= preAllocated.length - 4) { }
2449  
2450 < 0) {<= preAllocated.length - 4) { points.push({
2451 < 0) {<= preAllocated.length - 4) { clientX: clientX,
2452 < 0) {<= preAllocated.length - 4) { plotX: clientX,
2453 < 0) {<= preAllocated.length - 4) { plotY: plotY,
2454 < 0) {<= preAllocated.length - 4) { i: cropStart + i
2455 < 0) {<= preAllocated.length - 4) { });
2456 < 0) {<= preAllocated.length - 4) { }
2457 < 0) {<= preAllocated.length - 4) { };
2458  
2459 < 0) {<= preAllocated.length - 4) { // Get or create the renderer
2460 < 0) {<= preAllocated.length - 4) { renderer = createAndAttachRenderer(chart, series);
2461  
2462 < 0) {<= preAllocated.length - 4) { if (!this.visible) {
2463 < 0) {<= preAllocated.length - 4) { if (!isChartSeriesBoosting(chart) && renderer) {
2464 < 0) {<= preAllocated.length - 4) { renderer.clear();
2465 < 0) {<= preAllocated.length - 4) { this.image.attr({
2466 < 0) {<= preAllocated.length - 4) { href: ''
2467 < 0) {<= preAllocated.length - 4) { });
2468 < 0) {<= preAllocated.length - 4) { }
2469 < 0) {<= preAllocated.length - 4) { return;
2470 < 0) {<= preAllocated.length - 4) { }
2471  
2472 < 0) {<= preAllocated.length - 4) { // If we are zooming out from SVG mode, destroy the graphics
2473 < 0) {<= preAllocated.length - 4) { if (this.points || this.graph) {
2474 < 0) {<= preAllocated.length - 4) { this.destroyGraphics();
2475 < 0) {<= preAllocated.length - 4) { }
2476  
2477 < 0) {<= preAllocated.length - 4) { // If we're rendering per. series we should create the marker groups
2478 < 0) {<= preAllocated.length - 4) { // as usual.
2479 < 0) {<= preAllocated.length - 4) { if (!isChartSeriesBoosting(chart)) {
2480 < 0) {<= preAllocated.length - 4) { this.markerGroup = series.plotGroup(
2481 < 0) {<= preAllocated.length - 4) { 'markerGroup',
2482 < 0) {<= preAllocated.length - 4) { 'markers',
2483 < 0) {<= preAllocated.length - 4) { true,
2484 < 0) {<= preAllocated.length - 4) { 1,
2485 < 0) {<= preAllocated.length - 4) { chart.seriesGroup
2486 < 0) {<= preAllocated.length - 4) { );
2487 < 0) {<= preAllocated.length - 4) { } else {
2488 < 0) {<= preAllocated.length - 4) { //Use a single group for the markers
2489 < 0) {<= preAllocated.length - 4) { this.markerGroup = chart.markerGroup;
2490 < 0) {<= preAllocated.length - 4) { }
2491  
2492 < 0) {<= preAllocated.length - 4) { points = this.points = [];
2493  
2494 < 0) {<= preAllocated.length - 4) { // Do not start building while drawing
2495 < 0) {<= preAllocated.length - 4) { series.buildKDTree = noop;
2496  
2497 < 0) {<= preAllocated.length - 4) { if (renderer) {
2498 < 0) {<= preAllocated.length - 4) { allocateIfNotSeriesBoosting(renderer, this);
2499 < 0) {<= preAllocated.length - 4) { renderer.pushSeries(series);
2500 < 0) {<= preAllocated.length - 4) { // Perform the actual renderer if we're on series level
2501 < 0) {<= preAllocated.length - 4) { renderIfNotSeriesBoosting(renderer, this, chart);
2502 < 0) {<= preAllocated.length - 4) { //console.log(series, chart);
2503 < 0) {<= preAllocated.length - 4) { }
2504  
2505 < 0) {<= preAllocated.length - 4) { /* This builds the KD-tree */
2506 < 0) {<= preAllocated.length - 4) { function processPoint(d, i) {
2507 < 0) {<= preAllocated.length - 4) { var x,
2508 < 0) {<= preAllocated.length - 4) { y,
2509 < 0) {<= preAllocated.length - 4) { clientX,
2510 < 0) {<= preAllocated.length - 4) { plotY,
2511 < 0) {<= preAllocated.length - 4) { isNull,
2512 < 0) {<= preAllocated.length - 4) { low,
2513 < 0) {<= preAllocated.length - 4) { chartDestroyed = typeof chart.index === 'undefined',
2514 < 0) {<= preAllocated.length - 4) { isYInside = true;
2515  
2516 < 0) {<= preAllocated.length - 4) { if (!chartDestroyed) {
2517 < 0) {<= preAllocated.length - 4) { if (useRaw) {
2518 < 0) {<= preAllocated.length - 4) { x = d[0];
2519 < 0) {<= preAllocated.length - 4) { y = d[1];
2520 < 0) {<= preAllocated.length - 4) { } else {
2521 < 0) {<= preAllocated.length - 4) { x = d;
2522 < 0) {<= preAllocated.length - 4) { y = yData[i];
2523 < 0) {<= preAllocated.length - 4) { }
2524  
2525 < 0) {<= preAllocated.length - 4) { // Resolve low and high for range series
2526 < 0) {<= preAllocated.length - 4) { if (isRange) {
2527 < 0) {<= preAllocated.length - 4) { if (useRaw) {
2528 < 0) {<= preAllocated.length - 4) { y = d.slice(1, 3);
2529 < 0) {<= preAllocated.length - 4) { }
2530 < 0) {<= preAllocated.length - 4) { low = y[0];
2531 < 0) {<= preAllocated.length - 4) { y = y[1];
2532 < 0) {<= preAllocated.length - 4) { } else if (isStacked) {
2533 < 0) {<= preAllocated.length - 4) { x = d.x;
2534 < 0) {<= preAllocated.length - 4) { y = d.stackY;
2535 < 0) {<= preAllocated.length - 4) { low = y - d.y;
2536 < 0) {<= preAllocated.length - 4) { }
2537  
2538 < 0) {<= preAllocated.length - 4) { isNull = y === null;
2539  
2540 < 0) {<= preAllocated.length - 4) { // Optimize for scatter zooming
2541 < 0) {<= preAllocated.length - 4) { if (!requireSorting) {
2542 < 0) {<= preAllocated.length - 4) { isYInside = y >= yMin && y <= yMax;
2543 < 0) {<= preAllocated.length - 4) { }
2544  
2545 < 0) {<= preAllocated.length - 4) { if (!isNull && x >= xMin && x <= xMax && isYInside) {
2546  
2547 < 0) {<= preAllocated.length - 4) { // We use ceil to allow the KD tree to work with sub
2548 < 0) {<= preAllocated.length - 4) { // pixels, which can be used in boost to space pixels
2549 < 0) {<= preAllocated.length - 4) { clientX = Math.ceil(xAxis.toPixels(x, true));
2550  
2551 < 0) {<= preAllocated.length - 4) { if (sampling) {
2552 < 0) {<= preAllocated.length - 4) { if (minI === undefined || clientX === lastClientX) {
2553 < 0) {<= preAllocated.length - 4) { if (!isRange) {
2554 < 0) {<= preAllocated.length - 4) { low = y;
2555 < 0) {<= preAllocated.length - 4) { }
2556 < 0) {<= preAllocated.length - 4) { if (maxI === undefined || y > maxVal) {
2557 < 0) {<= preAllocated.length - 4) { maxVal = y;
2558 < 0) {<= preAllocated.length - 4) { maxI = i;
2559 < 0) {<= preAllocated.length - 4) { }
2560 < 0) {<= preAllocated.length - 4) { if (minI === undefined || low < minVal) {
2561 < 0) {<= preAllocated.length - 4) { minVal = low;
2562 < 0) {<= preAllocated.length - 4) { minI = i;
2563 < 0) {<= preAllocated.length - 4) { }
2564  
2565 < 0) {<= preAllocated.length - 4) { }
2566 < 0) {<= preAllocated.length - 4) { if (clientX !== lastClientX) { // Add points and reset
2567 < 0) {<= preAllocated.length - 4) { if (minI !== undefined) { // then maxI is also a number
2568 < 0) {<= preAllocated.length - 4) { plotY = yAxis.toPixels(maxVal, true);
2569 < 0) {<= preAllocated.length - 4) { yBottom = yAxis.toPixels(minVal, true);
2570  
2571 < 0) {<= preAllocated.length - 4) { addKDPoint(clientX, plotY, maxI);
2572 < 0) {<= preAllocated.length - 4) { if (yBottom !== plotY) {
2573 < 0) {<= preAllocated.length - 4) { addKDPoint(clientX, yBottom, minI);
2574 < 0) {<= preAllocated.length - 4) { }
2575 < 0) {<= preAllocated.length - 4) { }
2576  
2577 < 0) {<= preAllocated.length - 4) { minI = maxI = undefined;
2578 < 0) {<= preAllocated.length - 4) { lastClientX = clientX;
2579 < 0) {<= preAllocated.length - 4) { }
2580 < 0) {<= preAllocated.length - 4) { } else {
2581 < 0) {<= preAllocated.length - 4) { plotY = Math.ceil(yAxis.toPixels(y, true));
2582 < 0) {<= preAllocated.length - 4) { addKDPoint(clientX, plotY, i);
2583 < 0) {<= preAllocated.length - 4) { }
2584 < 0) {<= preAllocated.length - 4) { }
2585 < 0) {<= preAllocated.length - 4) { }
2586  
2587 < 0) {<= preAllocated.length - 4) { return !chartDestroyed;
2588 < 0) {<= preAllocated.length - 4) { }
2589  
2590 < 0) {<= preAllocated.length - 4) { function doneProcessing() {
2591 < 0) {<= preAllocated.length - 4) { fireEvent(series, 'renderedCanvas');
2592 < 0) {<= preAllocated.length - 4) { // Pass tests in Pointer.
2593 < 0) {<= preAllocated.length - 4) { // Replace this with a single property, and replace when zooming
2594 < 0) {<= preAllocated.length - 4) { // in below boostThreshold.
2595 < 0) {<= preAllocated.length - 4) { series.directTouch = false;
2596 < 0) {<= preAllocated.length - 4) { series.options.stickyTracking = true;
2597  
2598 < 0) {<= preAllocated.length - 4) { // Go back to prototype, ready to build
2599 < 0) {<= preAllocated.length - 4) { delete series.buildKDTree;
2600 < 0) {<= preAllocated.length - 4) { series.buildKDTree();
2601 < 0) {<= preAllocated.length - 4) { }
2602  
2603 < 0) {<= preAllocated.length - 4) { // Loop over the points to build the k-d tree
2604 < 0) {<= preAllocated.length - 4) { eachAsync(
2605 < 0) {<= preAllocated.length - 4) { isStacked ? series.data : (xData || rawData),
2606 < 0) {<= preAllocated.length - 4) { processPoint,
2607 < 0) {<= preAllocated.length - 4) { doneProcessing,
2608 < 0) {<= preAllocated.length - 4) { chart.renderer.forExport ? Number.MAX_VALUE : undefined
2609 < 0) {<= preAllocated.length - 4) { );
2610 < 0) {<= preAllocated.length - 4) { }
2611 < 0) {<= preAllocated.length - 4) { });
2612  
2613 < 0) {<= preAllocated.length - 4) { /*
2614 < 0) {<= preAllocated.length - 4) { * We need to handle heatmaps separatly, since we can't perform the
2615 < 0) {<= preAllocated.length - 4) { * size/color calculations in the shader easily.
2616 < 0) {<= preAllocated.length - 4) { *
2617 < 0) {<= preAllocated.length - 4) { * This likely needs future optimization.
2618 < 0) {<= preAllocated.length - 4) { *
2619 < 0) {<= preAllocated.length - 4) { */
2620 < 0) {<= preAllocated.length - 4) { each(['heatmap', 'treemap'],
2621 < 0) {<= preAllocated.length - 4) { function(t) {
2622 < 0) {<= preAllocated.length - 4) { if (seriesTypes[t]) {
2623 < 0) {<= preAllocated.length - 4) { wrap(seriesTypes[t].prototype, 'drawPoints', pointDrawHandler);
2624 < 0) {<= preAllocated.length - 4) { seriesTypes[t].prototype.directTouch = false; // Use k-d-tree
2625 < 0) {<= preAllocated.length - 4) { }
2626 < 0) {<= preAllocated.length - 4) { }
2627 < 0) {<= preAllocated.length - 4) { );
2628  
2629 < 0) {<= preAllocated.length - 4) { if (seriesTypes.bubble) {
2630 < 0) {<= preAllocated.length - 4) { // By default, the bubble series does not use the KD-tree, so force it
2631 < 0) {<= preAllocated.length - 4) { // to.
2632 < 0) {<= preAllocated.length - 4) { delete seriesTypes.bubble.prototype.buildKDTree;
2633 < 0) {<= preAllocated.length - 4) { seriesTypes.bubble.prototype.directTouch = false;
2634  
2635 < 0) {<= preAllocated.length - 4) { // Needed for markers to work correctly
2636 < 0) {<= preAllocated.length - 4) { wrap(
2637 < 0) {<= preAllocated.length - 4) { seriesTypes.bubble.prototype,
2638 < 0) {<= preAllocated.length - 4) { 'markerAttribs',
2639 < 0) {<= preAllocated.length - 4) { function(proceed) {
2640 < 0) {<= preAllocated.length - 4) { if (isSeriesBoosting(this)) {
2641 < 0) {<= preAllocated.length - 4) { return false;
2642 < 0) {<= preAllocated.length - 4) { }
2643 < 0) {<= preAllocated.length - 4) { return proceed.apply(this, [].slice.call(arguments, 1));
2644 < 0) {<= preAllocated.length - 4) { }
2645 < 0) {<= preAllocated.length - 4) { );
2646 < 0) {<= preAllocated.length - 4) { }
2647  
2648 < 0) {<= preAllocated.length - 4) { seriesTypes.scatter.prototype.fill = true;
2649  
2650 < 0) {<= preAllocated.length - 4) { extend(seriesTypes.area.prototype, {
2651 < 0) {<= preAllocated.length - 4) { fill: true,
2652 < 0) {<= preAllocated.length - 4) { fillOpacity: true,
2653 < 0) {<= preAllocated.length - 4) { sampling: true
2654 < 0) {<= preAllocated.length - 4) { });
2655  
2656 < 0) {<= preAllocated.length - 4) { extend(seriesTypes.column.prototype, {
2657 < 0) {<= preAllocated.length - 4) { fill: true,
2658 < 0) {<= preAllocated.length - 4) { sampling: true
2659 < 0) {<= preAllocated.length - 4) { });
2660  
2661 < 0) {<= preAllocated.length - 4) { wrap(Series.prototype, 'setVisible', function(proceed, vis) {
2662 < 0) {<= preAllocated.length - 4) { proceed.call(this, vis, false);
2663 < 0) {<= preAllocated.length - 4) { if (this.visible === false && this.ogl && this.canvas && this.image) {
2664 < 0) {<= preAllocated.length - 4) { this.ogl.clear();
2665 < 0) {<= preAllocated.length - 4) { this.image.attr({
2666 < 0) {<= preAllocated.length - 4) { href: ''
2667 < 0) {<= preAllocated.length - 4) { });
2668 < 0) {<= preAllocated.length - 4) { } else {
2669 < 0) {<= preAllocated.length - 4) { this.chart.redraw();
2670 < 0) {<= preAllocated.length - 4) { }
2671 < 0) {<= preAllocated.length - 4) { });
2672  
2673 < 0) {<= preAllocated.length - 4) { /**
2674 < 0) {<= preAllocated.length - 4) { * Take care of the canvas blitting
2675 < 0) {<= preAllocated.length - 4) { */
2676 < 0) {<= preAllocated.length - 4) { H.Chart.prototype.callbacks.push(function(chart) {
2677  
2678 < 0) {<= preAllocated.length - 4) { /* Convert chart-level canvas to image */
2679 < 0) {<= preAllocated.length - 4) { function canvasToSVG() {
2680 < 0) {<= preAllocated.length - 4) { if (chart.ogl && isChartSeriesBoosting(chart)) {
2681 < 0) {<= preAllocated.length - 4) { chart.ogl.render(chart);
2682 < 0) {<= preAllocated.length - 4) { }
2683 < 0) {<= preAllocated.length - 4) { }
2684  
2685 < 0) {<= preAllocated.length - 4) { /* Clear chart-level canvas */
2686 < 0) {<= preAllocated.length - 4) { function preRender() {
2687  
2688 < 0) {<= preAllocated.length - 4) { if (!isChartSeriesBoosting(chart) && chart.didBoost) {
2689 < 0) {<= preAllocated.length - 4) { chart.didBoost = false;
2690 < 0) {<= preAllocated.length - 4) { // Clear the canvas
2691 < 0) {<= preAllocated.length - 4) { if (chart.image) {
2692 < 0) {<= preAllocated.length - 4) { chart.image.attr({
2693 < 0) {<= preAllocated.length - 4) { href: ''
2694 < 0) {<= preAllocated.length - 4) { });
2695 < 0) {<= preAllocated.length - 4) { }
2696 < 0) {<= preAllocated.length - 4) { }
2697  
2698 < 0) {<= preAllocated.length - 4) { if (chart.canvas && chart.ogl && isChartSeriesBoosting(chart)) {
2699 < 0) {<= preAllocated.length - 4) { chart.didBoost = true;
2700  
2701 < 0) {<= preAllocated.length - 4) { // Allocate
2702 < 0) {<= preAllocated.length - 4) { chart.ogl.allocateBuffer(chart);
2703 < 0) {<= preAllocated.length - 4) { }
2704  
2705 < 0) {<= preAllocated.length - 4) { //see #6518 + #6739
2706 < 0) {<= preAllocated.length - 4) { if (chart.markerGroup && chart.xAxis && chart.xAxis.length > 0 && chart.yAxis && chart.yAxis.length > 0) {
2707 < 0) {<= preAllocated.length - 4) { chart.markerGroup.translate(
2708 < 0) {<= preAllocated.length - 4) { chart.xAxis[0].pos,
2709 < 0) {<= preAllocated.length - 4) { chart.yAxis[0].pos
2710 < 0) {<= preAllocated.length - 4) { );
2711 < 0) {<= preAllocated.length - 4) { }
2712  
2713 < 0) {<= preAllocated.length - 4) { }
2714  
2715 < 0) {<= preAllocated.length - 4) { addEvent(chart, 'predraw', preRender);
2716 < 0) {<= preAllocated.length - 4) { addEvent(chart, 'render', canvasToSVG);
2717 < 0) {<= preAllocated.length - 4) { });
2718 < 0) {<= preAllocated.length - 4) { } // if hasCanvasSupport
2719  
2720 < 0) {<= preAllocated.length - 4) { }(Highcharts));
2721 < 0) {<= preAllocated.length - 4) { }));