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
@@ -0,0 +1,48 @@
1
+ /*
2
+ Highcharts JS v4.1.10 (2015-12-07)
3
+
4
+ 3D features for Highcharts JS
5
+
6
+ @license: www.highcharts.com/license
7
+ */
8
+ (function(c){typeof module==="object"&&module.exports?module.exports=c:c(Highcharts)})(function(c){function r(d,b,a){var e,g,f=b.options.chart.options3d,c=!1;a?(c=b.inverted,a=b.plotWidth/2,b=b.plotHeight/2,e=f.depth/2,g=u(f.depth,1)*u(f.viewDistance,0)):(a=b.plotLeft+b.plotWidth/2,b=b.plotTop+b.plotHeight/2,e=f.depth/2,g=u(f.depth,1)*u(f.viewDistance,0));var j=[],k=a,i=b,l=e,w=g,a=A*(c?f.beta:-f.beta),f=A*(c?-f.alpha:f.alpha),o=p(a),q=m(a),n=p(f),y=m(f),x,s,z,t,v,C;B(d,function(a){x=(c?a.y:a.x)-
9
+ k;s=(c?a.x:a.y)-i;z=(a.z||0)-l;t=q*x-o*z;v=-o*n*x+y*s-q*n*z;C=o*y*x+n*s+q*y*z;w>0&&w<Number.POSITIVE_INFINITY&&(t*=w/(C+l+w),v*=w/(C+l+w));t+=k;v+=i;C+=l;j.push({x:c?v:t,y:c?t:v,z:C})});return j}function D(d){return d!==void 0&&d!==null}function I(d){var b=0,a,e;for(a=0;a<d.length;a++)e=(a+1)%d.length,b+=d[a].x*d[e].y-d[e].x*d[a].y;return b/2}function F(d){var b=0,a;for(a=0;a<d.length;a++)b+=d[a].z;return d.length?b/d.length:0}function q(d,b,a,e,c,f,h,j){var k=[];f>c&&f-c>o/2+1.0E-4?(k=k.concat(q(d,
10
+ b,a,e,c,c+o/2,h,j)),k=k.concat(q(d,b,a,e,c+o/2,f,h,j))):f<c&&c-f>o/2+1.0E-4?(k=k.concat(q(d,b,a,e,c,c-o/2,h,j)),k=k.concat(q(d,b,a,e,c-o/2,f,h,j))):(k=f-c,k=["C",d+a*m(c)-a*E*k*p(c)+h,b+e*p(c)+e*E*k*m(c)+j,d+a*m(f)+a*E*k*p(f)+h,b+e*p(f)-e*E*k*m(f)+j,d+a*m(f)+h,b+e*p(f)+j]);return k}function J(d){if(this.chart.is3d()){var b=this.chart.options.plotOptions.column.grouping;if(b!==void 0&&!b&&this.group.zIndex!==void 0&&!this.zIndexSet)this.group.attr({zIndex:this.group.zIndex*10}),this.zIndexSet=!0;var a=
11
+ this.options,e=this.options.states;this.borderWidth=a.borderWidth=D(a.edgeWidth)?a.edgeWidth:1;c.each(this.data,function(b){if(b.y!==null)b=b.pointAttr,this.borderColor=c.pick(a.edgeColor,b[""].fill),b[""].stroke=this.borderColor,b.hover.stroke=c.pick(e.hover.edgeColor,this.borderColor),b.select.stroke=c.pick(e.select.edgeColor,this.borderColor)})}d.apply(this,[].slice.call(arguments,1))}var B=c.each,M=c.extend,N=c.inArray,G=c.merge,u=c.pick,K=c.wrap,o=Math.PI,A=o/180,p=Math.sin,m=Math.cos,L=Math.round;
12
+ c.perspective=r;var E=4*(Math.sqrt(2)-1)/3/(o/2);c.SVGRenderer.prototype.toLinePath=function(d,b){var a=[];c.each(d,function(b){a.push("L",b.x,b.y)});d.length&&(a[0]="M",b&&a.push("Z"));return a};c.SVGRenderer.prototype.cuboid=function(d){var b=this.g(),d=this.cuboidPath(d);b.front=this.path(d[0]).attr({zIndex:d[3],"stroke-linejoin":"round"}).add(b);b.top=this.path(d[1]).attr({zIndex:d[4],"stroke-linejoin":"round"}).add(b);b.side=this.path(d[2]).attr({zIndex:d[5],"stroke-linejoin":"round"}).add(b);
13
+ b.fillSetter=function(a){var b=c.Color(a).brighten(0.1).get(),d=c.Color(a).brighten(-0.1).get();this.front.attr({fill:a});this.top.attr({fill:b});this.side.attr({fill:d});this.color=a;return this};b.opacitySetter=function(a){this.front.attr({opacity:a});this.top.attr({opacity:a});this.side.attr({opacity:a});return this};b.attr=function(a){a.shapeArgs||D(a.x)?(a=this.renderer.cuboidPath(a.shapeArgs||a),this.front.attr({d:a[0],zIndex:a[3]}),this.top.attr({d:a[1],zIndex:a[4]}),this.side.attr({d:a[2],
14
+ zIndex:a[5]})):c.SVGElement.prototype.attr.call(this,a);return this};b.animate=function(a,b,d){D(a.x)&&D(a.y)?(a=this.renderer.cuboidPath(a),this.front.attr({zIndex:a[3]}).animate({d:a[0]},b,d),this.top.attr({zIndex:a[4]}).animate({d:a[1]},b,d),this.side.attr({zIndex:a[5]}).animate({d:a[2]},b,d)):a.opacity?(this.front.animate(a,b,d),this.top.animate(a,b,d),this.side.animate(a,b,d)):c.SVGElement.prototype.animate.call(this,a,b,d);return this};b.destroy=function(){this.front.destroy();this.top.destroy();
15
+ this.side.destroy();return null};b.attr({zIndex:-d[3]});return b};c.SVGRenderer.prototype.cuboidPath=function(d){function b(a){return i[a]}var a=d.x,e=d.y,g=d.z,f=d.height,h=d.width,j=d.depth,k=c.map,i=[{x:a,y:e,z:g},{x:a+h,y:e,z:g},{x:a+h,y:e+f,z:g},{x:a,y:e+f,z:g},{x:a,y:e+f,z:g+j},{x:a+h,y:e+f,z:g+j},{x:a+h,y:e,z:g+j},{x:a,y:e,z:g+j}],i=r(i,c.charts[this.chartIndex],d.insidePlotArea),e=function(a,d){a=k(a,b);d=k(d,b);return I(a)<0?a:I(d)<0?d:[]},d=e([3,2,1,0],[7,6,5,4]),a=e([1,6,7,0],[4,5,2,3]),
16
+ e=e([1,2,5,6],[0,7,4,3]);return[this.toLinePath(d,!0),this.toLinePath(a,!0),this.toLinePath(e,!0),F(d),F(a),F(e)]};c.SVGRenderer.prototype.arc3d=function(d){function b(a){var b=!1,d={},e;for(e in a)N(e,g)!==-1&&(d[e]=a[e],delete a[e],b=!0);return b?d:!1}var a=this.g(),e=a.renderer,g="x,y,r,innerR,start,end".split(","),d=G(d);d.alpha*=A;d.beta*=A;a.top=e.path();a.side1=e.path();a.side2=e.path();a.inn=e.path();a.out=e.path();a.onAdd=function(){var b=a.parentGroup;a.top.add(a);a.out.add(b);a.inn.add(b);
17
+ a.side1.add(b);a.side2.add(b)};a.setPaths=function(b){var d=a.renderer.arc3dPath(b),e=d.zTop*100;a.attribs=b;a.top.attr({d:d.top,zIndex:d.zTop});a.inn.attr({d:d.inn,zIndex:d.zInn});a.out.attr({d:d.out,zIndex:d.zOut});a.side1.attr({d:d.side1,zIndex:d.zSide1});a.side2.attr({d:d.side2,zIndex:d.zSide2});a.zIndex=e;a.attr({zIndex:e});b.center&&(a.top.setRadialReference(b.center),delete b.center)};a.setPaths(d);a.fillSetter=function(a){var b=c.Color(a).brighten(-0.1).get();this.fill=a;this.side1.attr({fill:b});
18
+ this.side2.attr({fill:b});this.inn.attr({fill:b});this.out.attr({fill:b});this.top.attr({fill:a});return this};B(["opacity","translateX","translateY","visibility"],function(b){a[b+"Setter"]=function(b,d){a[d]=b;B(["out","inn","side1","side2","top"],function(e){a[e].attr(d,b)})}});K(a,"attr",function(d,e,c){var g;if(typeof e==="object"&&(g=b(e)))M(a.attribs,g),a.setPaths(a.attribs);return d.call(this,e,c)});K(a,"animate",function(a,d,e,c){var g,l=this.attribs,m;delete d.center;delete d.z;delete d.depth;
19
+ delete d.alpha;delete d.beta;if(e=u(e,this.renderer.globalAnimation))if(typeof e!=="object"&&(e={}),d=G(d),g=b(d))m=g,e.step=function(a,b){function d(a){return l[a]+(u(m[a],l[a])-l[a])*b.pos}b.elem.setPaths(G(l,{x:d("x"),y:d("y"),r:d("r"),innerR:d("innerR"),start:d("start"),end:d("end")}))};return a.call(this,d,e,c)});a.destroy=function(){this.top.destroy();this.out.destroy();this.inn.destroy();this.side1.destroy();this.side2.destroy();c.SVGElement.prototype.destroy.call(this)};a.hide=function(){this.top.hide();
20
+ this.out.hide();this.inn.hide();this.side1.hide();this.side2.hide()};a.show=function(){this.top.show();this.out.show();this.inn.show();this.side1.show();this.side2.show()};return a};c.SVGRenderer.prototype.arc3dPath=function(d){function b(a){a%=2*o;a>o&&(a=2*o-a);return a}var a=d.x,e=d.y,c=d.start,f=d.end-1.0E-5,h=d.r,j=d.innerR,k=d.depth,i=d.alpha,l=d.beta,w=m(c),u=p(c),d=m(f),r=p(f),n=h*m(l);h*=m(i);var y=j*m(l),x=j*m(i),j=k*p(l),s=k*p(i),k=["M",a+n*w,e+h*u],k=k.concat(q(a,e,n,h,c,f,0,0)),k=k.concat(["L",
21
+ a+y*d,e+x*r]),k=k.concat(q(a,e,y,x,f,c,0,0)),k=k.concat(["Z"]),z=l>0?o/2:0,l=i>0?0:o/2,z=c>-z?c:f>-z?-z:c,t=f<o-l?f:c<o-l?o-l:f,v=2*o-l,i=["M",a+n*m(z),e+h*p(z)],i=i.concat(q(a,e,n,h,z,t,0,0));f>v&&c<v?(i=i.concat(["L",a+n*m(t)+j,e+h*p(t)+s]),i=i.concat(q(a,e,n,h,t,v,j,s)),i=i.concat(["L",a+n*m(v),e+h*p(v)]),i=i.concat(q(a,e,n,h,v,f,0,0)),i=i.concat(["L",a+n*m(f)+j,e+h*p(f)+s]),i=i.concat(q(a,e,n,h,f,v,j,s)),i=i.concat(["L",a+n*m(v),e+h*p(v)]),i=i.concat(q(a,e,n,h,v,t,0,0))):f>o-l&&c<o-l&&(i=i.concat(["L",
22
+ a+n*m(t)+j,e+h*p(t)+s]),i=i.concat(q(a,e,n,h,t,f,j,s)),i=i.concat(["L",a+n*m(f),e+h*p(f)]),i=i.concat(q(a,e,n,h,f,t,0,0)));i=i.concat(["L",a+n*m(t)+j,e+h*p(t)+s]);i=i.concat(q(a,e,n,h,t,z,j,s));i=i.concat(["Z"]);l=["M",a+y*w,e+x*u];l=l.concat(q(a,e,y,x,c,f,0,0));l=l.concat(["L",a+y*m(f)+j,e+x*p(f)+s]);l=l.concat(q(a,e,y,x,f,c,j,s));l=l.concat(["Z"]);w=["M",a+n*w,e+h*u,"L",a+n*w+j,e+h*u+s,"L",a+y*w+j,e+x*u+s,"L",a+y*w,e+x*u,"Z"];a=["M",a+n*d,e+h*r,"L",a+n*d+j,e+h*r+s,"L",a+y*d+j,e+x*r+s,"L",a+y*d,
23
+ e+x*r,"Z"];r=Math.atan2(s,-j);e=Math.abs(f+r);d=Math.abs(c+r);c=Math.abs((c+f)/2+r);e=b(e);d=b(d);c=b(c);c*=1E5;f=d*1E5;e*=1E5;return{top:k,zTop:o*1E5+1,out:i,zOut:Math.max(c,f,e),inn:l,zInn:Math.max(c,f,e),side1:w,zSide1:e*0.99,side2:a,zSide2:f*0.99}};c.Chart.prototype.is3d=function(){return this.options.chart.options3d&&this.options.chart.options3d.enabled};c.wrap(c.Chart.prototype,"isInsidePlot",function(d){return this.is3d()||d.apply(this,[].slice.call(arguments,1))});c.getOptions().chart.options3d=
24
+ {enabled:!1,alpha:0,beta:0,depth:100,viewDistance:25,frame:{bottom:{size:1,color:"rgba(255,255,255,0)"},side:{size:1,color:"rgba(255,255,255,0)"},back:{size:1,color:"rgba(255,255,255,0)"}}};c.wrap(c.Chart.prototype,"init",function(d){var b=[].slice.call(arguments,1),a;if(b[0].chart.options3d&&b[0].chart.options3d.enabled)b[0].chart.options3d.alpha=(b[0].chart.options3d.alpha||0)%360,b[0].chart.options3d.beta=(b[0].chart.options3d.beta||0)%360,a=b[0].plotOptions||{},a=a.pie||{},a.borderColor=c.pick(a.borderColor,
25
+ void 0);d.apply(this,b)});c.wrap(c.Chart.prototype,"setChartSize",function(d){d.apply(this,[].slice.call(arguments,1));if(this.is3d()){var b=this.inverted,a=this.clipBox,c=this.margin;a[b?"y":"x"]=-(c[3]||0);a[b?"x":"y"]=-(c[0]||0);a[b?"height":"width"]=this.chartWidth+(c[3]||0)+(c[1]||0);a[b?"width":"height"]=this.chartHeight+(c[0]||0)+(c[2]||0)}});c.wrap(c.Chart.prototype,"redraw",function(d){if(this.is3d())this.isDirtyBox=!0;d.apply(this,[].slice.call(arguments,1))});c.wrap(c.Chart.prototype,"renderSeries",
26
+ function(d){var b=this.series.length;if(this.is3d())for(;b--;)d=this.series[b],d.translate(),d.render();else d.call(this)});c.Chart.prototype.retrieveStacks=function(d){var b=this.series,a={},e,g=1;c.each(this.series,function(c){e=u(c.options.stack,d?0:b.length-1-c.index);a[e]?a[e].series.push(c):(a[e]={series:[c],position:g},g++)});a.totalStacks=g+1;return a};c.wrap(c.Axis.prototype,"setOptions",function(d,b){var a;d.call(this,b);if(this.chart.is3d())a=this.options,a.tickWidth=c.pick(a.tickWidth,
27
+ 0),a.gridLineWidth=c.pick(a.gridLineWidth,1)});c.wrap(c.Axis.prototype,"render",function(d){d.apply(this,[].slice.call(arguments,1));if(this.chart.is3d()){var b=this.chart,a=b.renderer,c=b.options.chart.options3d,g=c.frame,f=g.bottom,h=g.back,g=g.side,j=c.depth,k=this.height,i=this.width,l=this.left,m=this.top;if(!this.isZAxis)this.horiz?(h={x:l,y:m+(b.xAxis[0].opposite?-f.size:k),z:0,width:i,height:f.size,depth:j,insidePlotArea:!1},this.bottomFrame?this.bottomFrame.animate(h):this.bottomFrame=a.cuboid(h).attr({fill:f.color,
28
+ zIndex:b.yAxis[0].reversed&&c.alpha>0?4:-1}).css({stroke:f.color}).add()):(c={x:l+(b.yAxis[0].opposite?0:-g.size),y:m+(b.xAxis[0].opposite?-f.size:0),z:j,width:i+g.size,height:k+f.size,depth:h.size,insidePlotArea:!1},this.backFrame?this.backFrame.animate(c):this.backFrame=a.cuboid(c).attr({fill:h.color,zIndex:-3}).css({stroke:h.color}).add(),b={x:l+(b.yAxis[0].opposite?i:-g.size),y:m+(b.xAxis[0].opposite?-f.size:0),z:0,width:g.size,height:k+f.size,depth:j,insidePlotArea:!1},this.sideFrame?this.sideFrame.animate(b):
29
+ this.sideFrame=a.cuboid(b).attr({fill:g.color,zIndex:-2}).css({stroke:g.color}).add())}});c.wrap(c.Axis.prototype,"getPlotLinePath",function(d){var b=d.apply(this,[].slice.call(arguments,1));if(!this.chart.is3d())return b;if(b===null)return b;var a=this.chart,c=a.options.chart.options3d,a=this.isZAxis?a.plotWidth:c.depth,c=this.opposite;this.horiz&&(c=!c);b=[this.swapZ({x:b[1],y:b[2],z:c?a:0}),this.swapZ({x:b[1],y:b[2],z:a}),this.swapZ({x:b[4],y:b[5],z:a}),this.swapZ({x:b[4],y:b[5],z:c?0:a})];b=r(b,
30
+ this.chart,!1);return b=this.chart.renderer.toLinePath(b,!1)});c.wrap(c.Axis.prototype,"getLinePath",function(d){return this.chart.is3d()?[]:d.apply(this,[].slice.call(arguments,1))});c.wrap(c.Axis.prototype,"getPlotBandPath",function(d){if(!this.chart.is3d())return d.apply(this,[].slice.call(arguments,1));var b=arguments,a=b[1],b=this.getPlotLinePath(b[2]);(a=this.getPlotLinePath(a))&&b?a.push("L",b[10],b[11],"L",b[7],b[8],"L",b[4],b[5],"L",b[1],b[2]):a=null;return a});c.wrap(c.Tick.prototype,"getMarkPath",
31
+ function(d){var b=d.apply(this,[].slice.call(arguments,1));if(!this.axis.chart.is3d())return b;b=[this.axis.swapZ({x:b[1],y:b[2],z:0}),this.axis.swapZ({x:b[4],y:b[5],z:0})];b=r(b,this.axis.chart,!1);return b=["M",b[0].x,b[0].y,"L",b[1].x,b[1].y]});c.wrap(c.Tick.prototype,"getLabelPosition",function(d){var b=d.apply(this,[].slice.call(arguments,1));if(!this.axis.chart.is3d())return b;var a=r([this.axis.swapZ({x:b.x,y:b.y,z:0})],this.axis.chart,!1)[0];a.x-=!this.axis.horiz&&this.axis.opposite?this.axis.transA:
32
+ 0;a.old=b;return a});c.wrap(c.Tick.prototype,"handleOverflow",function(d,b){if(this.axis.chart.is3d())b=b.old;return d.call(this,b)});c.wrap(c.Axis.prototype,"getTitlePosition",function(d){var b=this.chart.is3d(),a,c;if(b)c=this.axisTitleMargin,this.axisTitleMargin=0;a=d.apply(this,[].slice.call(arguments,1));if(b)a=r([this.swapZ({x:a.x,y:a.y,z:0})],this.chart,!1)[0],a[this.horiz?"y":"x"]+=(this.horiz?1:-1)*(this.opposite?-1:1)*c,this.axisTitleMargin=c;return a});c.wrap(c.Axis.prototype,"drawCrosshair",
33
+ function(d){var b=arguments;this.chart.is3d()&&b[2]&&(b[2]={plotX:b[2].plotXold||b[2].plotX,plotY:b[2].plotYold||b[2].plotY});d.apply(this,[].slice.call(b,1))});c.Axis.prototype.swapZ=function(d,b){if(this.isZAxis){var a=b?0:this.chart.plotLeft,c=this.chart;return{x:a+(c.yAxis[0].opposite?d.z:c.xAxis[0].width-d.z),y:d.y,z:d.x-a}}return d};var H=c.ZAxis=function(){this.isZAxis=!0;this.init.apply(this,arguments)};c.extend(H.prototype,c.Axis.prototype);c.extend(H.prototype,{setOptions:function(d){d=
34
+ c.merge({offset:0,lineWidth:0},d);c.Axis.prototype.setOptions.call(this,d);this.coll="zAxis"},setAxisSize:function(){c.Axis.prototype.setAxisSize.call(this);this.width=this.len=this.chart.options.chart.options3d.depth;this.right=this.chart.chartWidth-this.width-this.left},getSeriesExtremes:function(){var d=this,b=d.chart;d.hasVisibleSeries=!1;d.dataMin=d.dataMax=d.ignoreMinPadding=d.ignoreMaxPadding=null;d.buildStacks&&d.buildStacks();c.each(d.series,function(a){if(a.visible||!b.options.chart.ignoreHiddenSeries)if(d.hasVisibleSeries=
35
+ !0,a=a.zData,a.length)d.dataMin=Math.min(u(d.dataMin,a[0]),Math.min.apply(null,a)),d.dataMax=Math.max(u(d.dataMax,a[0]),Math.max.apply(null,a))})}});c.wrap(c.Chart.prototype,"getAxes",function(d){var b=this,a=this.options,a=a.zAxis=c.splat(a.zAxis||{});d.call(this);if(b.is3d())this.zAxis=[],c.each(a,function(a,d){a.index=d;a.isX=!0;(new H(b,a)).setScale()})});c.wrap(c.seriesTypes.column.prototype,"translate",function(d){d.apply(this,[].slice.call(arguments,1));if(this.chart.is3d()){var b=this.chart,
36
+ a=this.options,e=a.depth||25,g=(a.stacking?a.stack||0:this._i)*(e+(a.groupZPadding||1));a.grouping!==!1&&(g=0);g+=a.groupZPadding||1;c.each(this.data,function(a){if(a.y!==null){var d=a.shapeArgs,c=a.tooltipPos;a.shapeType="cuboid";d.z=g;d.depth=e;d.insidePlotArea=!0;c=r([{x:c[0],y:c[1],z:g}],b,!1)[0];a.tooltipPos=[c.x,c.y]}});this.z=g}});c.wrap(c.seriesTypes.column.prototype,"animate",function(d){if(this.chart.is3d()){var b=arguments[1],a=this.yAxis,e=this,g=this.yAxis.reversed;if(c.svg)b?c.each(e.data,
37
+ function(b){if(b.y!==null&&(b.height=b.shapeArgs.height,b.shapey=b.shapeArgs.y,b.shapeArgs.height=1,!g))b.shapeArgs.y=b.stackY?b.plotY+a.translate(b.stackY):b.plotY+(b.negative?-b.height:b.height)}):(c.each(e.data,function(a){if(a.y!==null)a.shapeArgs.height=a.height,a.shapeArgs.y=a.shapey,a.graphic&&a.graphic.animate(a.shapeArgs,e.options.animation)}),this.drawDataLabels(),e.animate=null)}else d.apply(this,[].slice.call(arguments,1))});c.wrap(c.seriesTypes.column.prototype,"init",function(d){d.apply(this,
38
+ [].slice.call(arguments,1));if(this.chart.is3d()){var b=this.options,a=b.grouping,c=b.stacking,g=u(this.yAxis.options.reversedStacks,!0),f=0;if(a===void 0||a){a=this.chart.retrieveStacks(c);f=b.stack||0;for(c=0;c<a[f].series.length;c++)if(a[f].series[c]===this)break;f=10*(a.totalStacks-a[f].position)+(g?c:-c);this.xAxis.reversed||(f=a.totalStacks*10-f)}b.zIndex=f}});c.wrap(c.Series.prototype,"alignDataLabel",function(c){if(this.chart.is3d()&&(this.type==="column"||this.type==="columnrange")){var b=
39
+ arguments[4],a={x:b.x,y:b.y,z:this.z},a=r([a],this.chart,!0)[0];b.x=a.x;b.y=a.y}c.apply(this,[].slice.call(arguments,1))});c.seriesTypes.columnrange&&c.wrap(c.seriesTypes.columnrange.prototype,"drawPoints",J);c.wrap(c.seriesTypes.column.prototype,"drawPoints",J);c.wrap(c.seriesTypes.pie.prototype,"translate",function(c){c.apply(this,[].slice.call(arguments,1));if(this.chart.is3d()){var b=this,a=b.options,e=a.depth||0,g=b.chart.options.chart.options3d,f=g.alpha,h=g.beta,j=a.stacking?(a.stack||0)*e:
40
+ b._i*e;j+=e/2;a.grouping!==!1&&(j=0);B(b.data,function(c){var d=c.shapeArgs;c.shapeType="arc3d";d.z=j;d.depth=e*0.75;d.alpha=f;d.beta=h;d.center=b.center;d=(d.end+d.start)/2;c.slicedTranslation={translateX:L(m(d)*a.slicedOffset*m(f*A)),translateY:L(p(d)*a.slicedOffset*m(f*A))}})}});c.wrap(c.seriesTypes.pie.prototype.pointClass.prototype,"haloPath",function(c){var b=arguments;return this.series.chart.is3d()?[]:c.call(this,b[1])});c.wrap(c.seriesTypes.pie.prototype,"drawPoints",function(d){var b=this.options,
41
+ a=b.states;if(this.chart.is3d())this.borderWidth=b.borderWidth=b.edgeWidth||1,this.borderColor=b.edgeColor=c.pick(b.edgeColor,b.borderColor,void 0),a.hover.borderColor=c.pick(a.hover.edgeColor,this.borderColor),a.hover.borderWidth=c.pick(a.hover.edgeWidth,this.borderWidth),a.select.borderColor=c.pick(a.select.edgeColor,this.borderColor),a.select.borderWidth=c.pick(a.select.edgeWidth,this.borderWidth),B(this.data,function(b){var c=b.pointAttr;c[""].stroke=b.series.borderColor||b.color;c[""]["stroke-width"]=
42
+ b.series.borderWidth;c.hover.stroke=a.hover.borderColor;c.hover["stroke-width"]=a.hover.borderWidth;c.select.stroke=a.select.borderColor;c.select["stroke-width"]=a.select.borderWidth});d.apply(this,[].slice.call(arguments,1));this.chart.is3d()&&B(this.points,function(a){var b=a.graphic;if(b)b[a.y?"show":"hide"]()})});c.wrap(c.seriesTypes.pie.prototype,"drawDataLabels",function(c){if(this.chart.is3d()){var b=this.chart.options.chart.options3d;B(this.data,function(a){var c=a.shapeArgs,d=c.r,f=(c.beta||
43
+ b.beta)*A,h=(c.start+c.end)/2,j=a.labelPos,k=-d*(1-m((c.alpha||b.alpha)*A))*p(h),i=d*(m(f)-1)*m(h);B([0,2,4],function(a){j[a]+=i;j[a+1]+=k})})}c.apply(this,[].slice.call(arguments,1))});c.wrap(c.seriesTypes.pie.prototype,"addPoint",function(c){c.apply(this,[].slice.call(arguments,1));this.chart.is3d()&&this.update(this.userOptions,!0)});c.wrap(c.seriesTypes.pie.prototype,"animate",function(d){if(this.chart.is3d()){var b=arguments[1],a=this.options.animation,e=this.center,g=this.group,f=this.markerGroup;
44
+ if(c.svg)if(a===!0&&(a={}),b){if(g.oldtranslateX=g.translateX,g.oldtranslateY=g.translateY,b={translateX:e[0],translateY:e[1],scaleX:0.001,scaleY:0.001},g.attr(b),f)f.attrSetters=g.attrSetters,f.attr(b)}else b={translateX:g.oldtranslateX,translateY:g.oldtranslateY,scaleX:1,scaleY:1},g.animate(b,a),f&&f.animate(b,a),this.animate=null}else d.apply(this,[].slice.call(arguments,1))});c.wrap(c.seriesTypes.scatter.prototype,"translate",function(d){d.apply(this,[].slice.call(arguments,1));if(this.chart.is3d()){var b=
45
+ this.chart,a=c.pick(this.zAxis,b.options.zAxis[0]),e=[],g,f,h;for(h=0;h<this.data.length;h++)g=this.data[h],f=a.isLog&&a.val2lin?a.val2lin(g.z):g.z,g.plotZ=a.translate(f),g.isInside=g.isInside?f>=a.min&&f<=a.max:!1,e.push({x:g.plotX,y:g.plotY,z:g.plotZ});b=r(e,b,!0);for(h=0;h<this.data.length;h++)g=this.data[h],a=b[h],g.plotXold=g.plotX,g.plotYold=g.plotY,g.plotX=a.x,g.plotY=a.y,g.plotZ=a.z}});c.wrap(c.seriesTypes.scatter.prototype,"init",function(c,b,a){if(b.is3d())this.axisTypes=["xAxis","yAxis",
46
+ "zAxis"],this.pointArrayMap=["x","y","z"],this.parallelArrays=["x","y","z"];c=c.apply(this,[b,a]);if(this.chart.is3d())this.tooltipOptions.pointFormat=this.userOptions.tooltip?this.userOptions.tooltip.pointFormat||"x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>z: <b>{point.z}</b><br/>":"x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>z: <b>{point.z}</b><br/>";return c});if(c.VMLRenderer)c.setOptions({animate:!1}),c.VMLRenderer.prototype.cuboid=c.SVGRenderer.prototype.cuboid,c.VMLRenderer.prototype.cuboidPath=
47
+ c.SVGRenderer.prototype.cuboidPath,c.VMLRenderer.prototype.toLinePath=c.SVGRenderer.prototype.toLinePath,c.VMLRenderer.prototype.createElement3D=c.SVGRenderer.prototype.createElement3D,c.VMLRenderer.prototype.arc3d=function(d){d=c.SVGRenderer.prototype.arc3d.call(this,d);d.css({zIndex:d.zIndex});return d},c.VMLRenderer.prototype.arc3dPath=c.SVGRenderer.prototype.arc3dPath,c.wrap(c.Axis.prototype,"render",function(c){c.apply(this,[].slice.call(arguments,1));this.sideFrame&&(this.sideFrame.css({zIndex:0}),
48
+ this.sideFrame.front.attr({fill:this.sideFrame.color}));this.bottomFrame&&(this.bottomFrame.css({zIndex:1}),this.bottomFrame.front.attr({fill:this.bottomFrame.color}));this.backFrame&&(this.backFrame.css({zIndex:0}),this.backFrame.front.attr({fill:this.backFrame.color}))})});
@@ -0,0 +1,1711 @@
1
+ // ==ClosureCompiler==
2
+ // @compilation_level SIMPLE_OPTIMIZATIONS
3
+
4
+ /**
5
+ * @license Highcharts JS v4.1.10 (2015-12-07)
6
+ *
7
+ * 3D features for Highcharts JS
8
+ *
9
+ * @license: www.highcharts.com/license
10
+ */
11
+
12
+ (function (factory) {
13
+ if (typeof module === 'object' && module.exports) {
14
+ module.exports = factory;
15
+ } else {
16
+ factory(Highcharts);
17
+ }
18
+ }(function (Highcharts) {
19
+ /**
20
+ Shorthands for often used function
21
+ */
22
+ var each = Highcharts.each,
23
+ extend = Highcharts.extend,
24
+ inArray = Highcharts.inArray,
25
+ merge = Highcharts.merge,
26
+ pick = Highcharts.pick,
27
+ wrap = Highcharts.wrap;
28
+ /**
29
+ * Mathematical Functionility
30
+ */
31
+ var PI = Math.PI,
32
+ deg2rad = (PI / 180), // degrees to radians
33
+ sin = Math.sin,
34
+ cos = Math.cos,
35
+ round = Math.round;
36
+
37
+ /**
38
+ * Transforms a given array of points according to the angles in chart.options.
39
+ * Parameters:
40
+ * - points: the array of points
41
+ * - chart: the chart
42
+ * - insidePlotArea: wether to verifiy the points are inside the plotArea
43
+ * Returns:
44
+ * - an array of transformed points
45
+ */
46
+ function perspective(points, chart, insidePlotArea) {
47
+ var options3d = chart.options.chart.options3d,
48
+ inverted = false,
49
+ origin;
50
+
51
+ if (insidePlotArea) {
52
+ inverted = chart.inverted;
53
+ origin = {
54
+ x: chart.plotWidth / 2,
55
+ y: chart.plotHeight / 2,
56
+ z: options3d.depth / 2,
57
+ vd: pick(options3d.depth, 1) * pick(options3d.viewDistance, 0)
58
+ };
59
+ } else {
60
+ origin = {
61
+ x: chart.plotLeft + (chart.plotWidth / 2),
62
+ y: chart.plotTop + (chart.plotHeight / 2),
63
+ z: options3d.depth / 2,
64
+ vd: pick(options3d.depth, 1) * pick(options3d.viewDistance, 0)
65
+ };
66
+ }
67
+
68
+ var result = [],
69
+ xe = origin.x,
70
+ ye = origin.y,
71
+ ze = origin.z,
72
+ vd = origin.vd,
73
+ angle1 = deg2rad * (inverted ? options3d.beta : -options3d.beta),
74
+ angle2 = deg2rad * (inverted ? -options3d.alpha : options3d.alpha),
75
+ s1 = sin(angle1),
76
+ c1 = cos(angle1),
77
+ s2 = sin(angle2),
78
+ c2 = cos(angle2);
79
+
80
+ var x, y, z, px, py, pz;
81
+
82
+ // Transform each point
83
+ each(points, function (point) {
84
+ x = (inverted ? point.y : point.x) - xe;
85
+ y = (inverted ? point.x : point.y) - ye;
86
+ z = (point.z || 0) - ze;
87
+
88
+ // Apply 3-D rotation
89
+ // Euler Angles (XYZ): cosA = cos(Alfa|Roll), cosB = cos(Beta|Pitch), cosG = cos(Gamma|Yaw)
90
+ //
91
+ // Composite rotation:
92
+ // | cosB * cosG | cosB * sinG | -sinB |
93
+ // | sinA * sinB * cosG - cosA * sinG | sinA * sinB * sinG + cosA * cosG | sinA * cosB |
94
+ // | cosA * sinB * cosG + sinA * sinG | cosA * sinB * sinG - sinA * cosG | cosA * cosB |
95
+ //
96
+ // Now, Gamma/Yaw is not used (angle=0), so we assume cosG = 1 and sinG = 0, so we get:
97
+ // | cosB | 0 | - sinB |
98
+ // | sinA * sinB | cosA | sinA * cosB |
99
+ // | cosA * sinB | - sinA | cosA * cosB |
100
+ //
101
+ // But in browsers, y is reversed, so we get sinA => -sinA. The general result is:
102
+ // | cosB | 0 | - sinB | | x | | px |
103
+ // | - sinA * sinB | cosA | - sinA * cosB | x | y | = | py |
104
+ // | cosA * sinB | sinA | cosA * cosB | | z | | pz |
105
+ //
106
+ // Result:
107
+ px = c1 * x - s1 * z;
108
+ py = -s1 * s2 * x + c2 * y - c1 * s2 * z;
109
+ pz = s1 * c2 * x + s2 * y + c1 * c2 * z;
110
+
111
+
112
+ // Apply perspective
113
+ if ((vd > 0) && (vd < Number.POSITIVE_INFINITY)) {
114
+ px = px * (vd / (pz + ze + vd));
115
+ py = py * (vd / (pz + ze + vd));
116
+ }
117
+
118
+ //Apply translation
119
+ px = px + xe;
120
+ py = py + ye;
121
+ pz = pz + ze;
122
+
123
+ result.push({
124
+ x: (inverted ? py : px),
125
+ y: (inverted ? px : py),
126
+ z: pz
127
+ });
128
+ });
129
+ return result;
130
+ }
131
+ // Make function acessible to plugins
132
+ Highcharts.perspective = perspective;
133
+ /***
134
+ EXTENSION TO THE SVG-RENDERER TO ENABLE 3D SHAPES
135
+ ***/
136
+ ////// HELPER METHODS //////
137
+
138
+ var dFactor = (4 * (Math.sqrt(2) - 1) / 3) / (PI / 2);
139
+
140
+ function defined(obj) {
141
+ return obj !== undefined && obj !== null;
142
+ }
143
+
144
+ //Shoelace algorithm -- http://en.wikipedia.org/wiki/Shoelace_formula
145
+ function shapeArea(vertexes) {
146
+ var area = 0,
147
+ i,
148
+ j;
149
+ for (i = 0; i < vertexes.length; i++) {
150
+ j = (i + 1) % vertexes.length;
151
+ area += vertexes[i].x * vertexes[j].y - vertexes[j].x * vertexes[i].y;
152
+ }
153
+ return area / 2;
154
+ }
155
+
156
+ function averageZ(vertexes) {
157
+ var z = 0,
158
+ i;
159
+ for (i = 0; i < vertexes.length; i++) {
160
+ z += vertexes[i].z;
161
+ }
162
+ return vertexes.length ? z / vertexes.length : 0;
163
+ }
164
+
165
+ /** Method to construct a curved path
166
+ * Can 'wrap' around more then 180 degrees
167
+ */
168
+ function curveTo(cx, cy, rx, ry, start, end, dx, dy) {
169
+ var result = [];
170
+ if ((end > start) && (end - start > PI / 2 + 0.0001)) {
171
+ result = result.concat(curveTo(cx, cy, rx, ry, start, start + (PI / 2), dx, dy));
172
+ result = result.concat(curveTo(cx, cy, rx, ry, start + (PI / 2), end, dx, dy));
173
+ } else if ((end < start) && (start - end > PI / 2 + 0.0001)) {
174
+ result = result.concat(curveTo(cx, cy, rx, ry, start, start - (PI / 2), dx, dy));
175
+ result = result.concat(curveTo(cx, cy, rx, ry, start - (PI / 2), end, dx, dy));
176
+ } else {
177
+ var arcAngle = end - start;
178
+ result = [
179
+ 'C',
180
+ cx + (rx * cos(start)) - ((rx * dFactor * arcAngle) * sin(start)) + dx,
181
+ cy + (ry * sin(start)) + ((ry * dFactor * arcAngle) * cos(start)) + dy,
182
+ cx + (rx * cos(end)) + ((rx * dFactor * arcAngle) * sin(end)) + dx,
183
+ cy + (ry * sin(end)) - ((ry * dFactor * arcAngle) * cos(end)) + dy,
184
+
185
+ cx + (rx * cos(end)) + dx,
186
+ cy + (ry * sin(end)) + dy
187
+ ];
188
+ }
189
+ return result;
190
+ }
191
+
192
+ Highcharts.SVGRenderer.prototype.toLinePath = function (points, closed) {
193
+ var result = [];
194
+
195
+ // Put "L x y" for each point
196
+ Highcharts.each(points, function (point) {
197
+ result.push('L', point.x, point.y);
198
+ });
199
+
200
+ if (points.length) {
201
+ // Set the first element to M
202
+ result[0] = 'M';
203
+
204
+ // If it is a closed line, add Z
205
+ if (closed) {
206
+ result.push('Z');
207
+ }
208
+ }
209
+
210
+ return result;
211
+ };
212
+
213
+ ////// CUBOIDS //////
214
+ Highcharts.SVGRenderer.prototype.cuboid = function (shapeArgs) {
215
+
216
+ var result = this.g(),
217
+ paths = this.cuboidPath(shapeArgs);
218
+
219
+ // create the 3 sides
220
+ result.front = this.path(paths[0]).attr({ zIndex: paths[3], 'stroke-linejoin': 'round' }).add(result);
221
+ result.top = this.path(paths[1]).attr({ zIndex: paths[4], 'stroke-linejoin': 'round' }).add(result);
222
+ result.side = this.path(paths[2]).attr({ zIndex: paths[5], 'stroke-linejoin': 'round' }).add(result);
223
+
224
+ // apply the fill everywhere, the top a bit brighter, the side a bit darker
225
+ result.fillSetter = function (color) {
226
+ var c0 = color,
227
+ c1 = Highcharts.Color(color).brighten(0.1).get(),
228
+ c2 = Highcharts.Color(color).brighten(-0.1).get();
229
+
230
+ this.front.attr({ fill: c0 });
231
+ this.top.attr({ fill: c1 });
232
+ this.side.attr({ fill: c2 });
233
+
234
+ this.color = color;
235
+ return this;
236
+ };
237
+
238
+ // apply opacaity everywhere
239
+ result.opacitySetter = function (opacity) {
240
+ this.front.attr({ opacity: opacity });
241
+ this.top.attr({ opacity: opacity });
242
+ this.side.attr({ opacity: opacity });
243
+ return this;
244
+ };
245
+
246
+ result.attr = function (args) {
247
+ if (args.shapeArgs || defined(args.x)) {
248
+ var shapeArgs = args.shapeArgs || args;
249
+ var paths = this.renderer.cuboidPath(shapeArgs);
250
+ this.front.attr({ d: paths[0], zIndex: paths[3] });
251
+ this.top.attr({ d: paths[1], zIndex: paths[4] });
252
+ this.side.attr({ d: paths[2], zIndex: paths[5] });
253
+ } else {
254
+ Highcharts.SVGElement.prototype.attr.call(this, args);
255
+ }
256
+
257
+ return this;
258
+ };
259
+
260
+ result.animate = function (args, duration, complete) {
261
+ if (defined(args.x) && defined(args.y)) {
262
+ var paths = this.renderer.cuboidPath(args);
263
+ this.front.attr({ zIndex: paths[3] }).animate({ d: paths[0] }, duration, complete);
264
+ this.top.attr({ zIndex: paths[4] }).animate({ d: paths[1] }, duration, complete);
265
+ this.side.attr({ zIndex: paths[5] }).animate({ d: paths[2] }, duration, complete);
266
+ } else if (args.opacity) {
267
+ this.front.animate(args, duration, complete);
268
+ this.top.animate(args, duration, complete);
269
+ this.side.animate(args, duration, complete);
270
+ } else {
271
+ Highcharts.SVGElement.prototype.animate.call(this, args, duration, complete);
272
+ }
273
+ return this;
274
+ };
275
+
276
+ // destroy all children
277
+ result.destroy = function () {
278
+ this.front.destroy();
279
+ this.top.destroy();
280
+ this.side.destroy();
281
+
282
+ return null;
283
+ };
284
+
285
+ // Apply the Z index to the cuboid group
286
+ result.attr({ zIndex: -paths[3] });
287
+
288
+ return result;
289
+ };
290
+
291
+ /**
292
+ * Generates a cuboid
293
+ */
294
+ Highcharts.SVGRenderer.prototype.cuboidPath = function (shapeArgs) {
295
+ var x = shapeArgs.x,
296
+ y = shapeArgs.y,
297
+ z = shapeArgs.z,
298
+ h = shapeArgs.height,
299
+ w = shapeArgs.width,
300
+ d = shapeArgs.depth,
301
+ chart = Highcharts.charts[this.chartIndex],
302
+ map = Highcharts.map;
303
+
304
+ // The 8 corners of the cube
305
+ var pArr = [
306
+ { x: x, y: y, z: z },
307
+ { x: x + w, y: y, z: z },
308
+ { x: x + w, y: y + h, z: z },
309
+ { x: x, y: y + h, z: z },
310
+ { x: x, y: y + h, z: z + d },
311
+ { x: x + w, y: y + h, z: z + d },
312
+ { x: x + w, y: y, z: z + d },
313
+ { x: x, y: y, z: z + d }
314
+ ];
315
+
316
+ // apply perspective
317
+ pArr = perspective(pArr, chart, shapeArgs.insidePlotArea);
318
+
319
+ // helper method to decide which side is visible
320
+ function mapPath(i) {
321
+ return pArr[i];
322
+ }
323
+ var pickShape = function (path1, path2) {
324
+ var ret;
325
+ path1 = map(path1, mapPath);
326
+ path2 = map(path2, mapPath);
327
+ if (shapeArea(path1) < 0) {
328
+ ret = path1;
329
+ } else if (shapeArea(path2) < 0) {
330
+ ret = path2;
331
+ } else {
332
+ ret = [];
333
+ }
334
+ return ret;
335
+ };
336
+
337
+ // front or back
338
+ var front = [3, 2, 1, 0];
339
+ var back = [7, 6, 5, 4];
340
+ var path1 = pickShape(front, back);
341
+
342
+ // top or bottom
343
+ var top = [1, 6, 7, 0];
344
+ var bottom = [4, 5, 2, 3];
345
+ var path2 = pickShape(top, bottom);
346
+
347
+ // side
348
+ var right = [1, 2, 5, 6];
349
+ var left = [0, 7, 4, 3];
350
+ var path3 = pickShape(right, left);
351
+
352
+ return [this.toLinePath(path1, true), this.toLinePath(path2, true), this.toLinePath(path3, true), averageZ(path1), averageZ(path2), averageZ(path3)];
353
+ };
354
+
355
+ ////// SECTORS //////
356
+ Highcharts.SVGRenderer.prototype.arc3d = function (attribs) {
357
+
358
+ var wrapper = this.g(),
359
+ renderer = wrapper.renderer,
360
+ customAttribs = ['x', 'y', 'r', 'innerR', 'start', 'end'];
361
+
362
+ /**
363
+ * Get custom attributes. Mutate the original object and return an object with only custom attr.
364
+ */
365
+ function suckOutCustom(params) {
366
+ var hasCA = false,
367
+ ca = {};
368
+ for (var key in params) {
369
+ if (inArray(key, customAttribs) !== -1) {
370
+ ca[key] = params[key];
371
+ delete params[key];
372
+ hasCA = true;
373
+ }
374
+ }
375
+ return hasCA ? ca : false;
376
+ }
377
+
378
+ attribs = merge(attribs);
379
+
380
+ attribs.alpha *= deg2rad;
381
+ attribs.beta *= deg2rad;
382
+
383
+ // Create the different sub sections of the shape
384
+ wrapper.top = renderer.path();
385
+ wrapper.side1 = renderer.path();
386
+ wrapper.side2 = renderer.path();
387
+ wrapper.inn = renderer.path();
388
+ wrapper.out = renderer.path();
389
+
390
+ /**
391
+ * Add all faces
392
+ */
393
+ wrapper.onAdd = function () {
394
+ var parent = wrapper.parentGroup;
395
+ wrapper.top.add(wrapper);
396
+ wrapper.out.add(parent);
397
+ wrapper.inn.add(parent);
398
+ wrapper.side1.add(parent);
399
+ wrapper.side2.add(parent);
400
+ };
401
+
402
+ /**
403
+ * Compute the transformed paths and set them to the composite shapes
404
+ */
405
+ wrapper.setPaths = function (attribs) {
406
+
407
+ var paths = wrapper.renderer.arc3dPath(attribs),
408
+ zIndex = paths.zTop * 100;
409
+
410
+ wrapper.attribs = attribs;
411
+
412
+ wrapper.top.attr({ d: paths.top, zIndex: paths.zTop });
413
+ wrapper.inn.attr({ d: paths.inn, zIndex: paths.zInn });
414
+ wrapper.out.attr({ d: paths.out, zIndex: paths.zOut });
415
+ wrapper.side1.attr({ d: paths.side1, zIndex: paths.zSide1 });
416
+ wrapper.side2.attr({ d: paths.side2, zIndex: paths.zSide2 });
417
+
418
+
419
+ // show all children
420
+ wrapper.zIndex = zIndex;
421
+ wrapper.attr({ zIndex: zIndex });
422
+
423
+ // Set the radial gradient center the first time
424
+ if (attribs.center) {
425
+ wrapper.top.setRadialReference(attribs.center);
426
+ delete attribs.center;
427
+ }
428
+ };
429
+ wrapper.setPaths(attribs);
430
+
431
+ // Apply the fill to the top and a darker shade to the sides
432
+ wrapper.fillSetter = function (value) {
433
+ var darker = Highcharts.Color(value).brighten(-0.1).get();
434
+
435
+ this.fill = value;
436
+
437
+ this.side1.attr({ fill: darker });
438
+ this.side2.attr({ fill: darker });
439
+ this.inn.attr({ fill: darker });
440
+ this.out.attr({ fill: darker });
441
+ this.top.attr({ fill: value });
442
+ return this;
443
+ };
444
+
445
+ // Apply the same value to all. These properties cascade down to the children
446
+ // when set to the composite arc3d.
447
+ each(['opacity', 'translateX', 'translateY', 'visibility'], function (setter) {
448
+ wrapper[setter + 'Setter'] = function (value, key) {
449
+ wrapper[key] = value;
450
+ each(['out', 'inn', 'side1', 'side2', 'top'], function (el) {
451
+ wrapper[el].attr(key, value);
452
+ });
453
+ };
454
+ });
455
+
456
+ /**
457
+ * Override attr to remove shape attributes and use those to set child paths
458
+ */
459
+ wrap(wrapper, 'attr', function (proceed, params, val) {
460
+ var ca;
461
+ if (typeof params === 'object') {
462
+ ca = suckOutCustom(params);
463
+ if (ca) {
464
+ extend(wrapper.attribs, ca);
465
+ wrapper.setPaths(wrapper.attribs);
466
+ }
467
+ }
468
+ return proceed.call(this, params, val);
469
+ });
470
+
471
+ /**
472
+ * Override the animate function by sucking out custom parameters related to the shapes directly,
473
+ * and update the shapes from the animation step.
474
+ */
475
+ wrap(wrapper, 'animate', function (proceed, params, animation, complete) {
476
+ var ca,
477
+ from = this.attribs,
478
+ to;
479
+
480
+ // Attribute-line properties connected to 3D. These shouldn't have been in the
481
+ // attribs collection in the first place.
482
+ delete params.center;
483
+ delete params.z;
484
+ delete params.depth;
485
+ delete params.alpha;
486
+ delete params.beta;
487
+
488
+ animation = pick(animation, this.renderer.globalAnimation);
489
+
490
+ if (animation) {
491
+ if (typeof animation !== 'object') {
492
+ animation = {};
493
+ }
494
+
495
+ params = merge(params); // Don't mutate the original object
496
+ ca = suckOutCustom(params);
497
+
498
+ if (ca) {
499
+ to = ca;
500
+ animation.step = function (a, fx) {
501
+ function interpolate(key) {
502
+ return from[key] + (pick(to[key], from[key]) - from[key]) * fx.pos;
503
+ }
504
+ fx.elem.setPaths(merge(from, {
505
+ x: interpolate('x'),
506
+ y: interpolate('y'),
507
+ r: interpolate('r'),
508
+ innerR: interpolate('innerR'),
509
+ start: interpolate('start'),
510
+ end: interpolate('end')
511
+ }));
512
+ };
513
+ }
514
+ }
515
+ return proceed.call(this, params, animation, complete);
516
+ });
517
+
518
+ // destroy all children
519
+ wrapper.destroy = function () {
520
+ this.top.destroy();
521
+ this.out.destroy();
522
+ this.inn.destroy();
523
+ this.side1.destroy();
524
+ this.side2.destroy();
525
+
526
+ Highcharts.SVGElement.prototype.destroy.call(this);
527
+ };
528
+ // hide all children
529
+ wrapper.hide = function () {
530
+ this.top.hide();
531
+ this.out.hide();
532
+ this.inn.hide();
533
+ this.side1.hide();
534
+ this.side2.hide();
535
+ };
536
+ wrapper.show = function () {
537
+ this.top.show();
538
+ this.out.show();
539
+ this.inn.show();
540
+ this.side1.show();
541
+ this.side2.show();
542
+ };
543
+ return wrapper;
544
+ };
545
+
546
+ /**
547
+ * Generate the paths required to draw a 3D arc
548
+ */
549
+ Highcharts.SVGRenderer.prototype.arc3dPath = function (shapeArgs) {
550
+ var cx = shapeArgs.x, // x coordinate of the center
551
+ cy = shapeArgs.y, // y coordinate of the center
552
+ start = shapeArgs.start, // start angle
553
+ end = shapeArgs.end - 0.00001, // end angle
554
+ r = shapeArgs.r, // radius
555
+ ir = shapeArgs.innerR, // inner radius
556
+ d = shapeArgs.depth, // depth
557
+ alpha = shapeArgs.alpha, // alpha rotation of the chart
558
+ beta = shapeArgs.beta; // beta rotation of the chart
559
+
560
+ // Derived Variables
561
+ var cs = cos(start), // cosinus of the start angle
562
+ ss = sin(start), // sinus of the start angle
563
+ ce = cos(end), // cosinus of the end angle
564
+ se = sin(end), // sinus of the end angle
565
+ rx = r * cos(beta), // x-radius
566
+ ry = r * cos(alpha), // y-radius
567
+ irx = ir * cos(beta), // x-radius (inner)
568
+ iry = ir * cos(alpha), // y-radius (inner)
569
+ dx = d * sin(beta), // distance between top and bottom in x
570
+ dy = d * sin(alpha); // distance between top and bottom in y
571
+
572
+ // TOP
573
+ var top = ['M', cx + (rx * cs), cy + (ry * ss)];
574
+ top = top.concat(curveTo(cx, cy, rx, ry, start, end, 0, 0));
575
+ top = top.concat([
576
+ 'L', cx + (irx * ce), cy + (iry * se)
577
+ ]);
578
+ top = top.concat(curveTo(cx, cy, irx, iry, end, start, 0, 0));
579
+ top = top.concat(['Z']);
580
+ // OUTSIDE
581
+ var b = (beta > 0 ? PI / 2 : 0),
582
+ a = (alpha > 0 ? 0 : PI / 2);
583
+
584
+ var start2 = start > -b ? start : (end > -b ? -b : start),
585
+ end2 = end < PI - a ? end : (start < PI - a ? PI - a : end),
586
+ midEnd = 2 * PI - a;
587
+
588
+ // When slice goes over bottom middle, need to add both, left and right outer side.
589
+ // Additionally, when we cross right hand edge, create sharp edge. Outer shape/wall:
590
+ //
591
+ // -------
592
+ // / ^ \
593
+ // 4) / / \ \ 1)
594
+ // / / \ \
595
+ // / / \ \
596
+ // (c)=> ==== ==== <=(d)
597
+ // \ \ / /
598
+ // \ \<=(a)/ /
599
+ // \ \ / / <=(b)
600
+ // 3) \ v / 2)
601
+ // -------
602
+ //
603
+ // (a) - inner side
604
+ // (b) - outer side
605
+ // (c) - left edge (sharp)
606
+ // (d) - right edge (sharp)
607
+ // 1..n - rendering order for startAngle = 0, when set to e.g 90, order changes clockwise (1->2, 2->3, n->1) and counterclockwise for negative startAngle
608
+
609
+ var out = ['M', cx + (rx * cos(start2)), cy + (ry * sin(start2))];
610
+ out = out.concat(curveTo(cx, cy, rx, ry, start2, end2, 0, 0));
611
+
612
+ if (end > midEnd && start < midEnd) { // When shape is wide, it can cross both, (c) and (d) edges, when using startAngle
613
+ // Go to outer side
614
+ out = out.concat([
615
+ 'L', cx + (rx * cos(end2)) + dx, cy + (ry * sin(end2)) + dy
616
+ ]);
617
+ // Curve to the right edge of the slice (d)
618
+ out = out.concat(curveTo(cx, cy, rx, ry, end2, midEnd, dx, dy));
619
+ // Go to the inner side
620
+ out = out.concat([
621
+ 'L', cx + (rx * cos(midEnd)), cy + (ry * sin(midEnd))
622
+ ]);
623
+ // Curve to the true end of the slice
624
+ out = out.concat(curveTo(cx, cy, rx, ry, midEnd, end, 0, 0));
625
+ // Go to the outer side
626
+ out = out.concat([
627
+ 'L', cx + (rx * cos(end)) + dx, cy + (ry * sin(end)) + dy
628
+ ]);
629
+ // Go back to middle (d)
630
+ out = out.concat(curveTo(cx, cy, rx, ry, end, midEnd, dx, dy));
631
+ out = out.concat([
632
+ 'L', cx + (rx * cos(midEnd)), cy + (ry * sin(midEnd))
633
+ ]);
634
+ // Go back to the left edge
635
+ out = out.concat(curveTo(cx, cy, rx, ry, midEnd, end2, 0, 0));
636
+ } else if (end > PI - a && start < PI - a) { // But shape can cross also only (c) edge:
637
+ // Go to outer side
638
+ out = out.concat([
639
+ 'L', cx + (rx * cos(end2)) + dx, cy + (ry * sin(end2)) + dy
640
+ ]);
641
+ // Curve to the true end of the slice
642
+ out = out.concat(curveTo(cx, cy, rx, ry, end2, end, dx, dy));
643
+ // Go to the inner side
644
+ out = out.concat([
645
+ 'L', cx + (rx * cos(end)), cy + (ry * sin(end))
646
+ ]);
647
+ // Go back to the artifical end2
648
+ out = out.concat(curveTo(cx, cy, rx, ry, end, end2, 0, 0));
649
+ }
650
+
651
+ out = out.concat([
652
+ 'L', cx + (rx * cos(end2)) + dx, cy + (ry * sin(end2)) + dy
653
+ ]);
654
+ out = out.concat(curveTo(cx, cy, rx, ry, end2, start2, dx, dy));
655
+ out = out.concat(['Z']);
656
+
657
+ // INSIDE
658
+ var inn = ['M', cx + (irx * cs), cy + (iry * ss)];
659
+ inn = inn.concat(curveTo(cx, cy, irx, iry, start, end, 0, 0));
660
+ inn = inn.concat([
661
+ 'L', cx + (irx * cos(end)) + dx, cy + (iry * sin(end)) + dy
662
+ ]);
663
+ inn = inn.concat(curveTo(cx, cy, irx, iry, end, start, dx, dy));
664
+ inn = inn.concat(['Z']);
665
+
666
+ // SIDES
667
+ var side1 = [
668
+ 'M', cx + (rx * cs), cy + (ry * ss),
669
+ 'L', cx + (rx * cs) + dx, cy + (ry * ss) + dy,
670
+ 'L', cx + (irx * cs) + dx, cy + (iry * ss) + dy,
671
+ 'L', cx + (irx * cs), cy + (iry * ss),
672
+ 'Z'
673
+ ];
674
+ var side2 = [
675
+ 'M', cx + (rx * ce), cy + (ry * se),
676
+ 'L', cx + (rx * ce) + dx, cy + (ry * se) + dy,
677
+ 'L', cx + (irx * ce) + dx, cy + (iry * se) + dy,
678
+ 'L', cx + (irx * ce), cy + (iry * se),
679
+ 'Z'
680
+ ];
681
+
682
+ // correction for changed position of vanishing point caused by alpha and beta rotations
683
+ var angleCorr = Math.atan2(dy, -dx),
684
+ angleEnd = Math.abs(end + angleCorr),
685
+ angleStart = Math.abs(start + angleCorr),
686
+ angleMid = Math.abs((start + end) / 2 + angleCorr);
687
+
688
+ // set to 0-PI range
689
+ function toZeroPIRange(angle) {
690
+ angle = angle % (2 * PI);
691
+ if (angle > PI) {
692
+ angle = 2 * PI - angle;
693
+ }
694
+ return angle;
695
+ }
696
+ angleEnd = toZeroPIRange(angleEnd);
697
+ angleStart = toZeroPIRange(angleStart);
698
+ angleMid = toZeroPIRange(angleMid);
699
+
700
+ // *1e5 is to compensate pInt in zIndexSetter
701
+ var incPrecision = 1e5,
702
+ a1 = angleMid * incPrecision,
703
+ a2 = angleStart * incPrecision,
704
+ a3 = angleEnd * incPrecision;
705
+
706
+ return {
707
+ top: top,
708
+ zTop: PI * incPrecision + 1, // max angle is PI, so this is allways higher
709
+ out: out,
710
+ zOut: Math.max(a1, a2, a3),
711
+ inn: inn,
712
+ zInn: Math.max(a1, a2, a3),
713
+ side1: side1,
714
+ zSide1: a3 * 0.99, // to keep below zOut and zInn in case of same values
715
+ side2: side2,
716
+ zSide2: a2 * 0.99
717
+ };
718
+ };
719
+ /***
720
+ EXTENSION FOR 3D CHARTS
721
+ ***/
722
+ // Shorthand to check the is3d flag
723
+ Highcharts.Chart.prototype.is3d = function () {
724
+ return this.options.chart.options3d && this.options.chart.options3d.enabled; // #4280
725
+ };
726
+
727
+ Highcharts.wrap(Highcharts.Chart.prototype, 'isInsidePlot', function (proceed) {
728
+ return this.is3d() || proceed.apply(this, [].slice.call(arguments, 1));
729
+ });
730
+
731
+ var defaultChartOptions = Highcharts.getOptions();
732
+ defaultChartOptions.chart.options3d = {
733
+ enabled: false,
734
+ alpha: 0,
735
+ beta: 0,
736
+ depth: 100,
737
+ viewDistance: 25,
738
+ frame: {
739
+ bottom: { size: 1, color: 'rgba(255,255,255,0)' },
740
+ side: { size: 1, color: 'rgba(255,255,255,0)' },
741
+ back: { size: 1, color: 'rgba(255,255,255,0)' }
742
+ }
743
+ };
744
+
745
+ Highcharts.wrap(Highcharts.Chart.prototype, 'init', function (proceed) {
746
+ var args = [].slice.call(arguments, 1),
747
+ plotOptions,
748
+ pieOptions;
749
+
750
+ if (args[0].chart.options3d && args[0].chart.options3d.enabled) {
751
+ // Normalize alpha and beta to (-360, 360) range
752
+ args[0].chart.options3d.alpha = (args[0].chart.options3d.alpha || 0) % 360;
753
+ args[0].chart.options3d.beta = (args[0].chart.options3d.beta || 0) % 360;
754
+
755
+ plotOptions = args[0].plotOptions || {};
756
+ pieOptions = plotOptions.pie || {};
757
+
758
+ pieOptions.borderColor = Highcharts.pick(pieOptions.borderColor, undefined);
759
+ }
760
+ proceed.apply(this, args);
761
+ });
762
+
763
+ Highcharts.wrap(Highcharts.Chart.prototype, 'setChartSize', function (proceed) {
764
+ proceed.apply(this, [].slice.call(arguments, 1));
765
+
766
+ if (this.is3d()) {
767
+ var inverted = this.inverted,
768
+ clipBox = this.clipBox,
769
+ margin = this.margin,
770
+ x = inverted ? 'y' : 'x',
771
+ y = inverted ? 'x' : 'y',
772
+ w = inverted ? 'height' : 'width',
773
+ h = inverted ? 'width' : 'height';
774
+
775
+ clipBox[x] = -(margin[3] || 0);
776
+ clipBox[y] = -(margin[0] || 0);
777
+ clipBox[w] = this.chartWidth + (margin[3] || 0) + (margin[1] || 0);
778
+ clipBox[h] = this.chartHeight + (margin[0] || 0) + (margin[2] || 0);
779
+ }
780
+ });
781
+
782
+ Highcharts.wrap(Highcharts.Chart.prototype, 'redraw', function (proceed) {
783
+ if (this.is3d()) {
784
+ // Set to force a redraw of all elements
785
+ this.isDirtyBox = true;
786
+ }
787
+ proceed.apply(this, [].slice.call(arguments, 1));
788
+ });
789
+
790
+ // Draw the series in the reverse order (#3803, #3917)
791
+ Highcharts.wrap(Highcharts.Chart.prototype, 'renderSeries', function (proceed) {
792
+ var series,
793
+ i = this.series.length;
794
+
795
+ if (this.is3d()) {
796
+ while (i--) {
797
+ series = this.series[i];
798
+ series.translate();
799
+ series.render();
800
+ }
801
+ } else {
802
+ proceed.call(this);
803
+ }
804
+ });
805
+
806
+ Highcharts.Chart.prototype.retrieveStacks = function (stacking) {
807
+ var series = this.series,
808
+ stacks = {},
809
+ stackNumber,
810
+ i = 1;
811
+
812
+ Highcharts.each(this.series, function (s) {
813
+ stackNumber = pick(s.options.stack, (stacking ? 0 : series.length - 1 - s.index)); // #3841, #4532
814
+ if (!stacks[stackNumber]) {
815
+ stacks[stackNumber] = { series: [s], position: i };
816
+ i++;
817
+ } else {
818
+ stacks[stackNumber].series.push(s);
819
+ }
820
+ });
821
+
822
+ stacks.totalStacks = i + 1;
823
+ return stacks;
824
+ };
825
+
826
+ /***
827
+ EXTENSION TO THE AXIS
828
+ ***/
829
+ Highcharts.wrap(Highcharts.Axis.prototype, 'setOptions', function (proceed, userOptions) {
830
+ var options;
831
+ proceed.call(this, userOptions);
832
+ if (this.chart.is3d()) {
833
+ options = this.options;
834
+ options.tickWidth = Highcharts.pick(options.tickWidth, 0);
835
+ options.gridLineWidth = Highcharts.pick(options.gridLineWidth, 1);
836
+ }
837
+ });
838
+
839
+ Highcharts.wrap(Highcharts.Axis.prototype, 'render', function (proceed) {
840
+ proceed.apply(this, [].slice.call(arguments, 1));
841
+
842
+ // Do not do this if the chart is not 3D
843
+ if (!this.chart.is3d()) {
844
+ return;
845
+ }
846
+
847
+ var chart = this.chart,
848
+ renderer = chart.renderer,
849
+ options3d = chart.options.chart.options3d,
850
+ frame = options3d.frame,
851
+ fbottom = frame.bottom,
852
+ fback = frame.back,
853
+ fside = frame.side,
854
+ depth = options3d.depth,
855
+ height = this.height,
856
+ width = this.width,
857
+ left = this.left,
858
+ top = this.top;
859
+
860
+ if (this.isZAxis) {
861
+ return;
862
+ }
863
+ if (this.horiz) {
864
+ var bottomShape = {
865
+ x: left,
866
+ y: top + (chart.xAxis[0].opposite ? -fbottom.size : height),
867
+ z: 0,
868
+ width: width,
869
+ height: fbottom.size,
870
+ depth: depth,
871
+ insidePlotArea: false
872
+ };
873
+ if (!this.bottomFrame) {
874
+ this.bottomFrame = renderer.cuboid(bottomShape).attr({
875
+ fill: fbottom.color,
876
+ zIndex: (chart.yAxis[0].reversed && options3d.alpha > 0 ? 4 : -1)
877
+ })
878
+ .css({
879
+ stroke: fbottom.color
880
+ }).add();
881
+ } else {
882
+ this.bottomFrame.animate(bottomShape);
883
+ }
884
+ } else {
885
+ // BACK
886
+ var backShape = {
887
+ x: left + (chart.yAxis[0].opposite ? 0 : -fside.size),
888
+ y: top + (chart.xAxis[0].opposite ? -fbottom.size : 0),
889
+ z: depth,
890
+ width: width + fside.size,
891
+ height: height + fbottom.size,
892
+ depth: fback.size,
893
+ insidePlotArea: false
894
+ };
895
+ if (!this.backFrame) {
896
+ this.backFrame = renderer.cuboid(backShape).attr({
897
+ fill: fback.color,
898
+ zIndex: -3
899
+ }).css({
900
+ stroke: fback.color
901
+ }).add();
902
+ } else {
903
+ this.backFrame.animate(backShape);
904
+ }
905
+ var sideShape = {
906
+ x: left + (chart.yAxis[0].opposite ? width : -fside.size),
907
+ y: top + (chart.xAxis[0].opposite ? -fbottom.size : 0),
908
+ z: 0,
909
+ width: fside.size,
910
+ height: height + fbottom.size,
911
+ depth: depth,
912
+ insidePlotArea: false
913
+ };
914
+ if (!this.sideFrame) {
915
+ this.sideFrame = renderer.cuboid(sideShape).attr({
916
+ fill: fside.color,
917
+ zIndex: -2
918
+ }).css({
919
+ stroke: fside.color
920
+ }).add();
921
+ } else {
922
+ this.sideFrame.animate(sideShape);
923
+ }
924
+ }
925
+ });
926
+
927
+ Highcharts.wrap(Highcharts.Axis.prototype, 'getPlotLinePath', function (proceed) {
928
+ var path = proceed.apply(this, [].slice.call(arguments, 1));
929
+
930
+ // Do not do this if the chart is not 3D
931
+ if (!this.chart.is3d()) {
932
+ return path;
933
+ }
934
+
935
+ if (path === null) {
936
+ return path;
937
+ }
938
+
939
+ var chart = this.chart,
940
+ options3d = chart.options.chart.options3d,
941
+ d = this.isZAxis ? chart.plotWidth : options3d.depth,
942
+ opposite = this.opposite;
943
+ if (this.horiz) {
944
+ opposite = !opposite;
945
+ }
946
+ var pArr = [
947
+ this.swapZ({ x: path[1], y: path[2], z: (opposite ? d : 0) }),
948
+ this.swapZ({ x: path[1], y: path[2], z: d }),
949
+ this.swapZ({ x: path[4], y: path[5], z: d }),
950
+ this.swapZ({ x: path[4], y: path[5], z: (opposite ? 0 : d) })
951
+ ];
952
+
953
+ pArr = perspective(pArr, this.chart, false);
954
+ path = this.chart.renderer.toLinePath(pArr, false);
955
+
956
+ return path;
957
+ });
958
+
959
+ // Do not draw axislines in 3D
960
+ Highcharts.wrap(Highcharts.Axis.prototype, 'getLinePath', function (proceed) {
961
+ return this.chart.is3d() ? [] : proceed.apply(this, [].slice.call(arguments, 1));
962
+ });
963
+
964
+ Highcharts.wrap(Highcharts.Axis.prototype, 'getPlotBandPath', function (proceed) {
965
+ // Do not do this if the chart is not 3D
966
+ if (!this.chart.is3d()) {
967
+ return proceed.apply(this, [].slice.call(arguments, 1));
968
+ }
969
+
970
+ var args = arguments,
971
+ from = args[1],
972
+ to = args[2],
973
+ toPath = this.getPlotLinePath(to),
974
+ path = this.getPlotLinePath(from);
975
+
976
+ if (path && toPath) {
977
+ path.push(
978
+ 'L',
979
+ toPath[10], // These two do not exist in the regular getPlotLine
980
+ toPath[11], // ---- # 3005
981
+ 'L',
982
+ toPath[7],
983
+ toPath[8],
984
+ 'L',
985
+ toPath[4],
986
+ toPath[5],
987
+ 'L',
988
+ toPath[1],
989
+ toPath[2]
990
+ );
991
+ } else { // outside the axis area
992
+ path = null;
993
+ }
994
+
995
+ return path;
996
+ });
997
+
998
+ /***
999
+ EXTENSION TO THE TICKS
1000
+ ***/
1001
+
1002
+ Highcharts.wrap(Highcharts.Tick.prototype, 'getMarkPath', function (proceed) {
1003
+ var path = proceed.apply(this, [].slice.call(arguments, 1));
1004
+
1005
+ // Do not do this if the chart is not 3D
1006
+ if (!this.axis.chart.is3d()) {
1007
+ return path;
1008
+ }
1009
+
1010
+ var pArr = [
1011
+ this.axis.swapZ({ x: path[1], y: path[2], z: 0 }),
1012
+ this.axis.swapZ({ x: path[4], y: path[5], z: 0 })
1013
+ ];
1014
+
1015
+ pArr = perspective(pArr, this.axis.chart, false);
1016
+ path = [
1017
+ 'M', pArr[0].x, pArr[0].y,
1018
+ 'L', pArr[1].x, pArr[1].y
1019
+ ];
1020
+ return path;
1021
+ });
1022
+
1023
+ Highcharts.wrap(Highcharts.Tick.prototype, 'getLabelPosition', function (proceed) {
1024
+ var pos = proceed.apply(this, [].slice.call(arguments, 1));
1025
+
1026
+ // Do not do this if the chart is not 3D
1027
+ if (!this.axis.chart.is3d()) {
1028
+ return pos;
1029
+ }
1030
+
1031
+ var newPos = perspective([this.axis.swapZ({ x: pos.x, y: pos.y, z: 0 })], this.axis.chart, false)[0];
1032
+ newPos.x = newPos.x - (!this.axis.horiz && this.axis.opposite ? this.axis.transA : 0); //#3788
1033
+ newPos.old = pos;
1034
+ return newPos;
1035
+ });
1036
+
1037
+ Highcharts.wrap(Highcharts.Tick.prototype, 'handleOverflow', function (proceed, xy) {
1038
+ if (this.axis.chart.is3d()) {
1039
+ xy = xy.old;
1040
+ }
1041
+ return proceed.call(this, xy);
1042
+ });
1043
+
1044
+ Highcharts.wrap(Highcharts.Axis.prototype, 'getTitlePosition', function (proceed) {
1045
+ var is3d = this.chart.is3d(),
1046
+ pos,
1047
+ axisTitleMargin;
1048
+
1049
+ // Pull out the axis title margin, that is not subject to the perspective
1050
+ if (is3d) {
1051
+ axisTitleMargin = this.axisTitleMargin;
1052
+ this.axisTitleMargin = 0;
1053
+ }
1054
+
1055
+ pos = proceed.apply(this, [].slice.call(arguments, 1));
1056
+
1057
+ if (is3d) {
1058
+ pos = perspective([this.swapZ({ x: pos.x, y: pos.y, z: 0 })], this.chart, false)[0];
1059
+
1060
+ // Re-apply the axis title margin outside the perspective
1061
+ pos[this.horiz ? 'y' : 'x'] += (this.horiz ? 1 : -1) * // horizontal axis reverses the margin ...
1062
+ (this.opposite ? -1 : 1) * // ... so does opposite axes
1063
+ axisTitleMargin;
1064
+ this.axisTitleMargin = axisTitleMargin;
1065
+ }
1066
+ return pos;
1067
+ });
1068
+
1069
+ Highcharts.wrap(Highcharts.Axis.prototype, 'drawCrosshair', function (proceed) {
1070
+ var args = arguments;
1071
+ if (this.chart.is3d()) {
1072
+ if (args[2]) {
1073
+ args[2] = {
1074
+ plotX: args[2].plotXold || args[2].plotX,
1075
+ plotY: args[2].plotYold || args[2].plotY
1076
+ };
1077
+ }
1078
+ }
1079
+ proceed.apply(this, [].slice.call(args, 1));
1080
+ });
1081
+
1082
+ /***
1083
+ Z-AXIS
1084
+ ***/
1085
+
1086
+ Highcharts.Axis.prototype.swapZ = function (p, insidePlotArea) {
1087
+ if (this.isZAxis) {
1088
+ var plotLeft = insidePlotArea ? 0 : this.chart.plotLeft;
1089
+ var chart = this.chart;
1090
+ return {
1091
+ x: plotLeft + (chart.yAxis[0].opposite ? p.z : chart.xAxis[0].width - p.z),
1092
+ y: p.y,
1093
+ z: p.x - plotLeft
1094
+ };
1095
+ }
1096
+ return p;
1097
+ };
1098
+
1099
+ var ZAxis = Highcharts.ZAxis = function () {
1100
+ this.isZAxis = true;
1101
+ this.init.apply(this, arguments);
1102
+ };
1103
+ Highcharts.extend(ZAxis.prototype, Highcharts.Axis.prototype);
1104
+ Highcharts.extend(ZAxis.prototype, {
1105
+ setOptions: function (userOptions) {
1106
+ userOptions = Highcharts.merge({
1107
+ offset: 0,
1108
+ lineWidth: 0
1109
+ }, userOptions);
1110
+ Highcharts.Axis.prototype.setOptions.call(this, userOptions);
1111
+ this.coll = 'zAxis';
1112
+ },
1113
+ setAxisSize: function () {
1114
+ Highcharts.Axis.prototype.setAxisSize.call(this);
1115
+ this.width = this.len = this.chart.options.chart.options3d.depth;
1116
+ this.right = this.chart.chartWidth - this.width - this.left;
1117
+ },
1118
+ getSeriesExtremes: function () {
1119
+ var axis = this,
1120
+ chart = axis.chart;
1121
+
1122
+ axis.hasVisibleSeries = false;
1123
+
1124
+ // Reset properties in case we're redrawing (#3353)
1125
+ axis.dataMin = axis.dataMax = axis.ignoreMinPadding = axis.ignoreMaxPadding = null;
1126
+
1127
+ if (axis.buildStacks) {
1128
+ axis.buildStacks();
1129
+ }
1130
+
1131
+ // loop through this axis' series
1132
+ Highcharts.each(axis.series, function (series) {
1133
+
1134
+ if (series.visible || !chart.options.chart.ignoreHiddenSeries) {
1135
+
1136
+ var seriesOptions = series.options,
1137
+ zData,
1138
+ threshold = seriesOptions.threshold;
1139
+
1140
+ axis.hasVisibleSeries = true;
1141
+
1142
+ // Validate threshold in logarithmic axes
1143
+ if (axis.isLog && threshold <= 0) {
1144
+ threshold = null;
1145
+ }
1146
+
1147
+ zData = series.zData;
1148
+ if (zData.length) {
1149
+ axis.dataMin = Math.min(pick(axis.dataMin, zData[0]), Math.min.apply(null, zData));
1150
+ axis.dataMax = Math.max(pick(axis.dataMax, zData[0]), Math.max.apply(null, zData));
1151
+ }
1152
+ }
1153
+ });
1154
+ }
1155
+ });
1156
+
1157
+
1158
+ /**
1159
+ * Extend the chart getAxes method to also get the color axis
1160
+ */
1161
+ Highcharts.wrap(Highcharts.Chart.prototype, 'getAxes', function (proceed) {
1162
+ var chart = this,
1163
+ options = this.options,
1164
+ zAxisOptions = options.zAxis = Highcharts.splat(options.zAxis || {});
1165
+
1166
+ proceed.call(this);
1167
+
1168
+ if (!chart.is3d()) {
1169
+ return;
1170
+ }
1171
+ this.zAxis = [];
1172
+ Highcharts.each(zAxisOptions, function (axisOptions, i) {
1173
+ axisOptions.index = i;
1174
+ axisOptions.isX = true; //Z-Axis is shown horizontally, so it's kind of a X-Axis
1175
+ var zAxis = new ZAxis(chart, axisOptions);
1176
+ zAxis.setScale();
1177
+ });
1178
+ });
1179
+ /***
1180
+ EXTENSION FOR 3D COLUMNS
1181
+ ***/
1182
+ Highcharts.wrap(Highcharts.seriesTypes.column.prototype, 'translate', function (proceed) {
1183
+ proceed.apply(this, [].slice.call(arguments, 1));
1184
+
1185
+ // Do not do this if the chart is not 3D
1186
+ if (!this.chart.is3d()) {
1187
+ return;
1188
+ }
1189
+
1190
+ var series = this,
1191
+ chart = series.chart,
1192
+ seriesOptions = series.options,
1193
+ depth = seriesOptions.depth || 25;
1194
+
1195
+ var stack = seriesOptions.stacking ? (seriesOptions.stack || 0) : series._i;
1196
+ var z = stack * (depth + (seriesOptions.groupZPadding || 1));
1197
+
1198
+ if (seriesOptions.grouping !== false) {
1199
+ z = 0;
1200
+ }
1201
+
1202
+ z += (seriesOptions.groupZPadding || 1);
1203
+
1204
+ Highcharts.each(series.data, function (point) {
1205
+ if (point.y !== null) {
1206
+ var shapeArgs = point.shapeArgs,
1207
+ tooltipPos = point.tooltipPos;
1208
+
1209
+ point.shapeType = 'cuboid';
1210
+ shapeArgs.z = z;
1211
+ shapeArgs.depth = depth;
1212
+ shapeArgs.insidePlotArea = true;
1213
+
1214
+ // Translate the tooltip position in 3d space
1215
+ tooltipPos = perspective([{ x: tooltipPos[0], y: tooltipPos[1], z: z }], chart, false)[0];
1216
+ point.tooltipPos = [tooltipPos.x, tooltipPos.y];
1217
+ }
1218
+ });
1219
+ // store for later use #4067
1220
+ series.z = z;
1221
+ });
1222
+
1223
+ Highcharts.wrap(Highcharts.seriesTypes.column.prototype, 'animate', function (proceed) {
1224
+ if (!this.chart.is3d()) {
1225
+ proceed.apply(this, [].slice.call(arguments, 1));
1226
+ } else {
1227
+ var args = arguments,
1228
+ init = args[1],
1229
+ yAxis = this.yAxis,
1230
+ series = this,
1231
+ reversed = this.yAxis.reversed;
1232
+
1233
+ if (Highcharts.svg) { // VML is too slow anyway
1234
+ if (init) {
1235
+ Highcharts.each(series.data, function (point) {
1236
+ if (point.y !== null) {
1237
+ point.height = point.shapeArgs.height;
1238
+ point.shapey = point.shapeArgs.y; //#2968
1239
+ point.shapeArgs.height = 1;
1240
+ if (!reversed) {
1241
+ if (point.stackY) {
1242
+ point.shapeArgs.y = point.plotY + yAxis.translate(point.stackY);
1243
+ } else {
1244
+ point.shapeArgs.y = point.plotY + (point.negative ? -point.height : point.height);
1245
+ }
1246
+ }
1247
+ }
1248
+ });
1249
+
1250
+ } else { // run the animation
1251
+ Highcharts.each(series.data, function (point) {
1252
+ if (point.y !== null) {
1253
+ point.shapeArgs.height = point.height;
1254
+ point.shapeArgs.y = point.shapey; //#2968
1255
+ // null value do not have a graphic
1256
+ if (point.graphic) {
1257
+ point.graphic.animate(point.shapeArgs, series.options.animation);
1258
+ }
1259
+ }
1260
+ });
1261
+
1262
+ // redraw datalabels to the correct position
1263
+ this.drawDataLabels();
1264
+
1265
+ // delete this function to allow it only once
1266
+ series.animate = null;
1267
+ }
1268
+ }
1269
+ }
1270
+ });
1271
+
1272
+ Highcharts.wrap(Highcharts.seriesTypes.column.prototype, 'init', function (proceed) {
1273
+ proceed.apply(this, [].slice.call(arguments, 1));
1274
+
1275
+ if (this.chart.is3d()) {
1276
+ var seriesOptions = this.options,
1277
+ grouping = seriesOptions.grouping,
1278
+ stacking = seriesOptions.stacking,
1279
+ reversedStacks = pick(this.yAxis.options.reversedStacks, true),
1280
+ z = 0;
1281
+
1282
+ if (!(grouping !== undefined && !grouping)) {
1283
+ var stacks = this.chart.retrieveStacks(stacking),
1284
+ stack = seriesOptions.stack || 0,
1285
+ i; // position within the stack
1286
+ for (i = 0; i < stacks[stack].series.length; i++) {
1287
+ if (stacks[stack].series[i] === this) {
1288
+ break;
1289
+ }
1290
+ }
1291
+ z = (10 * (stacks.totalStacks - stacks[stack].position)) + (reversedStacks ? i : -i); // #4369
1292
+
1293
+ // In case when axis is reversed, columns are also reversed inside the group (#3737)
1294
+ if (!this.xAxis.reversed) {
1295
+ z = (stacks.totalStacks * 10) - z;
1296
+ }
1297
+ }
1298
+
1299
+ seriesOptions.zIndex = z;
1300
+ }
1301
+ });
1302
+ function draw3DPoints(proceed) {
1303
+ // Do not do this if the chart is not 3D
1304
+ if (this.chart.is3d()) {
1305
+ var grouping = this.chart.options.plotOptions.column.grouping;
1306
+ if (grouping !== undefined && !grouping && this.group.zIndex !== undefined && !this.zIndexSet) {
1307
+ this.group.attr({ zIndex: this.group.zIndex * 10 });
1308
+ this.zIndexSet = true; // #4062 set zindex only once
1309
+ }
1310
+
1311
+ var options = this.options,
1312
+ states = this.options.states;
1313
+
1314
+ this.borderWidth = options.borderWidth = defined(options.edgeWidth) ? options.edgeWidth : 1; //#4055
1315
+
1316
+ Highcharts.each(this.data, function (point) {
1317
+ if (point.y !== null) {
1318
+ var pointAttr = point.pointAttr;
1319
+
1320
+ // Set the border color to the fill color to provide a smooth edge
1321
+ this.borderColor = Highcharts.pick(options.edgeColor, pointAttr[''].fill);
1322
+
1323
+ pointAttr[''].stroke = this.borderColor;
1324
+ pointAttr.hover.stroke = Highcharts.pick(states.hover.edgeColor, this.borderColor);
1325
+ pointAttr.select.stroke = Highcharts.pick(states.select.edgeColor, this.borderColor);
1326
+ }
1327
+ });
1328
+ }
1329
+
1330
+ proceed.apply(this, [].slice.call(arguments, 1));
1331
+ }
1332
+
1333
+ Highcharts.wrap(Highcharts.Series.prototype, 'alignDataLabel', function (proceed) {
1334
+
1335
+ // Only do this for 3D columns and columnranges
1336
+ if (this.chart.is3d() && (this.type === 'column' || this.type === 'columnrange')) {
1337
+ var series = this,
1338
+ chart = series.chart;
1339
+
1340
+ var args = arguments,
1341
+ alignTo = args[4];
1342
+
1343
+ var pos = ({ x: alignTo.x, y: alignTo.y, z: series.z });
1344
+ pos = perspective([pos], chart, true)[0];
1345
+ alignTo.x = pos.x;
1346
+ alignTo.y = pos.y;
1347
+ }
1348
+
1349
+ proceed.apply(this, [].slice.call(arguments, 1));
1350
+ });
1351
+
1352
+ if (Highcharts.seriesTypes.columnrange) {
1353
+ Highcharts.wrap(Highcharts.seriesTypes.columnrange.prototype, 'drawPoints', draw3DPoints);
1354
+ }
1355
+
1356
+ Highcharts.wrap(Highcharts.seriesTypes.column.prototype, 'drawPoints', draw3DPoints);
1357
+
1358
+ /***
1359
+ EXTENSION FOR 3D CYLINDRICAL COLUMNS
1360
+ Not supported
1361
+ ***/
1362
+ /*
1363
+ var defaultOptions = Highcharts.getOptions();
1364
+ defaultOptions.plotOptions.cylinder = Highcharts.merge(defaultOptions.plotOptions.column);
1365
+ var CylinderSeries = Highcharts.extendClass(Highcharts.seriesTypes.column, {
1366
+ type: 'cylinder'
1367
+ });
1368
+ Highcharts.seriesTypes.cylinder = CylinderSeries;
1369
+
1370
+ Highcharts.wrap(Highcharts.seriesTypes.cylinder.prototype, 'translate', function (proceed) {
1371
+ proceed.apply(this, [].slice.call(arguments, 1));
1372
+
1373
+ // Do not do this if the chart is not 3D
1374
+ if (!this.chart.is3d()) {
1375
+ return;
1376
+ }
1377
+
1378
+ var series = this,
1379
+ chart = series.chart,
1380
+ options = chart.options,
1381
+ cylOptions = options.plotOptions.cylinder,
1382
+ options3d = options.chart.options3d,
1383
+ depth = cylOptions.depth || 0,
1384
+ alpha = options3d.alpha;
1385
+
1386
+ var z = cylOptions.stacking ? (this.options.stack || 0) * depth : series._i * depth;
1387
+ z += depth / 2;
1388
+
1389
+ if (cylOptions.grouping !== false) { z = 0; }
1390
+
1391
+ Highcharts.each(series.data, function (point) {
1392
+ var shapeArgs = point.shapeArgs;
1393
+ point.shapeType = 'arc3d';
1394
+ shapeArgs.x += depth / 2;
1395
+ shapeArgs.z = z;
1396
+ shapeArgs.start = 0;
1397
+ shapeArgs.end = 2 * PI;
1398
+ shapeArgs.r = depth * 0.95;
1399
+ shapeArgs.innerR = 0;
1400
+ shapeArgs.depth = shapeArgs.height * (1 / sin((90 - alpha) * deg2rad)) - z;
1401
+ shapeArgs.alpha = 90 - alpha;
1402
+ shapeArgs.beta = 0;
1403
+ });
1404
+ });
1405
+ */
1406
+ /***
1407
+ EXTENSION FOR 3D PIES
1408
+ ***/
1409
+
1410
+ Highcharts.wrap(Highcharts.seriesTypes.pie.prototype, 'translate', function (proceed) {
1411
+ proceed.apply(this, [].slice.call(arguments, 1));
1412
+
1413
+ // Do not do this if the chart is not 3D
1414
+ if (!this.chart.is3d()) {
1415
+ return;
1416
+ }
1417
+
1418
+ var series = this,
1419
+ chart = series.chart,
1420
+ options = chart.options,
1421
+ seriesOptions = series.options,
1422
+ depth = seriesOptions.depth || 0,
1423
+ options3d = options.chart.options3d,
1424
+ alpha = options3d.alpha,
1425
+ beta = options3d.beta,
1426
+ z = seriesOptions.stacking ? (seriesOptions.stack || 0) * depth : series._i * depth;
1427
+
1428
+ z += depth / 2;
1429
+
1430
+ if (seriesOptions.grouping !== false) {
1431
+ z = 0;
1432
+ }
1433
+
1434
+ each(series.data, function (point) {
1435
+
1436
+ var shapeArgs = point.shapeArgs,
1437
+ angle;
1438
+
1439
+ point.shapeType = 'arc3d';
1440
+
1441
+ shapeArgs.z = z;
1442
+ shapeArgs.depth = depth * 0.75;
1443
+ shapeArgs.alpha = alpha;
1444
+ shapeArgs.beta = beta;
1445
+ shapeArgs.center = series.center;
1446
+
1447
+ angle = (shapeArgs.end + shapeArgs.start) / 2;
1448
+
1449
+ point.slicedTranslation = {
1450
+ translateX: round(cos(angle) * seriesOptions.slicedOffset * cos(alpha * deg2rad)),
1451
+ translateY: round(sin(angle) * seriesOptions.slicedOffset * cos(alpha * deg2rad))
1452
+ };
1453
+ });
1454
+ });
1455
+
1456
+ Highcharts.wrap(Highcharts.seriesTypes.pie.prototype.pointClass.prototype, 'haloPath', function (proceed) {
1457
+ var args = arguments;
1458
+ return this.series.chart.is3d() ? [] : proceed.call(this, args[1]);
1459
+ });
1460
+
1461
+ Highcharts.wrap(Highcharts.seriesTypes.pie.prototype, 'drawPoints', function (proceed) {
1462
+
1463
+ var options = this.options,
1464
+ states = options.states;
1465
+
1466
+ // Do not do this if the chart is not 3D
1467
+ if (this.chart.is3d()) {
1468
+ // Set the border color to the fill color to provide a smooth edge
1469
+ this.borderWidth = options.borderWidth = options.edgeWidth || 1;
1470
+ this.borderColor = options.edgeColor = Highcharts.pick(options.edgeColor, options.borderColor, undefined);
1471
+
1472
+ states.hover.borderColor = Highcharts.pick(states.hover.edgeColor, this.borderColor);
1473
+ states.hover.borderWidth = Highcharts.pick(states.hover.edgeWidth, this.borderWidth);
1474
+ states.select.borderColor = Highcharts.pick(states.select.edgeColor, this.borderColor);
1475
+ states.select.borderWidth = Highcharts.pick(states.select.edgeWidth, this.borderWidth);
1476
+
1477
+ each(this.data, function (point) {
1478
+ var pointAttr = point.pointAttr;
1479
+ pointAttr[''].stroke = point.series.borderColor || point.color;
1480
+ pointAttr['']['stroke-width'] = point.series.borderWidth;
1481
+ pointAttr.hover.stroke = states.hover.borderColor;
1482
+ pointAttr.hover['stroke-width'] = states.hover.borderWidth;
1483
+ pointAttr.select.stroke = states.select.borderColor;
1484
+ pointAttr.select['stroke-width'] = states.select.borderWidth;
1485
+ });
1486
+ }
1487
+
1488
+ proceed.apply(this, [].slice.call(arguments, 1));
1489
+
1490
+ if (this.chart.is3d()) {
1491
+ each(this.points, function (point) {
1492
+ var graphic = point.graphic;
1493
+
1494
+ // #4584 Check if has graphic - null points don't have it
1495
+ if (graphic) {
1496
+ // Hide null or 0 points (#3006, 3650)
1497
+ graphic[point.y ? 'show' : 'hide']();
1498
+ }
1499
+ });
1500
+ }
1501
+ });
1502
+
1503
+ Highcharts.wrap(Highcharts.seriesTypes.pie.prototype, 'drawDataLabels', function (proceed) {
1504
+ if (this.chart.is3d()) {
1505
+ var series = this,
1506
+ chart = series.chart,
1507
+ options3d = chart.options.chart.options3d;
1508
+ each(series.data, function (point) {
1509
+ var shapeArgs = point.shapeArgs,
1510
+ r = shapeArgs.r,
1511
+ a1 = (shapeArgs.alpha || options3d.alpha) * deg2rad, //#3240 issue with datalabels for 0 and null values
1512
+ b1 = (shapeArgs.beta || options3d.beta) * deg2rad,
1513
+ a2 = (shapeArgs.start + shapeArgs.end) / 2,
1514
+ labelPos = point.labelPos,
1515
+ labelIndexes = [0, 2, 4], // [x1, y1, x2, y2, x3, y3]
1516
+ yOffset = (-r * (1 - cos(a1)) * sin(a2)), // + (sin(a2) > 0 ? sin(a1) * d : 0)
1517
+ xOffset = r * (cos(b1) - 1) * cos(a2);
1518
+
1519
+ // Apply perspective on label positions
1520
+ each(labelIndexes, function (index) {
1521
+ labelPos[index] += xOffset;
1522
+ labelPos[index + 1] += yOffset;
1523
+ });
1524
+ });
1525
+ }
1526
+
1527
+ proceed.apply(this, [].slice.call(arguments, 1));
1528
+ });
1529
+
1530
+ Highcharts.wrap(Highcharts.seriesTypes.pie.prototype, 'addPoint', function (proceed) {
1531
+ proceed.apply(this, [].slice.call(arguments, 1));
1532
+ if (this.chart.is3d()) {
1533
+ // destroy (and rebuild) everything!!!
1534
+ this.update(this.userOptions, true); // #3845 pass the old options
1535
+ }
1536
+ });
1537
+
1538
+ Highcharts.wrap(Highcharts.seriesTypes.pie.prototype, 'animate', function (proceed) {
1539
+ if (!this.chart.is3d()) {
1540
+ proceed.apply(this, [].slice.call(arguments, 1));
1541
+ } else {
1542
+ var args = arguments,
1543
+ init = args[1],
1544
+ animation = this.options.animation,
1545
+ attribs,
1546
+ center = this.center,
1547
+ group = this.group,
1548
+ markerGroup = this.markerGroup;
1549
+
1550
+ if (Highcharts.svg) { // VML is too slow anyway
1551
+
1552
+ if (animation === true) {
1553
+ animation = {};
1554
+ }
1555
+ // Initialize the animation
1556
+ if (init) {
1557
+
1558
+ // Scale down the group and place it in the center
1559
+ group.oldtranslateX = group.translateX;
1560
+ group.oldtranslateY = group.translateY;
1561
+ attribs = {
1562
+ translateX: center[0],
1563
+ translateY: center[1],
1564
+ scaleX: 0.001, // #1499
1565
+ scaleY: 0.001
1566
+ };
1567
+
1568
+ group.attr(attribs);
1569
+ if (markerGroup) {
1570
+ markerGroup.attrSetters = group.attrSetters;
1571
+ markerGroup.attr(attribs);
1572
+ }
1573
+
1574
+ // Run the animation
1575
+ } else {
1576
+ attribs = {
1577
+ translateX: group.oldtranslateX,
1578
+ translateY: group.oldtranslateY,
1579
+ scaleX: 1,
1580
+ scaleY: 1
1581
+ };
1582
+ group.animate(attribs, animation);
1583
+
1584
+ if (markerGroup) {
1585
+ markerGroup.animate(attribs, animation);
1586
+ }
1587
+
1588
+ // Delete this function to allow it only once
1589
+ this.animate = null;
1590
+ }
1591
+
1592
+ }
1593
+ }
1594
+ });
1595
+ /***
1596
+ EXTENSION FOR 3D SCATTER CHART
1597
+ ***/
1598
+
1599
+ Highcharts.wrap(Highcharts.seriesTypes.scatter.prototype, 'translate', function (proceed) {
1600
+ //function translate3d(proceed) {
1601
+ proceed.apply(this, [].slice.call(arguments, 1));
1602
+
1603
+ if (!this.chart.is3d()) {
1604
+ return;
1605
+ }
1606
+
1607
+ var series = this,
1608
+ chart = series.chart,
1609
+ zAxis = Highcharts.pick(series.zAxis, chart.options.zAxis[0]),
1610
+ rawPoints = [],
1611
+ rawPoint,
1612
+ projectedPoints,
1613
+ projectedPoint,
1614
+ zValue,
1615
+ i;
1616
+
1617
+ for (i = 0; i < series.data.length; i++) {
1618
+ rawPoint = series.data[i];
1619
+ zValue = zAxis.isLog && zAxis.val2lin ? zAxis.val2lin(rawPoint.z) : rawPoint.z; // #4562
1620
+ rawPoint.plotZ = zAxis.translate(zValue);
1621
+
1622
+ rawPoint.isInside = rawPoint.isInside ? (zValue >= zAxis.min && zValue <= zAxis.max) : false;
1623
+
1624
+ rawPoints.push({
1625
+ x: rawPoint.plotX,
1626
+ y: rawPoint.plotY,
1627
+ z: rawPoint.plotZ
1628
+ });
1629
+ }
1630
+
1631
+ projectedPoints = perspective(rawPoints, chart, true);
1632
+
1633
+ for (i = 0; i < series.data.length; i++) {
1634
+ rawPoint = series.data[i];
1635
+ projectedPoint = projectedPoints[i];
1636
+
1637
+ rawPoint.plotXold = rawPoint.plotX;
1638
+ rawPoint.plotYold = rawPoint.plotY;
1639
+
1640
+ rawPoint.plotX = projectedPoint.x;
1641
+ rawPoint.plotY = projectedPoint.y;
1642
+ rawPoint.plotZ = projectedPoint.z;
1643
+
1644
+
1645
+ }
1646
+
1647
+ });
1648
+
1649
+ Highcharts.wrap(Highcharts.seriesTypes.scatter.prototype, 'init', function (proceed, chart, options) {
1650
+ if (chart.is3d()) {
1651
+ // add a third coordinate
1652
+ this.axisTypes = ['xAxis', 'yAxis', 'zAxis'];
1653
+ this.pointArrayMap = ['x', 'y', 'z'];
1654
+ this.parallelArrays = ['x', 'y', 'z'];
1655
+ }
1656
+
1657
+ var result = proceed.apply(this, [chart, options]);
1658
+
1659
+ if (this.chart.is3d()) {
1660
+ // Set a new default tooltip formatter
1661
+ var default3dScatterTooltip = 'x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>z: <b>{point.z}</b><br/>';
1662
+ if (this.userOptions.tooltip) {
1663
+ this.tooltipOptions.pointFormat = this.userOptions.tooltip.pointFormat || default3dScatterTooltip;
1664
+ } else {
1665
+ this.tooltipOptions.pointFormat = default3dScatterTooltip;
1666
+ }
1667
+ }
1668
+ return result;
1669
+ });
1670
+ /**
1671
+ * Extension to the VML Renderer
1672
+ */
1673
+ if (Highcharts.VMLRenderer) {
1674
+
1675
+ Highcharts.setOptions({ animate: false });
1676
+
1677
+ Highcharts.VMLRenderer.prototype.cuboid = Highcharts.SVGRenderer.prototype.cuboid;
1678
+ Highcharts.VMLRenderer.prototype.cuboidPath = Highcharts.SVGRenderer.prototype.cuboidPath;
1679
+
1680
+ Highcharts.VMLRenderer.prototype.toLinePath = Highcharts.SVGRenderer.prototype.toLinePath;
1681
+
1682
+ Highcharts.VMLRenderer.prototype.createElement3D = Highcharts.SVGRenderer.prototype.createElement3D;
1683
+
1684
+ Highcharts.VMLRenderer.prototype.arc3d = function (shapeArgs) {
1685
+ var result = Highcharts.SVGRenderer.prototype.arc3d.call(this, shapeArgs);
1686
+ result.css({ zIndex: result.zIndex });
1687
+ return result;
1688
+ };
1689
+
1690
+ Highcharts.VMLRenderer.prototype.arc3dPath = Highcharts.SVGRenderer.prototype.arc3dPath;
1691
+
1692
+ Highcharts.wrap(Highcharts.Axis.prototype, 'render', function (proceed) {
1693
+ proceed.apply(this, [].slice.call(arguments, 1));
1694
+ // VML doesn't support a negative z-index
1695
+ if (this.sideFrame) {
1696
+ this.sideFrame.css({ zIndex: 0 });
1697
+ this.sideFrame.front.attr({ fill: this.sideFrame.color });
1698
+ }
1699
+ if (this.bottomFrame) {
1700
+ this.bottomFrame.css({ zIndex: 1 });
1701
+ this.bottomFrame.front.attr({ fill: this.bottomFrame.color });
1702
+ }
1703
+ if (this.backFrame) {
1704
+ this.backFrame.css({ zIndex: 0 });
1705
+ this.backFrame.front.attr({ fill: this.backFrame.color });
1706
+ }
1707
+ });
1708
+
1709
+ }
1710
+
1711
+ }));