rgraph-rails 5.00 → 6.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/publish-geml.yaml +46 -0
  3. data/.gitignore +1 -0
  4. data/README.md +4 -5
  5. data/lib/rgraph-rails/version.rb +1 -1
  6. data/rgraph-rails.gemspec +4 -4
  7. data/vendor/assets/javascripts/RGraph.activity.js +1691 -0
  8. data/vendor/assets/javascripts/RGraph.bar.js +4253 -236
  9. data/vendor/assets/javascripts/RGraph.bipolar.js +3958 -162
  10. data/vendor/assets/javascripts/RGraph.common.annotate.js +414 -35
  11. data/vendor/assets/javascripts/RGraph.common.context.js +635 -30
  12. data/vendor/assets/javascripts/RGraph.common.core.js +10485 -419
  13. data/vendor/assets/javascripts/RGraph.common.csv.js +508 -27
  14. data/vendor/assets/javascripts/RGraph.common.dynamic.js +1693 -90
  15. data/vendor/assets/javascripts/RGraph.common.effects.js +1629 -89
  16. data/vendor/assets/javascripts/RGraph.common.key.js +1003 -53
  17. data/vendor/assets/javascripts/RGraph.common.moment.js +5670 -0
  18. data/vendor/assets/javascripts/RGraph.common.sheets.js +541 -31
  19. data/vendor/assets/javascripts/RGraph.common.sheets.php +351 -0
  20. data/vendor/assets/javascripts/RGraph.common.starburst.js +382 -0
  21. data/vendor/assets/javascripts/RGraph.common.table.js +386 -0
  22. data/vendor/assets/javascripts/RGraph.common.tooltips.js +1433 -32
  23. data/vendor/assets/javascripts/RGraph.drawing.background.js +660 -35
  24. data/vendor/assets/javascripts/RGraph.drawing.circle.js +618 -34
  25. data/vendor/assets/javascripts/RGraph.drawing.image.js +857 -52
  26. data/vendor/assets/javascripts/RGraph.drawing.line.js +712 -0
  27. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +760 -38
  28. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +740 -37
  29. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +573 -36
  30. data/vendor/assets/javascripts/RGraph.drawing.poly.js +667 -36
  31. data/vendor/assets/javascripts/RGraph.drawing.rect.js +638 -34
  32. data/vendor/assets/javascripts/RGraph.drawing.text.js +672 -37
  33. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +653 -52
  34. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +714 -51
  35. data/vendor/assets/javascripts/RGraph.fuel.js +1149 -59
  36. data/vendor/assets/javascripts/RGraph.funnel.js +1277 -56
  37. data/vendor/assets/javascripts/RGraph.gantt.js +1646 -82
  38. data/vendor/assets/javascripts/RGraph.gauge.js +1773 -89
  39. data/vendor/assets/javascripts/RGraph.hbar.js +3869 -159
  40. data/vendor/assets/javascripts/RGraph.horseshoe.js +970 -0
  41. data/vendor/assets/javascripts/RGraph.hprogress.js +1829 -81
  42. data/vendor/assets/javascripts/RGraph.line.js +5293 -244
  43. data/vendor/assets/javascripts/RGraph.meter.js +1570 -77
  44. data/vendor/assets/javascripts/RGraph.modaldialog.js +300 -19
  45. data/vendor/assets/javascripts/RGraph.odo.js +1553 -68
  46. data/vendor/assets/javascripts/RGraph.pie.js +3273 -129
  47. data/vendor/assets/javascripts/RGraph.radar.js +2333 -108
  48. data/vendor/assets/javascripts/RGraph.rose.js +2685 -114
  49. data/vendor/assets/javascripts/RGraph.rscatter.js +1920 -80
  50. data/vendor/assets/javascripts/RGraph.scatter.js +4215 -171
  51. data/vendor/assets/javascripts/RGraph.segmented.js +1006 -0
  52. data/vendor/assets/javascripts/RGraph.semicircularprogress.js +1980 -59
  53. data/vendor/assets/javascripts/RGraph.svg.activity.js +1696 -0
  54. data/vendor/assets/javascripts/RGraph.svg.bar.js +2575 -77
  55. data/vendor/assets/javascripts/RGraph.svg.bipolar.js +3533 -106
  56. data/vendor/assets/javascripts/RGraph.svg.common.ajax.js +240 -21
  57. data/vendor/assets/javascripts/RGraph.svg.common.core.js +7105 -299
  58. data/vendor/assets/javascripts/RGraph.svg.common.csv.js +408 -28
  59. data/vendor/assets/javascripts/RGraph.svg.common.fx.js +1291 -68
  60. data/vendor/assets/javascripts/RGraph.svg.common.key.js +451 -20
  61. data/vendor/assets/javascripts/RGraph.svg.common.sheets.js +543 -31
  62. data/vendor/assets/javascripts/RGraph.svg.common.table.js +391 -0
  63. data/vendor/assets/javascripts/RGraph.svg.common.tooltips.js +1072 -23
  64. data/vendor/assets/javascripts/RGraph.svg.funnel.js +1151 -32
  65. data/vendor/assets/javascripts/RGraph.svg.gauge.js +1429 -34
  66. data/vendor/assets/javascripts/RGraph.svg.hbar.js +2692 -65
  67. data/vendor/assets/javascripts/RGraph.svg.horseshoe.js +969 -0
  68. data/vendor/assets/javascripts/RGraph.svg.line.js +2855 -86
  69. data/vendor/assets/javascripts/RGraph.svg.pie.js +1630 -58
  70. data/vendor/assets/javascripts/RGraph.svg.radar.js +1772 -58
  71. data/vendor/assets/javascripts/RGraph.svg.rose.js +2419 -83
  72. data/vendor/assets/javascripts/RGraph.svg.scatter.js +2280 -65
  73. data/vendor/assets/javascripts/RGraph.svg.segmented.js +930 -0
  74. data/vendor/assets/javascripts/RGraph.svg.semicircularprogress.js +1612 -29
  75. data/vendor/assets/javascripts/RGraph.svg.waterfall.js +1525 -50
  76. data/vendor/assets/javascripts/RGraph.thermometer.js +1411 -64
  77. data/vendor/assets/javascripts/RGraph.vprogress.js +1915 -81
  78. data/vendor/assets/javascripts/RGraph.waterfall.js +1896 -89
  79. data/vendor/assets/javascripts/financial-data.js +1067 -0
  80. metadata +37 -16
  81. data/.travis.yml +0 -11
  82. data/vendor/assets/javascripts/RGraph.common.deprecated.js +0 -35
  83. data/vendor/assets/javascripts/RGraph.common.resizing.js +0 -38
  84. data/vendor/assets/javascripts/RGraph.common.zoom.js +0 -15
  85. data/vendor/assets/javascripts/RGraph.cornergauge.js +0 -71
@@ -1,59 +1,1631 @@
1
+ 'version:2023-09-16 (6.14)';
2
+ //
3
+ // o--------------------------------------------------------------------------------o
4
+ // | This file is part of the RGraph package - you can learn more at: |
5
+ // | |
6
+ // | https://www.rgraph.net |
7
+ // | |
8
+ // | RGraph is licensed under the Open Source MIT license. That means that it's |
9
+ // | totally free to use and there are no restrictions on what you can do with it! |
10
+ // o--------------------------------------------------------------------------------o
1
11
 
