highcharts-rails 4.1.5 → 4.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,7 +2,7 @@
2
2
  // @compilation_level SIMPLE_OPTIMIZATIONS
3
3
 
4
4
  /**
5
- * @license Highcharts JS v4.1.5 (2015-04-13)
5
+ * @license Highcharts JS v4.1.6 (2015-06-12)
6
6
  *
7
7
  * (c) 2009-2014 Torstein Honsi
8
8
  *
@@ -832,6 +832,7 @@ seriesTypes.arearange = extendClass(seriesTypes.area, {
832
832
  dataLabelOptions = this.options.dataLabels,
833
833
  align = dataLabelOptions.align,
834
834
  point,
835
+ up,
835
836
  inverted = this.chart.inverted;
836
837
 
837
838
  if (dataLabelOptions.enabled || this._hasPointLabels) {
@@ -840,6 +841,7 @@ seriesTypes.arearange = extendClass(seriesTypes.area, {
840
841
  i = length;
841
842
  while (i--) {
842
843
  point = data[i];
844
+ up = point.plotHigh > point.plotLow;
843
845
 
844
846
  // Set preliminary values
845
847
  point.y = point.high;
@@ -852,10 +854,10 @@ seriesTypes.arearange = extendClass(seriesTypes.area, {
852
854
  point.dataLabel = point.dataLabelUpper;
853
855
 
854
856
  // Set the default offset
855
- point.below = false;
857
+ point.below = up;
856
858
  if (inverted) {
857
859
  if (!align) {
858
- dataLabelOptions.align = 'left';
860
+ dataLabelOptions.align = up ? 'right' : 'left';
859
861
  }
860
862
  dataLabelOptions.x = dataLabelOptions.xHigh;
861
863
  } else {
@@ -871,6 +873,7 @@ seriesTypes.arearange = extendClass(seriesTypes.area, {
871
873
  i = length;
872
874
  while (i--) {
873
875
  point = data[i];
876
+ up = point.plotHigh > point.plotLow;
874
877
 
875
878
  // Move the generated labels from step 1, and reassign the original data labels
876
879
  point.dataLabelUpper = point.dataLabel;
@@ -881,10 +884,10 @@ seriesTypes.arearange = extendClass(seriesTypes.area, {
881
884
  point.plotY = point._plotY;
882
885
 
883
886
  // Set the default offset
884
- point.below = true;
887
+ point.below = !up;
885
888
  if (inverted) {
886
889
  if (!align) {
887
- dataLabelOptions.align = 'right';
890
+ dataLabelOptions.align = up ? 'left' : 'right';
888
891
  }
889
892
  dataLabelOptions.x = dataLabelOptions.xLow;
890
893
  } else {
@@ -966,11 +969,18 @@ seriesTypes.areasplinerange = extendClass(seriesTypes.arearange, {
966
969
  y = plotHigh;
967
970
  height = point.plotY - plotHigh;
968
971
 
969
- if (height < minPointLength) {
972
+ // Adjust for minPointLength
973
+ if (Math.abs(height) < minPointLength) {
970
974
  heightDifference = (minPointLength - height);
971
975
  height += heightDifference;
972
976
  y -= heightDifference / 2;
977
+
978
+ // Adjust for negative ranges or reversed Y axis (#1457)
979
+ } else if (height < 0) {
980
+ height *= -1;
981
+ y -= height;
973
982
  }
983
+
974
984
  shapeArgs.height = height;
975
985
  shapeArgs.y = y;
976
986
  });
@@ -1620,11 +1630,11 @@ seriesTypes.waterfall = extendClass(seriesTypes.column, {
1620
1630
  // sum points
1621
1631
  if (point.isSum) {
1622
1632
  shapeArgs.y = yAxis.translate(range[1], 0, 1);
1623
- shapeArgs.height = yAxis.translate(range[0], 0, 1) - shapeArgs.y;
1633
+ shapeArgs.height = Math.min(yAxis.translate(range[0], 0, 1), yAxis.len) - shapeArgs.y; // #4256
1624
1634
 
1625
1635
  } else if (point.isIntermediateSum) {
1626
1636
  shapeArgs.y = yAxis.translate(range[1], 0, 1);
1627
- shapeArgs.height = yAxis.translate(previousIntermediate, 0, 1) - shapeArgs.y;
1637
+ shapeArgs.height = Math.min(yAxis.translate(previousIntermediate, 0, 1), yAxis.len) - shapeArgs.y;
1628
1638
  previousIntermediate = range[1];
1629
1639
 
1630
1640
  // If it's not the sum point, update previous stack end position and get
@@ -2171,7 +2181,6 @@ Axis.prototype.beforePadding = function () {
2171
2181
  this.searchPoint = this.searchPointByAngle;
2172
2182
  } else {
2173
2183
  this.kdDimensions = 2;
2174
- this.kdComparer = 'distR';
2175
2184
  }
2176
2185
  }
2177
2186
  proceed.apply(this);
@@ -2364,7 +2373,7 @@ Axis.prototype.beforePadding = function () {
2364
2373
 
2365
2374
  // Postprocess plot coordinates
2366
2375
  if (chart.polar) {
2367
- this.kdByAngle = chart.tooltip.shared;
2376
+ this.kdByAngle = chart.tooltip && chart.tooltip.shared;
2368
2377
 
2369
2378
  if (!this.preventPostTranslate) {
2370
2379
  points = this.points;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Highcharts JS v4.1.5 (2015-04-13)
2
+ * Highcharts JS v4.1.6 (2015-06-12)
3
3
  * Highcharts Broken Axis module
4
4
  *
5
5
  * Author: Stephane Vanraes, Torstein Honsi
@@ -168,14 +168,15 @@
168
168
  i,
169
169
  j;
170
170
 
171
- // Min & Max Check
171
+ // Min & max check (#4247)
172
172
  for (i in breaks) {
173
173
  brk = breaks[i];
174
+ repeat = brk.repeat || Infinity;
174
175
  if (axis.isInBreak(brk, min)) {
175
- min += (brk.to % brk.repeat) - (min % brk.repeat);
176
+ min += (brk.to % repeat) - (min % repeat);
176
177
  }
177
178
  if (axis.isInBreak(brk, max)) {
178
- max -= (max % brk.repeat) - (brk.from % brk.repeat);
179
+ max -= (max % repeat) - (brk.from % repeat);
179
180
  }
180
181
  }
181
182
 
@@ -242,7 +243,6 @@
242
243
 
243
244
  axis.min = min;
244
245
  axis.max = max;
245
-
246
246
  };
247
247
  }
248
248
  });
@@ -265,7 +265,9 @@
265
265
 
266
266
  if (xAxis.isInAnyBreak(point.x, true) || yAxis.isInAnyBreak(point.y, true)) {
267
267
  points.splice(i, 1);
268
- this.data[i].destroyElements(); // removes the graphics for this point if they exist
268
+ if (this.data[i]) {
269
+ this.data[i].destroyElements(); // removes the graphics for this point if they exist
270
+ }
269
271
  }
270
272
  }
271
273
  }
@@ -422,7 +422,7 @@ if(!Array.prototype.indexOf){
422
422
  svg.trim = function(s) { return s.replace(/^\s+|\s+$/g, ''); }
423
423
 
424
424
  // compress spaces
425
- svg.compressSpaces = function(s) { return s.replace(/[\s\r\t\n]+/gm,' '); }
425
+ svg.compressSpaces = function(s) { return s ? s.replace(/[\s\r\t\n]+/gm,' ') : ''; }
426
426
 
427
427
  // ajax
428
428
  svg.ajax = function(url) {
@@ -2132,14 +2132,14 @@ if(!Array.prototype.indexOf){
2132
2132
  child.x = x;
2133
2133
  }
2134
2134
 
2135
- var childLength = child.measureText(ctx);
2135
+ var childLength = child.measureText ? child.measureText(ctx) : 0;
2136
2136
  if (textAnchor != 'start' && (i==0 || child.attribute('x').hasValue())) { // new group?
2137
2137
  // loop through rest of children
2138
2138
  var groupLength = childLength;
2139
2139
  for (var j=i+1; j<this.children.length; j++) {
2140
2140
  var childInGroup = this.children[j];
2141
2141
  if (childInGroup.attribute('x').hasValue()) break; // new group
2142
- groupLength += childInGroup.measureText(ctx);
2142
+ groupLength += childInGroup.measureText ? childInGroup.measureText(ctx) : 0;
2143
2143
  }
2144
2144
  child.x -= (textAnchor == 'end' ? groupLength : groupLength / 2.0);
2145
2145
  }
@@ -2908,7 +2908,7 @@ if (CanvasRenderingContext2D) {
2908
2908
  });
2909
2909
  }
2910
2910
  }/**
2911
- * @license Highcharts JS v4.1.5 (2015-04-13)
2911
+ * @license Highcharts JS v4.1.6 (2015-06-12)
2912
2912
  * CanVGRenderer Extension module
2913
2913
  *
2914
2914
  * (c) 2011-2012 Torstein Honsi, Erik Olsson
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.5 (2015-04-13)
2
+ * @license Highcharts JS v4.1.6 (2015-06-12)
3
3
  * Data module
4
4
  *
5
5
  * (c) 2012-2014 Torstein Honsi
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.5 (2015-04-13)
2
+ * @license Highcharts JS v4.1.6 (2015-06-12)
3
3
  * Exporting module
4
4
  *
5
5
  * (c) 2010-2014 Torstein Honsi
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.5 (2015-04-13)
2
+ * @license Highcharts JS v4.1.6 (2015-06-12)
3
3
  *
4
4
  * (c) 2011-2014 Torstein Honsi
5
5
  *
@@ -384,13 +384,31 @@ extend(ColorAxis.prototype, {
384
384
  },
385
385
 
386
386
  update: function (newOptions, redraw) {
387
+ var chart = this.chart,
388
+ legend = chart.legend;
389
+
387
390
  each(this.series, function (series) {
388
391
  series.isDirtyData = true; // Needed for Axis.update when choropleth colors change
389
392
  });
393
+
394
+ // When updating data classes, destroy old items and make sure new ones are created (#3207)
395
+ if (newOptions.dataClasses) {
396
+ each(legend.allItems, function (item) {
397
+ if (item.isDataClass) {
398
+ item.legendGroup.destroy();
399
+ }
400
+ });
401
+ chart.isDirtyLegend = true;
402
+ }
403
+
404
+ // Keep the options structure updated for export. Unlike xAxis and yAxis, the colorAxis is
405
+ // not an array. (#3207)
406
+ chart.options[this.coll] = merge(this.userOptions, newOptions);
407
+
390
408
  Axis.prototype.update.call(this, newOptions, redraw);
391
409
  if (this.legendItem) {
392
410
  this.setLegendColor();
393
- this.chart.legend.colorizeItem(this, true);
411
+ legend.colorizeItem(this, true);
394
412
  }
395
413
  },
396
414
 
@@ -437,6 +455,7 @@ extend(ColorAxis.prototype, {
437
455
  drawLegendSymbol: LegendSymbolMixin.drawRectangle,
438
456
  visible: true,
439
457
  setState: noop,
458
+ isDataClass: true,
440
459
  setVisible: function () {
441
460
  vis = this.visible = !vis;
442
461
  each(axis.series, function (series) {
@@ -589,6 +608,7 @@ seriesTypes.heatmap = extendClass(seriesTypes.scatter, merge(colorSeriesMixin, {
589
608
  hasPointSpecificOptions: true,
590
609
  supportsDrilldown: true,
591
610
  getExtremesFromAll: true,
611
+ directTouch: true,
592
612
 
593
613
  /**
594
614
  * Override the init method to add point ranges on both axes.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.5 (2015-04-13)
2
+ * @license Highcharts JS v4.1.6 (2015-06-12)
3
3
  * Plugin for displaying a message when there is no data visible in chart.
4
4
  *
5
5
  * (c) 2010-2014 Highsoft AS
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.5 (2015-04-13)
2
+ * @license Highcharts JS v4.1.6 (2015-06-12)
3
3
  * Solid angular gauge module
4
4
  *
5
5
  * (c) 2010-2014 Torstein Honsi
@@ -191,8 +191,8 @@
191
191
  H.each(series.points, function (point) {
192
192
  var graphic = point.graphic,
193
193
  rotation = yAxis.startAngleRad + yAxis.translate(point.y, null, null, null, true),
194
- radius = (pInt(pick(point.options.radius, options.radius, 100)) * center[2]) / 200, // docs: series<solidgauge>.data.radius http://jsfiddle.net/highcharts/7nwebu4b/
195
- innerRadius = (pInt(pick(point.options.innerRadius, options.innerRadius, 60)) * center[2]) / 200, // docs: series<solidgauge>.data.innerRadius
194
+ radius = (pInt(pick(point.options.radius, options.radius, 100)) * center[2]) / 200,
195
+ innerRadius = (pInt(pick(point.options.innerRadius, options.innerRadius, 60)) * center[2]) / 200,
196
196
  shapeArgs,
197
197
  d,
198
198
  toColor = yAxis.toColor(point.y, point),
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.5 (2015-04-13)
2
+ * @license Highcharts JS v4.1.6 (2015-06-12)
3
3
  *
4
4
  * (c) 2014 Highsoft AS
5
5
  * Authors: Jon Arild Nygard / Oystein Moseng
@@ -37,7 +37,7 @@
37
37
  },
38
38
  tooltip: {
39
39
  headerFormat: '',
40
- pointFormat: '<b>{point.name}</b>: {point.value}</b><br/>'
40
+ pointFormat: '<b>{point.name}</b>: {point.node.val}</b><br/>'
41
41
  },
42
42
  layoutAlgorithm: 'sliceAndDice',
43
43
  layoutStartingDirection: 'vertical',
@@ -93,7 +93,8 @@
93
93
  this.dataLabel.attr({ zIndex: (this.pointAttr[''].zIndex + 1) });
94
94
  }
95
95
  }
96
- }
96
+ },
97
+ setVisible: seriesTypes.pie.prototype.pointClass.prototype.setVisible
97
98
  }),
98
99
  handleLayout: function () {
99
100
  var series = this,
@@ -101,13 +102,9 @@
101
102
  seriesArea;
102
103
  if (this.points.length) {
103
104
  // Assign variables
104
- if (!tree) {
105
- this.nodeMap = [];
106
- tree = this.tree = this.getTree();
107
- }
108
- if (!this.rootNode) {
109
- this.rootNode = "";
110
- }
105
+ this.nodeMap = [];
106
+ tree = this.tree = this.getTree();
107
+ this.rootNode = pick(this.rootNode, "");
111
108
  this.levelMap = this.getLevels();
112
109
  each(series.points, function (point) {
113
110
  // Reset visibility
@@ -135,55 +132,43 @@
135
132
  parentList[""].push(item);
136
133
  });
137
134
  },
138
- getNodeTree = function (id, i, level, list, points, parent) {
135
+ getNodeTree = function (id, i, level, list, points, parent, visible) {
139
136
  var children = [],
140
- sortedChildren = [],
141
137
  childrenTotal = 0,
142
138
  val,
143
139
  point = points[i],
144
140
  nodeTree,
145
141
  node,
146
- insertNode,
147
142
  name;
148
- insertNode = function () {
149
- var i = 0,
150
- inserted = false;
151
- if (sortedChildren.length !== 0) {
152
- each(sortedChildren, function (child) {
153
- if (node.val > child.val && !inserted) {
154
- sortedChildren.splice(i, 0, node);
155
- inserted = true;
156
- }
157
- i = i + 1;
158
- });
159
- }
160
- if (!inserted) {
161
- sortedChildren.push(node);
162
- }
163
- };
164
143
 
165
144
  // Actions
166
- if (point) {
167
- name = point.name || "";
145
+ if (visible) {
146
+ visible = pick(point && point.visible, true);
168
147
  }
148
+ name = pick(point && point.name, "");
169
149
  if (list[id] !== undefined) {
170
150
  each(list[id], function (i) {
171
- node = getNodeTree(points[i].id, i, (level + 1), list, points, id);
172
- childrenTotal += node.val;
173
- insertNode();
174
- children.push(node);
151
+ node = getNodeTree(points[i].id, i, (level + 1), list, points, id, visible);
152
+ if (node.visible || !series.options.ignoreHiddenPoint) {
153
+ childrenTotal += node.val;
154
+ series.insertElementSorted(children, node, function (el, el2) {
155
+ return el.val > el2.val;
156
+ });
157
+ }
175
158
  });
176
159
  }
177
160
  val = pick((points[i] && points[i].value), childrenTotal, 0);
161
+ visible = val > 0 ? visible : false;
178
162
  nodeTree = {
179
163
  id: id,
180
164
  i: i,
181
- children: sortedChildren,
165
+ children: children,
182
166
  childrenTotal: childrenTotal,
183
167
  val: val,
184
168
  level: level,
185
169
  parent: parent,
186
- name: name
170
+ name: name,
171
+ visible: visible
187
172
  };
188
173
  series.nodeMap[nodeTree.id] = nodeTree;
189
174
  return nodeTree;
@@ -217,7 +202,7 @@
217
202
  }
218
203
  }
219
204
  }
220
- tree = getNodeTree("", -1, 0, parentList, this.points, null);
205
+ tree = getNodeTree("", -1, 0, parentList, this.points, null, true);
221
206
  return tree;
222
207
  },
223
208
  calculateArea: function (node, area) {
@@ -232,7 +217,6 @@
232
217
  level,
233
218
  levelNr = options.levelIsConstant ? node.level : (node.level - levelRoot),
234
219
  point;
235
- node.isVisible = (node.id === this.rootNode) || !!(this.nodeMap[node.parent] && this.nodeMap[node.parent].isVisible);
236
220
  levelNr = (levelNr > 0) ? levelNr : 0;
237
221
  // If layoutAlgorithm is set for the level of the children, then default is overwritten
238
222
  if (this.levelMap[levelNr + 1]) {
@@ -256,9 +240,7 @@
256
240
  childValues.direction = 1 - childValues.direction;
257
241
  }
258
242
  child.values = childValues;
259
- child.isVisible = node.isVisible;
260
243
  point.node = child;
261
- point.value = child.val;
262
244
  point.isLeaf = true;
263
245
  // If node has children, then call method recursively
264
246
  if (child.children.length) {
@@ -291,7 +273,7 @@
291
273
  x2 = Math.round(xAxis.translate(values.x + values.width, 0, 0, 0, 1));
292
274
  y1 = Math.round(yAxis.translate(values.y, 0, 0, 0, 1));
293
275
  y2 = Math.round(yAxis.translate(values.y + values.height, 0, 0, 0, 1));
294
- if (point.value > 0) {
276
+ if (node.visible || !series.options.ignoreHiddenPoint) {
295
277
  // Set point values
296
278
  point.shapeType = 'rect';
297
279
  point.shapeArgs = {
@@ -562,39 +544,43 @@
562
544
  }
563
545
  },
564
546
  /**
565
- * Extend drawDataLabels with logic to handle the levels option
566
- */
547
+ * Extend drawDataLabels with logic to handle custom options related to the treemap series:
548
+ * - Points which is not a leaf node, has dataLabels disabled by default.
549
+ * - Options set on series.levels is merged in.
550
+ * - Width of the dataLabel is set to match the width of the point shape.
551
+ */
567
552
  drawDataLabels: function () {
568
553
  var series = this,
554
+ dataLabelsGroup = series.dataLabelsGroup,
569
555
  points = series.points,
570
556
  options,
571
- level,
572
- dataLabelsGroup = this.dataLabelsGroup,
573
- dataLabels;
557
+ level;
574
558
  each(points, function (point) {
575
- if (point.node.isVisible) {
576
- level = series.levelMap[point.level];
577
- if (!point.isLeaf || level) {
578
- options = undefined;
579
- // If not a leaf, then label should be disabled as default
580
- if (!point.isLeaf) {
581
- options = {enabled: false};
582
- }
583
- if (level) {
584
- dataLabels = level.dataLabels;
585
- if (dataLabels) {
586
- options = merge(options, dataLabels);
587
- series._hasPointLabels = true;
588
- }
589
- }
590
- options = merge(options, point.options.dataLabels);
591
- point.dlOptions = options;
592
- } else {
593
- delete point.dlOptions;
594
- }
559
+ level = series.levelMap[point.level];
560
+ // Set options to new object to problems with scope
561
+ options = {style: {}};
562
+
563
+ // If not a leaf, then label should be disabled as default
564
+ if (!point.isLeaf) {
565
+ options.enabled = false;
566
+ }
567
+
568
+ // If options for level exists, include them as well
569
+ if (level && level.dataLabels) {
570
+ options = merge(options, level.dataLabels);
571
+ series._hasPointLabels = true;
572
+ }
573
+
574
+ // Set dataLabel width to the width of the point shape.
575
+ if (point.shapeArgs) {
576
+ options.style.width = point.shapeArgs.width;
595
577
  }
578
+
579
+ // Merge custom options with point options
580
+ point.dlOptions = merge(options, point.options.dataLabels);
596
581
  });
597
- this.dataLabelsGroup = this.group;
582
+
583
+ this.dataLabelsGroup = this.group; // Draw dataLabels in same group as points, because of z-index on hover
598
584
  Series.prototype.drawDataLabels.call(this);
599
585
  this.dataLabelsGroup = dataLabelsGroup;
600
586
  },
@@ -610,52 +596,50 @@
610
596
  hover,
611
597
  level;
612
598
  each(points, function (point) {
613
- if (point.node.isVisible) {
614
- level = series.levelMap[point.level];
615
- attr = {
616
- stroke: seriesOptions.borderColor,
617
- 'stroke-width': seriesOptions.borderWidth,
618
- dashstyle: seriesOptions.borderDashStyle,
619
- r: 0, // borderRadius gives wrong size relations and should always be disabled
620
- fill: pick(point.color, series.color)
621
- };
622
- // Overwrite standard series options with level options
623
- if (level) {
624
- attr.stroke = level.borderColor || attr.stroke;
625
- attr['stroke-width'] = level.borderWidth || attr['stroke-width'];
626
- attr.dashstyle = level.borderDashStyle || attr.dashstyle;
627
- }
628
- // Merge with point attributes
629
- attr.stroke = point.borderColor || attr.stroke;
630
- attr['stroke-width'] = point.borderWidth || attr['stroke-width'];
631
- attr.dashstyle = point.borderDashStyle || attr.dashstyle;
632
- attr.zIndex = (1000 - (point.level * 2));
599
+ level = series.levelMap[point.level];
600
+ attr = {
601
+ stroke: seriesOptions.borderColor,
602
+ 'stroke-width': seriesOptions.borderWidth,
603
+ dashstyle: seriesOptions.borderDashStyle,
604
+ r: 0, // borderRadius gives wrong size relations and should always be disabled
605
+ fill: pick(point.color, series.color)
606
+ };
607
+ // Overwrite standard series options with level options
608
+ if (level) {
609
+ attr.stroke = level.borderColor || attr.stroke;
610
+ attr['stroke-width'] = level.borderWidth || attr['stroke-width'];
611
+ attr.dashstyle = level.borderDashStyle || attr.dashstyle;
612
+ }
613
+ // Merge with point attributes
614
+ attr.stroke = point.borderColor || attr.stroke;
615
+ attr['stroke-width'] = point.borderWidth || attr['stroke-width'];
616
+ attr.dashstyle = point.borderDashStyle || attr.dashstyle;
617
+ attr.zIndex = (1000 - (point.level * 2));
633
618
 
634
- // Make a copy to prevent overwriting individual props
635
- point.pointAttr = merge(point.pointAttr);
636
- hover = point.pointAttr.hover;
637
- hover.zIndex = 1001;
638
- hover.fill = Color(attr.fill).brighten(seriesOptions.states.hover.brightness).get();
639
- // If not a leaf, then remove fill
640
- if (!point.isLeaf) {
641
- if (pick(seriesOptions.interactByLeaf, !seriesOptions.allowDrillToNode)) {
642
- attr.fill = 'none';
643
- delete hover.fill;
644
- } else {
645
- // TODO: let users set the opacity
646
- attr.fill = Color(attr.fill).setOpacity(0.15).get();
647
- hover.fill = Color(hover.fill).setOpacity(0.75).get();
648
- }
649
- }
650
- if (point.node.level <= series.nodeMap[series.rootNode].level) {
619
+ // Make a copy to prevent overwriting individual props
620
+ point.pointAttr = merge(point.pointAttr);
621
+ hover = point.pointAttr.hover;
622
+ hover.zIndex = 1001;
623
+ hover.fill = Color(attr.fill).brighten(seriesOptions.states.hover.brightness).get();
624
+ // If not a leaf, then remove fill
625
+ if (!point.isLeaf) {
626
+ if (pick(seriesOptions.interactByLeaf, !seriesOptions.allowDrillToNode)) {
651
627
  attr.fill = 'none';
652
- attr.zIndex = 0;
653
628
  delete hover.fill;
629
+ } else {
630
+ // TODO: let users set the opacity
631
+ attr.fill = Color(attr.fill).setOpacity(0.15).get();
632
+ hover.fill = Color(hover.fill).setOpacity(0.75).get();
654
633
  }
655
- point.pointAttr[''] = H.extend(point.pointAttr[''], attr);
656
- if (point.dataLabel) {
657
- point.dataLabel.attr({ zIndex: (point.pointAttr[''].zIndex + 1) });
658
- }
634
+ }
635
+ if (point.node.level <= series.nodeMap[series.rootNode].level) {
636
+ attr.fill = 'none';
637
+ attr.zIndex = 0;
638
+ delete hover.fill;
639
+ }
640
+ point.pointAttr[''] = H.extend(point.pointAttr[''], attr);
641
+ if (point.dataLabel) {
642
+ point.dataLabel.attr({ zIndex: (point.pointAttr[''].zIndex + 1) });
659
643
  }
660
644
  });
661
645
  // Call standard drawPoints
@@ -672,6 +656,29 @@
672
656
  series.drillTo();
673
657
  }
674
658
  },
659
+ /**
660
+ * Inserts an element into an array, sorted by a condition.
661
+ * Modifies the referenced array
662
+ * @param {*[]} arr The array which the element is inserted into.
663
+ * @param {*} el The element to insert.
664
+ * @param {function} cond The condition to sort on. First parameter is el, second parameter is array element
665
+ */
666
+ insertElementSorted: function (arr, el, cond) {
667
+ var i = 0,
668
+ inserted = false;
669
+ if (arr.length !== 0) {
670
+ each(arr, function (arrayElement) {
671
+ if (cond(el, arrayElement) && !inserted) {
672
+ arr.splice(i, 0, el);
673
+ inserted = true;
674
+ }
675
+ i = i + 1;
676
+ });
677
+ }
678
+ if (!inserted) {
679
+ arr.push(el);
680
+ }
681
+ },
675
682
  /**
676
683
  * Add drilling on the suitable points
677
684
  */
@@ -681,31 +688,29 @@
681
688
  each(points, function (point) {
682
689
  var drillId,
683
690
  drillName;
684
- if (point.node.isVisible) {
685
- H.removeEvent(point, 'click');
686
- if (point.graphic) {
687
- point.graphic.css({ cursor: 'default' });
688
- }
691
+ H.removeEvent(point, 'click.drillTo');
692
+ if (point.graphic) {
693
+ point.graphic.css({ cursor: 'default' });
694
+ }
689
695
 
690
- // Get the drill to id
691
- if (series.options.interactByLeaf) {
692
- drillId = series.drillToByLeaf(point);
693
- } else {
694
- drillId = series.drillToByGroup(point);
695
- }
696
+ // Get the drill to id
697
+ if (series.options.interactByLeaf) {
698
+ drillId = series.drillToByLeaf(point);
699
+ } else {
700
+ drillId = series.drillToByGroup(point);
701
+ }
696
702
 
697
- // If a drill id is returned, add click event and cursor.
698
- if (drillId) {
699
- drillName = series.nodeMap[series.rootNode].name || series.rootNode;
700
- if (point.graphic) {
701
- point.graphic.css({ cursor: 'pointer' });
702
- }
703
- H.addEvent(point, 'click', function () {
704
- point.setState(''); // Remove hover
705
- series.drillToNode(drillId);
706
- series.showDrillUpButton(drillName);
707
- });
703
+ // If a drill id is returned, add click event and cursor.
704
+ if (drillId) {
705
+ drillName = series.nodeMap[series.rootNode].name || series.rootNode;
706
+ if (point.graphic) {
707
+ point.graphic.css({ cursor: 'pointer' });
708
708
  }
709
+ H.addEvent(point, 'click.drillTo', function () {
710
+ point.setState(''); // Remove hover
711
+ series.drillToNode(drillId);
712
+ series.showDrillUpButton(drillName);
713
+ });
709
714
  }
710
715
  });
711
716
  },