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.
@@ -1,16 +1,20 @@
1
1
  /**
2
- * Highcharts Drilldown plugin
2
+ * Highcharts Drilldown module
3
3
  *
4
4
  * Author: Torstein Honsi
5
- * License: MIT License
5
+ * License: www.highcharts.com/license
6
6
  *
7
- * Demo: http://jsfiddle.net/highcharts/Vf3yT/
8
7
  */
9
8
 
10
- /*global Highcharts,HighchartsAdapter*/
11
- (function (H) {
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
- "use strict";
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 = HighchartsAdapter.fireEvent,
28
- inArray = HighchartsAdapter.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.raw || 'none';
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
- HighchartsAdapter.addAnimSetter(prop, function (fx) {
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
- }(Highcharts));
717
+ }));
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.9 (2015-10-07)
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
- // JSLint options:
11
- /*global Highcharts, HighchartsAdapter, document, window, Math, setTimeout */
12
-
13
- (function (Highcharts) { // encapsulate
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 = HighchartsAdapter.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; // docs: experimental, see #2473
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.stopPropagation();
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
- }(Highcharts));
780
+ }));
@@ -6,9 +6,14 @@
6
6
  *
7
7
  * License: www.highcharts.com/license
8
8
  */
9
-
10
- /*global Highcharts */
11
- (function (Highcharts) {
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
- return y > height - neckHeight || height === neckHeight ?
106
+ var top = (centerY - height / 2);
107
+
108
+ return y > neckY || height === neckHeight ?
102
109
  neckWidth :
103
- neckWidth + (width - neckWidth) * ((height - neckHeight - y) / (height - neckHeight));
110
+ neckWidth + (width - neckWidth) * (1 - (y - top) / (height - neckHeight));
104
111
  };
105
112
  series.getX = function (y, half) {
106
- return centerX + (half ? -1 : 1) * ((getWidthAt(reversed ? plotHeight - y : y) / 2) + options.dataLabels.distance);
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
- }(Highcharts));
322
+ }));
@@ -1,705 +1,711 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.9 (2015-10-07)
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));