highstock-rails 1.3.10 → 2.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
+ }));