highcharts_rails 0.1.0

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