highstock-rails 1.3.10 → 2.1.10

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