highcharts_rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }));