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,82 +1,1916 @@
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.VProgress=function(conf)
3
- {if(typeof conf==='object'&&typeof conf.id==='string'){var parseConfObjectForOptions=true;}else{var conf={id:arguments[0],min:arguments[1],max:arguments[2],value:arguments[3]}}
4
- this.id=conf.id;this.canvas=document.getElementById(this.id);this.context=this.canvas.getContext('2d');this.canvas.__object__=this;this.min=RGraph.stringsToNumbers(conf.min);this.max=RGraph.stringsToNumbers(conf.max);this.value=RGraph.stringsToNumbers(conf.value);this.type='vprogress';this.coords=[];this.isRGraph=true;this.currentValue=null;this.uid=RGraph.CreateUID();this.canvas.uid=this.canvas.uid?this.canvas.uid:RGraph.CreateUID();this.colorsParsed=false;this.coordsText=[];this.original_colors=[];this.firstDraw=true;this.propertyNameAliases={};this.properties={'chart.colors':['Gradient(white:#0c0)','Gradient(white:red)','Gradient(white:green)','yellow','pink','cyan','black','white','gray'],'chart.colors.stroke.inner':'#999','chart.colors.stroke.outer':'#999','chart.tickmarks.outer':true,'chart.tickmarks.inner':false,'chart.tickmarks.outer.count':0,'chart.tickmarks.inner.count':0,'chart.tickmarks.outer.color':'#999','chart.tickmarks.inner.color':'#999','chart.margin.left':25,'chart.margin.right':25,'chart.margin.top':25,'chart.margin.bottom':25,'chart.margin.inner':0,'chart.background.color':'Gradient(#ccc:#eee:#efefef)','chart.shadow':false,'chart.shadow.color':'rgba(0,0,0,0.5)','chart.shadow.blur':3,'chart.shadow.offsetx':3,'chart.shadow.offsety':3,'chart.title':'','chart.title.bold':null,'chart.title.italic':null,'chart.title.font':null,'chart.title.size':null,'chart.title.color':null,'chart.title.side':null,'chart.title.side.font':null,'chart.title.side.size':null,'chart.title.side.color':null,'chart.title.side.bold':null,'chart.title.side.italic':null,'chart.text.size':12,'chart.text.color':'black','chart.text.font':'Arial, Verdana, sans-serif','chart.text.bold':false,'chart.text.italic':false,'chart.text.accessible':true,'chart.text.accessible.overflow':'visible','chart.text.accessible.pointerevents':false,'chart.contextmenu':null,'chart.scale.decimals':0,'chart.scale.thousand':',','chart.scale.point':'.','chart.scale.units.pre':'','chart.scale.units.post':'','chart.tooltips':null,'chart.tooltips.effect':'fade','chart.tooltips.css.class':'RGraph_tooltip','chart.tooltips.highlight':true,'chart.tooltips.event':'onclick','chart.highlight.stroke':'rgba(0,0,0,0)','chart.highlight.fill':'rgba(255,255,255,0.7)','chart.annotatable':false,'chart.annotatable.color':'black','chart.arrows':false,'chart.resizable':false,'chart.resizable.handle.adjust':[0,0],'chart.resizable.handle.background':null,'chart.labels.inner':false,'chart.labels.inner.font':null,'chart.labels.inner.size':null,'chart.labels.inner.color':null,'chart.labels.inner.bold':null,'chart.labels.inner.italic':null,'chart.labels.inner.background.fill':'rgba(255,255,255,0.75)','chart.labels.inner.border':true,'chart.labels.inner.border.linewidth':1,'chart.labels.inner.border.color':'#ccc','chart.labels.inner.decimals':0,'chart.labels.inner.units.pre':'','chart.labels.inner.units.post':'','chart.labels.inner.scale.thousand':null,'chart.labels.inner.scale.point':null,'chart.labels.inner.specific':null,'chart.labels.count':10,'chart.labels.position':'right','chart.labels.offsetx':0,'chart.labels.offsety':0,'chart.labels.font':null,'chart.labels.size':null,'chart.labels.color':null,'chart.labels.bold':null,'chart.labels.italic':null,'chart.labels.specific':null,'chart.adjustable':false,'chart.key':null,'chart.key.background':'white','chart.key.position':'graph','chart.key.halign':'right','chart.key.shadow':false,'chart.key.shadow.color':'#666','chart.key.shadow.blur':3,'chart.key.shadow.offsetx':2,'chart.key.shadow.offsety':2,'chart.key.position.gutter.boxed':false,'chart.key.position.x':null,'chart.key.position.y':null,'chart.key.color.shape':'square','chart.key.rounded':true,'chart.key.linewidth':1,'chart.key.colors':null,'chart.key.interactive':false,'chart.key.interactive.highlight.chart.stroke':'#000','chart.key.interactive.highlight.chart.fill':'rgba(255,255,255,0.7)','chart.key.interactive.highlight.label':'rgba(255,0,0,0.2)','chart.key.labels.color':null,'chart.key.labels.font':null,'chart.key.labels.size':null,'chart.key.labels.bold':null,'chart.key.labels.italic':null,'chart.key.labels.offsetx':0,'chart.key.labels.offsety':0,'chart.events.click':null,'chart.events.mousemove':null,'chart.border.inner':true,'chart.bevelled':false,'chart.clearto':'rgba(0,0,0,0)'}
5
- if(!this.canvas){alert('[PROGRESS] No canvas support');return;}
6
- var linear_data=RGraph.arrayLinearize(this.value);for(var i=0;i<linear_data.length;++i){this['$'+i]={};}
7
- if(!this.canvas.__rgraph_aa_translated__){this.context.translate(0.5,0.5);this.canvas.__rgraph_aa_translated__=true;}
8
- var RG=RGraph,ca=this.canvas,co=ca.getContext('2d'),prop=this.properties,pa2=RG.path2,win=window,doc=document,ma=Math
9
- if(RG.Effects&&typeof RG.Effects.decorate==='function'){RG.Effects.decorate(this);}
10
- this.set=this.Set=function(name)
11
- {var value=typeof arguments[1]==='undefined'?null:arguments[1];if(arguments.length===1&&typeof name==='object'){RG.parseObjectStyleConfig(this,name);return this;}
12
- if(name.substr(0,6)!='chart.'){name='chart.'+name;}
13
- while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
14
- prop[name.toLowerCase()]=value;return this;};this.get=this.Get=function(name)
15
- {if(name.substr(0,6)!='chart.'){name='chart.'+name;}
16
- while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
17
- return prop[name.toLowerCase()];};this.draw=this.Draw=function()
18
- {RG.FireCustomEvent(this,'onbeforedraw');if(!this.colorsParsed){this.parseColors();this.colorsParsed=true;}
19
- this.currentValue=this.value;this.marginLeft=prop['chart.margin.left'];this.marginRight=prop['chart.margin.right'];this.marginTop=prop['chart.margin.top'];this.marginBottom=prop['chart.margin.bottom'];this.width=ca.width-this.marginLeft-this.marginRight;this.height=ca.height-this.marginTop-this.marginBottom;this.coords=[];this.coordsText=[];this.Drawbar();this.DrawTickMarks();this.DrawLabels();this.DrawTitles();if(prop['chart.bevelled']){this.DrawBevel();}
20
- if(prop['chart.contextmenu']){RG.ShowContext(this);}
21
- RG.InstallEventListeners(this);if(prop['chart.key']&&prop['chart.key'].length){RG.DrawKey(this,prop['chart.key'],prop['chart.colors']);}
22
- if(prop['chart.resizable']){RG.AllowResizing(this);}
23
- this.AllowAdjusting();if(this.firstDraw){this.firstDraw=false;RG.fireCustomEvent(this,'onfirstdraw');this.firstDrawFunc();}
24
- RG.FireCustomEvent(this,'ondraw');return this;};this.drawbar=this.Drawbar=function()
25
- {this.scale2=RG.getScale2(this,{'scale.max':this.max,'scale.min':this.min,'scale.strict':true,'scale.thousand':prop['chart.scale.thousand'],'scale.point':prop['chart.scale.point'],'scale.decimals':prop['chart.scale.decimals'],'scale.labels.count':prop['chart.labels.count'],'scale.round':prop['chart.scale.round'],'scale.units.pre':prop['chart.scale.units.pre'],'scale.units.post':prop['chart.scale.units.post']});if(prop['chart.shadow']){RG.setShadow(this,prop['chart.shadow.color'],prop['chart.shadow.offsetx'],prop['chart.shadow.offsety'],prop['chart.shadow.blur']);}
26
- co.fillStyle=prop['chart.background.color'];co.strokeStyle=prop['chart.colors.stroke.outer'];co.strokeRect(this.marginLeft,this.marginTop,this.width,this.height);co.fillRect(this.marginLeft,this.marginTop,this.width,this.height);RG.noShadow(this);co.strokeStyle=prop['chart.colors.stroke.outer'];co.fillStyle=prop['chart.colors'][0];var margin=prop['chart.margin.inner'];var barHeight=(ca.height-this.marginTop-this.marginBottom)*((RG.arraySum(this.value)-this.min)/(this.max-this.min));if(typeof this.value==='number'){co.lineWidth=1;co.strokeStyle=prop['chart.colors.stroke.inner'];if(prop['chart.border.inner']){this.drawCurvedBar({x:this.marginLeft+margin,y:this.marginTop+(this.height-barHeight),width:this.width-margin-margin,height:barHeight,stroke:prop['chart.colors.stroke.inner']});}
27
- this.drawCurvedBar({x:this.marginLeft+margin,y:this.marginTop+(this.height-barHeight),width:this.width-margin-margin,height:barHeight,fill:prop['chart.colors'][0]});}else if(typeof this.value=='object'){co.beginPath();co.strokeStyle=prop['chart.colors.stroke.inner'];var startPoint=ca.height-this.marginBottom;for(var i=0,len=this.value.length;i<len;++i){var segmentHeight=((this.value[i]-this.min)/(this.max-this.min))*(ca.height-this.marginBottom-this.marginTop);co.beginPath();co.fillStyle=prop['chart.colors'][i];if(prop['chart.border.inner']){this.drawCurvedBar({x:this.marginLeft+margin,y:startPoint-segmentHeight,width:this.width-margin-margin,height:segmentHeight,stroke:co.strokeStyle});}
28
- this.drawCurvedBar({x:this.marginLeft+margin,y:startPoint-segmentHeight,width:this.width-margin-margin,height:segmentHeight,fill:co.fillStyle});this.coords.push([this.marginLeft+margin,startPoint-segmentHeight,this.width-margin-margin,segmentHeight]);startPoint-=segmentHeight;}
29
- co.fill();}
30
- if(prop['chart.tickmarks.inner.count']>0){var spacing=(ca.height-this.marginTop-this.marginBottom)/prop['chart.tickmarks.inner.count'];co.lineWidth=1;co.strokeStyle=prop['chart.colors.stroke.inner'];co.beginPath();for(var y=this.marginTop;y<ca.height-this.marginBottom;y+=spacing){co.moveTo(this.marginLeft,Math.round(y));co.lineTo(this.marginLeft+3,Math.round(y));co.moveTo(ca.width-this.marginRight,Math.round(y));co.lineTo(ca.width-this.marginRight-3,Math.round(y));}
31
- co.stroke();}
32
- co.beginPath();co.strokeStyle=prop['chart.colors.stroke.inner'];if(typeof this.value=='number'){if(prop['chart.border.inner']){this.drawCurvedBar({x:this.marginLeft+margin,y:this.marginTop+this.height-barHeight,width:this.width-margin-margin,height:barHeight});}
33
- this.drawCurvedBar({x:this.marginLeft+margin,y:this.marginTop+this.height-barHeight,width:this.width-margin-margin,height:barHeight});this.coords.push([this.marginLeft+margin,this.marginTop+this.height-barHeight,this.width-margin-margin,barHeight]);}
34
- if(prop['chart.arrows']){var x=this.marginLeft-4;var y=ca.height-this.marginBottom-barHeight;co.lineWidth=1;co.fillStyle='black';co.strokeStyle='black';co.beginPath();co.moveTo(x,y);co.lineTo(x-4,y-2);co.lineTo(x-4,y+2);co.closePath();co.stroke();co.fill();x+=this.width+8;co.beginPath();co.moveTo(x,y);co.lineTo(x+4,y-2);co.lineTo(x+4,y+2);co.closePath();co.stroke();co.fill();pa2(co,'b');}
35
- if(prop['chart.labels.inner']){var textConf=RG.getTextConf({object:this,prefix:'chart.labels.inner'});RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:((ca.width-this.marginLeft-this.marginRight)/2)+this.marginLeft,y:this.coords[this.coords.length-1][1]-5,text:typeof prop['chart.labels.inner.specific']==='string'?prop['chart.labels.inner.specific']:RG.numberFormat({object:this,number:RG.arraySum(this.value).toFixed(typeof prop['chart.labels.inner.decimals']==='number'?prop['chart.labels.inner.decimals']:prop['chart.scale.decimals']),unitspre:typeof prop['chart.labels.inner.units.pre']==='string'?prop['chart.labels.inner.units.pre']:prop['chart.scale.units.pre'],unitspost:typeof prop['chart.labels.inner.units.post']==='string'?prop['chart.labels.inner.units.post']:prop['chart.scale.units.post'],point:typeof prop['chart.labels.inner.point']==='string'?prop['chart.labels.inner.point']:prop['chart.scale.point'],thousand:typeof prop['chart.labels.inner.thousand']==='string'?prop['chart.labels.inner.thousand']:prop['chart.scale.thousand']}),valign:'bottom',halign:'center',bounding:true,boundingFill:prop['chart.labels.inner.background.fill'],boundingStroke:prop['chart.labels.inner.border']?prop['chart.labels.inner.border.color']:'rgba(0,0,0,0)',boundingLinewidth:prop['chart.labels.inner.border.linewidth'],tag:'labels.inner'});}};this.drawTickMarks=this.DrawTickMarks=function()
36
- {co.strokeStyle=prop['chart.colors.stroke.outer'];if(prop['chart.tickmarks.outer']){co.beginPath();for(var i=0;i<=prop['chart.tickmarks.outer.count'];i++){var startX=prop['chart.labels.position']==='left'?this.marginLeft:ca.width-prop['chart.margin.right'],endX=prop['chart.labels.position']==='left'?startX-4:startX+4,yPos=(this.height*(i/prop['chart.tickmarks.outer.count']))+this.marginTop;co.moveTo(startX,ma.round(yPos));co.lineTo(endX,ma.round(yPos));}
37
- co.stroke();}};this.drawLabels=this.DrawLabels=function()
38
- {if(!RG.is_null(prop['chart.labels.specific'])){return this.DrawSpecificLabels();}
39
- co.fillStyle=prop['chart.text.color'];var position=prop['chart.labels.position'].toLowerCase();var xAlignment=position==='left'?'right':'left';var yAlignment='center';var count=prop['chart.labels.count'];var units_pre=prop['chart.scale.units.pre'];var units_post=prop['chart.scale.units.post'];var text_size=prop['chart.text.size'];var text_font=prop['chart.text.font'];var decimals=prop['chart.scale.decimals'];var offsetx=prop['chart.labels.offsetx'];var offsety=prop['chart.labels.offsety'];if(prop['chart.tickmarks.outer']){var textConf=RG.getTextConf({object:this,prefix:'chart.labels'});for(var i=0;i<count;++i){RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:position=='left'?(this.marginLeft-7+offsetx):(ca.width-this.marginRight+7)+offsetx,y:(((ca.height-this.marginTop-this.marginBottom)/count)*i)+this.marginTop+offsety,text:this.scale2.labels[this.scale2.labels.length-(i+1)],valign:yAlignment,halign:xAlignment,tag:'scale'});}
40
- if(this.min==0){RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:position=='left'?(this.marginLeft-5+offsetx):(ca.width-this.marginRight+5+offsetx),y:ca.height-this.marginBottom+offsety,text:RG.numberFormat({object:this,number:this.min.toFixed(this.min===0?0:decimals),unitspre:units_pre,unitspost:units_post,point:prop['chart.scale.point'],thousand:prop['chart.scale.thousand'],}),valign:yAlignment,halign:xAlignment,tag:'scale'});}
41
- if(this.min!=0){RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:position=='left'?(this.marginLeft-5+offsetx):(ca.width-this.marginRight+5+offsetx),y:ca.height-this.marginBottom+offsety,text:RG.number_format(this,this.min.toFixed(decimals),units_pre,units_post),valign:yAlignment,halign:xAlignment,tag:'scale'});}}};this.drawTitles=this.DrawTitles=function()
42
- {if(prop['chart.title']){var textConf=RG.getTextConf({object:this,prefix:'chart.title'});co.fillStyle=prop['chart.title.color'];RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:this.marginLeft+((ca.width-this.marginLeft-this.marginRight)/2),y:this.marginTop-5,text:prop['chart.title'],valign:'bottom',halign:'center',tag:'title'});}
43
- if(prop['chart.title.side']){co.fillStyle=prop['chart.title.side.color'];var textConf=RG.getTextConf({object:this,prefix:'chart.title.side'});RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:prop['chart.labels.position']=='right'?this.marginLeft-10:(ca.width-this.marginRight)+10,y:this.marginTop+(this.height/2),text:prop['chart.title.side'],valign:'bottom',halign:'center',accessible:false,angle:prop['chart.labels.position']=='right'?270:90,tag:'title.side'});}};this.getShape=this.getBar=function(e)
44
- {var mouseXY=RG.getMouseXY(e),mouseX=mouseXY[0],mouseY=mouseXY[1]
45
- for(var i=0,len=this.coords.length;i<len;i++){var x=this.coords[i][0],y=this.coords[i][1],w=this.coords[i][2],h=this.coords[i][3],idx=i;co.beginPath();this.drawCurvedBar({x:x,y:y,width:w,height:h});if(co.isPointInPath(mouseX,mouseY)){var tooltip=RG.parseTooltipText(prop['chart.tooltips'],i);return{0:this,'object':this,1:x,'x':x,2:y,'y':y,3:w,'width':w,4:h,'height':h,5:i,'index':i,'tooltip':tooltip};}}};this.getValue=function(e)
46
- {var mouseCoords=RG.getMouseXY(e);var mouseX=mouseCoords[0];var mouseY=mouseCoords[1];var value=(this.height-(mouseY-this.marginTop))/this.height;value*=this.max-this.min;value+=this.min;if(value>this.max)value=this.max;if(value<this.min)value=this.min;return value;};this.highlight=this.Highlight=function(shape)
47
- {if(typeof prop['chart.highlight.style']==='function'){(prop['chart.highlight.style'])(shape);}else{var last=shape.index===this.coords.length-1;this.drawCurvedBar({x:shape.x,y:shape.y,width:shape.width,height:shape.height,stroke:prop['chart.highlight.stroke'],fill:prop['chart.highlight.fill']});}};this.getObjectByXY=function(e)
48
- {var mouseXY=RG.getMouseXY(e);if(mouseXY[0]>this.marginLeft&&mouseXY[0]<(ca.width-this.marginRight)&&mouseXY[1]>=this.marginTop&&mouseXY[1]<=(ca.height-this.marginBottom)){return this;}};this.allowAdjusting=this.AllowAdjusting=function(){return;};this.adjusting_mousemove=this.Adjusting_mousemove=function(e)
49
- {if(prop['chart.adjustable']&&RG.Registry.get('chart.adjusting')&&RG.Registry.get('chart.adjusting').uid==this.uid){var mouseXY=RG.getMouseXY(e);var value=this.getValue(e);if(typeof value==='number'){RG.FireCustomEvent(this,'onadjust');this.value=Number(value.toFixed(prop['chart.scale.decimals']));RG.redrawCanvas(this.canvas);}}};this.drawSpecificLabels=this.DrawSpecificLabels=function()
50
- {var labels=prop['chart.labels.specific'];if(labels){var halign=prop['chart.labels.position']==='right'?'left':'right';var step=this.height/(labels.length-1);co.beginPath();co.fillStyle=prop['chart.text.color'];for(var i=0;i<labels.length;++i){var textConf=RG.getTextConf({object:this,prefix:'chart.labels'});RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:prop['chart.labels.position']=='right'?ca.width-this.marginRight+7:this.marginLeft-7,y:(this.height+this.marginTop)-(step*i),text:labels[i],valign:'center',halign:halign,tag:'labels.specific'});}
51
- co.fill();}};this.getYCoord=function(value)
52
- {if(value>this.max||value<this.min){return null;}
53
- var barHeight=ca.height-prop['chart.margin.top']-prop['chart.margin.bottom'];var coord=((value-this.min)/(this.max-this.min))*barHeight;coord=ca.height-coord-prop['chart.margin.bottom'];return coord;};this.overChartArea=function(e)
54
- {var mouseXY=RGraph.getMouseXY(e);var mouseX=mouseXY[0];var mouseY=mouseXY[1];if(mouseX>=this.marginLeft&&mouseX<=(ca.width-this.marginRight)&&mouseY>=this.marginTop&&mouseY<=(ca.height-this.marginBottom)){return true;}
55
- return false;};this.parseColors=function()
56
- {if(this.original_colors.length===0){this.original_colors['chart.colors']=RG.array_clone(prop['chart.colors']);this.original_colors['chart.tickmarks.inner.color']=RG.array_clone(prop['chart.tickmarks.inner.color']);this.original_colors['chart.tickmarks.outer.color']=RG.array_clone(prop['chart.tickmarks.outer.color']);this.original_colors['chart.colors.stroke.inner']=RG.array_clone(prop['chart.colors.stroke.inner']);this.original_colors['chart.colors.stroke.outer']=RG.array_clone(prop['chart.colors.stroke.outer']);this.original_colors['chart.highlight.fill']=RG.array_clone(prop['chart.highlight.fill']);this.original_colors['chart.highlight.stroke']=RG.array_clone(prop['chart.highlight.stroke']);this.original_colors['chart.background.color']=RG.array_clone(prop['chart.background.color']);}
57
- var colors=prop['chart.colors'];for(var i=0,len=colors.length;i<len;++i){colors[i]=this.parseSingleColorForGradient(colors[i]);}
58
- prop['chart.tickmarks.inner.color']=this.parseSingleColorForGradient(prop['chart.tickmarks.inner.color']);prop['chart.tickmarks.outer.color']=this.parseSingleColorForGradient(prop['chart.tickmarks.outer.color']);prop['chart.colors.stroke.inner']=this.parseSingleColorForGradient(prop['chart.colors.stroke.inner']);prop['chart.colors.stroke.outer']=this.parseSingleColorForGradient(prop['chart.colors.stroke.outer']);prop['chart.highlight.fill']=this.parseSingleColorForGradient(prop['chart.highlight.fill']);prop['chart.highlight.stroke']=this.parseSingleColorForGradient(prop['chart.highlight.stroke']);prop['chart.background.color']=this.parseSingleColorForGradient(prop['chart.background.color']);};this.reset=function()
59
- {};this.parseSingleColorForGradient=function(color)
60
- {if(!color||typeof color!='string'){return color;}
61
- if(color.match(/^gradient\((.*)\)$/i)){if(color.match(/^gradient\(({.*})\)$/i)){return RGraph.parseJSONGradient({object:this,def:RegExp.$1});}
62
- var parts=RegExp.$1.split(':');var grad=co.createLinearGradient(0,ca.height-prop['chart.margin.bottom'],0,prop['chart.margin.top']);var diff=1/(parts.length-1);grad.addColorStop(0,RG.trim(parts[0]));for(var j=1,len=parts.length;j<len;++j){grad.addColorStop(j*diff,RG.trim(parts[j]));}
63
- return grad?grad:color;}
64
- return grad?grad:color;};this.drawBevel=this.DrawBevel=function()
65
- {for(var i=0,height=0;i<this.coords.length;++i){height+=this.coords[i][3];}
66
- co.save();co.beginPath();co.rect(this.coords[0][0],this.coords[this.coords.length-1][1]-1,this.coords[0][2],height);co.clip();co.save();co.beginPath();this.drawCurvedBar({x:this.coords[0][0],y:this.coords[this.coords.length-1][1]-1,width:this.coords[0][2],height:height});co.clip();co.beginPath();co.shadowColor='black';co.shadowOffsetX=0;co.shadowOffsetY=0;co.shadowBlur=15;co.lineWidth=2;this.drawCurvedBar({x:this.coords[0][0]-1,y:this.coords[this.coords.length-1][1]-1,width:this.coords[0][2]+2,height:height+2+100});co.stroke();co.restore();co.restore();};this.interactiveKeyHighlight=function(index)
67
- {var coords=this.coords[index];co.beginPath();co.strokeStyle=prop['chart.key.interactive.highlight.chart.stroke'];co.lineWidth=2;co.fillStyle=prop['chart.key.interactive.highlight.chart.fill'];co.rect(coords[0],coords[1],coords[2],coords[3]);co.fill();co.stroke();co.lineWidth=1;};this.on=function(type,func)
68
- {if(type.substr(0,2)!=='on'){type='on'+type;}
69
- if(typeof this[type]!=='function'){this[type]=func;}else{RG.addCustomEventListener(this,type,func);}
70
- return this;};this.drawCurvedBar=function(opt)
71
- {pa2(co,'b r % % % %',opt.x,opt.y,opt.width,opt.height);if(opt.stroke){co.strokeStyle=opt.stroke;co.stroke();}
72
- if(opt.fill){co.fillStyle=opt.fill;co.fill();}};this.firstDrawFunc=function()
73
- {};this.exec=function(func)
74
- {func(this);return this;};this.grow=function()
75
- {var obj=this;var canvas=obj.canvas;var context=obj.context;var initial_value=obj.currentValue;var opt=arguments[0]||{};var numFrames=opt.frames||30;var frame=0
76
- var callback=arguments[1]||function(){};if(typeof obj.value==='object'){if(RGraph.is_null(obj.currentValue)){obj.currentValue=[];for(var i=0;i<obj.value.length;++i){obj.currentValue[i]=0;}}
77
- var diff=[];var increment=[];for(var i=0;i<obj.value.length;++i){diff[i]=obj.value[i]-Number(obj.currentValue[i]);increment[i]=diff[i]/numFrames;}
78
- if(initial_value==null){initial_value=[];for(var i=0;i<obj.value.length;++i){initial_value[i]=0;}}}else{var diff=obj.value-Number(obj.currentValue);var increment=diff/numFrames;}
79
- function iterator()
80
- {frame++;if(frame<=numFrames){if(typeof obj.value=='object'){obj.value=[];for(var i=0;i<initial_value.length;++i){obj.value[i]=initial_value[i]+(increment[i]*frame);}}else{obj.value=initial_value+(increment*frame);}
81
- RGraph.clear(obj.canvas);RGraph.redrawCanvas(obj.canvas);RGraph.Effects.updateCanvas(iterator);}else{callback();}}
82
- iterator();return this;};RG.register(this);if(parseConfObjectForOptions){RG.parseObjectStyleConfig(this,conf.options);}};
12
+ RGraph = window.RGraph || {isrgraph:true,isRGraph:true,rgraph:true};
13
+
14
+
15
+ //
16
+ // The progress bar constructor
17
+ //
18
+ RGraph.VProgress = function (conf)
19
+ {
20
+ this.id = conf.id;
21
+ this.canvas = document.getElementById(this.id);
22
+ this.context = this.canvas.getContext('2d');
23
+ this.canvas.__object__ = this;
24
+
25
+ this.min = RGraph.stringsToNumbers(conf.min);
26
+ this.max = RGraph.stringsToNumbers(conf.max);
27
+ this.value = RGraph.stringsToNumbers(conf.value);
28
+ this.type = 'vprogress';
29
+ this.coords = [];
30
+ this.isRGraph = true;
31
+ this.isrgraph = true;
32
+ this.rgraph = true;
33
+ this.currentValue = null;
34
+ this.uid = RGraph.createUID();
35
+ this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.createUID();
36
+ this.colorsParsed = false;
37
+ this.coordsText = [];
38
+ this.original_colors = [];
39
+ this.firstDraw = true; // After the first draw this will be false
40
+ this.stopAnimationRequested = false;// Used to control the animations
41
+
42
+
43
+
44
+
45
+
46
+ this.properties =
47
+ {
48
+ colors: ['#0c0','red','blue','yellow','pink','cyan','black','white','gray'],
49
+ colorsStrokeInner: '#999',
50
+ colorsStrokeOuter: '#999',
51
+
52
+ tickmarksOuter: true,
53
+ tickmarksInner: false,
54
+ tickmarksOuterCount: 0,
55
+ tickmarksInnerCount: 0,
56
+ tickmarksOuterColor: '#999',
57
+ tickmarksInnerColor: '#999',
58
+
59
+ marginLeft: 35,
60
+ marginRight: 35,
61
+ marginTop: 35,
62
+ marginBottom: 35,
63
+ marginInner: 0,
64
+
65
+
66
+ backgroundColor: 'Gradient(#ccc:#eee:#efefef)',
67
+
68
+ shadow: false,
69
+ shadowColor: 'rgba(0,0,0,0.5)',
70
+ shadowBlur: 3,
71
+ shadowOffsetx: 3,
72
+ shadowOffsety: 3,
73
+
74
+ title: '',
75
+ titleBold: null,
76
+ titleItalic: null,
77
+ titleFont: null,
78
+ titleSize: null,
79
+ titleColor: null,
80
+ titleHalign: null,
81
+ titleValign: null,
82
+ titleOffsetx: 0,
83
+ titleOffsety: 0,
84
+ titleSubtitle: '',
85
+ titleSubtitleSize: null,
86
+ titleSubtitleColor: '#aaa',
87
+ titleSubtitleFont: null,
88
+ titleSubtitleBold: null,
89
+ titleSubtitleItalic: null,
90
+ titleSubtitleOffsetx: 0,
91
+ titleSubtitleOffsety: 0,
92
+
93
+ titleSide: null,
94
+ titleSideFont: null,
95
+ titleSideSize: null,
96
+ titleSideColor: null,
97
+ titleSideBold: null,
98
+ titleSideItalic: null,
99
+ titleSideOffsetx: 0,
100
+ titleSideOffsety: 0,
101
+
102
+ textSize: 12,
103
+ textColor: 'black',
104
+ textFont: 'Arial, Verdana, sans-serif',
105
+ textBold: false,
106
+ textItalic: false,
107
+ textAccessible: false,
108
+ textAccessibleOverflow: 'visible',
109
+ textAccessiblePointerevents: false,
110
+ text: null,
111
+
112
+ contextmenu: null,
113
+
114
+ scaleDecimals: 0,
115
+ scaleThousand: ',',
116
+ scalePoint: '.',
117
+ scaleUnitsPre: '',
118
+ scaleUnitsPost: '',
119
+
120
+ tooltips: null,
121
+ tooltipsEffect: 'slide',
122
+ tooltipsCssClass: 'RGraph_tooltip',
123
+ tooltipsCss: null,
124
+ tooltipsHighlight: true,
125
+ tooltipsEvent: 'onclick',
126
+ tooltipsFormattedThousand: ',',
127
+ tooltipsFormattedPoint: '.',
128
+ tooltipsFormattedDecimals: 0,
129
+ tooltipsFormattedUnitsPre: '',
130
+ tooltipsFormattedUnitsPost: '',
131
+ tooltipsFormattedKeyColors: null,
132
+ tooltipsFormattedKeyColorsShape: 'square',
133
+ tooltipsFormattedKeyLabels: [],
134
+ tooltipsFormattedListType: 'ul',
135
+ tooltipsFormattedListItems: null,
136
+ tooltipsFormattedTableHeaders: null,
137
+ tooltipsFormattedTableData: null,
138
+ tooltipsPointer: true,
139
+ tooltipsPointerOffsetx: 0,
140
+ tooltipsPointerOffsety: 0,
141
+ tooltipsPositionStatic: true,
142
+ tooltipsHotspotIgnore: null,
143
+
144
+ highlightLinewidth: 1,
145
+ highlightStroke: 'rgba(0,0,0,0)',
146
+ highlightFill: 'rgba(255,255,255,0.7)',
147
+
148
+ annotatable: false,
149
+ annotatableColor: 'black',
150
+
151
+ arrows: false,
152
+
153
+ labelsInner: false,
154
+ labelsInnerFont: null,
155
+ labelsInnerSize: null,
156
+ labelsInnerColor: null,
157
+ labelsInnerBold: null,
158
+ labelsInnerItalic: null,
159
+ labelsInnerBackgroundFill: 'rgba(255,255,255,0.75)',
160
+ labelsInnerBorder: true,
161
+ labelsInnerBorderLinewidth: 1,
162
+ labelsInnerBorderColor: '#ccc',
163
+ labelsInnerDecimals: 0,
164
+ labelsInnerUnitsPre: '',
165
+ labelsInnerUnitsPost: '',
166
+ labelsInnerScaleThousand: null,
167
+ labelsInnerScalePoint: null,
168
+ labelsInnerSpecific: null,
169
+ labelsInnerOffsetx: 0,
170
+ labelsInnerOffsety: 0,
171
+
172
+ labelsCount: 10,
173
+ labelsPosition: 'right',
174
+ labelsOffsetx: 0,
175
+ labelsOffsety: 0,
176
+ labelsFont: null,
177
+ labelsSize: null,
178
+ labelsColor: null,
179
+ labelsBold: null,
180
+ labelsItalic: null,
181
+ labelsSpecific: null,
182
+ labelsSpecificFormattedDecimals: 0,
183
+ labelsSpecificFormattedUnitsPre: '',
184
+ labelsSpecificFormattedUnitsPost: '',
185
+ labelsSpecificFormattedThousand: ',',
186
+ labelsSpecificFormattedPoint: '.',
187
+
188
+ adjustable: false,
189
+
190
+ key: null,
191
+ keyBackground: 'white',
192
+ keyPosition: 'graph',
193
+ keyHalign: 'right',
194
+ keyShadow: false,
195
+ keyShadowColor: '#666',
196
+ keyShadowBlur: 3,
197
+ keyShadowOffsetx: 2,
198
+ keyShadowOffsety: 2,
199
+ keyPositionGutterBoxed: false,
200
+ keyPositionX: null,
201
+ keyPositionY: null,
202
+ keyColorShape: 'square',
203
+ keyRounded: true,
204
+ keyLinewidth: 1,
205
+ keyColors: null,
206
+ keyInteractive: false,
207
+ keyInteractiveHighlightChartStroke: '#000',
208
+ keyInteractiveHighlightChartFill: 'rgba(255,255,255,0.7)',
209
+ keyInteractiveHighlightLabel: 'rgba(255,0,0,0.2)',
210
+ keyLabelsColor: null,
211
+ keyLabelsFont: null,
212
+ keyLabelsSize: null,
213
+ keyLabelsBold: null,
214
+ keyLabelsItalic: null,
215
+ keyLabelsOffsetx: 0,
216
+ keyLabelsOffsety: 0,
217
+ keyFormattedDecimals: 0,
218
+ keyFormattedPoint: '.',
219
+ keyFormattedThousand: ',',
220
+ keyFormattedUnitsPre: '',
221
+ keyFormattedUnitsPost: '',
222
+ keyFormattedValueSpecific: null,
223
+ keyFormattedItemsCount: null,
224
+
225
+ borderInner: true,
226
+
227
+ beveled: false,
228
+
229
+ clearto: 'rgba(0,0,0,0)'
230
+ }
231
+
232
+ // Check for support
233
+ if (!this.canvas) {
234
+ alert('[PROGRESS] No canvas support');
235
+ return;
236
+ }
237
+
238
+
239
+ //
240
+ // Create the dollar objects so that functions can be added to them
241
+ //
242
+ var linear_data = RGraph.arrayLinearize(this.value);
243
+ for (var i=0; i<linear_data.length; ++i) {
244
+ this['$' + i] = {};
245
+ }
246
+
247
+
248
+
249
+
250
+ // Easy access to properties and the path function
251
+ var properties = this.properties;
252
+ this.path = RGraph.pathObjectFunction;
253
+
254
+
255
+
256
+ //
257
+ // "Decorate" the object with the generic effects if the effects library has been included
258
+ //
259
+ if (RGraph.Effects && typeof RGraph.Effects.decorate === 'function') {
260
+ RGraph.Effects.decorate(this);
261
+ }
262
+
263
+
264
+
265
+ // Add the responsive method. This method resides in the common file.
266
+ this.responsive = RGraph.responsive;
267
+
268
+
269
+
270
+
271
+
272
+
273
+
274
+
275
+ //
276
+ // A generic setter
277
+ //
278
+ // @param string name The name of the property to set or it can also be an object containing
279
+ // object style configuration
280
+ //
281
+ this.set = function (name)
282
+ {
283
+ var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
284
+
285
+ // Some BC for the beveled property
286
+ if (name === 'bevelled') {
287
+ name = 'beveled';
288
+ }
289
+
290
+ // the number of arguments is only one and it's an
291
+ // object - parse it for configuration data and return.
292
+ if (arguments.length === 1 && typeof arguments[0] === 'object') {
293
+ for (i in arguments[0]) {
294
+ if (typeof i === 'string') {
295
+ this.set(i, arguments[0][i]);
296
+ }
297
+ }
298
+
299
+ return this;
300
+ }
301
+
302
+ properties[name] = value;
303
+
304
+ return this;
305
+ };
306
+
307
+
308
+
309
+
310
+
311
+
312
+
313
+
314
+ //
315
+ // A generic getter
316
+ //
317
+ // @param string name The name of the property to get
318
+ //
319
+ this.get = function (name)
320
+ {
321
+ return properties[name];
322
+ };
323
+
324
+
325
+
326
+
327
+
328
+
329
+
330
+
331
+ //
332
+ // Draws the progress bar
333
+ //
334
+ this.draw = function ()
335
+ {
336
+ //
337
+ // Fire the onbeforedraw event
338
+ //
339
+ RGraph.fireCustomEvent(this, 'onbeforedraw');
340
+
341
+
342
+
343
+ // Translate half a pixel for antialiasing purposes - but only if it hasn't been
344
+ // done already
345
+ //
346
+ // MUST be the first thing done!
347
+ //
348
+ if (!this.canvas.__rgraph_aa_translated__) {
349
+ this.context.translate(0.5,0.5);
350
+
351
+ this.canvas.__rgraph_aa_translated__ = true;
352
+ }
353
+
354
+ //
355
+ // Parse the colors. This allows for simple gradient syntax
356
+ //
357
+ if (!this.colorsParsed) {
358
+
359
+ this.parseColors();
360
+
361
+
362
+ // Don't want to do this again
363
+ this.colorsParsed = true;
364
+ }
365
+
366
+
367
+ //
368
+ // Set the current value
369
+ //
370
+ this.currentValue = this.value;
371
+
372
+
373
+
374
+ //
375
+ // Populate the labels string/array if its a string
376
+ //
377
+ if (properties.labelsSpecific && properties.labelsSpecific.length) {
378
+ //
379
+ // If the labels option is a string then turn it
380
+ // into an array.
381
+ //
382
+ if (typeof properties.labelsSpecific === 'string') {
383
+ properties.labelsSpecific = RGraph.arrayPad({
384
+ array: [],
385
+ length: properties.labelsCount,
386
+ value: properties.labelsSpecific
387
+ });
388
+ }
389
+
390
+ for (var i=0; i<properties.labelsSpecific.length; ++i) {
391
+ properties.labelsSpecific[i] = RGraph.labelSubstitution({
392
+ object: this,
393
+ text: properties.labelsSpecific[i],
394
+ index: i,
395
+ value: (typeof this.value === 'object' && typeof this.value[i] === 'number') ? this.value[i] : this.value,
396
+ decimals: properties.labelsSpecificFormattedDecimals || 0,
397
+ unitsPre: properties.labelsSpecificFormattedUnitsPre || '',
398
+ unitsPost: properties.labelsSpecificFormattedUnitsPost || '',
399
+ thousand: properties.labelsSpecificFormattedThousand || ',',
400
+ point: properties.labelsSpecificFormattedPoint || '.'
401
+ });
402
+ }
403
+ }
404
+
405
+
406
+
407
+
408
+ //
409
+ // Make the margins easy ro access
410
+ //
411
+ this.marginLeft = properties.marginLeft;
412
+ this.marginRight = properties.marginRight;
413
+ this.marginTop = properties.marginTop;
414
+ this.marginBottom = properties.marginBottom;
415
+
416
+ // Figure out the width and height
417
+ this.width = this.canvas.width - this.marginLeft - this.marginRight;
418
+ this.height = this.canvas.height - this.marginTop - this.marginBottom;
419
+ this.coords = [];
420
+
421
+
422
+
423
+ //
424
+ // Stop this growing uncontrollably
425
+ //
426
+ this.coordsText = [];
427
+
428
+
429
+
430
+
431
+
432
+ this.drawbar();
433
+ this.drawTickMarks();
434
+ this.drawLabels();
435
+ this.drawTitles();
436
+
437
+
438
+ //
439
+ // Draw the bevel effect if requested
440
+ //
441
+ if (properties.beveled) {
442
+ this.drawBevel();
443
+ }
444
+
445
+
446
+
447
+ //
448
+ // Setup the context menu if required
449
+ //
450
+ if (properties.contextmenu) {
451
+ RGraph.showContext(this);
452
+ }
453
+
454
+
455
+
456
+
457
+ //
458
+ // Add custom text thats specified
459
+ //
460
+ RGraph.addCustomText(this);
461
+
462
+
463
+
464
+
465
+
466
+
467
+
468
+
469
+ //
470
+ // This installs the event listeners
471
+ //
472
+ RGraph.installEventListeners(this);
473
+
474
+ // Draw a key if necessary
475
+ if (properties.key && properties.key.length) {
476
+ RGraph.drawKey(this, properties.key, properties.colors);
477
+ }
478
+
479
+ //
480
+ // Instead of using RGraph.common.adjusting.js, handle them here
481
+ //
482
+ this.allowAdjusting();
483
+
484
+
485
+ //
486
+ // Fire the onfirstdraw event
487
+ //
488
+ if (this.firstDraw) {
489
+ this.firstDraw = false;
490
+ RGraph.fireCustomEvent(this, 'onfirstdraw');
491
+ this.firstDrawFunc();
492
+ }
493
+
494
+
495
+
496
+
497
+ //
498
+ // Fire the RGraph draw event
499
+ //
500
+ RGraph.fireCustomEvent(this, 'ondraw');
501
+
502
+
503
+
504
+
505
+
506
+
507
+
508
+
509
+
510
+
511
+ //
512
+ // Install any inline responsive configuration. This
513
+ // should be last in the draw function - even after
514
+ // the draw events.
515
+ //
516
+ RGraph.installInlineResponsive(this);
517
+
518
+
519
+
520
+
521
+
522
+
523
+
524
+
525
+
526
+ return this;
527
+ };
528
+
529
+
530
+
531
+
532
+
533
+
534
+
535
+
536
+ //
537
+ // Draw the bar itself
538
+ //
539
+ this.drawbar = function ()
540
+ {
541
+ //
542
+ // First get the scale
543
+ //
544
+ this.scale2 = RGraph.getScale({object: this, options: {
545
+ 'scale.max': this.max,
546
+ 'scale.min': this.min,
547
+ 'scale.strict': true,
548
+ 'scale.thousand': properties.scaleThousand,
549
+ 'scale.point': properties.scalePoint,
550
+ 'scale.decimals': properties.scaleDecimals,
551
+ 'scale.labels.count': properties.labelsCount,
552
+ 'scale.round': properties.scaleRound,
553
+ 'scale.units.pre': properties.scaleUnitsPre,
554
+ 'scale.units.post': properties.scaleUnitsPost
555
+ }});
556
+
557
+
558
+ // Set a shadow if requested
559
+ if (properties.shadow) {
560
+ RGraph.setShadow(
561
+ this,
562
+ properties.shadowColor,
563
+ properties.shadowOffsetx,
564
+ properties.shadowOffsety,
565
+ properties.shadowBlur
566
+ );
567
+ }
568
+
569
+ // Draw the outline
570
+ this.context.fillStyle = properties.backgroundColor;
571
+ this.context.strokeStyle = properties.colorsStrokeOuter;
572
+
573
+ this.context.strokeRect(
574
+ this.marginLeft,
575
+ this.marginTop,
576
+ this.width,
577
+ this.height
578
+ );
579
+
580
+ this.context.fillRect(
581
+ this.marginLeft,
582
+ this.marginTop,
583
+ this.width,
584
+ this.height
585
+ );
586
+
587
+
588
+ // Turn off any shadow
589
+ RGraph.noShadow(this);
590
+
591
+ this.context.strokeStyle = properties.colorsStrokeOuter;
592
+ this.context.fillStyle = properties.colors[0];
593
+ var margin = properties.marginInner;
594
+ var barHeight = (this.canvas.height - this.marginTop - this.marginBottom) * ((RGraph.arraySum(this.value) - this.min) / (this.max - this.min));
595
+
596
+ // Draw the actual bar itself
597
+ if (typeof this.value === 'number') {
598
+
599
+ this.context.lineWidth = 1;
600
+ this.context.strokeStyle = properties.colorsStrokeInner;
601
+
602
+ if (properties.borderInner) {
603
+ this.drawCurvedBar({
604
+ x: this.marginLeft + margin,
605
+ y: this.marginTop + (this.height - barHeight),
606
+ width: this.width - margin - margin,
607
+ height: barHeight,
608
+ stroke: properties.colorsStrokeInner
609
+ });
610
+ }
611
+
612
+ this.drawCurvedBar({
613
+ x: this.marginLeft + margin,
614
+ y: this.marginTop + (this.height - barHeight),
615
+ width: this.width - margin - margin,
616
+ height: barHeight,
617
+ fill: properties.colors[0]
618
+ });
619
+
620
+ } else if (typeof this.value == 'object') {
621
+
622
+ this.context.beginPath();
623
+ this.context.strokeStyle = properties.colorsStrokeInner;
624
+
625
+ var startPoint = this.canvas.height - this.marginBottom;
626
+
627
+ for (var i=0,len=this.value.length; i<len; ++i) {
628
+
629
+ var segmentHeight = ( (this.value[i] - this.min) / (this.max - this.min) ) * (this.canvas.height - this.marginBottom - this.marginTop);
630
+
631
+
632
+ this.context.beginPath();
633
+ this.context.fillStyle = properties.colors[i];
634
+
635
+ if (properties.borderInner) {
636
+ this.drawCurvedBar({
637
+ x: this.marginLeft + margin,
638
+ y: startPoint - segmentHeight,
639
+ width: this.width - margin - margin,
640
+ height: segmentHeight,
641
+ stroke: this.context.strokeStyle
642
+ });
643
+ }
644
+
645
+ this.drawCurvedBar({
646
+ x: this.marginLeft + margin,
647
+ y: startPoint - segmentHeight,
648
+ width: this.width - margin - margin,
649
+ height: segmentHeight,
650
+ fill: this.context.fillStyle
651
+ });
652
+
653
+
654
+
655
+ // Store the coords
656
+ this.coords.push([
657
+ this.marginLeft + margin,
658
+ startPoint - segmentHeight,
659
+ this.width - margin - margin,
660
+ segmentHeight
661
+ ]);
662
+
663
+ startPoint -= segmentHeight;
664
+ }
665
+
666
+ this.context.fill();
667
+ }
668
+
669
+
670
+
671
+ //
672
+ // Inner inner tickmarks
673
+ //
674
+ if (properties.tickmarksInnerCount > 0) {
675
+
676
+ var spacing = (this.canvas.height - this.marginTop - this.marginBottom) / properties.tickmarksInnerCount;
677
+
678
+ this.context.lineWidth = 1;
679
+ this.context.strokeStyle = properties.colorsStrokeInner;
680
+
681
+ this.context.beginPath();
682
+
683
+ for (var y = this.marginTop; y<this.canvas.height - this.marginBottom; y+=spacing) {
684
+ this.context.moveTo(this.marginLeft, Math.round(y));
685
+ this.context.lineTo(this.marginLeft + 3, Math.round(y));
686
+
687
+ this.context.moveTo(this.canvas.width - this.marginRight, Math.round(y));
688
+ this.context.lineTo(this.canvas.width - this.marginRight - 3, Math.round(y));
689
+ }
690
+
691
+ this.context.stroke();
692
+ }
693
+
694
+ this.context.beginPath();
695
+ this.context.strokeStyle = properties.colorsStrokeInner;
696
+
697
+ if (typeof this.value == 'number') {
698
+
699
+ if (properties.borderInner) {
700
+ this.drawCurvedBar({
701
+ x: this.marginLeft + margin,
702
+ y: this.marginTop + this.height - barHeight,
703
+ width: this.width - margin - margin,
704
+ height: barHeight
705
+ });
706
+ }
707
+
708
+ this.drawCurvedBar({
709
+ x: this.marginLeft + margin,
710
+ y: this.marginTop + this.height - barHeight,
711
+ width: this.width - margin - margin,
712
+ height: barHeight
713
+ });
714
+
715
+ // Store the coords
716
+ this.coords.push([
717
+ this.marginLeft + margin,
718
+ this.marginTop + this.height - barHeight,
719
+ this.width - margin - margin,
720
+ barHeight
721
+ ]);
722
+ }
723
+
724
+
725
+ //
726
+ // Draw the arrows indicating the level if requested
727
+ //
728
+ if (properties.arrows) {
729
+ var x = this.marginLeft - 4;
730
+ var y = this.canvas.height - this.marginBottom - barHeight;
731
+
732
+ this.context.lineWidth = 1;
733
+ this.context.fillStyle = 'black';
734
+ this.context.strokeStyle = 'black';
735
+
736
+ this.context.beginPath();
737
+ this.context.moveTo(x, y);
738
+ this.context.lineTo(x - 4, y - 2);
739
+ this.context.lineTo(x - 4, y + 2);
740
+ this.context.closePath();
741
+
742
+ this.context.stroke();
743
+ this.context.fill();
744
+
745
+ x += this.width + 8;
746
+
747
+ this.context.beginPath();
748
+ this.context.moveTo(x, y);
749
+ this.context.lineTo(x + 4, y - 2);
750
+ this.context.lineTo(x + 4, y + 2);
751
+ this.context.closePath();
752
+
753
+ this.context.stroke();
754
+ this.context.fill();
755
+
756
+ this.context.beginPath();
757
+ }
758
+
759
+
760
+
761
+
762
+ //
763
+ // Draw the "in-bar" label
764
+ //
765
+ if (properties.labelsInner) {
766
+
767
+ var textConf = RGraph.getTextConf({
768
+ object: this,
769
+ prefix: 'labelsInner'
770
+ });
771
+
772
+ RGraph.text({
773
+
774
+ object: this,
775
+
776
+ font: textConf.font,
777
+ size: textConf.size,
778
+ color: textConf.color,
779
+ bold: textConf.bold,
780
+ italic: textConf.italic,
781
+
782
+ x: ((this.canvas.width - this.marginLeft - this.marginRight) / 2) + this.marginLeft + properties.labelsInnerOffsetx,
783
+ y: this.coords[this.coords.length - 1][1] - 5 + properties.labelsInnerOffsety,
784
+
785
+ text: typeof properties.labelsInnerSpecific === 'string'
786
+ ?
787
+ properties.labelsInnerSpecific
788
+ :
789
+ RGraph.numberFormat({
790
+ object: this,
791
+ number: RGraph.arraySum(this.value).toFixed(typeof properties.labelsInnerDecimals === 'number' ? properties.labelsInnerDecimals : properties.scaleDecimals),
792
+ unitspre: typeof properties.labelsInnerUnitsPre === 'string' ? properties.labelsInnerUnitsPre : properties.scaleUnitsPre,
793
+ unitspost: typeof properties.labelsInnerUnitsPost === 'string' ? properties.labelsInnerUnitsPost : properties.scaleUnitsPost,
794
+ point: typeof properties.labelsInnerPoint === 'string' ? properties.labelsInnerPoint : properties.scalePoint,
795
+ thousand: typeof properties.labelsInnerThousand === 'string' ? properties.labelsInnerThousand : properties.scaleThousand
796
+ }),
797
+ valign: 'bottom',
798
+ halign: 'center',
799
+ bounding: true,
800
+ boundingFill: properties.labelsInnerBackgroundFill,
801
+ boundingStroke: properties.labelsInnerBorder ? properties.labelsInnerBorderColor : 'rgba(0,0,0,0)',
802
+ boundingLinewidth: properties.labelsInnerBorderLinewidth,
803
+ tag: 'labels.inner'
804
+ });
805
+ }
806
+ };
807
+
808
+
809
+
810
+
811
+
812
+
813
+
814
+
815
+ //
816
+ // The function that draws the OUTER tick marks.
817
+ //
818
+ this.drawTickMarks = function ()
819
+ {
820
+ this.context.strokeStyle = properties.colorsStrokeOuter;
821
+
822
+ if (properties.tickmarksOuter) {
823
+ this.context.beginPath();
824
+ for (var i=0; i<=properties.tickmarksOuterCount; i++) {
825
+
826
+ var startX = properties.labelsPosition === 'left' ? this.marginLeft : this.canvas.width - properties.marginRight,
827
+ endX = properties.labelsPosition === 'left' ? startX - 4 : startX + 4,
828
+ yPos = (this.height * (i / properties.tickmarksOuterCount)) + this.marginTop;
829
+
830
+ this.context.moveTo(startX, Math.round(yPos));
831
+ this.context.lineTo(endX, Math.round(yPos));
832
+ }
833
+ this.context.stroke();
834
+ }
835
+ };
836
+
837
+
838
+
839
+
840
+
841
+
842
+
843
+
844
+ //
845
+ // The function that draws the labels
846
+ //
847
+ this.drawLabels = function ()
848
+ {
849
+ if (!RGraph.isNull(properties.labelsSpecific)) {
850
+ return this.drawSpecificLabels();
851
+ }
852
+
853
+ this.context.fillStyle = properties.textColor;
854
+
855
+ var position = properties.labelsPosition.toLowerCase();
856
+ var xAlignment = position === 'left' ? 'right' : 'left';
857
+ var yAlignment = 'center';
858
+ var count = properties.labelsCount;
859
+ var units_pre = properties.scaleUnitsPre;
860
+ var units_post = properties.scaleUnitsPost;
861
+ var text_size = properties.textSize;
862
+ var text_font = properties.textFont;
863
+ var decimals = properties.scaleDecimals;
864
+ var offsetx = properties.labelsOffsetx;
865
+ var offsety = properties.labelsOffsety;
866
+
867
+ if (properties.tickmarksOuter) {
868
+
869
+ var textConf = RGraph.getTextConf({
870
+ object: this,
871
+ prefix: 'labels'
872
+ });
873
+
874
+ for (var i=0; i<count ; ++i) {
875
+ RGraph.text({
876
+
877
+ object: this,
878
+
879
+ font: textConf.font,
880
+ size: textConf.size,
881
+ color: textConf.color,
882
+ bold: textConf.bold,
883
+ italic: textConf.italic,
884
+
885
+ x: position == 'left' ? (this.marginLeft - 7 + offsetx) : (this.canvas.width - this.marginRight + 7) + offsetx,
886
+ y: (((this.canvas.height - this.marginTop - this.marginBottom) / count) * i) + this.marginTop + offsety,
887
+ text: this.scale2.labels[this.scale2.labels.length - (i+1)],
888
+ valign: yAlignment,
889
+ halign: xAlignment,
890
+ tag: 'scale'
891
+ });
892
+ }
893
+
894
+ //
895
+ // Show zero?
896
+ //
897
+ if (this.min == 0) {
898
+
899
+ RGraph.text({
900
+
901
+ object: this,
902
+
903
+ font: textConf.font,
904
+ size: textConf.size,
905
+ color: textConf.color,
906
+ bold: textConf.bold,
907
+ italic: textConf.italic,
908
+
909
+ x: position == 'left' ? (this.marginLeft - 5 + offsetx) : (this.canvas.width - this.marginRight + 5 + offsetx),
910
+ y: this.canvas.height - this.marginBottom + offsety,
911
+ text: RGraph.numberFormat({
912
+ object: this,
913
+ number: this.min.toFixed(this.min === 0 ? 0 : decimals),
914
+ unitspre: units_pre,
915
+ unitspost: units_post,
916
+ point: properties.scalePoint,
917
+ thousand: properties.scaleThousand,
918
+ }),
919
+ valign: yAlignment,
920
+ halign: xAlignment,
921
+ tag: 'scale'
922
+ });
923
+ }
924
+
925
+
926
+
927
+
928
+ //
929
+ // min is set
930
+ //
931
+ if (this.min != 0) {
932
+ RGraph.text({
933
+
934
+ object: this,
935
+
936
+ font: textConf.font,
937
+ size: textConf.size,
938
+ color: textConf.color,
939
+ bold: textConf.bold,
940
+ italic: textConf.italic,
941
+
942
+ x: position == 'left' ? (this.marginLeft - 5 + offsetx) : (this.canvas.width - this.marginRight + 5 + offsetx),
943
+ y: this.canvas.height - this.marginBottom + offsety,
944
+ text: RGraph.numberFormat({
945
+ object: this,
946
+ number: this.min.toFixed(decimals),
947
+ unitspre: units_pre,
948
+ unitspost: units_post
949
+ }),
950
+ valign: yAlignment,
951
+ halign: xAlignment,
952
+ tag: 'scale'
953
+ });
954
+ }
955
+ }
956
+ };
957
+
958
+
959
+
960
+
961
+
962
+
963
+
964
+
965
+ //
966
+ // Draws titles
967
+ //
968
+ this.drawTitles = function ()
969
+ {
970
+ // Draw the main title and subtitle
971
+ RGraph.drawTitle(this);
972
+
973
+
974
+
975
+
976
+
977
+ // Draw side title
978
+ if (properties.titleSide) {
979
+
980
+ this.context.fillStyle = properties.titleSideColor;
981
+
982
+
983
+ var textConf = RGraph.getTextConf({
984
+ object: this,
985
+ prefix: 'titleSide'
986
+ });
987
+ var x = properties.labelsPosition == 'right' ? this.marginLeft - 10 : (this.canvas.width - this.marginRight) + 10;
988
+ var y = this.marginTop + (this.height / 2);
989
+
990
+ // Add any use specified offset
991
+ if (typeof properties.titleSideOffsetx === 'number') x += properties.titleSideOffsetx;
992
+ if (typeof properties.titleSideOffsety === 'number') y += properties.titleSideOffsety;
993
+
994
+ RGraph.text({
995
+ object: this,
996
+ font: textConf.font,
997
+ size: textConf.size,
998
+ color: textConf.color,
999
+ bold: textConf.bold,
1000
+ italic: textConf.italic,
1001
+ x: x,
1002
+ y: y,
1003
+ text: properties.titleSide,
1004
+ valign: 'bottom',
1005
+ halign: 'center',
1006
+ accessible: false,
1007
+ angle: properties.labelsPosition == 'right' ? 270 : 90,
1008
+ tag: 'title.side'
1009
+ });
1010
+ }
1011
+ };
1012
+
1013
+
1014
+
1015
+
1016
+
1017
+
1018
+
1019
+
1020
+ //
1021
+ // Returns the focused bar
1022
+ //
1023
+ // @param event e The event object
1024
+ //
1025
+ this.getShape = function (e)
1026
+ {
1027
+ var mouseXY = RGraph.getMouseXY(e),
1028
+ mouseX = mouseXY[0],
1029
+ mouseY = mouseXY[1]
1030
+
1031
+ for (var i=0,len=this.coords.length; i<len; i++) {
1032
+
1033
+ if (RGraph.tooltipsHotspotIgnore(this, i)) {
1034
+ continue;
1035
+ }
1036
+
1037
+ var x = this.coords[i][0],
1038
+ y = this.coords[i][1],
1039
+ w = this.coords[i][2],
1040
+ h = this.coords[i][3],
1041
+ idx = i;
1042
+
1043
+ this.context.beginPath();
1044
+ this.drawCurvedBar({
1045
+ x: x,
1046
+ y: y,
1047
+ width: w,
1048
+ height: h
1049
+ });
1050
+
1051
+ if (this.context.isPointInPath(mouseX, mouseY)) {
1052
+
1053
+ var tooltip = RGraph.parseTooltipText ? RGraph.parseTooltipText(properties.tooltips, i) : null;
1054
+
1055
+ return {
1056
+ object: this,
1057
+ x: x,
1058
+ y: y,
1059
+ width: w,
1060
+ height: h,
1061
+ index: i,
1062
+ dataset: 0,
1063
+ sequentialIndex: i,
1064
+ tooltip: typeof tooltip === 'string' ? tooltip : null
1065
+ };
1066
+ }
1067
+ }
1068
+ };
1069
+
1070
+
1071
+
1072
+
1073
+
1074
+
1075
+
1076
+
1077
+ //
1078
+ // This function returns the value that the mouse is positioned at, regardless of
1079
+ // the actual indicated value.
1080
+ //
1081
+ // @param object e The event object
1082
+ //
1083
+ this.getValue = function (e)
1084
+ {
1085
+ var mouseCoords = RGraph.getMouseXY(e);
1086
+ var mouseX = mouseCoords[0];
1087
+ var mouseY = mouseCoords[1];
1088
+
1089
+ var value = (this.height - (mouseY - this.marginTop)) / this.height;
1090
+ value *= this.max - this.min;
1091
+ value += this.min;
1092
+
1093
+ // Bounds checking
1094
+ if (value > this.max) value = this.max;
1095
+ if (value < this.min) value = this.min;
1096
+
1097
+ return value;
1098
+ };
1099
+
1100
+
1101
+
1102
+
1103
+
1104
+
1105
+
1106
+
1107
+ //
1108
+ // Each object type has its own Highlight() function which highlights the appropriate shape
1109
+ //
1110
+ // @param object shape The shape to highlight
1111
+ //
1112
+ this.highlight = function (shape)
1113
+ {
1114
+ if (properties.tooltipsHighlight) {
1115
+ if (typeof properties.highlightStyle === 'function') {
1116
+ (properties.highlightStyle)(shape);
1117
+
1118
+ // Highlight all of the rects except this one - essentially an inverted highlight
1119
+ } else if (typeof properties.highlightStyle === 'string' && properties.highlightStyle === 'invert') {
1120
+ for (var i=0; i<this.coords.length; ++i) {
1121
+ if (i !== shape.sequentialIndex) {
1122
+ this.path(
1123
+ 'b lw % r % % % % s % f %',
1124
+ properties.highlightLinewidth,
1125
+ this.coords[i][0] - 0.5, this.coords[i][1] - 0.5, this.coords[i][2] + 1, this.coords[i][3] + 1,
1126
+ properties.highlightStroke,
1127
+ properties.highlightFill
1128
+ );
1129
+ }
1130
+ }
1131
+
1132
+ } else {
1133
+
1134
+ var last = shape.index === this.coords.length - 1;
1135
+
1136
+ this.path('lw %', properties.highlightLinewidth);
1137
+
1138
+ this.drawCurvedBar({
1139
+ x: shape.x - 0.5,
1140
+ y: shape.y - 0.5,
1141
+ width: shape.width + 1,
1142
+ height: shape.height + 1,
1143
+ stroke: properties.highlightStroke,
1144
+ fill: properties.highlightFill
1145
+ });
1146
+
1147
+ // Reset the linewidth
1148
+ this.path('lw %', 1);
1149
+ }
1150
+ }
1151
+ };
1152
+
1153
+
1154
+
1155
+
1156
+
1157
+
1158
+
1159
+
1160
+ //
1161
+ // The getObjectByXY() worker method. Don't call this call:
1162
+ //
1163
+ // RGraph.ObjectRegistry.getObjectByXY(e)
1164
+ //
1165
+ // @param object e The event object
1166
+ //
1167
+ this.getObjectByXY = function (e)
1168
+ {
1169
+ var mouseXY = RGraph.getMouseXY(e);
1170
+
1171
+ if (
1172
+ mouseXY[0] > this.marginLeft
1173
+ && mouseXY[0] < (this.canvas.width - this.marginRight)
1174
+ && mouseXY[1] >= this.marginTop
1175
+ && mouseXY[1] <= (this.canvas.height - this.marginBottom)
1176
+ ) {
1177
+
1178
+ return this;
1179
+ }
1180
+ };
1181
+
1182
+
1183
+
1184
+
1185
+
1186
+
1187
+
1188
+
1189
+ //
1190
+ // This function allows the VProgress to be adjustable.
1191
+ // UPDATE: Not any more
1192
+ //
1193
+ this.allowAdjusting = function () {return;};
1194
+
1195
+
1196
+
1197
+
1198
+
1199
+
1200
+
1201
+
1202
+ //
1203
+ // This method handles the adjusting calculation for when the mouse
1204
+ // is moved
1205
+ //
1206
+ // @param object e The event object
1207
+ //
1208
+ this.adjusting_mousemove = function (e)
1209
+ {
1210
+ //
1211
+ // Handle adjusting for the HProgress
1212
+ //
1213
+ if (properties.adjustable && RGraph.Registry.get('adjusting') && RGraph.Registry.get('adjusting').uid == this.uid) {
1214
+
1215
+ var mouseXY = RGraph.getMouseXY(e);
1216
+ var value = this.getValue(e);
1217
+
1218
+ if (typeof value === 'number') {
1219
+
1220
+ // Fire the onadjust event
1221
+ RGraph.fireCustomEvent(this, 'onadjust');
1222
+
1223
+ this.value = Number(value.toFixed(properties.scaleDecimals));
1224
+ RGraph.redrawCanvas(this.canvas);
1225
+ }
1226
+ }
1227
+ };
1228
+
1229
+
1230
+
1231
+
1232
+
1233
+
1234
+
1235
+
1236
+ //
1237
+ // Draws labelsSpecific
1238
+ //
1239
+ this.drawSpecificLabels = function ()
1240
+ {
1241
+ var labels = properties.labelsSpecific;
1242
+
1243
+ if (labels) {
1244
+
1245
+ var halign = properties.labelsPosition === 'right' ? 'left' : 'right';
1246
+ var step = this.height / (labels.length - 1);
1247
+
1248
+ this.context.beginPath();
1249
+
1250
+ this.context.fillStyle = properties.textColor;
1251
+
1252
+ for (var i=0; i<labels.length; ++i) {
1253
+
1254
+ var textConf = RGraph.getTextConf({
1255
+ object: this,
1256
+ prefix: 'labels'
1257
+ });
1258
+
1259
+ RGraph.text({
1260
+
1261
+ object: this,
1262
+
1263
+ font: textConf.font,
1264
+ size: textConf.size,
1265
+ color: textConf.color,
1266
+ bold: textConf.bold,
1267
+ italic: textConf.italic,
1268
+
1269
+ x: properties.labelsPosition == 'right' ? this.canvas.width - this.marginRight + 7 : this.marginLeft - 7,
1270
+ y: (this.height + this.marginTop) - (step * i),
1271
+ text: labels[i],
1272
+ valign: 'center',
1273
+ halign: halign,
1274
+ tag: 'labels.specific',
1275
+ cssClass: properties.labelsSpecific
1276
+ ? RGraph.getLabelsCSSClassName({
1277
+ object: this,
1278
+ name: 'labelsClass',
1279
+ index: i
1280
+ })
1281
+ : ''
1282
+ });
1283
+ }
1284
+ this.context.fill();
1285
+ }
1286
+ };
1287
+
1288
+
1289
+
1290
+
1291
+
1292
+
1293
+
1294
+
1295
+ //
1296
+ // This function returns the appropriate Y coordinate for the given Y value
1297
+ //
1298
+ // @param int value The Y value you want the coordinate for
1299
+ // @returm int The coordinate
1300
+ //
1301
+ this.getYCoord = function (value)
1302
+ {
1303
+ if (value > this.max || value < this.min) {
1304
+ return null;
1305
+ }
1306
+
1307
+ var barHeight = this.canvas.height - properties.marginTop - properties.marginBottom;
1308
+ var coord = ((value - this.min) / (this.max - this.min)) * barHeight;
1309
+ coord = this.canvas.height - coord - properties.marginBottom;
1310
+
1311
+ return coord;
1312
+ };
1313
+
1314
+
1315
+
1316
+
1317
+
1318
+
1319
+
1320
+
1321
+ //
1322
+ // This returns true/false as to whether the cursor is over the chart area.
1323
+ // The cursor does not necessarily have to be over the bar itself.
1324
+ //
1325
+ this.overChartArea = function (e)
1326
+ {
1327
+ var mouseXY = RGraph.getMouseXY(e);
1328
+ var mouseX = mouseXY[0];
1329
+ var mouseY = mouseXY[1];
1330
+
1331
+ if ( mouseX >= this.marginLeft
1332
+ && mouseX <= (this.canvas.width - this.marginRight)
1333
+ && mouseY >= this.marginTop
1334
+ && mouseY <= (this.canvas.height - this.marginBottom)
1335
+ ) {
1336
+
1337
+ return true;
1338
+ }
1339
+
1340
+ return false;
1341
+ };
1342
+
1343
+
1344
+
1345
+
1346
+
1347
+
1348
+
1349
+
1350
+ //
1351
+ //
1352
+ //
1353
+ this.parseColors = function ()
1354
+ {
1355
+ // Save the original colors so that they can be restored when the canvas is reset
1356
+ if (this.original_colors.length === 0) {
1357
+ this.original_colors.colors = RGraph.arrayClone(properties.colors);
1358
+ this.original_colors.tickmarksInnerColor = RGraph.arrayClone(properties.tickmarksInnerColor);
1359
+ this.original_colors.tickmarksOuterColor = RGraph.arrayClone(properties.tickmarksOuterColor);
1360
+ this.original_colors.colorsStrokeInner = RGraph.arrayClone(properties.colorsStrokeInner);
1361
+ this.original_colors.colorsStrokeOuter = RGraph.arrayClone(properties.colorsStrokeOuter);
1362
+ this.original_colors.highlightFill = RGraph.arrayClone(properties.highlightFill);
1363
+ this.original_colors.highlightStroke = RGraph.arrayClone(properties.highlightStroke);
1364
+ this.original_colors.backgroundColor = RGraph.arrayClone(properties.backgroundColor);
1365
+ }
1366
+
1367
+ var colors = properties.colors;
1368
+
1369
+ for (var i=0,len=colors.length; i<len; ++i) {
1370
+ colors[i] = this.parseSingleColorForGradient(colors[i]);
1371
+ }
1372
+
1373
+ properties.tickmarksInnerColor = this.parseSingleColorForGradient(properties.tickmarksInnerColor);
1374
+ properties.tickmarksOuterColor = this.parseSingleColorForGradient(properties.tickmarksOuterColor);
1375
+ properties.colorsStrokeInner = this.parseSingleColorForGradient(properties.colorsStrokeInner);
1376
+ properties.colorsStrokeOuter = this.parseSingleColorForGradient(properties.colorsStrokeOuter);
1377
+ properties.highlightFill = this.parseSingleColorForGradient(properties.highlightFill);
1378
+ properties.highlightStroke = this.parseSingleColorForGradient(properties.highlightStroke);
1379
+ properties.backgroundColor = this.parseSingleColorForGradient(properties.backgroundColor);
1380
+ };
1381
+
1382
+
1383
+
1384
+
1385
+
1386
+
1387
+
1388
+
1389
+ //
1390
+ // Use this function to reset the object to the post-constructor state. Eg reset colors if
1391
+ // need be etc
1392
+ //
1393
+ this.reset = function ()
1394
+ {
1395
+ };
1396
+
1397
+
1398
+
1399
+
1400
+
1401
+
1402
+
1403
+
1404
+ //
1405
+ // This parses a single color value
1406
+ //
1407
+ this.parseSingleColorForGradient = function (color)
1408
+ {
1409
+ if (!color || typeof color != 'string') {
1410
+ return color;
1411
+ }
1412
+
1413
+ if (color.match(/^gradient\((.*)\)$/i)) {
1414
+
1415
+ // Allow for JSON gradients
1416
+ if (color.match(/^gradient\(({.*})\)$/i)) {
1417
+ return RGraph.parseJSONGradient({
1418
+ object: this,
1419
+ def: RegExp.$1
1420
+ });
1421
+ }
1422
+
1423
+ var parts = RegExp.$1.split(':');
1424
+
1425
+ // Create the gradient
1426
+ var grad = this.context.createLinearGradient(0, this.canvas.height - properties.marginBottom, 0, properties.marginTop);
1427
+
1428
+ var diff = 1 / (parts.length - 1);
1429
+
1430
+ grad.addColorStop(0, RGraph.trim(parts[0]));
1431
+
1432
+ for (var j=1,len=parts.length; j<len; ++j) {
1433
+ grad.addColorStop(j * diff, RGraph.trim(parts[j]));
1434
+ }
1435
+
1436
+ return grad ? grad : color;
1437
+ }
1438
+
1439
+ return grad ? grad : color;
1440
+ };
1441
+
1442
+
1443
+
1444
+
1445
+
1446
+
1447
+
1448
+
1449
+ //
1450
+ // Draws the bevel effect
1451
+ //
1452
+ this.drawBevel = function ()
1453
+ {
1454
+ // In case of multiple segments - this adds up all the lengths
1455
+ for (var i=0,height=0; i<this.coords.length; ++i) {
1456
+ height += this.coords[i][3];
1457
+ }
1458
+
1459
+ this.context.save();
1460
+ this.context.beginPath();
1461
+ this.context.rect(
1462
+ this.coords[0][0],
1463
+ this.coords[this.coords.length - 1][1] - 1,
1464
+ this.coords[0][2],
1465
+ height
1466
+ );
1467
+ this.context.clip();
1468
+
1469
+ this.context.save();
1470
+ // Draw a path to clip to
1471
+ this.context.beginPath();
1472
+ this.drawCurvedBar({
1473
+ x: this.coords[0][0],
1474
+ y: this.coords[this.coords.length - 1][1] - 1,
1475
+ width: this.coords[0][2],
1476
+ height: height
1477
+ });
1478
+ this.context.clip();
1479
+
1480
+ // Now draw the rect with a shadow
1481
+ this.context.beginPath();
1482
+
1483
+ this.context.shadowColor = 'black';
1484
+ this.context.shadowOffsetX = 0;
1485
+ this.context.shadowOffsetY = 0;
1486
+ this.context.shadowBlur = 15;
1487
+
1488
+ this.context.lineWidth = 2;
1489
+
1490
+ this.drawCurvedBar({
1491
+ x: this.coords[0][0] - 1,
1492
+ y: this.coords[this.coords.length - 1][1] - 1,
1493
+ width: this.coords[0][2] + 2,
1494
+ height: height + 2 + 100
1495
+ });
1496
+
1497
+ this.context.stroke();
1498
+
1499
+ this.context.restore();
1500
+ this.context.restore();
1501
+ };
1502
+
1503
+
1504
+
1505
+
1506
+
1507
+
1508
+
1509
+
1510
+ //
1511
+ // This function handles highlighting an entire data-series for the interactive
1512
+ // key
1513
+ //
1514
+ // @param int index The index of the data series to be highlighted
1515
+ //
1516
+ this.interactiveKeyHighlight = function (index)
1517
+ {
1518
+ var coords = this.coords[index];
1519
+
1520
+ this.context.beginPath();
1521
+
1522
+ this.context.strokeStyle = properties.keyInteractiveHighlightChartStroke;
1523
+ this.context.lineWidth = 2;
1524
+ this.context.fillStyle = properties.keyInteractiveHighlightChartFill;
1525
+
1526
+ this.context.rect(coords[0] - 0.5, coords[1] - 0.5, coords[2] + 1, coords[3] + 1);
1527
+ this.context.fill();
1528
+ this.context.stroke();
1529
+
1530
+ // Reset the linewidth
1531
+ this.context.lineWidth = 1;
1532
+ };
1533
+
1534
+
1535
+
1536
+
1537
+
1538
+
1539
+
1540
+
1541
+ //
1542
+ // Using a function to add events makes it easier to facilitate method chaining
1543
+ //
1544
+ // @param string type The type of even to add
1545
+ // @param function func
1546
+ //
1547
+ this.on = function (type, func)
1548
+ {
1549
+ if (type.substr(0,2) !== 'on') {
1550
+ type = 'on' + type;
1551
+ }
1552
+
1553
+ if (typeof this[type] !== 'function') {
1554
+ this[type] = func;
1555
+ } else {
1556
+ RGraph.addCustomEventListener(this, type, func);
1557
+ }
1558
+
1559
+ return this;
1560
+ };
1561
+
1562
+
1563
+
1564
+
1565
+
1566
+
1567
+
1568
+
1569
+ //
1570
+ // Draws a bar with a curved end
1571
+ //
1572
+ // DOESN'T DRAW A CURVED BAR ANY MORE - JUST A REGULAR SQUARE ENDED BAR
1573
+ //
1574
+ // @param object opt The coords and colours
1575
+ //
1576
+ this.drawCurvedBar = function (opt)
1577
+ {
1578
+ this.path(
1579
+ 'b r % % % %',
1580
+ opt.x,opt.y,opt.width,opt.height
1581
+ );
1582
+
1583
+ if (opt.stroke) {
1584
+ this.context.strokeStyle = opt.stroke;
1585
+ this.context.stroke();
1586
+ }
1587
+
1588
+ if (opt.fill) {
1589
+ this.context.fillStyle = opt.fill;
1590
+ this.context.fill();
1591
+ }
1592
+ };
1593
+
1594
+
1595
+
1596
+
1597
+
1598
+
1599
+
1600
+
1601
+ //
1602
+ // This function runs once only
1603
+ // (put at the end of the file (before any effects))
1604
+ //
1605
+ this.firstDrawFunc = function ()
1606
+ {
1607
+ };
1608
+
1609
+
1610
+
1611
+
1612
+
1613
+
1614
+
1615
+
1616
+ //
1617
+ // Used in chaining. Runs a function there and then - not waiting for
1618
+ // the events to fire (eg the onbeforedraw event)
1619
+ //
1620
+ // @param function func The function to execute
1621
+ //
1622
+ this.exec = function (func)
1623
+ {
1624
+ func(this);
1625
+
1626
+ return this;
1627
+ };
1628
+
1629
+
1630
+
1631
+
1632
+
1633
+
1634
+
1635
+
1636
+ //
1637
+ // HProgress Grow effect (which is also the VPogress Grow effect)
1638
+ //
1639
+ // @param object obj The chart object
1640
+ //
1641
+ this.grow = function ()
1642
+ {
1643
+ // Cancel any stop request if one is pending
1644
+ this.cancelStopAnimation();
1645
+
1646
+
1647
+ var obj = this;
1648
+ var canvas = this.canvas;
1649
+ var context = this.context;
1650
+ var initial_value = this.currentValue;
1651
+ var opt = arguments[0] || {};
1652
+ var numFrames = opt.frames || 30;
1653
+ var frame = 0
1654
+ var callback = arguments[1] || function () {};
1655
+
1656
+ if (typeof this.value === 'object') {
1657
+
1658
+ if (RGraph.isNull(this.currentValue)) {
1659
+ this.currentValue = [];
1660
+ for (var i=0; i<this.value.length; ++i) {
1661
+ this.currentValue[i] = 0;
1662
+ }
1663
+ }
1664
+
1665
+ var diff = [];
1666
+ var increment = [];
1667
+
1668
+ for (var i=0; i<this.value.length; ++i) {
1669
+ diff[i] = this.value[i] - Number(this.currentValue[i]);
1670
+ increment[i] = diff[i] / numFrames;
1671
+ }
1672
+
1673
+ if (initial_value == null) {
1674
+ initial_value = [];
1675
+ for (var i=0; i< this.value.length; ++i) {
1676
+ initial_value[i] = 0;
1677
+ }
1678
+ }
1679
+
1680
+ } else {
1681
+
1682
+ var diff = this.value - Number(this.currentValue);
1683
+ var increment = diff / numFrames;
1684
+ }
1685
+
1686
+
1687
+
1688
+
1689
+
1690
+
1691
+ function iterator ()
1692
+ {
1693
+ if (obj.stopAnimationRequested) {
1694
+
1695
+ // Reset the flag
1696
+ obj.stopAnimationRequested = false;
1697
+
1698
+ return;
1699
+ }
1700
+
1701
+
1702
+ frame++;
1703
+
1704
+ if (frame <= numFrames) {
1705
+
1706
+ if (typeof obj.value == 'object') {
1707
+ obj.value = [];
1708
+ for (var i=0; i<initial_value.length; ++i) {
1709
+ obj.value[i] = initial_value[i] + (increment[i] * frame);
1710
+ }
1711
+ } else {
1712
+ obj.value = initial_value + (increment * frame);
1713
+ }
1714
+
1715
+ RGraph.clear(obj.canvas);
1716
+ RGraph.redrawCanvas(obj.canvas);
1717
+
1718
+ RGraph.Effects.updateCanvas(iterator);
1719
+ } else {
1720
+ callback();
1721
+ }
1722
+ }
1723
+
1724
+ iterator();
1725
+
1726
+ return this;
1727
+ };
1728
+
1729
+
1730
+
1731
+
1732
+
1733
+
1734
+
1735
+
1736
+ //
1737
+ // Couple of functions that allow you to control the
1738
+ // animation effect
1739
+ //
1740
+ this.stopAnimation = function ()
1741
+ {
1742
+ this.stopAnimationRequested = true;
1743
+ };
1744
+
1745
+ this.cancelStopAnimation = function ()
1746
+ {
1747
+ this.stopAnimationRequested = false;
1748
+ };
1749
+
1750
+
1751
+
1752
+
1753
+
1754
+
1755
+
1756
+
1757
+ //
1758
+ // A worker function that handles Bar chart specific tooltip substitutions
1759
+ //
1760
+ this.tooltipSubstitutions = function (opt)
1761
+ {
1762
+ return {
1763
+ index: opt.index,
1764
+ dataset: 0,
1765
+ sequentialIndex: opt.index,
1766
+ value: typeof this.value === 'object' ? this.value[opt.index] : this.value,
1767
+ values: typeof this.value === 'object' ? [this.value[opt.index]] : [this.value]
1768
+ };
1769
+ };
1770
+
1771
+
1772
+
1773
+
1774
+
1775
+
1776
+
1777
+
1778
+ //
1779
+ // A worker function that returns the correct color/label/value
1780
+ //
1781
+ // @param object specific The indexes that are applicable
1782
+ // @param number index The appropriate index
1783
+ //
1784
+ this.tooltipsFormattedCustom = function (specific, index)
1785
+ {
1786
+ var color = (properties.tooltipsFormattedKeyColors && properties.tooltipsFormattedKeyColors[specific.index]) ? properties.tooltipsFormattedKeyColors[specific.index] : properties.colors[specific.index];
1787
+ var label = (properties.tooltipsFormattedKeyLabels && properties.tooltipsFormattedKeyLabels[specific.index]) ? properties.tooltipsFormattedKeyLabels[specific.index] : '';
1788
+
1789
+ return {
1790
+ label: label,
1791
+ color: color
1792
+ };
1793
+ };
1794
+
1795
+
1796
+
1797
+
1798
+
1799
+
1800
+
1801
+
1802
+ //
1803
+ // This allows for static tooltip positioning
1804
+ //
1805
+ this.positionTooltipStatic = function (args)
1806
+ {
1807
+ var obj = args.object,
1808
+ e = args.event,
1809
+ tooltip = args.tooltip,
1810
+ index = args.index,
1811
+ canvasXY = RGraph.getCanvasXY(obj.canvas)
1812
+ coords = this.coords[args.index];
1813
+
1814
+ // Position the tooltip in the X direction
1815
+ args.tooltip.style.left = (
1816
+ canvasXY[0] // The X coordinate of the canvas
1817
+ + coords[0] // The X coordinate of the bar on the chart
1818
+ - (tooltip.offsetWidth / 2) // Subtract half of the tooltip width
1819
+ + (coords[2] / 2) // Add half of the bar width
1820
+ + obj.properties.tooltipsOffsetx // Add any user defined offset
1821
+ ) + 'px';
1822
+
1823
+ args.tooltip.style.top = (
1824
+ canvasXY[1] // The Y coordinate of the canvas
1825
+ + coords[1] // The Y coordinate of the bar on the chart
1826
+ - tooltip.offsetHeight // The height of the tooltip
1827
+ - 10 // An arbitrary amount
1828
+ + obj.properties.tooltipsOffsety // Add any user defined offset
1829
+ ) + 'px';
1830
+
1831
+
1832
+
1833
+ // If the top of the tooltip is off the top of the page
1834
+ // then move the tooltip down
1835
+ if(parseFloat(args.tooltip.style.top) < 0) {
1836
+ args.tooltip.style.top = parseFloat(args.tooltip.style.top) + 20 + 'px';
1837
+ }
1838
+ };
1839
+
1840
+
1841
+
1842
+
1843
+
1844
+
1845
+
1846
+
1847
+ //
1848
+ // This returns the relevant value for the formatted key
1849
+ // macro %{value}. THIS VALUE SHOULD NOT BE FORMATTED.
1850
+ //
1851
+ // @param number index The index in the dataset to get
1852
+ // the value for
1853
+ //
1854
+ this.getKeyValue = function (index)
1855
+ {
1856
+ return RGraph.isArray(this.properties.keyFormattedValueSpecific) && RGraph.isNumber(this.properties.keyFormattedValueSpecific[index])
1857
+ ? this.properties.keyFormattedValueSpecific[index]
1858
+ : (RGraph.isArray(this.value) ? this.value[index] : this.value);
1859
+ };
1860
+
1861
+
1862
+
1863
+
1864
+
1865
+
1866
+
1867
+
1868
+ //
1869
+ // Returns how many data-points there should be when a string
1870
+ // based key property has been specified. For example, this:
1871
+ //
1872
+ // key: '%{property:_labels[%{index}]} %{value_formatted}'
1873
+ //
1874
+ // ...depending on how many bits of data ther is might get
1875
+ // turned into this:
1876
+ //
1877
+ // key: [
1878
+ // '%{property:_labels[%{index}]} %{value_formatted}',
1879
+ // '%{property:_labels[%{index}]} %{value_formatted}',
1880
+ // '%{property:_labels[%{index}]} %{value_formatted}',
1881
+ // '%{property:_labels[%{index}]} %{value_formatted}',
1882
+ // '%{property:_labels[%{index}]} %{value_formatted}',
1883
+ // ]
1884
+ //
1885
+ // ... ie in that case there would be 4 data-points so the
1886
+ // template is repeated 4 times.
1887
+ //
1888
+ this.getKeyNumDatapoints = function ()
1889
+ {
1890
+ return this.value.length;
1891
+ };
1892
+
1893
+
1894
+
1895
+
1896
+
1897
+
1898
+
1899
+ //
1900
+ // The chart is now always registered
1901
+ //
1902
+ RGraph.register(this);
1903
+
1904
+
1905
+
1906
+
1907
+
1908
+
1909
+
1910
+
1911
+ //
1912
+ // This is the 'end' of the constructor so if the first argument
1913
+ // contains configuration data - handle that.
1914
+ //
1915
+ RGraph.parseObjectStyleConfig(this, conf.options);
1916
+ };