highcharts-rails 4.1.9 → 4.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.markdown +55 -0
- data/app/assets/images/highcharts/search.png +0 -0
- data/app/assets/javascripts/highcharts.js +18962 -18796
- data/app/assets/javascripts/highcharts/adapters/standalone-framework.js +152 -131
- data/app/assets/javascripts/highcharts/highcharts-3d.js +1702 -1561
- data/app/assets/javascripts/highcharts/highcharts-more.js +2655 -2639
- data/app/assets/javascripts/highcharts/modules/boost.js +72 -35
- data/app/assets/javascripts/highcharts/modules/broken-axis.js +45 -32
- data/app/assets/javascripts/highcharts/modules/canvas-tools.js +8 -7
- data/app/assets/javascripts/highcharts/modules/data.js +646 -642
- data/app/assets/javascripts/highcharts/modules/drilldown.js +15 -11
- data/app/assets/javascripts/highcharts/modules/exporting.js +17 -12
- data/app/assets/javascripts/highcharts/modules/funnel.js +19 -12
- data/app/assets/javascripts/highcharts/modules/heatmap.js +702 -696
- data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +10 -4
- data/app/assets/javascripts/highcharts/modules/offline-exporting.js +241 -238
- data/app/assets/javascripts/highcharts/modules/solid-gauge.js +12 -9
- data/app/assets/javascripts/highcharts/modules/treemap.js +67 -86
- data/app/assets/javascripts/highcharts/themes/grid-light.js +1 -1
- data/app/assets/javascripts/highcharts/themes/sand-signika.js +1 -1
- data/lib/highcharts/version.rb +1 -1
- metadata +3 -2
@@ -1,16 +1,20 @@
|
|
1
1
|
/**
|
2
|
-
* Highcharts Drilldown
|
2
|
+
* Highcharts Drilldown module
|
3
3
|
*
|
4
4
|
* Author: Torstein Honsi
|
5
|
-
* License:
|
5
|
+
* License: www.highcharts.com/license
|
6
6
|
*
|
7
|
-
* Demo: http://jsfiddle.net/highcharts/Vf3yT/
|
8
7
|
*/
|
9
8
|
|
10
|
-
|
11
|
-
(
|
9
|
+
(function (factory) {
|
10
|
+
if (typeof module === 'object' && module.exports) {
|
11
|
+
module.exports = factory;
|
12
|
+
} else {
|
13
|
+
factory(Highcharts);
|
14
|
+
}
|
15
|
+
}(function (H) {
|
12
16
|
|
13
|
-
|
17
|
+
'use strict';
|
14
18
|
|
15
19
|
var noop = function () {},
|
16
20
|
defaultOptions = H.getOptions(),
|
@@ -24,8 +28,8 @@
|
|
24
28
|
PieSeries = seriesTypes.pie,
|
25
29
|
ColumnSeries = seriesTypes.column,
|
26
30
|
Tick = H.Tick,
|
27
|
-
fireEvent =
|
28
|
-
inArray =
|
31
|
+
fireEvent = H.fireEvent,
|
32
|
+
inArray = H.inArray,
|
29
33
|
ddSeriesId = 1;
|
30
34
|
|
31
35
|
// Utilities
|
@@ -42,7 +46,7 @@
|
|
42
46
|
|
43
47
|
// Unsupported color, return to-color (#3920)
|
44
48
|
if (!to.rgba.length || !from.rgba.length) {
|
45
|
-
ret = to.
|
49
|
+
ret = to.input || 'none';
|
46
50
|
|
47
51
|
// Interpolate
|
48
52
|
} else {
|
@@ -61,7 +65,7 @@
|
|
61
65
|
* Handle animation of the color attributes directly
|
62
66
|
*/
|
63
67
|
each(['fill', 'stroke'], function (prop) {
|
64
|
-
|
68
|
+
H.addAnimSetter(prop, function (fx) {
|
65
69
|
fx.elem.attr(prop, tweenColors(H.Color(fx.start), H.Color(fx.end), fx.pos));
|
66
70
|
});
|
67
71
|
});
|
@@ -710,4 +714,4 @@
|
|
710
714
|
}
|
711
715
|
}
|
712
716
|
|
713
|
-
}
|
717
|
+
}));
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS v4.1.
|
2
|
+
* @license Highcharts JS v4.1.10 (2015-12-07)
|
3
3
|
* Exporting module
|
4
4
|
*
|
5
5
|
* (c) 2010-2014 Torstein Honsi
|
@@ -7,16 +7,20 @@
|
|
7
7
|
* License: www.highcharts.com/license
|
8
8
|
*/
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
/* eslint indent:0 */
|
11
|
+
(function (factory) {
|
12
|
+
if (typeof module === 'object' && module.exports) {
|
13
|
+
module.exports = factory;
|
14
|
+
} else {
|
15
|
+
factory(Highcharts);
|
16
|
+
}
|
17
|
+
}(function (Highcharts) {
|
14
18
|
|
15
19
|
// create shortcuts
|
16
20
|
var Chart = Highcharts.Chart,
|
17
21
|
addEvent = Highcharts.addEvent,
|
18
22
|
removeEvent = Highcharts.removeEvent,
|
19
|
-
fireEvent =
|
23
|
+
fireEvent = Highcharts.fireEvent,
|
20
24
|
createElement = Highcharts.createElement,
|
21
25
|
discardElement = Highcharts.discardElement,
|
22
26
|
css = Highcharts.css,
|
@@ -257,16 +261,14 @@ extend(Chart.prototype, {
|
|
257
261
|
cssHeight,
|
258
262
|
html,
|
259
263
|
options = merge(chart.options, additionalOptions), // copy the options and add extra options
|
260
|
-
allowHTML = options.exporting.allowHTML;
|
264
|
+
allowHTML = options.exporting.allowHTML;
|
261
265
|
|
262
266
|
|
263
267
|
// IE compatibility hack for generating SVG content that it doesn't really understand
|
264
268
|
if (!doc.createElementNS) {
|
265
|
-
/*jslint unparam: true*//* allow unused parameter ns in function below */
|
266
269
|
doc.createElementNS = function (ns, tagName) {
|
267
270
|
return doc.createElement(tagName);
|
268
271
|
};
|
269
|
-
/*jslint unparam: false*/
|
270
272
|
}
|
271
273
|
|
272
274
|
// create a sandbox where a new chart will be generated
|
@@ -368,7 +370,7 @@ extend(Chart.prototype, {
|
|
368
370
|
|
369
371
|
// IE9 beta bugs with innerHTML. Test again with final IE9.
|
370
372
|
svg = svg.replace(/(url\(#highcharts-[0-9]+)"/g, '$1')
|
371
|
-
.replace(/"/g,
|
373
|
+
.replace(/"/g, '\'');
|
372
374
|
|
373
375
|
return svg;
|
374
376
|
},
|
@@ -429,6 +431,7 @@ extend(Chart.prototype, {
|
|
429
431
|
}
|
430
432
|
|
431
433
|
chart.isPrinting = true;
|
434
|
+
chart.pointer.reset(null, 0);
|
432
435
|
|
433
436
|
fireEvent(chart, 'beforePrint');
|
434
437
|
|
@@ -555,7 +558,9 @@ extend(Chart.prototype, {
|
|
555
558
|
css(this, menuItemStyle);
|
556
559
|
},
|
557
560
|
onclick: function (e) {
|
558
|
-
e
|
561
|
+
if (e) { // IE7
|
562
|
+
e.stopPropagation();
|
563
|
+
}
|
559
564
|
hide();
|
560
565
|
if (item.onclick) {
|
561
566
|
item.onclick.apply(chart, arguments);
|
@@ -772,4 +777,4 @@ Chart.prototype.callbacks.push(function (chart) {
|
|
772
777
|
});
|
773
778
|
|
774
779
|
|
775
|
-
}
|
780
|
+
}));
|
@@ -6,9 +6,14 @@
|
|
6
6
|
*
|
7
7
|
* License: www.highcharts.com/license
|
8
8
|
*/
|
9
|
-
|
10
|
-
|
11
|
-
(
|
9
|
+
/* eslint indent:0 */
|
10
|
+
(function (factory) {
|
11
|
+
if (typeof module === 'object' && module.exports) {
|
12
|
+
module.exports = factory;
|
13
|
+
} else {
|
14
|
+
factory(Highcharts);
|
15
|
+
}
|
16
|
+
}(function (Highcharts) {
|
12
17
|
|
13
18
|
'use strict';
|
14
19
|
|
@@ -82,7 +87,7 @@ seriesTypes.funnel = Highcharts.extendClass(seriesTypes.pie, {
|
|
82
87
|
height = getLength(options.height, plotHeight),
|
83
88
|
neckWidth = getLength(options.neckWidth, plotWidth),
|
84
89
|
neckHeight = getLength(options.neckHeight, plotHeight),
|
85
|
-
neckY = height - neckHeight,
|
90
|
+
neckY = (centerY - height / 2) + height - neckHeight,
|
86
91
|
data = series.data,
|
87
92
|
path,
|
88
93
|
fraction,
|
@@ -98,12 +103,14 @@ seriesTypes.funnel = Highcharts.extendClass(seriesTypes.pie, {
|
|
98
103
|
|
99
104
|
// Return the width at a specific y coordinate
|
100
105
|
series.getWidthAt = getWidthAt = function (y) {
|
101
|
-
|
106
|
+
var top = (centerY - height / 2);
|
107
|
+
|
108
|
+
return y > neckY || height === neckHeight ?
|
102
109
|
neckWidth :
|
103
|
-
neckWidth + (width - neckWidth) * (
|
110
|
+
neckWidth + (width - neckWidth) * (1 - (y - top) / (height - neckHeight));
|
104
111
|
};
|
105
112
|
series.getX = function (y, half) {
|
106
|
-
|
113
|
+
return centerX + (half ? -1 : 1) * ((getWidthAt(reversed ? plotHeight - y : y) / 2) + options.dataLabels.distance);
|
107
114
|
};
|
108
115
|
|
109
116
|
// Expose
|
@@ -232,13 +239,13 @@ seriesTypes.funnel = Highcharts.extendClass(seriesTypes.pie, {
|
|
232
239
|
shapeArgs = point.shapeArgs;
|
233
240
|
|
234
241
|
if (!graphic) { // Create the shapes
|
235
|
-
point.graphic = renderer.path(shapeArgs)
|
236
|
-
attr({
|
242
|
+
point.graphic = renderer.path(shapeArgs)
|
243
|
+
.attr({
|
237
244
|
fill: point.color,
|
238
245
|
stroke: pick(pointOptions.borderColor, options.borderColor),
|
239
246
|
'stroke-width': pick(pointOptions.borderWidth, options.borderWidth)
|
240
|
-
})
|
241
|
-
add(series.group);
|
247
|
+
})
|
248
|
+
.add(series.group);
|
242
249
|
|
243
250
|
} else { // Update the shapes
|
244
251
|
graphic.animate(shapeArgs);
|
@@ -312,4 +319,4 @@ Highcharts.seriesTypes.pyramid = Highcharts.extendClass(Highcharts.seriesTypes.f
|
|
312
319
|
type: 'pyramid'
|
313
320
|
});
|
314
321
|
|
315
|
-
}
|
322
|
+
}));
|
@@ -1,705 +1,711 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS v4.1.
|
2
|
+
* @license Highcharts JS v4.1.10 (2015-12-07)
|
3
3
|
*
|
4
4
|
* (c) 2011-2014 Torstein Honsi
|
5
5
|
*
|
6
6
|
* License: www.highcharts.com/license
|
7
7
|
*/
|
8
|
+
/* eslint indent: [2, 4] */
|
9
|
+
(function (factory) {
|
10
|
+
if (typeof module === 'object' && module.exports) {
|
11
|
+
module.exports = factory;
|
12
|
+
} else {
|
13
|
+
factory(Highcharts);
|
14
|
+
}
|
15
|
+
}(function (Highcharts) {
|
16
|
+
|
17
|
+
|
18
|
+
var UNDEFINED,
|
19
|
+
Axis = Highcharts.Axis,
|
20
|
+
Chart = Highcharts.Chart,
|
21
|
+
Color = Highcharts.Color,
|
22
|
+
Legend = Highcharts.Legend,
|
23
|
+
LegendSymbolMixin = Highcharts.LegendSymbolMixin,
|
24
|
+
Series = Highcharts.Series,
|
25
|
+
Point = Highcharts.Point,
|
26
|
+
|
27
|
+
defaultOptions = Highcharts.getOptions(),
|
28
|
+
each = Highcharts.each,
|
29
|
+
extend = Highcharts.extend,
|
30
|
+
extendClass = Highcharts.extendClass,
|
31
|
+
merge = Highcharts.merge,
|
32
|
+
pick = Highcharts.pick,
|
33
|
+
seriesTypes = Highcharts.seriesTypes,
|
34
|
+
wrap = Highcharts.wrap,
|
35
|
+
noop = function () {};
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
/**
|
41
|
+
* The ColorAxis object for inclusion in gradient legends
|
42
|
+
*/
|
43
|
+
var ColorAxis = Highcharts.ColorAxis = function () {
|
44
|
+
this.isColorAxis = true;
|
45
|
+
this.init.apply(this, arguments);
|
46
|
+
};
|
47
|
+
extend(ColorAxis.prototype, Axis.prototype);
|
48
|
+
extend(ColorAxis.prototype, {
|
49
|
+
defaultColorAxisOptions: {
|
50
|
+
lineWidth: 0,
|
51
|
+
minPadding: 0,
|
52
|
+
maxPadding: 0,
|
53
|
+
gridLineWidth: 1,
|
54
|
+
tickPixelInterval: 72,
|
55
|
+
startOnTick: true,
|
56
|
+
endOnTick: true,
|
57
|
+
offset: 0,
|
58
|
+
marker: {
|
59
|
+
animation: {
|
60
|
+
duration: 50
|
61
|
+
},
|
62
|
+
color: 'gray',
|
63
|
+
width: 0.01
|
64
|
+
},
|
65
|
+
labels: {
|
66
|
+
overflow: 'justify'
|
67
|
+
},
|
68
|
+
minColor: '#EFEFFF',
|
69
|
+
maxColor: '#003875',
|
70
|
+
tickLength: 5
|
71
|
+
},
|
72
|
+
init: function (chart, userOptions) {
|
73
|
+
var horiz = chart.options.legend.layout !== 'vertical',
|
74
|
+
options;
|
75
|
+
|
76
|
+
// Build the options
|
77
|
+
options = merge(this.defaultColorAxisOptions, {
|
78
|
+
side: horiz ? 2 : 1,
|
79
|
+
reversed: !horiz
|
80
|
+
}, userOptions, {
|
81
|
+
opposite: !horiz,
|
82
|
+
showEmpty: false,
|
83
|
+
title: null,
|
84
|
+
isColor: true
|
85
|
+
});
|
86
|
+
|
87
|
+
Axis.prototype.init.call(this, chart, options);
|
88
|
+
|
89
|
+
// Base init() pushes it to the xAxis array, now pop it again
|
90
|
+
//chart[this.isXAxis ? 'xAxis' : 'yAxis'].pop();
|
91
|
+
|
92
|
+
// Prepare data classes
|
93
|
+
if (userOptions.dataClasses) {
|
94
|
+
this.initDataClasses(userOptions);
|
95
|
+
}
|
96
|
+
this.initStops(userOptions);
|
97
|
+
|
98
|
+
// Override original axis properties
|
99
|
+
this.horiz = horiz;
|
100
|
+
this.zoomEnabled = false;
|
101
|
+
},
|
102
|
+
|
103
|
+
/*
|
104
|
+
* Return an intermediate color between two colors, according to pos where 0
|
105
|
+
* is the from color and 1 is the to color.
|
106
|
+
* NOTE: Changes here should be copied
|
107
|
+
* to the same function in drilldown.src.js and solid-gauge-src.js.
|
108
|
+
*/
|
109
|
+
tweenColors: function (from, to, pos) {
|
110
|
+
// Check for has alpha, because rgba colors perform worse due to lack of
|
111
|
+
// support in WebKit.
|
112
|
+
var hasAlpha,
|
113
|
+
ret;
|
114
|
+
|
115
|
+
// Unsupported color, return to-color (#3920)
|
116
|
+
if (!to.rgba.length || !from.rgba.length) {
|
117
|
+
ret = to.input || 'none';
|
118
|
+
|
119
|
+
// Interpolate
|
120
|
+
} else {
|
121
|
+
from = from.rgba;
|
122
|
+
to = to.rgba;
|
123
|
+
hasAlpha = (to[3] !== 1 || from[3] !== 1);
|
124
|
+
ret = (hasAlpha ? 'rgba(' : 'rgb(') +
|
125
|
+
Math.round(to[0] + (from[0] - to[0]) * (1 - pos)) + ',' +
|
126
|
+
Math.round(to[1] + (from[1] - to[1]) * (1 - pos)) + ',' +
|
127
|
+
Math.round(to[2] + (from[2] - to[2]) * (1 - pos)) +
|
128
|
+
(hasAlpha ? (',' + (to[3] + (from[3] - to[3]) * (1 - pos))) : '') + ')';
|
129
|
+
}
|
130
|
+
return ret;
|
131
|
+
},
|
132
|
+
|
133
|
+
initDataClasses: function (userOptions) {
|
134
|
+
var axis = this,
|
135
|
+
chart = this.chart,
|
136
|
+
dataClasses,
|
137
|
+
colorCounter = 0,
|
138
|
+
options = this.options,
|
139
|
+
len = userOptions.dataClasses.length;
|
140
|
+
this.dataClasses = dataClasses = [];
|
141
|
+
this.legendItems = [];
|
142
|
+
|
143
|
+
each(userOptions.dataClasses, function (dataClass, i) {
|
144
|
+
var colors;
|
145
|
+
|
146
|
+
dataClass = merge(dataClass);
|
147
|
+
dataClasses.push(dataClass);
|
148
|
+
if (!dataClass.color) {
|
149
|
+
if (options.dataClassColor === 'category') {
|
150
|
+
colors = chart.options.colors;
|
151
|
+
dataClass.color = colors[colorCounter++];
|
152
|
+
// loop back to zero
|
153
|
+
if (colorCounter === colors.length) {
|
154
|
+
colorCounter = 0;
|
155
|
+
}
|
156
|
+
} else {
|
157
|
+
dataClass.color = axis.tweenColors(
|
158
|
+
Color(options.minColor),
|
159
|
+
Color(options.maxColor),
|
160
|
+
len < 2 ? 0.5 : i / (len - 1) // #3219
|
161
|
+
);
|
162
|
+
}
|
163
|
+
}
|
164
|
+
});
|
165
|
+
},
|
166
|
+
|
167
|
+
initStops: function (userOptions) {
|
168
|
+
this.stops = userOptions.stops || [
|
169
|
+
[0, this.options.minColor],
|
170
|
+
[1, this.options.maxColor]
|
171
|
+
];
|
172
|
+
each(this.stops, function (stop) {
|
173
|
+
stop.color = Color(stop[1]);
|
174
|
+
});
|
175
|
+
},
|
176
|
+
|
177
|
+
/**
|
178
|
+
* Extend the setOptions method to process extreme colors and color
|
179
|
+
* stops.
|
180
|
+
*/
|
181
|
+
setOptions: function (userOptions) {
|
182
|
+
Axis.prototype.setOptions.call(this, userOptions);
|
183
|
+
|
184
|
+
this.options.crosshair = this.options.marker;
|
185
|
+
this.coll = 'colorAxis';
|
186
|
+
},
|
187
|
+
|
188
|
+
setAxisSize: function () {
|
189
|
+
var symbol = this.legendSymbol,
|
190
|
+
chart = this.chart,
|
191
|
+
x,
|
192
|
+
y,
|
193
|
+
width,
|
194
|
+
height;
|
195
|
+
|
196
|
+
if (symbol) {
|
197
|
+
this.left = x = symbol.attr('x');
|
198
|
+
this.top = y = symbol.attr('y');
|
199
|
+
this.width = width = symbol.attr('width');
|
200
|
+
this.height = height = symbol.attr('height');
|
201
|
+
this.right = chart.chartWidth - x - width;
|
202
|
+
this.bottom = chart.chartHeight - y - height;
|
203
|
+
|
204
|
+
this.len = this.horiz ? width : height;
|
205
|
+
this.pos = this.horiz ? x : y;
|
206
|
+
}
|
207
|
+
},
|
208
|
+
|
209
|
+
/**
|
210
|
+
* Translate from a value to a color
|
211
|
+
*/
|
212
|
+
toColor: function (value, point) {
|
213
|
+
var pos,
|
214
|
+
stops = this.stops,
|
215
|
+
from,
|
216
|
+
to,
|
217
|
+
color,
|
218
|
+
dataClasses = this.dataClasses,
|
219
|
+
dataClass,
|
220
|
+
i;
|
221
|
+
|
222
|
+
if (dataClasses) {
|
223
|
+
i = dataClasses.length;
|
224
|
+
while (i--) {
|
225
|
+
dataClass = dataClasses[i];
|
226
|
+
from = dataClass.from;
|
227
|
+
to = dataClass.to;
|
228
|
+
if ((from === UNDEFINED || value >= from) && (to === UNDEFINED || value <= to)) {
|
229
|
+
color = dataClass.color;
|
230
|
+
if (point) {
|
231
|
+
point.dataClass = i;
|
232
|
+
}
|
233
|
+
break;
|
234
|
+
}
|
235
|
+
}
|
236
|
+
|
237
|
+
} else {
|
238
|
+
|
239
|
+
if (this.isLog) {
|
240
|
+
value = this.val2lin(value);
|
241
|
+
}
|
242
|
+
pos = 1 - ((this.max - value) / ((this.max - this.min) || 1));
|
243
|
+
i = stops.length;
|
244
|
+
while (i--) {
|
245
|
+
if (pos > stops[i][0]) {
|
246
|
+
break;
|
247
|
+
}
|
248
|
+
}
|
249
|
+
from = stops[i] || stops[i + 1];
|
250
|
+
to = stops[i + 1] || from;
|
251
|
+
|
252
|
+
// The position within the gradient
|
253
|
+
pos = 1 - (to[0] - pos) / ((to[0] - from[0]) || 1);
|
254
|
+
|
255
|
+
color = this.tweenColors(
|
256
|
+
from.color,
|
257
|
+
to.color,
|
258
|
+
pos
|
259
|
+
);
|
260
|
+
}
|
261
|
+
return color;
|
262
|
+
},
|
263
|
+
|
264
|
+
/**
|
265
|
+
* Override the getOffset method to add the whole axis groups inside the legend.
|
266
|
+
*/
|
267
|
+
getOffset: function () {
|
268
|
+
var group = this.legendGroup,
|
269
|
+
sideOffset = this.chart.axisOffset[this.side];
|
270
|
+
|
271
|
+
if (group) {
|
272
|
+
|
273
|
+
// Hook for the getOffset method to add groups to this parent group
|
274
|
+
this.axisParent = group;
|
275
|
+
|
276
|
+
// Call the base
|
277
|
+
Axis.prototype.getOffset.call(this);
|
278
|
+
|
279
|
+
// First time only
|
280
|
+
if (!this.added) {
|
281
|
+
|
282
|
+
this.added = true;
|
283
|
+
|
284
|
+
this.labelLeft = 0;
|
285
|
+
this.labelRight = this.width;
|
286
|
+
}
|
287
|
+
// Reset it to avoid color axis reserving space
|
288
|
+
this.chart.axisOffset[this.side] = sideOffset;
|
289
|
+
}
|
290
|
+
},
|
291
|
+
|
292
|
+
/**
|
293
|
+
* Create the color gradient
|
294
|
+
*/
|
295
|
+
setLegendColor: function () {
|
296
|
+
var grad,
|
297
|
+
horiz = this.horiz,
|
298
|
+
options = this.options,
|
299
|
+
reversed = this.reversed,
|
300
|
+
one = reversed ? 1 : 0,
|
301
|
+
zero = reversed ? 0 : 1;
|
302
|
+
|
303
|
+
grad = horiz ? [one, 0, zero, 0] : [0, zero, 0, one]; // #3190
|
304
|
+
this.legendColor = {
|
305
|
+
linearGradient: { x1: grad[0], y1: grad[1], x2: grad[2], y2: grad[3] },
|
306
|
+
stops: options.stops || [
|
307
|
+
[0, options.minColor],
|
308
|
+
[1, options.maxColor]
|
309
|
+
]
|
310
|
+
};
|
311
|
+
},
|
312
|
+
|
313
|
+
/**
|
314
|
+
* The color axis appears inside the legend and has its own legend symbol
|
315
|
+
*/
|
316
|
+
drawLegendSymbol: function (legend, item) {
|
317
|
+
var padding = legend.padding,
|
318
|
+
legendOptions = legend.options,
|
319
|
+
horiz = this.horiz,
|
320
|
+
width = pick(legendOptions.symbolWidth, horiz ? 200 : 12),
|
321
|
+
height = pick(legendOptions.symbolHeight, horiz ? 12 : 200),
|
322
|
+
labelPadding = pick(legendOptions.labelPadding, horiz ? 16 : 30),
|
323
|
+
itemDistance = pick(legendOptions.itemDistance, 10);
|
324
|
+
|
325
|
+
this.setLegendColor();
|
326
|
+
|
327
|
+
// Create the gradient
|
328
|
+
item.legendSymbol = this.chart.renderer.rect(
|
329
|
+
0,
|
330
|
+
legend.baseline - 11,
|
331
|
+
width,
|
332
|
+
height
|
333
|
+
).attr({
|
334
|
+
zIndex: 1
|
335
|
+
}).add(item.legendGroup);
|
336
|
+
|
337
|
+
// Set how much space this legend item takes up
|
338
|
+
this.legendItemWidth = width + padding + (horiz ? itemDistance : labelPadding);
|
339
|
+
this.legendItemHeight = height + padding + (horiz ? labelPadding : 0);
|
340
|
+
},
|
341
|
+
/**
|
342
|
+
* Fool the legend
|
343
|
+
*/
|
344
|
+
setState: noop,
|
345
|
+
visible: true,
|
346
|
+
setVisible: noop,
|
347
|
+
getSeriesExtremes: function () {
|
348
|
+
var series;
|
349
|
+
if (this.series.length) {
|
350
|
+
series = this.series[0];
|
351
|
+
this.dataMin = series.valueMin;
|
352
|
+
this.dataMax = series.valueMax;
|
353
|
+
}
|
354
|
+
},
|
355
|
+
drawCrosshair: function (e, point) {
|
356
|
+
var plotX = point && point.plotX,
|
357
|
+
plotY = point && point.plotY,
|
358
|
+
crossPos,
|
359
|
+
axisPos = this.pos,
|
360
|
+
axisLen = this.len;
|
361
|
+
|
362
|
+
if (point) {
|
363
|
+
crossPos = this.toPixels(point[point.series.colorKey]);
|
364
|
+
if (crossPos < axisPos) {
|
365
|
+
crossPos = axisPos - 2;
|
366
|
+
} else if (crossPos > axisPos + axisLen) {
|
367
|
+
crossPos = axisPos + axisLen + 2;
|
368
|
+
}
|
369
|
+
|
370
|
+
point.plotX = crossPos;
|
371
|
+
point.plotY = this.len - crossPos;
|
372
|
+
Axis.prototype.drawCrosshair.call(this, e, point);
|
373
|
+
point.plotX = plotX;
|
374
|
+
point.plotY = plotY;
|
375
|
+
|
376
|
+
if (this.cross) {
|
377
|
+
this.cross
|
378
|
+
.attr({
|
379
|
+
fill: this.crosshair.color
|
380
|
+
})
|
381
|
+
.add(this.legendGroup);
|
382
|
+
}
|
383
|
+
}
|
384
|
+
},
|
385
|
+
getPlotLinePath: function (a, b, c, d, pos) {
|
386
|
+
return typeof pos === 'number' ? // crosshairs only // #3969 pos can be 0 !!
|
387
|
+
(this.horiz ?
|
388
|
+
['M', pos - 4, this.top - 6, 'L', pos + 4, this.top - 6, pos, this.top, 'Z'] :
|
389
|
+
['M', this.left, pos, 'L', this.left - 6, pos + 6, this.left - 6, pos - 6, 'Z']
|
390
|
+
) :
|
391
|
+
Axis.prototype.getPlotLinePath.call(this, a, b, c, d);
|
392
|
+
},
|
393
|
+
|
394
|
+
update: function (newOptions, redraw) {
|
395
|
+
var chart = this.chart,
|
396
|
+
legend = chart.legend;
|
397
|
+
|
398
|
+
each(this.series, function (series) {
|
399
|
+
series.isDirtyData = true; // Needed for Axis.update when choropleth colors change
|
400
|
+
});
|
401
|
+
|
402
|
+
// When updating data classes, destroy old items and make sure new ones are created (#3207)
|
403
|
+
if (newOptions.dataClasses && legend.allItems) {
|
404
|
+
each(legend.allItems, function (item) {
|
405
|
+
if (item.isDataClass) {
|
406
|
+
item.legendGroup.destroy();
|
407
|
+
}
|
408
|
+
});
|
409
|
+
chart.isDirtyLegend = true;
|
410
|
+
}
|
411
|
+
|
412
|
+
// Keep the options structure updated for export. Unlike xAxis and yAxis, the colorAxis is
|
413
|
+
// not an array. (#3207)
|
414
|
+
chart.options[this.coll] = merge(this.userOptions, newOptions);
|
415
|
+
|
416
|
+
Axis.prototype.update.call(this, newOptions, redraw);
|
417
|
+
if (this.legendItem) {
|
418
|
+
this.setLegendColor();
|
419
|
+
legend.colorizeItem(this, true);
|
420
|
+
}
|
421
|
+
},
|
422
|
+
|
423
|
+
/**
|
424
|
+
* Get the legend item symbols for data classes
|
425
|
+
*/
|
426
|
+
getDataClassLegendSymbols: function () {
|
427
|
+
var axis = this,
|
428
|
+
chart = this.chart,
|
429
|
+
legendItems = this.legendItems,
|
430
|
+
legendOptions = chart.options.legend,
|
431
|
+
valueDecimals = legendOptions.valueDecimals,
|
432
|
+
valueSuffix = legendOptions.valueSuffix || '',
|
433
|
+
name;
|
434
|
+
|
435
|
+
if (!legendItems.length) {
|
436
|
+
each(this.dataClasses, function (dataClass, i) {
|
437
|
+
var vis = true,
|
438
|
+
from = dataClass.from,
|
439
|
+
to = dataClass.to;
|
440
|
+
|
441
|
+
// Assemble the default name. This can be overridden by legend.options.labelFormatter
|
442
|
+
name = '';
|
443
|
+
if (from === UNDEFINED) {
|
444
|
+
name = '< ';
|
445
|
+
} else if (to === UNDEFINED) {
|
446
|
+
name = '> ';
|
447
|
+
}
|
448
|
+
if (from !== UNDEFINED) {
|
449
|
+
name += Highcharts.numberFormat(from, valueDecimals) + valueSuffix;
|
450
|
+
}
|
451
|
+
if (from !== UNDEFINED && to !== UNDEFINED) {
|
452
|
+
name += ' - ';
|
453
|
+
}
|
454
|
+
if (to !== UNDEFINED) {
|
455
|
+
name += Highcharts.numberFormat(to, valueDecimals) + valueSuffix;
|
456
|
+
}
|
457
|
+
|
458
|
+
// Add a mock object to the legend items
|
459
|
+
legendItems.push(extend({
|
460
|
+
chart: chart,
|
461
|
+
name: name,
|
462
|
+
options: {},
|
463
|
+
drawLegendSymbol: LegendSymbolMixin.drawRectangle,
|
464
|
+
visible: true,
|
465
|
+
setState: noop,
|
466
|
+
isDataClass: true,
|
467
|
+
setVisible: function () {
|
468
|
+
vis = this.visible = !vis;
|
469
|
+
each(axis.series, function (series) {
|
470
|
+
each(series.points, function (point) {
|
471
|
+
if (point.dataClass === i) {
|
472
|
+
point.setVisible(vis);
|
473
|
+
}
|
474
|
+
});
|
475
|
+
});
|
476
|
+
|
477
|
+
chart.legend.colorizeItem(this, vis);
|
478
|
+
}
|
479
|
+
}, dataClass));
|
480
|
+
});
|
481
|
+
}
|
482
|
+
return legendItems;
|
483
|
+
},
|
484
|
+
name: '' // Prevents 'undefined' in legend in IE8
|
485
|
+
});
|
486
|
+
|
487
|
+
/**
|
488
|
+
* Handle animation of the color attributes directly
|
489
|
+
*/
|
490
|
+
each(['fill', 'stroke'], function (prop) {
|
491
|
+
Highcharts.addAnimSetter(prop, function (fx) {
|
492
|
+
fx.elem.attr(prop, ColorAxis.prototype.tweenColors(Color(fx.start), Color(fx.end), fx.pos));
|
493
|
+
});
|
494
|
+
});
|
495
|
+
|
496
|
+
/**
|
497
|
+
* Extend the chart getAxes method to also get the color axis
|
498
|
+
*/
|
499
|
+
wrap(Chart.prototype, 'getAxes', function (proceed) {
|
500
|
+
|
501
|
+
var options = this.options,
|
502
|
+
colorAxisOptions = options.colorAxis;
|
503
|
+
|
504
|
+
proceed.call(this);
|
505
|
+
|
506
|
+
this.colorAxis = [];
|
507
|
+
if (colorAxisOptions) {
|
508
|
+
new ColorAxis(this, colorAxisOptions); // eslint-disable-line no-new
|
509
|
+
}
|
510
|
+
});
|
511
|
+
|
512
|
+
|
513
|
+
/**
|
514
|
+
* Wrap the legend getAllItems method to add the color axis. This also removes the
|
515
|
+
* axis' own series to prevent them from showing up individually.
|
516
|
+
*/
|
517
|
+
wrap(Legend.prototype, 'getAllItems', function (proceed) {
|
518
|
+
var allItems = [],
|
519
|
+
colorAxis = this.chart.colorAxis[0];
|
520
|
+
|
521
|
+
if (colorAxis) {
|
522
|
+
|
523
|
+
// Data classes
|
524
|
+
if (colorAxis.options.dataClasses) {
|
525
|
+
allItems = allItems.concat(colorAxis.getDataClassLegendSymbols());
|
526
|
+
// Gradient legend
|
527
|
+
} else {
|
528
|
+
// Add this axis on top
|
529
|
+
allItems.push(colorAxis);
|
530
|
+
}
|
531
|
+
|
532
|
+
// Don't add the color axis' series
|
533
|
+
each(colorAxis.series, function (series) {
|
534
|
+
series.options.showInLegend = false;
|
535
|
+
});
|
536
|
+
}
|
537
|
+
|
538
|
+
return allItems.concat(proceed.call(this));
|
539
|
+
});
|
540
|
+
/**
|
541
|
+
* Mixin for maps and heatmaps
|
542
|
+
*/
|
543
|
+
var colorPointMixin = {
|
544
|
+
/**
|
545
|
+
* Set the visibility of a single point
|
546
|
+
*/
|
547
|
+
setVisible: function (vis) {
|
548
|
+
var point = this,
|
549
|
+
method = vis ? 'show' : 'hide';
|
550
|
+
|
551
|
+
// Show and hide associated elements
|
552
|
+
each(['graphic', 'dataLabel'], function (key) {
|
553
|
+
if (point[key]) {
|
554
|
+
point[key][method]();
|
555
|
+
}
|
556
|
+
});
|
557
|
+
}
|
558
|
+
};
|
559
|
+
var colorSeriesMixin = {
|
560
|
+
|
561
|
+
pointAttrToOptions: { // mapping between SVG attributes and the corresponding options
|
562
|
+
stroke: 'borderColor',
|
563
|
+
'stroke-width': 'borderWidth',
|
564
|
+
fill: 'color',
|
565
|
+
dashstyle: 'dashStyle'
|
566
|
+
},
|
567
|
+
pointArrayMap: ['value'],
|
568
|
+
axisTypes: ['xAxis', 'yAxis', 'colorAxis'],
|
569
|
+
optionalAxis: 'colorAxis',
|
570
|
+
trackerGroups: ['group', 'markerGroup', 'dataLabelsGroup'],
|
571
|
+
getSymbol: noop,
|
572
|
+
parallelArrays: ['x', 'y', 'value'],
|
573
|
+
colorKey: 'value',
|
574
|
+
|
575
|
+
/**
|
576
|
+
* In choropleth maps, the color is a result of the value, so this needs translation too
|
577
|
+
*/
|
578
|
+
translateColors: function () {
|
579
|
+
var series = this,
|
580
|
+
nullColor = this.options.nullColor,
|
581
|
+
colorAxis = this.colorAxis,
|
582
|
+
colorKey = this.colorKey;
|
583
|
+
|
584
|
+
each(this.data, function (point) {
|
585
|
+
var value = point[colorKey],
|
586
|
+
color;
|
587
|
+
|
588
|
+
color = point.options.color ||
|
589
|
+
(value === null ? nullColor : (colorAxis && value !== undefined) ? colorAxis.toColor(value, point) : point.color || series.color);
|
590
|
+
|
591
|
+
if (color) {
|
592
|
+
point.color = color;
|
593
|
+
}
|
594
|
+
});
|
595
|
+
}
|
596
|
+
};
|
597
|
+
|
598
|
+
/**
|
599
|
+
* Extend the default options with map options
|
600
|
+
*/
|
601
|
+
defaultOptions.plotOptions.heatmap = merge(defaultOptions.plotOptions.scatter, {
|
602
|
+
animation: false,
|
603
|
+
borderWidth: 0,
|
604
|
+
nullColor: '#F8F8F8',
|
605
|
+
dataLabels: {
|
606
|
+
formatter: function () { // #2945
|
607
|
+
return this.point.value;
|
608
|
+
},
|
609
|
+
inside: true,
|
610
|
+
verticalAlign: 'middle',
|
611
|
+
crop: false,
|
612
|
+
overflow: false,
|
613
|
+
padding: 0 // #3837
|
614
|
+
},
|
615
|
+
marker: null,
|
616
|
+
pointRange: null, // dynamically set to colsize by default
|
617
|
+
tooltip: {
|
618
|
+
pointFormat: '{point.x}, {point.y}: {point.value}<br/>'
|
619
|
+
},
|
620
|
+
states: {
|
621
|
+
normal: {
|
622
|
+
animation: true
|
623
|
+
},
|
624
|
+
hover: {
|
625
|
+
halo: false, // #3406, halo is not required on heatmaps
|
626
|
+
brightness: 0.2
|
627
|
+
}
|
628
|
+
}
|
629
|
+
});
|
630
|
+
|
631
|
+
// The Heatmap series type
|
632
|
+
seriesTypes.heatmap = extendClass(seriesTypes.scatter, merge(colorSeriesMixin, {
|
633
|
+
type: 'heatmap',
|
634
|
+
pointArrayMap: ['y', 'value'],
|
635
|
+
hasPointSpecificOptions: true,
|
636
|
+
pointClass: extendClass(Point, colorPointMixin),
|
637
|
+
supportsDrilldown: true,
|
638
|
+
getExtremesFromAll: true,
|
639
|
+
directTouch: true,
|
640
|
+
|
641
|
+
/**
|
642
|
+
* Override the init method to add point ranges on both axes.
|
643
|
+
*/
|
644
|
+
init: function () {
|
645
|
+
var options;
|
646
|
+
seriesTypes.scatter.prototype.init.apply(this, arguments);
|
647
|
+
|
648
|
+
options = this.options;
|
649
|
+
options.pointRange = pick(options.pointRange, options.colsize || 1); // #3758, prevent resetting in setData
|
650
|
+
this.yAxis.axisPointRange = options.rowsize || 1; // general point range
|
651
|
+
},
|
652
|
+
translate: function () {
|
653
|
+
var series = this,
|
654
|
+
options = series.options,
|
655
|
+
xAxis = series.xAxis,
|
656
|
+
yAxis = series.yAxis,
|
657
|
+
between = function (x, a, b) {
|
658
|
+
return Math.min(Math.max(a, x), b);
|
659
|
+
};
|
660
|
+
|
661
|
+
series.generatePoints();
|
662
|
+
|
663
|
+
each(series.points, function (point) {
|
664
|
+
var xPad = (options.colsize || 1) / 2,
|
665
|
+
yPad = (options.rowsize || 1) / 2,
|
666
|
+
x1 = between(Math.round(xAxis.len - xAxis.translate(point.x - xPad, 0, 1, 0, 1)), 0, xAxis.len),
|
667
|
+
x2 = between(Math.round(xAxis.len - xAxis.translate(point.x + xPad, 0, 1, 0, 1)), 0, xAxis.len),
|
668
|
+
y1 = between(Math.round(yAxis.translate(point.y - yPad, 0, 1, 0, 1)), 0, yAxis.len),
|
669
|
+
y2 = between(Math.round(yAxis.translate(point.y + yPad, 0, 1, 0, 1)), 0, yAxis.len);
|
670
|
+
|
671
|
+
// Set plotX and plotY for use in K-D-Tree and more
|
672
|
+
point.plotX = point.clientX = (x1 + x2) / 2;
|
673
|
+
point.plotY = (y1 + y2) / 2;
|
674
|
+
|
675
|
+
point.shapeType = 'rect';
|
676
|
+
point.shapeArgs = {
|
677
|
+
x: Math.min(x1, x2),
|
678
|
+
y: Math.min(y1, y2),
|
679
|
+
width: Math.abs(x2 - x1),
|
680
|
+
height: Math.abs(y2 - y1)
|
681
|
+
};
|
682
|
+
});
|
683
|
+
|
684
|
+
series.translateColors();
|
685
|
+
|
686
|
+
// Make sure colors are updated on colorAxis update (#2893)
|
687
|
+
if (this.chart.hasRendered) {
|
688
|
+
each(series.points, function (point) {
|
689
|
+
point.shapeArgs.fill = point.options.color || point.color; // #3311
|
690
|
+
});
|
691
|
+
}
|
692
|
+
},
|
693
|
+
drawPoints: seriesTypes.column.prototype.drawPoints,
|
694
|
+
animate: noop,
|
695
|
+
getBox: noop,
|
696
|
+
drawLegendSymbol: LegendSymbolMixin.drawRectangle,
|
697
|
+
|
698
|
+
getExtremes: function () {
|
699
|
+
// Get the extremes from the value data
|
700
|
+
Series.prototype.getExtremes.call(this, this.valueData);
|
701
|
+
this.valueMin = this.dataMin;
|
702
|
+
this.valueMax = this.dataMax;
|
703
|
+
|
704
|
+
// Get the extremes from the y data
|
705
|
+
Series.prototype.getExtremes.call(this);
|
706
|
+
}
|
707
|
+
|
708
|
+
}));
|
8
709
|
|
9
|
-
/*global HighchartsAdapter*/
|
10
|
-
(function (Highcharts) {
|
11
710
|
|
12
|
-
|
13
|
-
var UNDEFINED,
|
14
|
-
Axis = Highcharts.Axis,
|
15
|
-
Chart = Highcharts.Chart,
|
16
|
-
Color = Highcharts.Color,
|
17
|
-
Legend = Highcharts.Legend,
|
18
|
-
LegendSymbolMixin = Highcharts.LegendSymbolMixin,
|
19
|
-
Series = Highcharts.Series,
|
20
|
-
Point = Highcharts.Point,
|
21
|
-
|
22
|
-
defaultOptions = Highcharts.getOptions(),
|
23
|
-
each = Highcharts.each,
|
24
|
-
extend = Highcharts.extend,
|
25
|
-
extendClass = Highcharts.extendClass,
|
26
|
-
merge = Highcharts.merge,
|
27
|
-
pick = Highcharts.pick,
|
28
|
-
seriesTypes = Highcharts.seriesTypes,
|
29
|
-
wrap = Highcharts.wrap,
|
30
|
-
noop = function () {};
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
/**
|
36
|
-
* The ColorAxis object for inclusion in gradient legends
|
37
|
-
*/
|
38
|
-
var ColorAxis = Highcharts.ColorAxis = function () {
|
39
|
-
this.isColorAxis = true;
|
40
|
-
this.init.apply(this, arguments);
|
41
|
-
};
|
42
|
-
extend(ColorAxis.prototype, Axis.prototype);
|
43
|
-
extend(ColorAxis.prototype, {
|
44
|
-
defaultColorAxisOptions: {
|
45
|
-
lineWidth: 0,
|
46
|
-
minPadding: 0,
|
47
|
-
maxPadding: 0,
|
48
|
-
gridLineWidth: 1,
|
49
|
-
tickPixelInterval: 72,
|
50
|
-
startOnTick: true,
|
51
|
-
endOnTick: true,
|
52
|
-
offset: 0,
|
53
|
-
marker: {
|
54
|
-
animation: {
|
55
|
-
duration: 50
|
56
|
-
},
|
57
|
-
color: 'gray',
|
58
|
-
width: 0.01
|
59
|
-
},
|
60
|
-
labels: {
|
61
|
-
overflow: 'justify'
|
62
|
-
},
|
63
|
-
minColor: '#EFEFFF',
|
64
|
-
maxColor: '#003875',
|
65
|
-
tickLength: 5
|
66
|
-
},
|
67
|
-
init: function (chart, userOptions) {
|
68
|
-
var horiz = chart.options.legend.layout !== 'vertical',
|
69
|
-
options;
|
70
|
-
|
71
|
-
// Build the options
|
72
|
-
options = merge(this.defaultColorAxisOptions, {
|
73
|
-
side: horiz ? 2 : 1,
|
74
|
-
reversed: !horiz
|
75
|
-
}, userOptions, {
|
76
|
-
opposite: !horiz,
|
77
|
-
showEmpty: false,
|
78
|
-
title: null,
|
79
|
-
isColor: true
|
80
|
-
});
|
81
|
-
|
82
|
-
Axis.prototype.init.call(this, chart, options);
|
83
|
-
|
84
|
-
// Base init() pushes it to the xAxis array, now pop it again
|
85
|
-
//chart[this.isXAxis ? 'xAxis' : 'yAxis'].pop();
|
86
|
-
|
87
|
-
// Prepare data classes
|
88
|
-
if (userOptions.dataClasses) {
|
89
|
-
this.initDataClasses(userOptions);
|
90
|
-
}
|
91
|
-
this.initStops(userOptions);
|
92
|
-
|
93
|
-
// Override original axis properties
|
94
|
-
this.horiz = horiz;
|
95
|
-
this.zoomEnabled = false;
|
96
|
-
},
|
97
|
-
|
98
|
-
/*
|
99
|
-
* Return an intermediate color between two colors, according to pos where 0
|
100
|
-
* is the from color and 1 is the to color.
|
101
|
-
* NOTE: Changes here should be copied
|
102
|
-
* to the same function in drilldown.src.js and solid-gauge-src.js.
|
103
|
-
*/
|
104
|
-
tweenColors: function (from, to, pos) {
|
105
|
-
// Check for has alpha, because rgba colors perform worse due to lack of
|
106
|
-
// support in WebKit.
|
107
|
-
var hasAlpha,
|
108
|
-
ret;
|
109
|
-
|
110
|
-
// Unsupported color, return to-color (#3920)
|
111
|
-
if (!to.rgba.length || !from.rgba.length) {
|
112
|
-
ret = to.raw || 'none';
|
113
|
-
|
114
|
-
// Interpolate
|
115
|
-
} else {
|
116
|
-
from = from.rgba;
|
117
|
-
to = to.rgba;
|
118
|
-
hasAlpha = (to[3] !== 1 || from[3] !== 1);
|
119
|
-
ret = (hasAlpha ? 'rgba(' : 'rgb(') +
|
120
|
-
Math.round(to[0] + (from[0] - to[0]) * (1 - pos)) + ',' +
|
121
|
-
Math.round(to[1] + (from[1] - to[1]) * (1 - pos)) + ',' +
|
122
|
-
Math.round(to[2] + (from[2] - to[2]) * (1 - pos)) +
|
123
|
-
(hasAlpha ? (',' + (to[3] + (from[3] - to[3]) * (1 - pos))) : '') + ')';
|
124
|
-
}
|
125
|
-
return ret;
|
126
|
-
},
|
127
|
-
|
128
|
-
initDataClasses: function (userOptions) {
|
129
|
-
var axis = this,
|
130
|
-
chart = this.chart,
|
131
|
-
dataClasses,
|
132
|
-
colorCounter = 0,
|
133
|
-
options = this.options,
|
134
|
-
len = userOptions.dataClasses.length;
|
135
|
-
this.dataClasses = dataClasses = [];
|
136
|
-
this.legendItems = [];
|
137
|
-
|
138
|
-
each(userOptions.dataClasses, function (dataClass, i) {
|
139
|
-
var colors;
|
140
|
-
|
141
|
-
dataClass = merge(dataClass);
|
142
|
-
dataClasses.push(dataClass);
|
143
|
-
if (!dataClass.color) {
|
144
|
-
if (options.dataClassColor === 'category') {
|
145
|
-
colors = chart.options.colors;
|
146
|
-
dataClass.color = colors[colorCounter++];
|
147
|
-
// loop back to zero
|
148
|
-
if (colorCounter === colors.length) {
|
149
|
-
colorCounter = 0;
|
150
|
-
}
|
151
|
-
} else {
|
152
|
-
dataClass.color = axis.tweenColors(
|
153
|
-
Color(options.minColor),
|
154
|
-
Color(options.maxColor),
|
155
|
-
len < 2 ? 0.5 : i / (len - 1) // #3219
|
156
|
-
);
|
157
|
-
}
|
158
|
-
}
|
159
|
-
});
|
160
|
-
},
|
161
|
-
|
162
|
-
initStops: function (userOptions) {
|
163
|
-
this.stops = userOptions.stops || [
|
164
|
-
[0, this.options.minColor],
|
165
|
-
[1, this.options.maxColor]
|
166
|
-
];
|
167
|
-
each(this.stops, function (stop) {
|
168
|
-
stop.color = Color(stop[1]);
|
169
|
-
});
|
170
|
-
},
|
171
|
-
|
172
|
-
/**
|
173
|
-
* Extend the setOptions method to process extreme colors and color
|
174
|
-
* stops.
|
175
|
-
*/
|
176
|
-
setOptions: function (userOptions) {
|
177
|
-
Axis.prototype.setOptions.call(this, userOptions);
|
178
|
-
|
179
|
-
this.options.crosshair = this.options.marker;
|
180
|
-
this.coll = 'colorAxis';
|
181
|
-
},
|
182
|
-
|
183
|
-
setAxisSize: function () {
|
184
|
-
var symbol = this.legendSymbol,
|
185
|
-
chart = this.chart,
|
186
|
-
x,
|
187
|
-
y,
|
188
|
-
width,
|
189
|
-
height;
|
190
|
-
|
191
|
-
if (symbol) {
|
192
|
-
this.left = x = symbol.attr('x');
|
193
|
-
this.top = y = symbol.attr('y');
|
194
|
-
this.width = width = symbol.attr('width');
|
195
|
-
this.height = height = symbol.attr('height');
|
196
|
-
this.right = chart.chartWidth - x - width;
|
197
|
-
this.bottom = chart.chartHeight - y - height;
|
198
|
-
|
199
|
-
this.len = this.horiz ? width : height;
|
200
|
-
this.pos = this.horiz ? x : y;
|
201
|
-
}
|
202
|
-
},
|
203
|
-
|
204
|
-
/**
|
205
|
-
* Translate from a value to a color
|
206
|
-
*/
|
207
|
-
toColor: function (value, point) {
|
208
|
-
var pos,
|
209
|
-
stops = this.stops,
|
210
|
-
from,
|
211
|
-
to,
|
212
|
-
color,
|
213
|
-
dataClasses = this.dataClasses,
|
214
|
-
dataClass,
|
215
|
-
i;
|
216
|
-
|
217
|
-
if (dataClasses) {
|
218
|
-
i = dataClasses.length;
|
219
|
-
while (i--) {
|
220
|
-
dataClass = dataClasses[i];
|
221
|
-
from = dataClass.from;
|
222
|
-
to = dataClass.to;
|
223
|
-
if ((from === UNDEFINED || value >= from) && (to === UNDEFINED || value <= to)) {
|
224
|
-
color = dataClass.color;
|
225
|
-
if (point) {
|
226
|
-
point.dataClass = i;
|
227
|
-
}
|
228
|
-
break;
|
229
|
-
}
|
230
|
-
}
|
231
|
-
|
232
|
-
} else {
|
233
|
-
|
234
|
-
if (this.isLog) {
|
235
|
-
value = this.val2lin(value);
|
236
|
-
}
|
237
|
-
pos = 1 - ((this.max - value) / ((this.max - this.min) || 1));
|
238
|
-
i = stops.length;
|
239
|
-
while (i--) {
|
240
|
-
if (pos > stops[i][0]) {
|
241
|
-
break;
|
242
|
-
}
|
243
|
-
}
|
244
|
-
from = stops[i] || stops[i + 1];
|
245
|
-
to = stops[i + 1] || from;
|
246
|
-
|
247
|
-
// The position within the gradient
|
248
|
-
pos = 1 - (to[0] - pos) / ((to[0] - from[0]) || 1);
|
249
|
-
|
250
|
-
color = this.tweenColors(
|
251
|
-
from.color,
|
252
|
-
to.color,
|
253
|
-
pos
|
254
|
-
);
|
255
|
-
}
|
256
|
-
return color;
|
257
|
-
},
|
258
|
-
|
259
|
-
/**
|
260
|
-
* Override the getOffset method to add the whole axis groups inside the legend.
|
261
|
-
*/
|
262
|
-
getOffset: function () {
|
263
|
-
var group = this.legendGroup,
|
264
|
-
sideOffset = this.chart.axisOffset[this.side];
|
265
|
-
|
266
|
-
if (group) {
|
267
|
-
|
268
|
-
// Hook for the getOffset method to add groups to this parent group
|
269
|
-
this.axisParent = group;
|
270
|
-
|
271
|
-
// Call the base
|
272
|
-
Axis.prototype.getOffset.call(this);
|
273
|
-
|
274
|
-
// First time only
|
275
|
-
if (!this.added) {
|
276
|
-
|
277
|
-
this.added = true;
|
278
|
-
|
279
|
-
this.labelLeft = 0;
|
280
|
-
this.labelRight = this.width;
|
281
|
-
}
|
282
|
-
// Reset it to avoid color axis reserving space
|
283
|
-
this.chart.axisOffset[this.side] = sideOffset;
|
284
|
-
}
|
285
|
-
},
|
286
|
-
|
287
|
-
/**
|
288
|
-
* Create the color gradient
|
289
|
-
*/
|
290
|
-
setLegendColor: function () {
|
291
|
-
var grad,
|
292
|
-
horiz = this.horiz,
|
293
|
-
options = this.options,
|
294
|
-
reversed = this.reversed;
|
295
|
-
|
296
|
-
grad = horiz ? [+reversed, 0, +!reversed, 0] : [0, +!reversed, 0, +reversed]; // #3190
|
297
|
-
this.legendColor = {
|
298
|
-
linearGradient: { x1: grad[0], y1: grad[1], x2: grad[2], y2: grad[3] },
|
299
|
-
stops: options.stops || [
|
300
|
-
[0, options.minColor],
|
301
|
-
[1, options.maxColor]
|
302
|
-
]
|
303
|
-
};
|
304
|
-
},
|
305
|
-
|
306
|
-
/**
|
307
|
-
* The color axis appears inside the legend and has its own legend symbol
|
308
|
-
*/
|
309
|
-
drawLegendSymbol: function (legend, item) {
|
310
|
-
var padding = legend.padding,
|
311
|
-
legendOptions = legend.options,
|
312
|
-
horiz = this.horiz,
|
313
|
-
box,
|
314
|
-
width = pick(legendOptions.symbolWidth, horiz ? 200 : 12),
|
315
|
-
height = pick(legendOptions.symbolHeight, horiz ? 12 : 200),
|
316
|
-
labelPadding = pick(legendOptions.labelPadding, horiz ? 16 : 30),
|
317
|
-
itemDistance = pick(legendOptions.itemDistance, 10);
|
318
|
-
|
319
|
-
this.setLegendColor();
|
320
|
-
|
321
|
-
// Create the gradient
|
322
|
-
item.legendSymbol = this.chart.renderer.rect(
|
323
|
-
0,
|
324
|
-
legend.baseline - 11,
|
325
|
-
width,
|
326
|
-
height
|
327
|
-
).attr({
|
328
|
-
zIndex: 1
|
329
|
-
}).add(item.legendGroup);
|
330
|
-
box = item.legendSymbol.getBBox();
|
331
|
-
|
332
|
-
// Set how much space this legend item takes up
|
333
|
-
this.legendItemWidth = width + padding + (horiz ? itemDistance : labelPadding);
|
334
|
-
this.legendItemHeight = height + padding + (horiz ? labelPadding : 0);
|
335
|
-
},
|
336
|
-
/**
|
337
|
-
* Fool the legend
|
338
|
-
*/
|
339
|
-
setState: noop,
|
340
|
-
visible: true,
|
341
|
-
setVisible: noop,
|
342
|
-
getSeriesExtremes: function () {
|
343
|
-
var series;
|
344
|
-
if (this.series.length) {
|
345
|
-
series = this.series[0];
|
346
|
-
this.dataMin = series.valueMin;
|
347
|
-
this.dataMax = series.valueMax;
|
348
|
-
}
|
349
|
-
},
|
350
|
-
drawCrosshair: function (e, point) {
|
351
|
-
var plotX = point && point.plotX,
|
352
|
-
plotY = point && point.plotY,
|
353
|
-
crossPos,
|
354
|
-
axisPos = this.pos,
|
355
|
-
axisLen = this.len;
|
356
|
-
|
357
|
-
if (point) {
|
358
|
-
crossPos = this.toPixels(point[point.series.colorKey]);
|
359
|
-
if (crossPos < axisPos) {
|
360
|
-
crossPos = axisPos - 2;
|
361
|
-
} else if (crossPos > axisPos + axisLen) {
|
362
|
-
crossPos = axisPos + axisLen + 2;
|
363
|
-
}
|
364
|
-
|
365
|
-
point.plotX = crossPos;
|
366
|
-
point.plotY = this.len - crossPos;
|
367
|
-
Axis.prototype.drawCrosshair.call(this, e, point);
|
368
|
-
point.plotX = plotX;
|
369
|
-
point.plotY = plotY;
|
370
|
-
|
371
|
-
if (this.cross) {
|
372
|
-
this.cross
|
373
|
-
.attr({
|
374
|
-
fill: this.crosshair.color
|
375
|
-
})
|
376
|
-
.add(this.legendGroup);
|
377
|
-
}
|
378
|
-
}
|
379
|
-
},
|
380
|
-
getPlotLinePath: function (a, b, c, d, pos) {
|
381
|
-
if (typeof pos === 'number') { // crosshairs only // #3969 pos can be 0 !!
|
382
|
-
return this.horiz ?
|
383
|
-
['M', pos - 4, this.top - 6, 'L', pos + 4, this.top - 6, pos, this.top, 'Z'] :
|
384
|
-
['M', this.left, pos, 'L', this.left - 6, pos + 6, this.left - 6, pos - 6, 'Z'];
|
385
|
-
} else {
|
386
|
-
return Axis.prototype.getPlotLinePath.call(this, a, b, c, d);
|
387
|
-
}
|
388
|
-
},
|
389
|
-
|
390
|
-
update: function (newOptions, redraw) {
|
391
|
-
var chart = this.chart,
|
392
|
-
legend = chart.legend;
|
393
|
-
|
394
|
-
each(this.series, function (series) {
|
395
|
-
series.isDirtyData = true; // Needed for Axis.update when choropleth colors change
|
396
|
-
});
|
397
|
-
|
398
|
-
// When updating data classes, destroy old items and make sure new ones are created (#3207)
|
399
|
-
if (newOptions.dataClasses && legend.allItems) {
|
400
|
-
each(legend.allItems, function (item) {
|
401
|
-
if (item.isDataClass) {
|
402
|
-
item.legendGroup.destroy();
|
403
|
-
}
|
404
|
-
});
|
405
|
-
chart.isDirtyLegend = true;
|
406
|
-
}
|
407
|
-
|
408
|
-
// Keep the options structure updated for export. Unlike xAxis and yAxis, the colorAxis is
|
409
|
-
// not an array. (#3207)
|
410
|
-
chart.options[this.coll] = merge(this.userOptions, newOptions);
|
411
|
-
|
412
|
-
Axis.prototype.update.call(this, newOptions, redraw);
|
413
|
-
if (this.legendItem) {
|
414
|
-
this.setLegendColor();
|
415
|
-
legend.colorizeItem(this, true);
|
416
|
-
}
|
417
|
-
},
|
418
|
-
|
419
|
-
/**
|
420
|
-
* Get the legend item symbols for data classes
|
421
|
-
*/
|
422
|
-
getDataClassLegendSymbols: function () {
|
423
|
-
var axis = this,
|
424
|
-
chart = this.chart,
|
425
|
-
legendItems = this.legendItems,
|
426
|
-
legendOptions = chart.options.legend,
|
427
|
-
valueDecimals = legendOptions.valueDecimals,
|
428
|
-
valueSuffix = legendOptions.valueSuffix || '',
|
429
|
-
name;
|
430
|
-
|
431
|
-
if (!legendItems.length) {
|
432
|
-
each(this.dataClasses, function (dataClass, i) {
|
433
|
-
var vis = true,
|
434
|
-
from = dataClass.from,
|
435
|
-
to = dataClass.to;
|
436
|
-
|
437
|
-
// Assemble the default name. This can be overridden by legend.options.labelFormatter
|
438
|
-
name = '';
|
439
|
-
if (from === UNDEFINED) {
|
440
|
-
name = '< ';
|
441
|
-
} else if (to === UNDEFINED) {
|
442
|
-
name = '> ';
|
443
|
-
}
|
444
|
-
if (from !== UNDEFINED) {
|
445
|
-
name += Highcharts.numberFormat(from, valueDecimals) + valueSuffix;
|
446
|
-
}
|
447
|
-
if (from !== UNDEFINED && to !== UNDEFINED) {
|
448
|
-
name += ' - ';
|
449
|
-
}
|
450
|
-
if (to !== UNDEFINED) {
|
451
|
-
name += Highcharts.numberFormat(to, valueDecimals) + valueSuffix;
|
452
|
-
}
|
453
|
-
|
454
|
-
// Add a mock object to the legend items
|
455
|
-
legendItems.push(extend({
|
456
|
-
chart: chart,
|
457
|
-
name: name,
|
458
|
-
options: {},
|
459
|
-
drawLegendSymbol: LegendSymbolMixin.drawRectangle,
|
460
|
-
visible: true,
|
461
|
-
setState: noop,
|
462
|
-
isDataClass: true,
|
463
|
-
setVisible: function () {
|
464
|
-
vis = this.visible = !vis;
|
465
|
-
each(axis.series, function (series) {
|
466
|
-
each(series.points, function (point) {
|
467
|
-
if (point.dataClass === i) {
|
468
|
-
point.setVisible(vis);
|
469
|
-
}
|
470
|
-
});
|
471
|
-
});
|
472
|
-
|
473
|
-
chart.legend.colorizeItem(this, vis);
|
474
|
-
}
|
475
|
-
}, dataClass));
|
476
|
-
});
|
477
|
-
}
|
478
|
-
return legendItems;
|
479
|
-
},
|
480
|
-
name: '' // Prevents 'undefined' in legend in IE8
|
481
|
-
});
|
482
|
-
|
483
|
-
/**
|
484
|
-
* Handle animation of the color attributes directly
|
485
|
-
*/
|
486
|
-
each(['fill', 'stroke'], function (prop) {
|
487
|
-
HighchartsAdapter.addAnimSetter(prop, function (fx) {
|
488
|
-
fx.elem.attr(prop, ColorAxis.prototype.tweenColors(Color(fx.start), Color(fx.end), fx.pos));
|
489
|
-
});
|
490
|
-
});
|
491
|
-
|
492
|
-
/**
|
493
|
-
* Extend the chart getAxes method to also get the color axis
|
494
|
-
*/
|
495
|
-
wrap(Chart.prototype, 'getAxes', function (proceed) {
|
496
|
-
|
497
|
-
var options = this.options,
|
498
|
-
colorAxisOptions = options.colorAxis;
|
499
|
-
|
500
|
-
proceed.call(this);
|
501
|
-
|
502
|
-
this.colorAxis = [];
|
503
|
-
if (colorAxisOptions) {
|
504
|
-
proceed = new ColorAxis(this, colorAxisOptions); // Fake assignment for jsLint
|
505
|
-
}
|
506
|
-
});
|
507
|
-
|
508
|
-
|
509
|
-
/**
|
510
|
-
* Wrap the legend getAllItems method to add the color axis. This also removes the
|
511
|
-
* axis' own series to prevent them from showing up individually.
|
512
|
-
*/
|
513
|
-
wrap(Legend.prototype, 'getAllItems', function (proceed) {
|
514
|
-
var allItems = [],
|
515
|
-
colorAxis = this.chart.colorAxis[0];
|
516
|
-
|
517
|
-
if (colorAxis) {
|
518
|
-
|
519
|
-
// Data classes
|
520
|
-
if (colorAxis.options.dataClasses) {
|
521
|
-
allItems = allItems.concat(colorAxis.getDataClassLegendSymbols());
|
522
|
-
// Gradient legend
|
523
|
-
} else {
|
524
|
-
// Add this axis on top
|
525
|
-
allItems.push(colorAxis);
|
526
|
-
}
|
527
|
-
|
528
|
-
// Don't add the color axis' series
|
529
|
-
each(colorAxis.series, function (series) {
|
530
|
-
series.options.showInLegend = false;
|
531
|
-
});
|
532
|
-
}
|
533
|
-
|
534
|
-
return allItems.concat(proceed.call(this));
|
535
|
-
});/**
|
536
|
-
* Mixin for maps and heatmaps
|
537
|
-
*/
|
538
|
-
var colorPointMixin = {
|
539
|
-
/**
|
540
|
-
* Set the visibility of a single point
|
541
|
-
*/
|
542
|
-
setVisible: function (vis) {
|
543
|
-
var point = this,
|
544
|
-
method = vis ? 'show' : 'hide';
|
545
|
-
|
546
|
-
// Show and hide associated elements
|
547
|
-
each(['graphic', 'dataLabel'], function (key) {
|
548
|
-
if (point[key]) {
|
549
|
-
point[key][method]();
|
550
|
-
}
|
551
|
-
});
|
552
|
-
}
|
553
|
-
};
|
554
|
-
var colorSeriesMixin = {
|
555
|
-
|
556
|
-
pointAttrToOptions: { // mapping between SVG attributes and the corresponding options
|
557
|
-
stroke: 'borderColor',
|
558
|
-
'stroke-width': 'borderWidth',
|
559
|
-
fill: 'color',
|
560
|
-
dashstyle: 'dashStyle'
|
561
|
-
},
|
562
|
-
pointArrayMap: ['value'],
|
563
|
-
axisTypes: ['xAxis', 'yAxis', 'colorAxis'],
|
564
|
-
optionalAxis: 'colorAxis',
|
565
|
-
trackerGroups: ['group', 'markerGroup', 'dataLabelsGroup'],
|
566
|
-
getSymbol: noop,
|
567
|
-
parallelArrays: ['x', 'y', 'value'],
|
568
|
-
colorKey: 'value',
|
569
|
-
|
570
|
-
/**
|
571
|
-
* In choropleth maps, the color is a result of the value, so this needs translation too
|
572
|
-
*/
|
573
|
-
translateColors: function () {
|
574
|
-
var series = this,
|
575
|
-
nullColor = this.options.nullColor,
|
576
|
-
colorAxis = this.colorAxis,
|
577
|
-
colorKey = this.colorKey;
|
578
|
-
|
579
|
-
each(this.data, function (point) {
|
580
|
-
var value = point[colorKey],
|
581
|
-
color;
|
582
|
-
|
583
|
-
color = point.options.color ||
|
584
|
-
(value === null ? nullColor : (colorAxis && value !== undefined) ? colorAxis.toColor(value, point) : point.color || series.color);
|
585
|
-
|
586
|
-
if (color) {
|
587
|
-
point.color = color;
|
588
|
-
}
|
589
|
-
});
|
590
|
-
}
|
591
|
-
};
|
592
|
-
/**
|
593
|
-
* Extend the default options with map options
|
594
|
-
*/
|
595
|
-
defaultOptions.plotOptions.heatmap = merge(defaultOptions.plotOptions.scatter, {
|
596
|
-
animation: false,
|
597
|
-
borderWidth: 0,
|
598
|
-
nullColor: '#F8F8F8',
|
599
|
-
dataLabels: {
|
600
|
-
formatter: function () { // #2945
|
601
|
-
return this.point.value;
|
602
|
-
},
|
603
|
-
inside: true,
|
604
|
-
verticalAlign: 'middle',
|
605
|
-
crop: false,
|
606
|
-
overflow: false,
|
607
|
-
padding: 0 // #3837
|
608
|
-
},
|
609
|
-
marker: null,
|
610
|
-
pointRange: null, // dynamically set to colsize by default
|
611
|
-
tooltip: {
|
612
|
-
pointFormat: '{point.x}, {point.y}: {point.value}<br/>'
|
613
|
-
},
|
614
|
-
states: {
|
615
|
-
normal: {
|
616
|
-
animation: true
|
617
|
-
},
|
618
|
-
hover: {
|
619
|
-
halo: false, // #3406, halo is not required on heatmaps
|
620
|
-
brightness: 0.2
|
621
|
-
}
|
622
|
-
}
|
623
|
-
});
|
624
|
-
|
625
|
-
// The Heatmap series type
|
626
|
-
seriesTypes.heatmap = extendClass(seriesTypes.scatter, merge(colorSeriesMixin, {
|
627
|
-
type: 'heatmap',
|
628
|
-
pointArrayMap: ['y', 'value'],
|
629
|
-
hasPointSpecificOptions: true,
|
630
|
-
pointClass: extendClass(Point, colorPointMixin),
|
631
|
-
supportsDrilldown: true,
|
632
|
-
getExtremesFromAll: true,
|
633
|
-
directTouch: true,
|
634
|
-
|
635
|
-
/**
|
636
|
-
* Override the init method to add point ranges on both axes.
|
637
|
-
*/
|
638
|
-
init: function () {
|
639
|
-
var options;
|
640
|
-
seriesTypes.scatter.prototype.init.apply(this, arguments);
|
641
|
-
|
642
|
-
options = this.options;
|
643
|
-
this.pointRange = options.pointRange = pick(options.pointRange, options.colsize || 1); // #3758, prevent resetting in setData
|
644
|
-
this.yAxis.axisPointRange = options.rowsize || 1; // general point range
|
645
|
-
},
|
646
|
-
translate: function () {
|
647
|
-
var series = this,
|
648
|
-
options = series.options,
|
649
|
-
xAxis = series.xAxis,
|
650
|
-
yAxis = series.yAxis,
|
651
|
-
between = function (x, a, b) {
|
652
|
-
return Math.min(Math.max(a, x), b);
|
653
|
-
};
|
654
|
-
|
655
|
-
series.generatePoints();
|
656
|
-
|
657
|
-
each(series.points, function (point) {
|
658
|
-
var xPad = (options.colsize || 1) / 2,
|
659
|
-
yPad = (options.rowsize || 1) / 2,
|
660
|
-
x1 = between(Math.round(xAxis.len - xAxis.translate(point.x - xPad, 0, 1, 0, 1)), 0, xAxis.len),
|
661
|
-
x2 = between(Math.round(xAxis.len - xAxis.translate(point.x + xPad, 0, 1, 0, 1)), 0, xAxis.len),
|
662
|
-
y1 = between(Math.round(yAxis.translate(point.y - yPad, 0, 1, 0, 1)), 0, yAxis.len),
|
663
|
-
y2 = between(Math.round(yAxis.translate(point.y + yPad, 0, 1, 0, 1)), 0, yAxis.len);
|
664
|
-
|
665
|
-
// Set plotX and plotY for use in K-D-Tree and more
|
666
|
-
point.plotX = point.clientX = (x1 + x2) / 2;
|
667
|
-
point.plotY = (y1 + y2) / 2;
|
668
|
-
|
669
|
-
point.shapeType = 'rect';
|
670
|
-
point.shapeArgs = {
|
671
|
-
x: Math.min(x1, x2),
|
672
|
-
y: Math.min(y1, y2),
|
673
|
-
width: Math.abs(x2 - x1),
|
674
|
-
height: Math.abs(y2 - y1)
|
675
|
-
};
|
676
|
-
});
|
677
|
-
|
678
|
-
series.translateColors();
|
679
|
-
|
680
|
-
// Make sure colors are updated on colorAxis update (#2893)
|
681
|
-
if (this.chart.hasRendered) {
|
682
|
-
each(series.points, function (point) {
|
683
|
-
point.shapeArgs.fill = point.options.color || point.color; // #3311
|
684
|
-
});
|
685
|
-
}
|
686
|
-
},
|
687
|
-
drawPoints: seriesTypes.column.prototype.drawPoints,
|
688
|
-
animate: noop,
|
689
|
-
getBox: noop,
|
690
|
-
drawLegendSymbol: LegendSymbolMixin.drawRectangle,
|
691
|
-
|
692
|
-
getExtremes: function () {
|
693
|
-
// Get the extremes from the value data
|
694
|
-
Series.prototype.getExtremes.call(this, this.valueData);
|
695
|
-
this.valueMin = this.dataMin;
|
696
|
-
this.valueMax = this.dataMax;
|
697
|
-
|
698
|
-
// Get the extremes from the y data
|
699
|
-
Series.prototype.getExtremes.call(this);
|
700
|
-
}
|
701
|
-
|
702
711
|
}));
|
703
|
-
|
704
|
-
|
705
|
-
}(Highcharts));
|