2
- RGraph=window.RGraph||{isRGraph:true};RGraph.SVG=RGraph.SVG||{};(function(win,doc,undefined)
3
- {var RG=RGraph,ua=navigator.userAgent,ma=Math,win=window,doc=document;RG.SVG.Pie=function(conf)
4
- {this.set=function(name,value)
5
- {if(arguments.length===1&&typeof name==='object'){for(i in arguments[0]){if(typeof i==='string'){name=ret.name;value=ret.value;this.set(name,value);}}}else{var ret=RG.SVG.commonSetter({object:this,name:name,value:value});name=ret.name;value=ret.value;this.properties[name]=value;if(name==='colors'){this.originalColors=RG.SVG.arrayClone(value);this.colorsParsed=false;}}
6
- return this;};this.get=function(name)
7
- {return this.properties[name];};this.id=conf.id;this.uid=RG.SVG.createUID();this.container=document.getElementById(this.id);this.layers={};this.svg=RG.SVG.createSVG({object:this,container:this.container});this.isRGraph=true;this.width=Number(this.svg.getAttribute('width'));this.height=Number(this.svg.getAttribute('height'));this.data=conf.data;this.type='pie';this.angles=[];this.colorsParsed=false;this.originalColors={};this.gradientCounter=1;this.nodes=[];this.shadowNodes=[];this.propertyNameAliases={};RG.SVG.OR.add(this);this.container.style.display='inline-block';this.properties={centerx:null,centery:null,radius:null,marginLeft:35,marginRight:35,marginTop:35,marginBottom:35,colors:['#f66','#6f6','#66f','#ff6','#6ff','#ccc','pink','orange','cyan','maroon','olive','teal'],colorsStroke:'rgba(0,0,0,0)',textColor:'black',textFont:'Arial, Verdana, sans-serif',textSize:12,textBold:false,textItalic:false,labels:[],labelsSticks:true,labelsSticksHlength:50,linewidth:1,tooltips:null,tooltipsOverride:null,tooltipsEffect:'fade',tooltipsCssClass:'RGraph_tooltip',tooltipsEvent:'click',highlightStroke:'rgba(0,0,0,0)',highlightFill:'rgba(255,255,255,0.7)',highlightLinewidth:1,highlightStyle:'normal',highlightStyleOutlineWidth:7,title:'',titleX:null,titleY:null,titleHalign:'center',titleValign:null,titleSize:null,titleColor:null,titleFont:null,titleBold:null,titleItalic:null,titleSubtitle:null,titleSubtitleX:null,titleSubtitleY:null,titleSubtitleHalign:'center',titleSubtitleValign:null,titleSubtitleSize:null,titleSubtitleColor:'#aaa',titleSubtitleFont:null,titleSubtitleBold:null,titleSubtitleItalic:null,shadow:false,shadowOffsetx:2,shadowOffsety:2,shadowBlur:2,shadowOpacity:0.25,exploded:0,roundRobinMultiplier:1,donut:false,donutWidth:75,key:null,keyColors:null,keyOffsetx:0,keyOffsety:0,keyLabelsOffsetx:0,keyLabelsOffsety:-1,keyLabelsColor:null,keyLabelsFont:null,keyLabelsSize:null,keyLabelsBold:null,keyLabelsItalic:null};RG.SVG.getGlobals(this);if(RG.SVG.FX&&typeof RG.SVG.FX.decorate==='function'){RG.SVG.FX.decorate(this);}
8
- var prop=this.properties;this.draw=function()
9
- {RG.SVG.fireCustomEvent(this,'onbeforedraw');this.angles=[];this.width=Number(this.svg.getAttribute('width'));this.height=Number(this.svg.getAttribute('height'));RG.SVG.createDefs(this);this.graphWidth=this.width-prop.marginLeft-prop.marginRight;this.graphHeight=this.height-prop.marginTop-prop.marginBottom;this.centerx=(this.graphWidth/2)+prop.marginLeft;this.centery=(this.graphHeight/2)+prop.marginTop;this.radius=ma.min(this.graphWidth,this.graphHeight)/2;this.centerx=typeof prop.centerx==='number'?prop.centerx:this.centerx;this.centery=typeof prop.centery==='number'?prop.centery:this.centery;this.radius=typeof prop.radius==='number'?prop.radius:this.radius;if(typeof prop.radius==='string'&&prop.radius.match(/^\+|-\d+$/))this.radius+=parseFloat(prop.radius);if(typeof prop.centerx==='string'&&prop.centerx.match(/^\+|-\d+$/))this.centerx+=parseFloat(prop.centerx);if(typeof prop.centery==='string'&&prop.centery.match(/^\+|-\d+$/))this.centery+=parseFloat(prop.centery);RG.SVG.resetColorsToOriginalValues({object:this});this.parseColors();this.max=RG.SVG.arrayMax(this.data);this.total=RG.SVG.arraySum(this.data);if(typeof prop.exploded==='number'&&prop.exploded>0){var val=prop.exploded;prop.exploded=[];for(var i=0;i<this.data.length;++i){prop.exploded[i]=val;}}
10
- this.drawSegments({shadow:true});RG.SVG.drawTitle(this);if(prop.labelsSticks){this.drawLabelsSticks();}else{this.drawLabels();}
11
- this.drawIngraphLabels();if(typeof prop.key!==null&&RG.SVG.drawKey){RG.SVG.drawKey(this);}else if(!RGraph.SVG.isNull(prop.key)){alert('The drawKey() function does not exist - have you forgotten to include the key library?');}
12
- var obj=this;document.body.addEventListener('mousedown',function(e)
13
- {RG.SVG.removeHighlight(obj);},false);RG.SVG.fireCustomEvent(this,'ondraw');return this;};this.drawSegments=function(opt)
14
- {var start=0,end=0,angle=0,sum=RG.SVG.arraySum(this.data),segment=0;for(var i=0,len=this.data.length;i<len;++i){var value=this.data[i]*prop.roundRobinMultiplier;start=angle;segment=((value/sum)*RG.SVG.TRIG.TWOPI);end=start+segment;var explosion=RG.SVG.TRIG.getRadiusEndPoint({angle:start+(segment/2),r:prop.exploded[i]});var explosionX=explosion[1],explosionY=explosion[0];this.angles[i]={start:start,end:end,angle:end-start,halfway:((end-start)/2)+start,cx:this.centerx+(parseFloat(explosionX)||0),cy:this.centery-(parseFloat(explosionY)||0),radius:this.radius,object:this};angle+=(end-start);}
15
- if(opt.shadow){RG.SVG.setShadow({object:this,offsetx:prop.shadowOffsetx,offsety:prop.shadowOffsety,blur:prop.shadowBlur,opacity:prop.shadowOpacity,id:'dropShadow'});}
16
- for(var i=0;i<this.angles.length;++i){var path=RG.SVG.TRIG.getArcPath({cx:this.angles[i].cx,cy:this.angles[i].cy,r:this.radius,start:this.angles[i].start,end:this.angles[i].end});if(prop.donut){var donutWidth=prop.donutWidth;var donut_path=RG.SVG.TRIG.getArcPath3({cx:this.angles[i].cx,cy:this.angles[i].cy,r:this.radius-donutWidth,start:this.angles[i].end,end:this.angles[i].start,moveto:false,anticlockwise:true});var xy=RG.SVG.TRIG.getRadiusEndPoint({angle:this.angles[i].end-RG.SVG.TRIG.HALFPI,r:this.radius-donutWidth});path=path
17
- +" L {1} {2} ".format(xy[0]+this.angles[i].cx,xy[1]+this.angles[i].cy)
18
- +donut_path
19
- +" Z";}else{path=path+" L {1} {2} ".format(this.angles[i].cx,this.angles[i].cy)+" Z"}
20
- var arc=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'path',attr:{d:path,fill:prop.colors[i],stroke:prop.colorsStroke,'stroke-width':prop.linewidth,'data-tooltip':(!RG.SVG.isNull(prop.tooltips)&&prop.tooltips.length)?prop.tooltips[i]:'','data-index':i,'data-value':value,'data-start-angle':this.angles[i].start,'data-end-angle':this.angles[i].end,'data-radius':this.radius,filter:(prop.shadow&&opt.shadow)?'url(#dropShadow)':''}});this.angles[i].element=arc;if(prop.shadow&&opt.shadow){this.shadowNodes[i]=arc;}else{this.nodes[i]=arc;}
21
- if(prop.tooltips&&prop.tooltips[i]&&(!opt.shadow||!prop.shadow)){if(prop.tooltipsEvent!=='mousemove'){prop.tooltipsEvent='click';}
22
- (function(index,obj)
23
- {arc.addEventListener(prop.tooltipsEvent,function(e)
24
- {var tooltip=RG.SVG.REG.get('tooltip');if(tooltip&&prop.tooltipsEvent==='mousemove'&&index===tooltip.__index__){return;}
25
- obj.removeHighlight();RG.SVG.tooltip({object:obj,index:index,sequentialIndex:index,text:prop.tooltips[index],event:e});obj.highlight(e.target);var highlight=RG.SVG.REG.get('highlight');if(prop.tooltipsEvent==='mousemove'){highlight.style.cursor='pointer';}},false);if(prop.tooltipsEvent==='click'){arc.addEventListener('mousemove',function(e)
26
- {e.target.style.cursor='pointer';},false);}}(i,this));}}
27
- if(prop.shadow&&opt.shadow){this.redrawSegments();}};this.redrawSegments=function()
28
- {this.drawSegments({shadow:false});};this.drawLabels=function()
29
- {var angles=this.angles,prop=this.properties,labels=prop.labels;for(var i=0;i<angles.length;++i){var endpoint=RG.SVG.TRIG.getRadiusEndPoint({angle:angles[i].halfway-RG.SVG.TRIG.HALFPI,r:angles[i].radius+15});var x=endpoint[0]+angles[i].cx,y=endpoint[1]+angles[i].cy,valign,halign;if(angles[i].halfway>0&&angles[i].halfway<RG.SVG.TRIG.HALFPI){halign='left';valign='bottom';}else if(angles[i].halfway>RG.SVG.TRIG.HALFPI&&angles[i].halfway<RG.SVG.TRIG.PI){halign='left';valign='top';}else if(angles[i].halfway>RG.SVG.TRIG.PI&&angles[i].halfway<(RG.SVG.TRIG.HALFPI+RG.SVG.TRIG.PI)){halign='right';valign='top';}else if(angles[i].halfway>(RG.SVG.TRIG.HALFPI+RG.SVG.TRIG.PI)&&angles[i].halfway<RG.SVG.TRIG.TWOPI){halign='right';valign='top';}
30
- RG.SVG.text({object:this,parent:this.svg.all,tag:'labels',text:typeof labels[i]==='string'?labels[i]:'',x:x,y:y,valign:valign,halign:halign,font:prop.labelsFont||prop.textFont,size:typeof prop.labelsSize==='number'?prop.labelsSize:prop.textSize,bold:typeof prop.labelsBold==='boolean'?prop.labelsBold:prop.textBold,italic:typeof prop.labelsItalic==='boolean'?prop.labelsItalic:prop.textItalic,color:prop.labelsColor||prop.textColor});}};this.drawIngraphLabels=function()
31
- {if(prop.labelsIngraph){for(var i=0;i<this.angles.length;++i){var halign=prop.labelsIngraphHalign||'center',valign=prop.labelsIngraphValign||'center',font=prop.labelsIngraphFont||prop.textFont,size=typeof prop.labelsIngraphSize==='number'?prop.labelsIngraphSize:prop.textSize,italic=typeof prop.labelsIngraphItalic==='boolean'?prop.labelsIngraphItalic:prop.textItalic,bold=typeof prop.labelsIngraphBold==='boolean'?prop.labelsIngraphBold:prop.textBold,color=prop.labelsIngraphColor||prop.textColor,bgcolor=prop.labelsIngraphBackground||'transparent',decimals=prop.labelsIngraphDecimals||0,padding=typeof prop.labelsIngraphBackground==='string'?3:0;var xy=RG.SVG.TRIG.getRadiusEndPoint({angle:this.angles[i].halfway-RG.SVG.TRIG.HALFPI,r:this.angles[i].radius*(typeof prop.labelsIngraphRadiusPos==='number'?prop.labelsIngraphRadiusPos:0.5)});if(typeof prop.labelsIngraphSpecific==='object'&&prop.labelsIngraphSpecific){if(typeof prop.labelsIngraphSpecific[i]==='string'){var str=prop.labelsIngraphSpecific[i];}else{var str='';}}else{if(typeof prop.labelsIngraphFormatter==='function'){var str=prop.labelsIngraphFormatter({object:this,number:this.data[i].toFixed(decimals)})}else{var str=RG.SVG.numberFormat({prepend:prop.labelsIngraphUnitsPre,append:prop.labelsIngraphUnitsPost,point:prop.labelsIngraphPoint,thousand:prop.labelsIngraphThousand,num:this.data[i].toFixed(decimals),object:this});}}
32
- RG.SVG.text({object:this,parent:this.svg.all,tag:'labels.ingraph',x:this.angles[i].cx+xy[0],y:this.angles[i].cy+xy[1],text:str,halign:halign,valign:valign,font:font,size:size,bold:bold,italic:italic,color:color,background:bgcolor,padding:padding});}}};this.drawLabelsSticks=function()
33
- {var labels_right=[],labels_left=[],labels_coords=[];for(var i=0;i<this.angles.length;++i){var angle=(this.angles[i].start+((this.angles[i].end-this.angles[i].start)/2))-RGraph.SVG.TRIG.HALFPI,endpoint_inner=RG.SVG.TRIG.getRadiusEndPoint({angle:angle,r:this.radius+5}),endpoint_outer=RG.SVG.TRIG.getRadiusEndPoint({angle:angle,r:this.radius+30}),explosion=[(typeof prop.exploded==='number'?prop.exploded:prop.exploded[i]),ma.cos(angle)*(typeof prop.exploded==='number'?prop.exploded:prop.exploded[i]),ma.sin(angle)*(typeof prop.exploded==='number'?prop.exploded:prop.exploded[i])];labels_coords[i]=[];var labels={};if(angle>RG.SVG.TRIG.HALFPI){var index=labels_left.length;labels_left[index]=[];labels_left[index].text=prop.labels[i];labels_left[index].halign='right';labels=labels_left;labels_coords[i].halign='right';}else{var index=labels_right.length;labels_right[index]=[];labels_right[index].text=prop.labels[i];labels_right[index].halign='right';labels=labels_right;labels_coords[i].halign='left';}
34
- endpoint_inner[0]+=(explosion[1]||0);endpoint_inner[1]+=(explosion[2]||0);endpoint_outer[0]+=(explosion[1]||0);endpoint_outer[1]+=(explosion[2]||0);var x,y;if(labels[index].text){var stick=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'path',attr:{d:'M {1} {2} L {3} {4}'.format(this.centerx+endpoint_inner[0],this.centery+endpoint_inner[1],this.centerx+endpoint_outer[0],this.centery+endpoint_outer[1]),stroke:'#999',fill:'rgba(0,0,0,0)'}});}
35
- if(stick){labels[index].stick=stick;}
36
- x=(this.centerx+endpoint_outer[0]+(angle>1.57?-50:50));y=(this.centery+endpoint_outer[1]);labels_coords[i].x=x;labels_coords[i].y=y;labels_coords[i].text=prop.labels[i];}
37
- var vspace_right=(this.height-prop.marginTop-prop.marginBottom)/labels_right.length;var vspace_left=(this.height-prop.marginTop-prop.marginBottom)/labels_left.length;x=y=0;for(var i=0;i<labels_right.length;++i){if(labels_right[i]&&labels_right[i].text){x=this.centerx+this.radius+100;y=prop.marginTop+(vspace_right*i)+(vspace_right/2);RGraph.SVG.text({object:this,parent:this.svg.all,tag:'labels.sticks',text:typeof labels_right[i].text==='string'?labels_right[i].text:'',x:x,y:y,valign:'center',halign:labels_right[i].text,font:prop.labelsFont||prop.textFont,size:typeof prop.labelsSize==='number'?prop.labelsSize:prop.textSize,bold:typeof prop.labelsBold==='boolean'?prop.labelsBold:prop.textBold,italic:typeof prop.labelsItalic==='boolean'?prop.labelsItalic:prop.textItalic,color:prop.labelsColor||prop.textColor});var str=labels_right[i].stick.getAttribute('d').replace(/ L /,' Q ')+' {1} {2}';labels_right[i].stick.setAttribute('d',str.format(x-5,y));}}
38
- for(var i=0;i<labels_left.length;++i){if(labels_left[i]&&labels_left[i].text){x=this.centerx-this.radius-100;y=this.height-(prop.marginTop+(vspace_left*i)+(vspace_left/2));RGraph.SVG.text({object:this,parent:this.svg.all,tag:'labels.sticks',text:typeof labels_left[i].text==='string'?labels_left[i].text:'',x:x-7,y:y,valign:'center',halign:labels_left[i].halign,font:prop.labelsFont||prop.textFont,size:typeof prop.labelsSize==='number'?prop.labelsSize:prop.textSize,bold:typeof prop.labelsBold==='boolean'?prop.labelsBold:prop.textBold,italic:typeof prop.labelsItalic==='boolean'?prop.labelsItalic:prop.textItalic,color:prop.labelsColor||prop.textColor});var str=labels_left[i].stick.getAttribute('d').replace(/ L /,' Q ')+' {1} {2}';labels_left[i].stick.setAttribute('d',str.format(x-5,y));}}};this.highlight=function(segment)
39
- {if(prop.highlightStyle==='outline'){var index=segment.getAttribute('data-index');var path=RGraph.SVG.TRIG.getArcPath3({start:this.angles[index].start,end:this.angles[index].end,cx:this.angles[index].cx,cy:this.angles[index].cy,r:this.angles[index].radius+2,anticlockwise:false,lineto:false});path+=RGraph.SVG.TRIG.getArcPath3({start:this.angles[index].end,end:this.angles[index].start,cx:this.angles[index].cx,cy:this.angles[index].cy,r:this.angles[index].radius+2+prop.highlightStyleOutlineWidth,anticlockwise:true});var highlight=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'path',attr:{d:path,fill:prop.colors[index],stroke:'transparent'},style:{pointerEvents:'none'}});}else{var highlight=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'path',attr:{d:segment.getAttribute('d'),fill:prop.highlightFill,stroke:prop.highlightStroke,'stroke-width':prop.highlightLinewidth},style:{pointerEvents:'none'}});}
40
- if(prop.tooltipsEvent==='mousemove'){highlight.addEventListener('mouseout',function(e)
41
- {highlight.parentNode.removeChild(highlight);RG.SVG.hideTooltip();RG.SVG.REG.set('highlight',null);},false);}
42
- RG.SVG.REG.set('highlight',highlight);};this.parseColors=function()
43
- {if(!Object.keys(this.originalColors).length){this.originalColors={colors:RG.SVG.arrayClone(prop.colors),highlightFill:RG.SVG.arrayClone(prop.highlightFill)}}
44
- var colors=prop.colors;if(colors){for(var i=0;i<colors.length;++i){colors[i]=RG.SVG.parseColorRadial({object:this,color:colors[i]});}}
45
- prop.highlightFill=RG.SVG.parseColorRadial({object:this,color:prop.highlightFill});};this.roundRobin=function()
46
- {var obj=this,opt=arguments[0]||{},data=RG.SVG.arrayClone(this.data),prop=this.properties,frame=1,frames=opt.frames||30,callback=typeof opt.callback==='function'?opt.callback:function(){},dataSum=RG.SVG.arraySum(this.data),textColor=prop.textColor,ingraph=prop.labelsIngraph,multiplier=0;prop.textColor='rgba(0,0,0,0)';prop.labelsIngraph=false;obj.draw();var angles=RG.SVG.arrayClone(this.angles);function iterator()
47
- {multiplier=(1/frames)*frame++;for(var i=0;i<angles.length;++i){var value=obj.data[i];obj.angles[i].start=angles[i].start*multiplier;obj.angles[i].end=angles[i].end*multiplier;var segment=((obj.angles[i].end-obj.angles[i].start)/2),explodedX=ma.cos(obj.angles[i].start+segment-RG.SVG.TRIG.HALFPI)*(prop.exploded[i]||0),explodedY=ma.sin(obj.angles[i].start+segment-RG.SVG.TRIG.HALFPI)*(prop.exploded[i]||0);var path=RG.SVG.TRIG.getArcPath({cx:obj.centerx+explodedX,cy:obj.centery+explodedY,r:obj.radius,start:obj.angles[i].start,end:obj.angles[i].end});if(prop.donut){var donutWidth=prop.donutWidth;var donut_path=RG.SVG.TRIG.getArcPath3({cx:obj.angles[i].cx,cy:obj.angles[i].cy,r:obj.radius-donutWidth,start:obj.angles[i].end,end:obj.angles[i].start,moveto:false,anticlockwise:true});var xy=RG.SVG.TRIG.getRadiusEndPoint({angle:obj.angles[i].end-RG.SVG.TRIG.HALFPI,r:obj.radius-donutWidth});path=path
48
- +" L {1} {2} ".format(xy[0]+obj.angles[i].cx,xy[1]+obj.angles[i].cy)
49
- +donut_path
50
- +" Z";}else{path=path+" L {1} {2} ".format(obj.angles[i].cx,obj.angles[i].cy)+" Z"}
51
- path=path+" L {1} {2} Z".format(obj.centerx+explodedX,obj.centery+explodedY);if(obj.shadowNodes&&obj.shadowNodes[i]){obj.shadowNodes[i].setAttribute('d',path);}
52
- obj.nodes[i].setAttribute('d',path);}
53
- if(frame<=frames){RG.SVG.FX.update(iterator);}else{prop.textColor=textColor;prop.labelsIngraph=ingraph;RG.SVG.redraw(obj.svg);callback(obj);}}
54
- iterator();return this;};this.on=function(type,func)
55
- {if(type.substr(0,2)!=='on'){type='on'+type;}
56
- RG.SVG.addCustomEventListener(this,type,func);return this;};this.exec=function(func)
57
- {func(this);return this;};this.removeHighlight=function()
58
- {var highlight=RG.SVG.REG.get('highlight');if(highlight&&highlight.parentNode){highlight.parentNode.removeChild(highlight);}
59
- RG.SVG.REG.set('highlight',null);};for(i in conf.options){if(typeof i==='string'){this.set(i,conf.options[i]);}}};return this;})(window,document);
12
+ RGraph = window.RGraph || {isrgraph:true,isRGraph:true,rgraph:true};
13
+ RGraph.SVG = RGraph.SVG || {};
14
+
15
+ // Module pattern
16
+ (function (win, doc, undefined)
17
+ {
18
+ RGraph.SVG.Pie = function (conf)
19
+ {
20
+ //
21
+ // A setter that the constructor uses (at the end)
22
+ // to set all of the properties
23
+ //
24
+ // @param string name The name of the property to set
25
+ // @param string value The value to set the property to
26
+ //
27
+ this.set = function (name, value)
28
+ {
29
+ if (arguments.length === 1 && typeof name === 'object') {
30
+ for (i in arguments[0]) {
31
+ if (typeof i === 'string') {
32
+
33
+ name = ret.name;
34
+ value = ret.value;
35
+
36
+ this.set(name, value);
37
+ }
38
+ }
39
+ } else {
40
+ var ret = RGraph.SVG.commonSetter({
41
+ object: this,
42
+ name: name,
43
+ value: value
44
+ });
45
+
46
+ name = ret.name;
47
+ value = ret.value;
48
+
49
+ this.properties[name] = value;
50
+
51
+ // If setting the colors, update the originalColors
52
+ // property too
53
+ if (name === 'colors') {
54
+ this.originalColors = RGraph.SVG.arrayClone(value);
55
+ this.colorsParsed = false;
56
+ }
57
+ }
58
+
59
+ return this;
60
+ };
61
+
62
+
63
+
64
+
65
+
66
+
67
+
68
+
69
+ //
70
+ // A getter.
71
+ //
72
+ // @param name string The name of the property to get
73
+ //
74
+ this.get = function (name)
75
+ {
76
+ return this.properties[name];
77
+ };
78
+
79
+
80
+
81
+
82
+
83
+
84
+
85
+
86
+ // Convert strings to numbers
87
+ conf.data = RGraph.SVG.stringsToNumbers(conf.data);
88
+
89
+
90
+
91
+
92
+
93
+ this.id = conf.id;
94
+ this.uid = RGraph.SVG.createUID();
95
+ this.container = document.getElementById(this.id);
96
+ this.layers = {}; // MUST be before the SVG tag is created!
97
+ this.svg = RGraph.SVG.createSVG({object: this,container: this.container});
98
+ this.isRGraph = true;
99
+ this.isrgraph = true;
100
+ this.rgraph = true;
101
+ this.width = Number(this.svg.getAttribute('width'));
102
+ this.height = Number(this.svg.getAttribute('height'));
103
+ this.data = conf.data;
104
+ this.type = 'pie';
105
+ this.angles = [];
106
+ this.colorsParsed = false;
107
+ this.originalColors = {};
108
+ this.gradientCounter = 1;
109
+ this.nodes = [];
110
+ this.shadowNodes = [];
111
+ this.firstDraw = true; // After the first draw this will be false
112
+
113
+
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+ // Add this object to the ObjectRegistry
124
+ RGraph.SVG.OR.add(this);
125
+
126
+ // Set the DIV container to be inline-block
127
+ this.container.style.display = 'inline-block';
128
+
129
+ this.properties =
130
+ {
131
+ centerx: null,
132
+ centery: null,
133
+ radius: null,
134
+
135
+ marginLeft: 35,
136
+ marginRight: 35,
137
+ marginTop: 35,
138
+ marginBottom: 35,
139
+
140
+ colors: [
141
+ '#f66', '#6f6', '#66f', '#ff6', '#6ff', '#ccc',
142
+ 'pink', 'orange', 'cyan', 'maroon', 'olive', 'teal'
143
+ ],
144
+ colorsStroke: 'rgba(0,0,0,0)',
145
+
146
+ textColor: 'black',
147
+ textFont: 'Arial, Verdana, sans-serif',
148
+ textSize: 12,
149
+ textBold: false,
150
+ textItalic: false,
151
+ text: null,
152
+
153
+ labels: [],
154
+ labelsSticks: true,
155
+ labelsSticksOffset: 50,
156
+ labelsFormattedDecimals: 0,
157
+ labelsFormattedPoint: '.',
158
+ labelsFormattedThousand: ',',
159
+ labelsFormattedUnitsPre: '',
160
+ labelsFormattedUnitsPost: '',
161
+
162
+ linewidth: 1,
163
+
164
+ tooltips: null,
165
+ tooltipsOverride: null,
166
+ tooltipsEffect: 'fade',
167
+ tooltipsCssClass: 'RGraph_tooltip',
168
+ tooltipsCss: null,
169
+ tooltipsEvent: 'click',
170
+ tooltipsFormattedThousand: ',',
171
+ tooltipsFormattedPoint: '.',
172
+ tooltipsFormattedDecimals: 0,
173
+ tooltipsFormattedUnitsPre: '',
174
+ tooltipsFormattedUnitsPost: '',
175
+ tooltipsFormattedKeyColors: null,
176
+ tooltipsFormattedKeyColorsShape: 'square',
177
+ tooltipsFormattedKeyLabels: [],
178
+ tooltipsFormattedTableHeaders: null,
179
+ tooltipsFormattedTableData: null,
180
+ tooltipsPointer: true,
181
+ tooltipsPointerOffsetx: 0,
182
+ tooltipsPointerOffsety: 0,
183
+ tooltipsPositionStatic: true,
184
+
185
+ highlightStroke: 'rgba(0,0,0,0)',
186
+ highlightFill: 'rgba(255,255,255,0.7)',
187
+ highlightLinewidth: 1,
188
+ highlightStyle: 'normal',
189
+ highlightStyleOutlineWidth: 7,
190
+
191
+ title: '',
192
+ titleX: null,
193
+ titleY: null,
194
+ titleHalign: 'center',
195
+ titleValign: null,
196
+ titleSize: null,
197
+ titleColor: null,
198
+ titleFont: null,
199
+ titleBold: null,
200
+ titleItalic: null,
201
+
202
+ titleSubtitle: null,
203
+ titleSubtitleSize: null,
204
+ titleSubtitleColor: '#aaa',
205
+ titleSubtitleFont: null,
206
+ titleSubtitleBold: null,
207
+ titleSubtitleItalic: null,
208
+
209
+ shadow: false,
210
+ shadowOffsetx: 2,
211
+ shadowOffsety: 2,
212
+ shadowBlur: 2,
213
+ shadowColor: 'rgba(0,0,0,.25)',
214
+
215
+ exploded: 0,
216
+ roundRobinMultiplier: 1,
217
+
218
+ donut: false,
219
+ donutWidth: 75,
220
+
221
+ key: null,
222
+ keyColors: null,
223
+ keyOffsetx: 0,
224
+ keyOffsety: 0,
225
+ keyLabelsOffsetx: 0,
226
+ keyLabelsOffsety: -1,
227
+ keyLabelsColor: null,
228
+ keyLabelsFont: null,
229
+ keyLabelsSize: null,
230
+ keyLabelsBold: null,
231
+ keyLabelsItalic: null
232
+ };
233
+
234
+
235
+
236
+
237
+ //
238
+ // Copy the global object properties to this instance
239
+ //
240
+ RGraph.SVG.getGlobals(this);
241
+
242
+
243
+
244
+
245
+
246
+ //
247
+ // "Decorate" the object with the generic effects if the effects library has been included
248
+ //
249
+ if (RGraph.SVG.FX && typeof RGraph.SVG.FX.decorate === 'function') {
250
+ RGraph.SVG.FX.decorate(this);
251
+ }
252
+
253
+
254
+
255
+
256
+
257
+ // Add the responsive function to the object
258
+ this.responsive = RGraph.SVG.responsive;
259
+
260
+
261
+
262
+
263
+
264
+ var properties = this.properties;
265
+
266
+
267
+
268
+
269
+
270
+
271
+
272
+
273
+ //
274
+ // The draw method draws the Bar chart
275
+ //
276
+ this.draw = function ()
277
+ {
278
+ // Fire the beforedraw event
279
+ RGraph.SVG.fireCustomEvent(this, 'onbeforedraw');
280
+
281
+
282
+
283
+
284
+
285
+
286
+
287
+
288
+
289
+
290
+
291
+
292
+
293
+ //(Re)set this so it doesn't grow endlessly
294
+ this.angles = [];
295
+
296
+
297
+
298
+
299
+
300
+
301
+
302
+
303
+
304
+
305
+
306
+ // Should the first thing that's done inthe.draw() function
307
+ // except for the onbeforedraw event
308
+ this.width = Number(this.svg.getAttribute('width'));
309
+ this.height = Number(this.svg.getAttribute('height'));
310
+
311
+
312
+
313
+
314
+
315
+
316
+
317
+
318
+
319
+
320
+
321
+
322
+
323
+
324
+
325
+ // Create the defs tag if necessary
326
+ RGraph.SVG.createDefs(this);
327
+
328
+
329
+
330
+
331
+ this.graphWidth = this.width - properties.marginLeft - properties.marginRight;
332
+ this.graphHeight = this.height - properties.marginTop - properties.marginBottom;
333
+
334
+
335
+
336
+ // Work out the center point
337
+ this.centerx = (this.graphWidth / 2) + properties.marginLeft;
338
+ this.centery = (this.graphHeight / 2) + properties.marginTop;
339
+ this.radius = Math.min(this.graphWidth, this.graphHeight) / 2;
340
+
341
+
342
+
343
+ // Allow the user to override the calculated centerx/y/radius
344
+ this.centerx = typeof properties.centerx === 'number' ? properties.centerx : this.centerx;
345
+ this.centery = typeof properties.centery === 'number' ? properties.centery : this.centery;
346
+ this.radius = typeof properties.radius === 'number' ? properties.radius : this.radius;
347
+
348
+ //
349
+ // Allow the centerx/centery/radius to be a plus/minus
350
+ //
351
+ if (typeof properties.radius === 'string' && properties.radius.match(/^\+|-\d+$/) ) this.radius += parseFloat(properties.radius);
352
+ if (typeof properties.centerx === 'string' && properties.centerx.match(/^\+|-\d+$/) ) this.centerx += parseFloat(properties.centerx);
353
+ if (typeof properties.centery === 'string' && properties.centery.match(/^\+|-\d+$/) ) this.centery += parseFloat(properties.centery);
354
+
355
+
356
+ // Parse the colors for gradients
357
+ // Must be after the cx/cy/r calculations
358
+ RGraph.SVG.resetColorsToOriginalValues({object:this});
359
+ this.parseColors();
360
+
361
+
362
+ // Go through the data and work out the maximum value
363
+ this.max = RGraph.SVG.arrayMax(this.data);
364
+ this.total = RGraph.SVG.arraySum(this.data);
365
+
366
+ // Set the explosion to be an array if it's a number
367
+ if (typeof properties.exploded === 'number' && properties.exploded > 0) {
368
+ var val = properties.exploded;
369
+
370
+ properties.exploded = [];
371
+
372
+ for (var i=0; i<this.data.length; ++i) {
373
+ properties.exploded[i] = val;
374
+ }
375
+ }
376
+
377
+
378
+
379
+ // Draw the segments
380
+ this.drawSegments({shadow: true});
381
+
382
+
383
+
384
+ // Draw the title and subtitle
385
+ RGraph.SVG.drawTitle(this);
386
+
387
+
388
+
389
+ // Draw the labels
390
+
391
+ //
392
+ // If the xaxisLabels option is a string then turn it
393
+ // into an array.
394
+ //
395
+ if (properties.labels && properties.labels.length) {
396
+ if (typeof properties.labels === 'string') {
397
+ properties.labels = RGraph.SVG.arrayPad({
398
+ array: [],
399
+ length: this.data.length,
400
+ value: properties.labels
401
+ });
402
+ }
403
+
404
+ // Label substitution
405
+ //
406
+ for (var i=0; i<properties.labels.length; ++i) {
407
+ properties.labels[i] = RGraph.SVG.labelSubstitution({
408
+ object: this,
409
+ text: properties.labels[i],
410
+ index: i,
411
+ value: this.data[i],
412
+ decimals: properties.labelsFormattedDecimals || 0,
413
+ unitsPre: properties.labelsFormattedUnitsPre || '',
414
+ unitsPost: properties.labelsFormattedUnitsPost || '',
415
+ thousand: properties.labelsFormattedThousand || ',',
416
+ point: properties.labelsFormattedPoint || '.'
417
+ });
418
+ }
419
+ }
420
+
421
+ if (properties.labelsSticks) {
422
+ this.drawLabelsSticks();
423
+ } else {
424
+ this.drawLabels();
425
+ }
426
+
427
+
428
+ //
429
+ // Draw the ingraph labels if required
430
+ //
431
+ this.drawIngraphLabels();
432
+
433
+
434
+
435
+
436
+ // Draw the key
437
+ if (typeof properties.key !== null && RGraph.SVG.drawKey) {
438
+ RGraph.SVG.drawKey(this);
439
+ } else if (!RGraph.SVG.isNull(properties.key)) {
440
+ alert('The drawKey() function does not exist - have you forgotten to include the key library?');
441
+ }
442
+
443
+
444
+
445
+
446
+
447
+ // Add the event listener that clears the highlight if
448
+ // there is any. Must be MOUSEDOWN (ie before the click event)
449
+ var obj = this;
450
+ document.body.addEventListener('mousedown', function (e)
451
+ {
452
+ RGraph.SVG.removeHighlight(obj);
453
+ }, false);
454
+
455
+
456
+
457
+
458
+
459
+
460
+
461
+
462
+ //
463
+ // Allow the addition of custom text via the
464
+ // text: property.
465
+ //
466
+ RGraph.SVG.addCustomText(this);
467
+
468
+
469
+
470
+
471
+
472
+
473
+
474
+
475
+
476
+
477
+
478
+
479
+ //
480
+ // Fire the onfirstdraw event
481
+ //
482
+ if (this.firstDraw) {
483
+ this.firstDraw = false;
484
+ RGraph.SVG.fireCustomEvent(this, 'onfirstdraw');
485
+ }
486
+
487
+
488
+
489
+
490
+ // Fire the draw event
491
+ RGraph.SVG.fireCustomEvent(this, 'ondraw');
492
+
493
+
494
+
495
+
496
+
497
+
498
+
499
+ //
500
+ // Install any inline responsive configuration. This
501
+ // should be last in the draw function - even after
502
+ // the draw events.
503
+ //
504
+ RGraph.SVG.installInlineResponsive(this);
505
+
506
+
507
+
508
+
509
+
510
+
511
+
512
+
513
+
514
+
515
+
516
+ return this;
517
+ };
518
+
519
+
520
+
521
+
522
+
523
+
524
+
525
+
526
+ //
527
+ // New create() shortcut function
528
+ // For example:
529
+ // this.create('rect,x:0,y:0,width:100,height:100'[,parent]);
530
+ //
531
+ // @param str string The tag definition to parse and create
532
+ // @param object The (optional) parent element
533
+ // @return object The new tag
534
+ //
535
+ this.create = function (str)
536
+ {
537
+ var def = RGraph.SVG.create.parseStr(this, str);
538
+ def.svg = this.svg;
539
+
540
+ // By default the parent is the SVG tag - but if
541
+ // requested then change it to the tag that has
542
+ // been given
543
+ if (arguments[1]) {
544
+ def.parent = arguments[1];
545
+ }
546
+
547
+ return RGraph.SVG.create(def);
548
+ };
549
+
550
+
551
+
552
+
553
+
554
+
555
+
556
+
557
+ //
558
+ // Draws the segments
559
+ //
560
+ // @param bool Whether or not this is a redraw. If this is a redraw
561
+ // shadows are omitted
562
+ //
563
+ this.drawSegments = function (opt)
564
+ {
565
+ var start = 0,
566
+ end = 0,
567
+ angle = 0,
568
+ sum = RGraph.SVG.arraySum(this.data),
569
+ segment = 0;
570
+
571
+
572
+
573
+
574
+ // Work out the start and end angles for the data
575
+ for (var i=0,len=this.data.length; i<len; ++i) {
576
+
577
+ var value = this.data[i] * properties.roundRobinMultiplier;
578
+
579
+ start = angle;
580
+ segment = ((value / sum) * RGraph.SVG.TRIG.TWOPI);
581
+ end = start + segment;
582
+
583
+ var explosion = RGraph.SVG.TRIG.getRadiusEndPoint({
584
+ angle: start + (segment / 2),
585
+ r: properties.exploded[i]
586
+ });
587
+
588
+ var explosionX = explosion[1],
589
+ explosionY = explosion[0];
590
+
591
+
592
+ this.angles[i] = {
593
+ start: start,
594
+ end: end,
595
+ angle: end - start,
596
+ halfway: ((end - start) / 2) + start,
597
+ cx: this.centerx + (parseFloat(explosionX) || 0),
598
+ cy: this.centery - (parseFloat(explosionY) || 0),
599
+ radius: this.radius,
600
+ object: this
601
+ };
602
+
603
+ // Increase the angle at which we start drawing the next segment at
604
+ angle += (end - start);
605
+ }
606
+
607
+
608
+
609
+ if (opt.shadow) {
610
+ RGraph.SVG.setShadow({
611
+ object: this,
612
+ offsetx: properties.shadowOffsetx,
613
+ offsety: properties.shadowOffsety,
614
+ blur: properties.shadowBlur,
615
+ color: properties.shadowColor,
616
+ id: 'dropShadow'
617
+ });
618
+ }
619
+
620
+
621
+ //
622
+ // This loop goes thru the angles that were
623
+ // generated above and adds them to the
624
+ // scene
625
+ //
626
+ for (var i=0; i<this.angles.length; ++i) {
627
+
628
+ var path = RGraph.SVG.TRIG.getArcPath({
629
+ cx: this.angles[i].cx,
630
+ cy: this.angles[i].cy,
631
+ r: this.radius,
632
+ start: this.angles[i].start,
633
+ end: this.angles[i].end
634
+ });
635
+
636
+
637
+
638
+
639
+
640
+ // Donut
641
+ if (properties.donut) {
642
+
643
+ var donutWidth = properties.donutWidth;
644
+
645
+ var donut_path = RGraph.SVG.TRIG.getArcPath3({
646
+ cx: this.angles[i].cx,
647
+ cy: this.angles[i].cy,
648
+ r: this.radius - donutWidth,
649
+ start: this.angles[i].end,
650
+ end: this.angles[i].start,
651
+ moveto: false,
652
+ anticlockwise: true
653
+ });
654
+
655
+ var xy = RGraph.SVG.TRIG.getRadiusEndPoint({
656
+ angle: this.angles[i].end - RGraph.SVG.TRIG.HALFPI,
657
+ r: this.radius - donutWidth
658
+ });
659
+
660
+
661
+
662
+
663
+ path = path
664
+ + " L {1} {2} ".format(xy[0] + this.angles[i].cx, xy[1] + this.angles[i].cy)
665
+ + donut_path
666
+ + " Z";
667
+
668
+
669
+ } else {
670
+
671
+ path = path + " L {1} {2} ".format(
672
+ this.angles[i].cx,
673
+ this.angles[i].cy
674
+ ) + " Z"
675
+ }
676
+
677
+
678
+
679
+ var arc = RGraph.SVG.create({
680
+ svg: this.svg,
681
+ parent: this.svg.all,
682
+ type: 'path',
683
+ attr: {
684
+ d: path,
685
+ fill: properties.colors[i],
686
+ stroke: properties.colorsStroke,
687
+ 'stroke-width': properties.linewidth,
688
+ 'data-tooltip': (!RGraph.SVG.isNull(properties.tooltips) && properties.tooltips.length) ? properties.tooltips[i] : '',
689
+ 'data-index': i,
690
+ 'data-value': value,
691
+ 'data-start-angle': this.angles[i].start,
692
+ 'data-end-angle': this.angles[i].end,
693
+ 'data-radius': this.radius,
694
+ filter: (properties.shadow && opt.shadow) ? 'url(#dropShadow)' : ''
695
+ }
696
+ });
697
+
698
+ // Store the path with the relevant entry in the obj.angles array
699
+ this.angles[i].element = arc;
700
+
701
+
702
+ // Store a reference to the node
703
+ if (properties.shadow && opt.shadow) {
704
+ this.shadowNodes[i] = arc;
705
+ } else {
706
+ this.nodes[i] = arc;
707
+ }
708
+
709
+ if (properties.tooltips && (properties.tooltips[i] || typeof properties.tooltips === 'string') && (!opt.shadow || !properties.shadow)) {
710
+
711
+ // Make the tooltipsEvent default to click
712
+ if (properties.tooltipsEvent !== 'mousemove') {
713
+ properties.tooltipsEvent = 'click';
714
+ }
715
+
716
+ (function (index, obj)
717
+ {
718
+ arc.addEventListener(properties.tooltipsEvent, function (e)
719
+ {
720
+ // If the event for tooltips is mousemove and the
721
+ // tooltip is already visible then do nothing
722
+ var tooltip = RGraph.SVG.REG.get('tooltip');
723
+ if (tooltip && properties.tooltipsEvent === 'mousemove' && index === tooltip.__index__) {
724
+ return;
725
+ }
726
+
727
+
728
+
729
+
730
+
731
+ obj.removeHighlight();
732
+
733
+ // Show the tooltip
734
+ RGraph.SVG.tooltip({
735
+ object: obj,
736
+ index: index,
737
+ sequentialIndex: index,
738
+ text: typeof properties.tooltips === 'string' ? properties.tooltips : properties.tooltips[index],
739
+ event: e
740
+ });
741
+
742
+ // Highlight the rect that has been clicked on
743
+ obj.highlight(e.target);
744
+
745
+ var highlight = RGraph.SVG.REG.get('highlight');
746
+
747
+ if (properties.tooltipsEvent === 'mousemove') {
748
+ highlight.style.cursor = 'pointer';
749
+ }
750
+
751
+ }, false);
752
+
753
+ // Install the event listener that changes the
754
+ // cursor if necessary
755
+ if (properties.tooltipsEvent === 'click') {
756
+ arc.addEventListener('mousemove', function (e)
757
+ {
758
+ e.target.style.cursor = 'pointer';
759
+ }, false);
760
+ }
761
+
762
+ }(i, this));
763
+ }
764
+ }
765
+
766
+ //
767
+ // Redraw the segments if necessary so that they're on
768
+ // top of any shadow
769
+ //
770
+ if (properties.shadow && opt.shadow) {
771
+ this.redrawSegments();
772
+ }
773
+ };
774
+
775
+
776
+
777
+
778
+
779
+
780
+
781
+
782
+ //
783
+ // Redraw the Bars o that the bars appear above any shadow
784
+ //
785
+ this.redrawSegments = function ()
786
+ {
787
+ this.drawSegments({shadow: false});
788
+ };
789
+
790
+
791
+
792
+
793
+
794
+
795
+
796
+
797
+ //
798
+ // Draw the labels
799
+ //
800
+ this.drawLabels = function ()
801
+ {
802
+ var angles = this.angles,
803
+ labels = properties.labels,
804
+ textConf = RGraph.SVG.getTextConf({
805
+ object: this,
806
+ prefix: 'labels'
807
+ });
808
+
809
+ for (var i=0; i<angles.length; ++i) {
810
+
811
+ var endpoint = RGraph.SVG.TRIG.getRadiusEndPoint({
812
+ angle: angles[i].halfway - RGraph.SVG.TRIG.HALFPI,
813
+ r: angles[i].radius + 15
814
+ });
815
+
816
+ var x = endpoint[0] + angles[i].cx,
817
+ y = endpoint[1] + angles[i].cy,
818
+ valign,
819
+ halign;
820
+
821
+ // Figure out the valign and halign based on the quadrant
822
+ // the center of the sgement is in.
823
+ if (angles[i].halfway > 0 && angles[i].halfway < RGraph.SVG.TRIG.HALFPI) {
824
+ halign = 'left';
825
+ valign = 'bottom';
826
+ } else if (angles[i].halfway > RGraph.SVG.TRIG.HALFPI && angles[i].halfway < RGraph.SVG.TRIG.PI) {
827
+ halign = 'left';
828
+ valign = 'top';
829
+ } else if (angles[i].halfway > RGraph.SVG.TRIG.PI && angles[i].halfway < (RGraph.SVG.TRIG.HALFPI + RGraph.SVG.TRIG.PI)) {
830
+ halign = 'right';
831
+ valign = 'top';
832
+ } else if (angles[i].halfway > (RGraph.SVG.TRIG.HALFPI + RGraph.SVG.TRIG.PI) && angles[i].halfway < RGraph.SVG.TRIG.TWOPI) {
833
+ halign = 'right';
834
+ valign = 'top';
835
+ }
836
+
837
+ RGraph.SVG.text({
838
+ object: this,
839
+ parent: this.svg.all,
840
+ tag: 'labels',
841
+
842
+ text: typeof labels[i] === 'string' ? labels[i] : '',
843
+
844
+ x: x,
845
+ y: y,
846
+
847
+ valign: valign,
848
+ halign: halign,
849
+
850
+ font: textConf.font,
851
+ size: textConf.size,
852
+ bold: textConf.bold,
853
+ italic: textConf.italic,
854
+ color: textConf.color
855
+ });
856
+ }
857
+ };
858
+
859
+
860
+
861
+
862
+
863
+
864
+
865
+
866
+ //
867
+ // Draws the ingraph labels
868
+ //
869
+ this.drawIngraphLabels = function ()
870
+ {
871
+ if (properties.labelsIngraph) {
872
+
873
+ var textConf = RGraph.SVG.getTextConf({
874
+ object: this,
875
+ prefix: 'labelsIngraph'
876
+ });
877
+
878
+ for (var i=0; i<this.angles.length; ++i) {
879
+
880
+ // Some defaults
881
+ var halign = properties.labelsIngraphHalign || 'center',
882
+ valign = properties.labelsIngraphValign || 'center',
883
+
884
+ bgcolor = properties.labelsIngraphBackground || 'transparent',
885
+ decimals = properties.labelsIngraphDecimals || 0,
886
+ padding = typeof properties.labelsIngraphBackground === 'string' ? 3 : 0;
887
+
888
+ // Work out the coordinates
889
+ var xy = RGraph.SVG.TRIG.getRadiusEndPoint({
890
+ angle: this.angles[i].halfway - RGraph.SVG.TRIG.HALFPI,
891
+ r: this.angles[i].radius * (typeof properties.labelsIngraphRadiusPos === 'number' ? properties.labelsIngraphRadiusPos : 0.5)
892
+ });
893
+
894
+ if (typeof properties.labelsIngraphSpecific === 'object' && properties.labelsIngraphSpecific) {
895
+ if (typeof properties.labelsIngraphSpecific[i] === 'string') {
896
+ var str = properties.labelsIngraphSpecific[i];
897
+ } else {
898
+ var str = '';
899
+ }
900
+ } else {
901
+ if (typeof properties.labelsIngraphFormatter === 'function') {
902
+ var str = properties.labelsIngraphFormatter({
903
+ object: this,
904
+ number: this.data[i].toFixed(decimals)
905
+ })
906
+ } else {
907
+
908
+ var str = RGraph.SVG.numberFormat({
909
+ prepend: properties.labelsIngraphUnitsPre,
910
+ append: properties.labelsIngraphUnitsPost,
911
+ point: properties.labelsIngraphPoint,
912
+ thousand: properties.labelsIngraphThousand,
913
+ num: this.data[i].toFixed(decimals),
914
+ object: this
915
+ });
916
+ }
917
+ }
918
+
919
+ // Draw the text
920
+ RGraph.SVG.text({
921
+ object: this,
922
+ parent: this.svg.all,
923
+ tag: 'labels.ingraph',
924
+ x: this.angles[i].cx + xy[0],
925
+ y: this.angles[i].cy + xy[1],
926
+ text: str,
927
+ halign: halign,
928
+ valign: valign,
929
+
930
+ font: textConf.font,
931
+ size: textConf.size,
932
+ bold: textConf.bold,
933
+ italic: textConf.italic,
934
+ color: textConf.color,
935
+
936
+ background: bgcolor,
937
+ padding: padding
938
+ });
939
+ }
940
+ }
941
+ };
942
+
943
+
944
+
945
+
946
+
947
+
948
+
949
+
950
+ //
951
+ // This function draws the labels in a list format
952
+ //
953
+ this.drawLabelsSticks = function ()
954
+ {
955
+ var labels_right = [],
956
+ labels_left = [],
957
+ labels_coords = [];
958
+
959
+ for (var i=0; i<this.angles.length; ++i) {
960
+
961
+ var angle = (this.angles[i].start + ((this.angles[i].end - this.angles[i].start) / 2)) - RGraph.SVG.TRIG.HALFPI, // Midpoint
962
+
963
+ endpoint_inner = RGraph.SVG.TRIG.getRadiusEndPoint({angle: angle, r: this.radius + 5}),
964
+ endpoint_outer = RGraph.SVG.TRIG.getRadiusEndPoint({angle: angle, r: this.radius + 30}),
965
+
966
+ explosion = [
967
+ (typeof properties.exploded === 'number' ? properties.exploded : properties.exploded[i]),
968
+ Math.cos(angle) * (typeof properties.exploded === 'number' ? properties.exploded : properties.exploded[i]),
969
+ Math.sin(angle) * (typeof properties.exploded === 'number' ? properties.exploded : properties.exploded[i])
970
+ ];
971
+
972
+ // Initialise this array
973
+ labels_coords[i] = [];
974
+
975
+ // Initialise this
976
+ var labels = {};
977
+
978
+
979
+
980
+
981
+
982
+ // Push the label into the correct array
983
+ if (angle > RGraph.SVG.TRIG.HALFPI) {
984
+
985
+ var index = labels_left.length;
986
+
987
+ labels_left[index] = [];
988
+ labels_left[index].text = properties.labels[i];
989
+ labels_left[index].halign = 'right';
990
+ labels = labels_left;
991
+
992
+ labels_coords[i].halign = 'right';
993
+ } else {
994
+
995
+ var index = labels_right.length;
996
+
997
+ labels_right[index] = [];
998
+ labels_right[index].text = properties.labels[i];
999
+ labels_right[index].halign = 'right';
1000
+ labels = labels_right;
1001
+
1002
+ labels_coords[i].halign = 'left';
1003
+ }
1004
+
1005
+
1006
+
1007
+
1008
+
1009
+
1010
+
1011
+ endpoint_inner[0] += (explosion[1] || 0);
1012
+ endpoint_inner[1] += (explosion[2] || 0);
1013
+
1014
+ endpoint_outer[0] += (explosion[1] || 0);
1015
+ endpoint_outer[1] += (explosion[2] || 0);
1016
+
1017
+ var x,y;
1018
+
1019
+ if (labels[index].text) {
1020
+ var stick = RGraph.SVG.create({
1021
+ svg: this.svg,
1022
+ parent: this.svg.all,
1023
+ type: 'path',
1024
+ attr: {
1025
+ d: 'M {1} {2} L {3} {4}'.format(
1026
+ this.centerx + endpoint_inner[0],
1027
+ this.centery + endpoint_inner[1],
1028
+ this.centerx + endpoint_outer[0],
1029
+ this.centery + endpoint_outer[1]
1030
+ ),
1031
+ stroke: '#999',
1032
+ fill: 'rgba(0,0,0,0)'
1033
+ }
1034
+ });
1035
+ }
1036
+
1037
+ // The path is altered later so this needs saving
1038
+ if (stick) {
1039
+ labels[index].stick = stick;
1040
+ }
1041
+
1042
+ x = (this.centerx + endpoint_outer[0] + (angle > 1.57 ? -50 : 50));
1043
+ y = (this.centery + endpoint_outer[1]);
1044
+
1045
+
1046
+ labels_coords[i].x = x ;
1047
+ labels_coords[i].y = y;
1048
+ labels_coords[i].text = properties.labels[i];
1049
+ }
1050
+
1051
+ // Calculate the spacing for each side
1052
+ var vspace_right = (this.height - properties.marginTop - properties.marginBottom) / labels_right.length;
1053
+ var vspace_left = (this.height - properties.marginTop - properties.marginBottom) / labels_left.length;
1054
+
1055
+ // Reset these
1056
+ x = y = 0;
1057
+
1058
+
1059
+
1060
+ // Get the text configuration
1061
+ var textConf = RGraph.SVG.getTextConf({
1062
+ object: this,
1063
+ prefix: 'labels'
1064
+ });
1065
+
1066
+ // Loop through the RHS labels
1067
+ for (var i=0; i<labels_right.length; ++i) {
1068
+ if (labels_right[i] && labels_right[i].text) {
1069
+
1070
+ x = this.centerx + this.radius + properties.labelsSticksOffset;
1071
+ y = properties.marginTop + (vspace_right * i) + (vspace_right / 2);
1072
+
1073
+
1074
+ // Add the label to the scene
1075
+ RGraph.SVG.text({
1076
+
1077
+ object: this,
1078
+ parent: this.svg.all,
1079
+ tag: 'labels.sticks',
1080
+
1081
+ text: typeof labels_right[i].text === 'string' ? labels_right[i].text : '',
1082
+
1083
+ x: x,
1084
+ y: y,
1085
+
1086
+ valign: 'center',
1087
+ halign: labels_right[i].text,
1088
+
1089
+ font: textConf.font,
1090
+ size: textConf.size,
1091
+ bold: textConf.bold,
1092
+ italic: textConf.italic,
1093
+ color: textConf.color
1094
+ });
1095
+
1096
+ // Now update the path of the stick
1097
+ var str = labels_right[i].stick.getAttribute('d').replace(/ L /, ' Q ') + ' {1} {2}';
1098
+
1099
+ labels_right[i].stick.setAttribute(
1100
+ 'd',
1101
+ str.format(
1102
+ x - 5,
1103
+ y
1104
+ )
1105
+ );
1106
+ }
1107
+ }
1108
+
1109
+
1110
+
1111
+
1112
+
1113
+ // Loop through the LHS labels
1114
+ for (var i=0; i<labels_left.length; ++i) {
1115
+ if (labels_left[i] && labels_left[i].text) {
1116
+
1117
+ x = this.centerx - this.radius - properties.labelsSticksOffset;
1118
+ y = this.height - (properties.marginTop + (vspace_left * i) + (vspace_left / 2));
1119
+
1120
+
1121
+ // Add the label to the scene
1122
+ RGraph.SVG.text({
1123
+
1124
+ object: this,
1125
+ parent: this.svg.all,
1126
+ tag: 'labels.sticks',
1127
+
1128
+ text: typeof labels_left[i].text === 'string' ? labels_left[i].text : '',
1129
+
1130
+ x: x - 7,
1131
+ y: y,
1132
+
1133
+ valign: 'center',
1134
+ halign: labels_left[i].halign,
1135
+
1136
+ font: textConf.font,
1137
+ size: textConf.size,
1138
+ bold: textConf.bold,
1139
+ italic: textConf.italic,
1140
+ color: textConf.color
1141
+ });
1142
+
1143
+ // Now update the path of the stick
1144
+ var str = labels_left[i].stick.getAttribute('d').replace(/ L /, ' Q ') + ' {1} {2}';
1145
+
1146
+ labels_left[i].stick.setAttribute(
1147
+ 'd',
1148
+ str.format(
1149
+ x - 5,
1150
+ y
1151
+ )
1152
+ );
1153
+ }
1154
+ }
1155
+ };
1156
+
1157
+
1158
+
1159
+
1160
+
1161
+
1162
+
1163
+
1164
+ //
1165
+ // This function can be used to highlight a segment on the chart
1166
+ //
1167
+ // @param object segment The segment to highlight
1168
+ //
1169
+ this.highlight = function (segment)
1170
+ {
1171
+ // Outline style highlighting
1172
+ if (properties.highlightStyle === 'outline') {
1173
+
1174
+ var index = segment.getAttribute('data-index');
1175
+
1176
+ var path = RGraph.SVG.TRIG.getArcPath3({
1177
+ start: this.angles[index].start,
1178
+ end: this.angles[index].end,
1179
+ cx: this.angles[index].cx,
1180
+ cy: this.angles[index].cy,
1181
+ r: this.angles[index].radius + 2,
1182
+ anticlockwise: false,
1183
+ lineto: false
1184
+ });
1185
+
1186
+ // Add the reverse arc
1187
+ path += RGraph.SVG.TRIG.getArcPath3({
1188
+ start: this.angles[index].end,
1189
+ end: this.angles[index].start,
1190
+ cx: this.angles[index].cx,
1191
+ cy: this.angles[index].cy,
1192
+ r: this.angles[index].radius + 2 + properties.highlightStyleOutlineWidth,
1193
+ anticlockwise: true
1194
+ });
1195
+
1196
+ var highlight = RGraph.SVG.create({
1197
+ svg: this.svg,
1198
+ parent: this.svg.all,
1199
+ type: 'path',
1200
+ attr: {
1201
+ d: path,
1202
+ fill: properties.colors[index],
1203
+ stroke: 'transparent'
1204
+ },
1205
+ style: {
1206
+ pointerEvents: 'none'
1207
+ }
1208
+ });
1209
+
1210
+ // Regular highlighting
1211
+ } else {
1212
+
1213
+ var highlight = RGraph.SVG.create({
1214
+ svg: this.svg,
1215
+ parent: this.svg.all,
1216
+ type: 'path',
1217
+ attr: {
1218
+ d: segment.getAttribute('d'),
1219
+ fill: properties.highlightFill,
1220
+ stroke: properties.highlightStroke,
1221
+ 'stroke-width': properties.highlightLinewidth
1222
+ },
1223
+ style: {
1224
+ pointerEvents: 'none'
1225
+ }
1226
+ });
1227
+ }
1228
+
1229
+ if (properties.tooltipsEvent === 'mousemove') {
1230
+ highlight.addEventListener('mouseout', function (e)
1231
+ {
1232
+ highlight.parentNode.removeChild(highlight);
1233
+ RGraph.SVG.hideTooltip();
1234
+
1235
+ RGraph.SVG.REG.set('highlight', null);
1236
+ }, false);
1237
+ }
1238
+
1239
+
1240
+ // Store the highlight rect in the registry so
1241
+ // it can be cleared later
1242
+ RGraph.SVG.REG.set('highlight', highlight);
1243
+ };
1244
+
1245
+
1246
+
1247
+
1248
+
1249
+
1250
+
1251
+
1252
+ //
1253
+ // This allows for easy specification of gradients
1254
+ //
1255
+ this.parseColors = function ()
1256
+ {
1257
+ // Save the original colors so that they can be restored when the canvas is reset
1258
+ if (!Object.keys(this.originalColors).length) {
1259
+ this.originalColors = {
1260
+ colors: RGraph.SVG.arrayClone(properties.colors),
1261
+ highlightFill: RGraph.SVG.arrayClone(properties.highlightFill)
1262
+ }
1263
+ }
1264
+
1265
+
1266
+ // colors
1267
+ var colors = properties.colors;
1268
+
1269
+ if (colors) {
1270
+ for (var i=0; i<colors.length; ++i) {
1271
+ colors[i] = RGraph.SVG.parseColorRadial({
1272
+ object: this,
1273
+ color: colors[i]
1274
+ });
1275
+ }
1276
+ }
1277
+
1278
+ // Highlight fill
1279
+ properties.highlightFill = RGraph.SVG.parseColorRadial({
1280
+ object: this,
1281
+ color: properties.highlightFill
1282
+ });
1283
+ };
1284
+
1285
+
1286
+
1287
+
1288
+
1289
+
1290
+
1291
+
1292
+ //
1293
+ // A roundRobin effect for the Pie chart
1294
+ //
1295
+ // @param object Options for the effect
1296
+ // @param function An optional callback function to call when
1297
+ // the effect is complete
1298
+ //
1299
+ this.roundrobin =
1300
+ this.roundRobin = function ()
1301
+ {
1302
+ var obj = this,
1303
+ opt = arguments[0] || {},
1304
+ data = RGraph.SVG.arrayClone(this.data),
1305
+ frame = 1,
1306
+ frames = opt.frames || 30,
1307
+ callback = typeof opt.callback === 'function' ? opt.callback : function () {},
1308
+ dataSum = RGraph.SVG.arraySum(this.data),
1309
+ textColor = properties.textColor,
1310
+ ingraph = properties.labelsIngraph,
1311
+ multiplier = 0;
1312
+
1313
+ // Set the text colors to transparent
1314
+ properties.textColor = 'rgba(0,0,0,0)';
1315
+ properties.labelsIngraph = false;
1316
+
1317
+
1318
+ // Draw the chart first
1319
+ obj.draw();
1320
+
1321
+ // Now get the resulting angles
1322
+ var angles = RGraph.SVG.arrayClone(this.angles);
1323
+
1324
+
1325
+ function iterator ()
1326
+ {
1327
+ multiplier = (1 / frames) * frame++;
1328
+
1329
+ for (var i=0; i<angles.length; ++i) {
1330
+
1331
+ var value = obj.data[i];
1332
+
1333
+ obj.angles[i].start = angles[i].start * multiplier;
1334
+ obj.angles[i].end = angles[i].end * multiplier;
1335
+
1336
+ //var segment = (((value * properties.roundRobinMultiplier) / dataSum) * RGraph.SVG.TRIG.TWOPI);
1337
+ var segment = ((obj.angles[i].end - obj.angles[i].start) / 2),
1338
+ explodedX = Math.cos(obj.angles[i].start + segment - RGraph.SVG.TRIG.HALFPI) * (properties.exploded[i] || 0),
1339
+ explodedY = Math.sin(obj.angles[i].start + segment - RGraph.SVG.TRIG.HALFPI) * (properties.exploded[i] || 0);
1340
+
1341
+
1342
+
1343
+ var path = RGraph.SVG.TRIG.getArcPath({
1344
+ cx: obj.centerx + explodedX,
1345
+ cy: obj.centery + explodedY,
1346
+ r: obj.radius,
1347
+ start: obj.angles[i].start,
1348
+ end: obj.angles[i].end
1349
+ });
1350
+
1351
+
1352
+
1353
+
1354
+
1355
+ // Donut
1356
+ if (properties.donut) {
1357
+
1358
+ var donutWidth = properties.donutWidth;
1359
+
1360
+ var donut_path = RGraph.SVG.TRIG.getArcPath3({
1361
+ cx: obj.angles[i].cx,
1362
+ cy: obj.angles[i].cy,
1363
+ r: obj.radius - donutWidth,
1364
+ start: obj.angles[i].end,
1365
+ end: obj.angles[i].start,
1366
+ moveto: false,
1367
+ anticlockwise: true
1368
+ });
1369
+
1370
+ var xy = RGraph.SVG.TRIG.getRadiusEndPoint({
1371
+ angle: obj.angles[i].end - RGraph.SVG.TRIG.HALFPI,
1372
+ r: obj.radius - donutWidth
1373
+ });
1374
+
1375
+ path = path
1376
+ + " L {1} {2} ".format(xy[0] + obj.angles[i].cx, xy[1] + obj.angles[i].cy)
1377
+ + donut_path
1378
+ + " Z";
1379
+
1380
+ } else {
1381
+
1382
+ path = path + " L {1} {2} ".format(
1383
+ obj.angles[i].cx,
1384
+ obj.angles[i].cy
1385
+ ) + " Z"
1386
+ }
1387
+
1388
+
1389
+
1390
+
1391
+
1392
+
1393
+
1394
+
1395
+
1396
+ path = path + " L {1} {2} Z".format(
1397
+ obj.centerx + explodedX,
1398
+ obj.centery + explodedY
1399
+ );
1400
+
1401
+ if (obj.shadowNodes && obj.shadowNodes[i]) {
1402
+ obj.shadowNodes[i].setAttribute('d', path);
1403
+ }
1404
+ obj.nodes[i].setAttribute('d', path);
1405
+ }
1406
+
1407
+
1408
+ if (frame <= frames) {
1409
+ RGraph.SVG.FX.update(iterator);
1410
+ } else {
1411
+ properties.textColor = textColor;
1412
+ properties.labelsIngraph = ingraph;
1413
+
1414
+ RGraph.SVG.redraw(obj.svg);
1415
+
1416
+ callback(obj);
1417
+ }
1418
+ }
1419
+
1420
+ iterator();
1421
+
1422
+ return this;
1423
+ };
1424
+
1425
+
1426
+
1427
+
1428
+
1429
+
1430
+
1431
+
1432
+ //
1433
+ // Using a function to add events makes it easier to facilitate method
1434
+ // chaining
1435
+ //
1436
+ // @param string type The type of even to add
1437
+ // @param function func
1438
+ //
1439
+ this.on = function (type, func)
1440
+ {
1441
+ if (type.substr(0,2) !== 'on') {
1442
+ type = 'on' + type;
1443
+ }
1444
+
1445
+ RGraph.SVG.addCustomEventListener(this, type, func);
1446
+
1447
+ return this;
1448
+ };
1449
+
1450
+
1451
+
1452
+
1453
+
1454
+
1455
+
1456
+
1457
+ //
1458
+ // Used in chaining. Runs a function there and then - not waiting for
1459
+ // the events to fire (eg the onbeforedraw event)
1460
+ //
1461
+ // @param function func The function to execute
1462
+ //
1463
+ this.exec = function (func)
1464
+ {
1465
+ func(this);
1466
+
1467
+ return this;
1468
+ };
1469
+
1470
+
1471
+
1472
+
1473
+
1474
+
1475
+
1476
+
1477
+ //
1478
+ // Remove highlight from the chart (tooltips)
1479
+ //
1480
+ this.removeHighlight = function ()
1481
+ {
1482
+ //var highlight = RGraph.SVG.REG.get('highlight');
1483
+ //if (highlight && highlight.parentNode) {
1484
+ // highlight.parentNode.removeChild(highlight);
1485
+ //}
1486
+
1487
+ //RGraph.SVG.REG.set('highlight', null);
1488
+
1489
+ RGraph.SVG.removeHighlight();
1490
+ };
1491
+
1492
+
1493
+
1494
+
1495
+
1496
+
1497
+
1498
+
1499
+ //
1500
+ // A worker function that handles Bar chart specific tooltip substitutions
1501
+ //
1502
+ this.tooltipSubstitutions = function (opt)
1503
+ {
1504
+ return {
1505
+ index: opt.index,
1506
+ dataset: 0,
1507
+ sequentialIndex: opt.index,
1508
+ value: this.data[opt.index],
1509
+ values: [this.data[opt.index]]
1510
+ };
1511
+ };
1512
+
1513
+
1514
+
1515
+
1516
+
1517
+
1518
+
1519
+
1520
+ //
1521
+ // A worker function that returns the correct color/label/value
1522
+ //
1523
+ // @param object specific The indexes that are applicable
1524
+ // @param number index The appropriate index
1525
+ //
1526
+ this.tooltipsFormattedCustom = function (specific, index, colors)
1527
+ {
1528
+ var color = colors[specific.index];
1529
+ var label = ( (typeof properties.tooltipsFormattedKeyLabels === 'object' && typeof properties.tooltipsFormattedKeyLabels[specific.index] === 'string') ? properties.tooltipsFormattedKeyLabels[specific.index] : '');
1530
+
1531
+ return {
1532
+ label: label,
1533
+ color: color
1534
+ };
1535
+ };
1536
+
1537
+
1538
+
1539
+
1540
+
1541
+
1542
+
1543
+
1544
+ //
1545
+ // This allows for static tooltip positioning
1546
+ //
1547
+ this.positionTooltipStatic = function (args)
1548
+ {
1549
+ var obj = args.object,
1550
+ e = args.event,
1551
+ tooltip = args.tooltip,
1552
+ index = args.index,
1553
+ svgXY = RGraph.SVG.getSVGXY(obj.svg),
1554
+ segment = this.angles[args.index],
1555
+ angle = segment.halfway,
1556
+ multiplier = 0.5;
1557
+
1558
+ //
1559
+ // Determine the correct radius to use when calculating the
1560
+ // coordinates of the tooltip
1561
+ //
1562
+ if (properties.donut) {
1563
+ // Determine the radius
1564
+ var radius = (this.radius - properties.donutWidth) + (properties.donutWidth / 2);
1565
+
1566
+ } else {
1567
+ var radius = this.radius * multiplier;
1568
+ }
1569
+
1570
+ // Account for any explosion
1571
+ if (properties.exploded[index]) {
1572
+ radius += properties.exploded[index];
1573
+ }
1574
+
1575
+ var endpoint = RGraph.SVG.TRIG.getRadiusEndPoint({
1576
+ angle: angle - RGraph.SVG.TRIG.HALFPI,
1577
+ r: radius
1578
+ });
1579
+
1580
+ // Position the tooltip in the X direction
1581
+ args.tooltip.style.left = (
1582
+ svgXY[0] // The X coordinate of the canvas
1583
+ + this.centerx // The center X coord
1584
+ + endpoint[0] // The endpoint X coordinate
1585
+ - (tooltip.offsetWidth / 2) // Subtract half of the tooltip width
1586
+ ) + 'px';
1587
+
1588
+ args.tooltip.style.top = (
1589
+ svgXY[1] // The Y coordinate of the canvas
1590
+ + this.centery // The center Y coord
1591
+ + endpoint[1] // The endpoint Y coordinate
1592
+ - tooltip.offsetHeight // The height of the tooltip
1593
+ - 10 // An arbitrary amount
1594
+ ) + 'px';
1595
+ };
1596
+
1597
+
1598
+
1599
+
1600
+
1601
+
1602
+
1603
+
1604
+ //
1605
+ // Set the options that the user has provided
1606
+ //
1607
+ for (i in conf.options) {
1608
+ if (typeof i === 'string') {
1609
+ this.set(i, conf.options[i]);
1610
+ }
1611
+ }
1612
+ };
1613
+
1614
+
1615
+
1616
+
1617
+
1618
+
1619
+
1620
+
1621
+ return this;
1622
+
1623
+
1624
+
1625
+
1626
+
1627
+
1628
+
1629
+
1630
+ // End module pattern
1631
+ })(window, document);