corrade-nucleus-nucleons – Blame information for rev 20

Subversion Repositories:
Rev:
Rev Author Line No. Line
20 office 1 /**
2 * @license Highcharts JS v5.0.12 (2017-05-24)
3 * Highcharts Drilldown module
4 *
5 * Author: Torstein Honsi
6 * License: www.highcharts.com/license
7 *
8 */
9 'use strict';
10 (function(factory) {
11 if (typeof module === 'object' && module.exports) {
12 module.exports = factory;
13 } else {
14 factory(Highcharts);
15 }
16 }(function(Highcharts) {
17 (function(H) {
18 /**
19 * Highcharts Drilldown module
20 *
21 * Author: Torstein Honsi
22 * License: www.highcharts.com/license
23 *
24 */
25  
26  
27 var noop = H.noop,
28 color = H.color,
29 defaultOptions = H.defaultOptions,
30 each = H.each,
31 extend = H.extend,
32 format = H.format,
33 objectEach = H.objectEach,
34 pick = H.pick,
35 wrap = H.wrap,
36 Chart = H.Chart,
37 seriesTypes = H.seriesTypes,
38 PieSeries = seriesTypes.pie,
39 ColumnSeries = seriesTypes.column,
40 Tick = H.Tick,
41 fireEvent = H.fireEvent,
42 inArray = H.inArray,
43 ddSeriesId = 1;
44  
45 // Add language
46 extend(defaultOptions.lang, {
47 drillUpText: '◁ Back to {series.name}'
48 });
49 defaultOptions.drilldown = {
50  
51 activeAxisLabelStyle: {
52 cursor: 'pointer',
53 color: '#003399',
54 fontWeight: 'bold',
55 textDecoration: 'underline'
56 },
57 activeDataLabelStyle: {
58 cursor: 'pointer',
59 color: '#003399',
60 fontWeight: 'bold',
61 textDecoration: 'underline'
62 },
63  
64 animation: {
65 duration: 500
66 },
67 drillUpButton: {
68 position: {
69 align: 'right',
70 x: -10,
71 y: 10
72 }
73 // relativeTo: 'plotBox'
74 // theme
75 }
76 };
77  
78 /**
79 * A general fadeIn method
80 */
81 H.SVGRenderer.prototype.Element.prototype.fadeIn = function(animation) {
82 this
83 .attr({
84 opacity: 0.1,
85 visibility: 'inherit'
86 })
87 .animate({
88 opacity: pick(this.newOpacity, 1) // newOpacity used in maps
89 }, animation || {
90 duration: 250
91 });
92 };
93  
94 /**
95 * Add a series to the chart as drilldown from a specific point in the parent
96 * series. This method is used for async drilldown, when clicking a point in a
97 * series should result in loading and displaying a more high-resolution series.
98 * When not async, the setup is simpler using the {@link
99 * https://api.highcharts.com/highcharts/drilldown.series|drilldown.series}
100 * options structure.
101 *
102 * @memberOf Highcharts.Chart
103 * @function #addSeriesAsDrilldown
104 *
105 * @param {Highcharts.Point} point
106 * The point from which the drilldown will start.
107 * @param {SeriesOptions} options
108 * The series options for the new, detailed series.
109 *
110 * @sample highcharts/drilldown/async/ Async drilldown
111 */
112 Chart.prototype.addSeriesAsDrilldown = function(point, options) {
113 this.addSingleSeriesAsDrilldown(point, options);
114 this.applyDrilldown();
115 };
116 Chart.prototype.addSingleSeriesAsDrilldown = function(point, ddOptions) {
117 var oldSeries = point.series,
118 xAxis = oldSeries.xAxis,
119 yAxis = oldSeries.yAxis,
120 newSeries,
121 pointIndex,
122 levelSeries = [],
123 levelSeriesOptions = [],
124 level,
125 levelNumber,
126 last,
127 colorProp;
128  
129  
130  
131 colorProp = {
132 color: point.color || oldSeries.color
133 };
134  
135  
136 if (!this.drilldownLevels) {
137 this.drilldownLevels = [];
138 }
139  
140 levelNumber = oldSeries.options._levelNumber || 0;
141  
142 // See if we can reuse the registered series from last run
143 last = this.drilldownLevels[this.drilldownLevels.length - 1];
144 if (last && last.levelNumber !== levelNumber) {
145 last = undefined;
146 }
147  
148 ddOptions = extend(extend({
149 _ddSeriesId: ddSeriesId++
150 }, colorProp), ddOptions);
151 pointIndex = inArray(point, oldSeries.points);
152  
153 // Record options for all current series
154 each(oldSeries.chart.series, function(series) {
155 if (series.xAxis === xAxis && !series.isDrilling) {
156 series.options._ddSeriesId = series.options._ddSeriesId || ddSeriesId++;
157 series.options._colorIndex = series.userOptions._colorIndex;
158 series.options._levelNumber = series.options._levelNumber || levelNumber; // #3182
159  
160 if (last) {
161 levelSeries = last.levelSeries;
162 levelSeriesOptions = last.levelSeriesOptions;
163 } else {
164 levelSeries.push(series);
165 levelSeriesOptions.push(series.options);
166 }
167 }
168 });
169  
170 // Add a record of properties for each drilldown level
171 level = extend({
172 levelNumber: levelNumber,
173 seriesOptions: oldSeries.options,
174 levelSeriesOptions: levelSeriesOptions,
175 levelSeries: levelSeries,
176 shapeArgs: point.shapeArgs,
177 bBox: point.graphic ? point.graphic.getBBox() : {}, // no graphic in line series with markers disabled
178 color: point.isNull ? new H.Color(color).setOpacity(0).get() : color,
179 lowerSeriesOptions: ddOptions,
180 pointOptions: oldSeries.options.data[pointIndex],
181 pointIndex: pointIndex,
182 oldExtremes: {
183 xMin: xAxis && xAxis.userMin,
184 xMax: xAxis && xAxis.userMax,
185 yMin: yAxis && yAxis.userMin,
186 yMax: yAxis && yAxis.userMax
187 }
188 }, colorProp);
189  
190 // Push it to the lookup array
191 this.drilldownLevels.push(level);
192  
193 // Reset names to prevent extending (#6704)
194 if (xAxis && xAxis.names) {
195 xAxis.names.length = 0;
196 }
197  
198 newSeries = level.lowerSeries = this.addSeries(ddOptions, false);
199 newSeries.options._levelNumber = levelNumber + 1;
200 if (xAxis) {
201 xAxis.oldPos = xAxis.pos;
202 xAxis.userMin = xAxis.userMax = null;
203 yAxis.userMin = yAxis.userMax = null;
204 }
205  
206 // Run fancy cross-animation on supported and equal types
207 if (oldSeries.type === newSeries.type) {
208 newSeries.animate = newSeries.animateDrilldown || noop;
209 newSeries.options.animation = true;
210 }
211 };
212  
213 Chart.prototype.applyDrilldown = function() {
214 var drilldownLevels = this.drilldownLevels,
215 levelToRemove;
216  
217 if (drilldownLevels && drilldownLevels.length > 0) { // #3352, async loading
218 levelToRemove = drilldownLevels[drilldownLevels.length - 1].levelNumber;
219 each(this.drilldownLevels, function(level) {
220 if (level.levelNumber === levelToRemove) {
221 each(level.levelSeries, function(series) {
222 if (series.options && series.options._levelNumber === levelToRemove) { // Not removed, not added as part of a multi-series drilldown
223 series.remove(false);
224 }
225 });
226 }
227 });
228 }
229  
230 this.redraw();
231 this.showDrillUpButton();
232 };
233  
234 Chart.prototype.getDrilldownBackText = function() {
235 var drilldownLevels = this.drilldownLevels,
236 lastLevel;
237 if (drilldownLevels && drilldownLevels.length > 0) { // #3352, async loading
238 lastLevel = drilldownLevels[drilldownLevels.length - 1];
239 lastLevel.series = lastLevel.seriesOptions;
240 return format(this.options.lang.drillUpText, lastLevel);
241 }
242  
243 };
244  
245 Chart.prototype.showDrillUpButton = function() {
246 var chart = this,
247 backText = this.getDrilldownBackText(),
248 buttonOptions = chart.options.drilldown.drillUpButton,
249 attr,
250 states;
251  
252  
253 if (!this.drillUpButton) {
254 attr = buttonOptions.theme;
255 states = attr && attr.states;
256  
257 this.drillUpButton = this.renderer.button(
258 backText,
259 null,
260 null,
261 function() {
262 chart.drillUp();
263 },
264 attr,
265 states && states.hover,
266 states && states.select
267 )
268 .addClass('highcharts-drillup-button')
269 .attr({
270 align: buttonOptions.position.align,
271 zIndex: 7
272 })
273 .add()
274 .align(buttonOptions.position, false, buttonOptions.relativeTo || 'plotBox');
275 } else {
276 this.drillUpButton.attr({
277 text: backText
278 })
279 .align();
280 }
281 };
282  
283 /**
284 * When the chart is drilled down to a child series, calling `chart.drillUp()`
285 * will drill up to the parent series.
286 *
287 * @memberOf Highcharts.Chart
288 * @name #drillUp
289 */
290 Chart.prototype.drillUp = function() {
291 var chart = this,
292 drilldownLevels = chart.drilldownLevels,
293 levelNumber = drilldownLevels[drilldownLevels.length - 1].levelNumber,
294 i = drilldownLevels.length,
295 chartSeries = chart.series,
296 seriesI,
297 level,
298 oldSeries,
299 newSeries,
300 oldExtremes,
301 addSeries = function(seriesOptions) {
302 var addedSeries;
303 each(chartSeries, function(series) {
304 if (series.options._ddSeriesId === seriesOptions._ddSeriesId) {
305 addedSeries = series;
306 }
307 });
308  
309 addedSeries = addedSeries || chart.addSeries(seriesOptions, false);
310 if (addedSeries.type === oldSeries.type && addedSeries.animateDrillupTo) {
311 addedSeries.animate = addedSeries.animateDrillupTo;
312 }
313 if (seriesOptions === level.seriesOptions) {
314 newSeries = addedSeries;
315 }
316 };
317  
318 while (i--) {
319  
320 level = drilldownLevels[i];
321 if (level.levelNumber === levelNumber) {
322 drilldownLevels.pop();
323  
324 // Get the lower series by reference or id
325 oldSeries = level.lowerSeries;
326 if (!oldSeries.chart) { // #2786
327 seriesI = chartSeries.length; // #2919
328 while (seriesI--) {
329 if (chartSeries[seriesI].options.id === level.lowerSeriesOptions.id &&
330 chartSeries[seriesI].options._levelNumber === levelNumber + 1) { // #3867
331 oldSeries = chartSeries[seriesI];
332 break;
333 }
334 }
335 }
336 oldSeries.xData = []; // Overcome problems with minRange (#2898)
337  
338 each(level.levelSeriesOptions, addSeries);
339  
340 fireEvent(chart, 'drillup', {
341 seriesOptions: level.seriesOptions
342 });
343  
344 if (newSeries.type === oldSeries.type) {
345 newSeries.drilldownLevel = level;
346 newSeries.options.animation = chart.options.drilldown.animation;
347  
348 if (oldSeries.animateDrillupFrom && oldSeries.chart) { // #2919
349 oldSeries.animateDrillupFrom(level);
350 }
351 }
352 newSeries.options._levelNumber = levelNumber;
353  
354 oldSeries.remove(false);
355  
356 // Reset the zoom level of the upper series
357 if (newSeries.xAxis) {
358 oldExtremes = level.oldExtremes;
359 newSeries.xAxis.setExtremes(oldExtremes.xMin, oldExtremes.xMax, false);
360 newSeries.yAxis.setExtremes(oldExtremes.yMin, oldExtremes.yMax, false);
361 }
362 }
363 }
364  
365 // Fire a once-off event after all series have been drilled up (#5158)
366 fireEvent(chart, 'drillupall');
367  
368 this.redraw();
369  
370 if (this.drilldownLevels.length === 0) {
371 this.drillUpButton = this.drillUpButton.destroy();
372 } else {
373 this.drillUpButton.attr({
374 text: this.getDrilldownBackText()
375 })
376 .align();
377 }
378  
379 this.ddDupes.length = []; // #3315
380 };
381  
382  
383 ColumnSeries.prototype.supportsDrilldown = true;
384  
385 /**
386 * When drilling up, keep the upper series invisible until the lower series has
387 * moved into place
388 */
389 ColumnSeries.prototype.animateDrillupTo = function(init) {
390 if (!init) {
391 var newSeries = this,
392 level = newSeries.drilldownLevel;
393  
394 // First hide all items before animating in again
395 each(this.points, function(point) {
396 var dataLabel = point.dataLabel;
397  
398 if (point.graphic) { // #3407
399 point.graphic.hide();
400 }
401  
402 if (dataLabel) {
403 // The data label is initially hidden, make sure it is not faded
404 // in (#6127)
405 dataLabel.hidden = dataLabel.attr('visibility') === 'hidden';
406  
407 if (!dataLabel.hidden) {
408 dataLabel.hide();
409 if (point.connector) {
410 point.connector.hide();
411 }
412 }
413 }
414 });
415  
416  
417 // Do dummy animation on first point to get to complete
418 setTimeout(function() {
419 if (newSeries.points) { // May be destroyed in the meantime, #3389
420 each(newSeries.points, function(point, i) {
421 // Fade in other points
422 var verb =
423 i === (level && level.pointIndex) ? 'show' : 'fadeIn',
424 inherit = verb === 'show' ? true : undefined,
425 dataLabel = point.dataLabel;
426  
427  
428 if (point.graphic) { // #3407
429 point.graphic[verb](inherit);
430 }
431  
432 if (dataLabel && !dataLabel.hidden) { // #6127
433 dataLabel[verb](inherit);
434 if (point.connector) {
435 point.connector[verb](inherit);
436 }
437 }
438 });
439 }
440 }, Math.max(this.chart.options.drilldown.animation.duration - 50, 0));
441  
442 // Reset
443 this.animate = noop;
444 }
445  
446 };
447  
448 ColumnSeries.prototype.animateDrilldown = function(init) {
449 var series = this,
450 drilldownLevels = this.chart.drilldownLevels,
451 animateFrom,
452 animationOptions = this.chart.options.drilldown.animation,
453 xAxis = this.xAxis;
454  
455 if (!init) {
456 each(drilldownLevels, function(level) {
457 if (series.options._ddSeriesId === level.lowerSeriesOptions._ddSeriesId) {
458 animateFrom = level.shapeArgs;
459  
460 // Add the point colors to animate from
461 animateFrom.fill = level.color;
462  
463 }
464 });
465  
466 animateFrom.x += (pick(xAxis.oldPos, xAxis.pos) - xAxis.pos);
467  
468 each(this.points, function(point) {
469 var animateTo = point.shapeArgs;
470  
471  
472 // Add the point colors to animate to
473 animateTo.fill = point.color;
474  
475  
476 if (point.graphic) {
477 point.graphic
478 .attr(animateFrom)
479 .animate(
480 extend(point.shapeArgs, {
481 fill: point.color || series.color
482 }),
483 animationOptions
484 );
485 }
486 if (point.dataLabel) {
487 point.dataLabel.fadeIn(animationOptions);
488 }
489 });
490 this.animate = null;
491 }
492  
493 };
494  
495 /**
496 * When drilling up, pull out the individual point graphics from the lower series
497 * and animate them into the origin point in the upper series.
498 */
499 ColumnSeries.prototype.animateDrillupFrom = function(level) {
500 var animationOptions = this.chart.options.drilldown.animation,
501 group = this.group,
502 // For 3d column series all columns are added to one group
503 // so we should not delete the whole group. #5297
504 removeGroup = group !== this.chart.seriesGroup,
505 series = this;
506  
507 // Cancel mouse events on the series group (#2787)
508 each(series.trackerGroups, function(key) {
509 if (series[key]) { // we don't always have dataLabelsGroup
510 series[key].on('mouseover');
511 }
512 });
513  
514 if (removeGroup) {
515 delete this.group;
516 }
517  
518 each(this.points, function(point) {
519 var graphic = point.graphic,
520 animateTo = level.shapeArgs,
521 complete = function() {
522 graphic.destroy();
523 if (group && removeGroup) {
524 group = group.destroy();
525 }
526 };
527  
528 if (graphic) {
529  
530 delete point.graphic;
531  
532  
533 animateTo.fill = level.color;
534  
535  
536 if (animationOptions) {
537 graphic.animate(
538 animateTo,
539 H.merge(animationOptions, {
540 complete: complete
541 })
542 );
543 } else {
544 graphic.attr(animateTo);
545 complete();
546 }
547 }
548 });
549 };
550  
551 if (PieSeries) {
552 extend(PieSeries.prototype, {
553 supportsDrilldown: true,
554 animateDrillupTo: ColumnSeries.prototype.animateDrillupTo,
555 animateDrillupFrom: ColumnSeries.prototype.animateDrillupFrom,
556  
557 animateDrilldown: function(init) {
558 var level = this.chart.drilldownLevels[this.chart.drilldownLevels.length - 1],
559 animationOptions = this.chart.options.drilldown.animation,
560 animateFrom = level.shapeArgs,
561 start = animateFrom.start,
562 angle = animateFrom.end - start,
563 startAngle = angle / this.points.length;
564  
565 if (!init) {
566 each(this.points, function(point, i) {
567 var animateTo = point.shapeArgs;
568  
569  
570 animateFrom.fill = level.color;
571 animateTo.fill = point.color;
572  
573  
574 if (point.graphic) {
575 point.graphic
576 .attr(H.merge(animateFrom, {
577 start: start + i * startAngle,
578 end: start + (i + 1) * startAngle
579 }))[animationOptions ? 'animate' : 'attr'](
580 animateTo,
581 animationOptions
582 );
583 }
584 });
585 this.animate = null;
586 }
587 }
588 });
589 }
590  
591 H.Point.prototype.doDrilldown = function(_holdRedraw, category, originalEvent) {
592 var series = this.series,
593 chart = series.chart,
594 drilldown = chart.options.drilldown,
595 i = (drilldown.series || []).length,
596 seriesOptions;
597  
598 if (!chart.ddDupes) {
599 chart.ddDupes = [];
600 }
601  
602 while (i-- && !seriesOptions) {
603 if (drilldown.series[i].id === this.drilldown && inArray(this.drilldown, chart.ddDupes) === -1) {
604 seriesOptions = drilldown.series[i];
605 chart.ddDupes.push(this.drilldown);
606 }
607 }
608  
609 // Fire the event. If seriesOptions is undefined, the implementer can check for
610 // seriesOptions, and call addSeriesAsDrilldown async if necessary.
611 fireEvent(chart, 'drilldown', {
612 point: this,
613 seriesOptions: seriesOptions,
614 category: category,
615 originalEvent: originalEvent,
616 points: category !== undefined && this.series.xAxis.getDDPoints(category).slice(0)
617 }, function(e) {
618 var chart = e.point.series && e.point.series.chart,
619 seriesOptions = e.seriesOptions;
620 if (chart && seriesOptions) {
621 if (_holdRedraw) {
622 chart.addSingleSeriesAsDrilldown(e.point, seriesOptions);
623 } else {
624 chart.addSeriesAsDrilldown(e.point, seriesOptions);
625 }
626 }
627 });
628  
629  
630 };
631  
632 /**
633 * Drill down to a given category. This is the same as clicking on an axis label.
634 */
635 H.Axis.prototype.drilldownCategory = function(x, e) {
636 objectEach(this.getDDPoints(x), function(point) {
637 if (point && point.series && point.series.visible && point.doDrilldown) { // #3197
638 point.doDrilldown(true, x, e);
639 }
640 });
641 this.chart.applyDrilldown();
642 };
643  
644 /**
645 * Return drillable points for this specific X value
646 */
647 H.Axis.prototype.getDDPoints = function(x) {
648 var ret = [];
649 each(this.series, function(series) {
650 var i,
651 xData = series.xData,
652 points = series.points;
653  
654 for (i = 0; i < xData.length; i++) {
655 < xData.length; i++) { if (xData[i] === x && series.options.data[i] && series.options.data[i].drilldown) {
656 < xData.length; i++) { ret.push(points ? points[i] : true);
657 < xData.length; i++) { break;
658 < xData.length; i++) { }
659 < xData.length; i++) { }
660 < xData.length; i++) { });
661 < xData.length; i++) { return ret;
662 < xData.length; i++) { };
663  
664  
665 < xData.length; i++) { /**
666 < xData.length; i++) { * Make a tick label drillable, or remove drilling on update
667 < xData.length; i++) { */
668 < xData.length; i++) { Tick.prototype.drillable = function() {
669 < xData.length; i++) { var pos = this.pos,
670 < xData.length; i++) { label = this.label,
671 < xData.length; i++) { axis = this.axis,
672 < xData.length; i++) { isDrillable = axis.coll === 'xAxis' && axis.getDDPoints,
673 < xData.length; i++) { ddPointsX = isDrillable && axis.getDDPoints(pos);
674  
675 < xData.length; i++) { if (isDrillable) {
676 < xData.length; i++) { if (label && ddPointsX.length) {
677 < xData.length; i++) { label.drillable = true;
678  
679  
680 < xData.length; i++) { if (!label.basicStyles) {
681 < xData.length; i++) { label.basicStyles = H.merge(label.styles);
682 < xData.length; i++) { }
683  
684  
685 < xData.length; i++) { label
686 < xData.length; i++) { .addClass('highcharts-drilldown-axis-label')
687  
688 < xData.length; i++) { .css(axis.chart.options.drilldown.activeAxisLabelStyle)
689  
690 < xData.length; i++) { .on('click', function(e) {
691 < xData.length; i++) { axis.drilldownCategory(pos, e);
692 < xData.length; i++) { });
693  
694 < xData.length; i++) { } else if (label && label.drillable) {
695  
696  
697 < xData.length; i++) { label.styles = {}; // reset for full overwrite of styles
698 < xData.length; i++) { label.css(label.basicStyles);
699  
700  
701 < xData.length; i++) { label.on('click', null); // #3806
702 < xData.length; i++) { label.removeClass('highcharts-drilldown-axis-label');
703 < xData.length; i++) { }
704 < xData.length; i++) { }
705 < xData.length; i++) { };
706  
707 < xData.length; i++) { /**
708 < xData.length; i++) { * Always keep the drillability updated (#3951)
709 < xData.length; i++) { */
710 < xData.length; i++) { wrap(Tick.prototype, 'addLabel', function(proceed) {
711 < xData.length; i++) { proceed.call(this);
712 < xData.length; i++) { this.drillable();
713 < xData.length; i++) { });
714  
715  
716 < xData.length; i++) { /**
717 < xData.length; i++) { * On initialization of each point, identify its label and make it clickable. Also, provide a
718 < xData.length; i++) { * list of points associated to that label.
719 < xData.length; i++) { */
720 < xData.length; i++) { wrap(H.Point.prototype, 'init', function(proceed, series, options, x) {
721 < xData.length; i++) { var point = proceed.call(this, series, options, x),
722 < xData.length; i++) { xAxis = series.xAxis,
723 < xData.length; i++) { tick = xAxis && xAxis.ticks[x];
724  
725 < xData.length; i++) { if (point.drilldown) {
726  
727 < xData.length; i++) { // Add the click event to the point
728 < xData.length; i++) { H.addEvent(point, 'click', function(e) {
729 < xData.length; i++) { if (series.xAxis && series.chart.options.drilldown.allowPointDrilldown === false) {
730 < xData.length; i++) { series.xAxis.drilldownCategory(point.x, e); // #5822, x changed
731 < xData.length; i++) { } else {
732 < xData.length; i++) { point.doDrilldown(undefined, undefined, e);
733 < xData.length; i++) { }
734 < xData.length; i++) { });
735 < xData.length; i++) { /*wrap(point, 'importEvents', function (proceed) { // wrapping importEvents makes point.click event work
736 < xData.length; i++) { if (!this.hasImportedEvents) {
737 < xData.length; i++) { proceed.call(this);
738 < xData.length; i++) { H.addEvent(this, 'click', function () {
739 < xData.length; i++) { this.doDrilldown();
740 < xData.length; i++) { });
741 < xData.length; i++) { }
742 < xData.length; i++) { });*/
743  
744 < xData.length; i++) { }
745  
746 < xData.length; i++) { // Add or remove click handler and style on the tick label
747 < xData.length; i++) { if (tick) {
748 < xData.length; i++) { tick.drillable();
749 < xData.length; i++) { }
750  
751 < xData.length; i++) { return point;
752 < xData.length; i++) { });
753  
754 < xData.length; i++) { wrap(H.Series.prototype, 'drawDataLabels', function(proceed) {
755 < xData.length; i++) { var css = this.chart.options.drilldown.activeDataLabelStyle,
756 < xData.length; i++) { renderer = this.chart.renderer;
757  
758 < xData.length; i++) { proceed.call(this);
759  
760 < xData.length; i++) { each(this.points, function(point) {
761 < xData.length; i++) { var pointCSS = {};
762 < xData.length; i++) { if (point.drilldown && point.dataLabel) {
763 < xData.length; i++) { if (css.color === 'contrast') {
764 < xData.length; i++) { pointCSS.color = renderer.getContrast(point.color || this.color);
765 < xData.length; i++) { }
766 < xData.length; i++) { point.dataLabel
767 < xData.length; i++) { .addClass('highcharts-drilldown-data-label');
768  
769  
770 < xData.length; i++) { point.dataLabel
771 < xData.length; i++) { .css(css)
772 < xData.length; i++) { .css(pointCSS);
773  
774 < xData.length; i++) { }
775 < xData.length; i++) { }, this);
776 < xData.length; i++) { });
777  
778 < xData.length; i++) { // Mark the trackers with a pointer
779 < xData.length; i++) { var drawTrackerWrapper = function(proceed) {
780 < xData.length; i++) { proceed.call(this);
781 < xData.length; i++) { each(this.points, function(point) {
782 < xData.length; i++) { if (point.drilldown && point.graphic) {
783 < xData.length; i++) { point.graphic.addClass('highcharts-drilldown-point');
784  
785  
786 < xData.length; i++) { point.graphic.css({
787 < xData.length; i++) { cursor: 'pointer'
788 < xData.length; i++) { });
789  
790 < xData.length; i++) { }
791 < xData.length; i++) { });
792 < xData.length; i++) { };
793  
794 < xData.length; i++) { objectEach(seriesTypes, function(seriesType) {
795 < xData.length; i++) { if (seriesType.prototype.supportsDrilldown) {
796 < xData.length; i++) { wrap(seriesType.prototype, 'drawTracker', drawTrackerWrapper);
797 < xData.length; i++) { }
798 < xData.length; i++) { });
799  
800 < xData.length; i++) { }(Highcharts));
801 < xData.length; i++) {}));