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,90 +1,1774 @@
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.Gauge=function(conf)
3
- {if(typeof conf==='object'&&typeof conf.id==='string'){var id=conf.id,canvas=document.getElementById(id),min=conf.min,max=conf.max,value=conf.value,parseConfObjectForOptions=true;}else{var id=conf,canvas=document.getElementById(id),min=arguments[1],max=arguments[2],value=arguments[3];}
4
- this.id=id;this.canvas=canvas;this.context=this.canvas.getContext?this.canvas.getContext("2d",{alpha:(typeof id==='object'&&id.alpha===false)?false:true}):null;this.canvas.__object__=this;this.type='gauge';this.min=RGraph.stringsToNumbers(min);this.max=RGraph.stringsToNumbers(max);this.value=RGraph.stringsToNumbers(value);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.valueOriginal=this.value;if(typeof(this.value)=='object'){for(var i=0;i<this.value.length;++i){if(this.value[i]>this.max)this.value[i]=max;if(this.value[i]<this.min)this.value[i]=min;}}else{if(this.value>this.max)this.value=max;if(this.value<this.min)this.value=min;}
5
- this.properties={'chart.angles.start':null,'chart.angles.end':null,'chart.centerx':null,'chart.centery':null,'chart.radius':null,'chart.margin.left':15,'chart.margin.right':15,'chart.margin.top':15,'chart.margin.bottom':15,'chart.border.width':10,'chart.text.font':'Arial, Verdana, sans-serif','chart.text.size':12,'chart.text.color':'#666','chart.text.bold':false,'chart.text.italic':false,'chart.text.accessible':true,'chart.text.accessible.overflow':'visible','chart.text.accessible.pointerevents':false,'chart.title.top':'','chart.title.top.font':null,'chart.title.top.size':null,'chart.title.top.color':null,'chart.title.top.bold':null,'chart.title.top.italic':null,'chart.title.top.pos':null,'chart.title.bottom':'','chart.title.bottom.font':null,'chart.title.bottom.size':null,'chart.title.bottom.color':null,'chart.title.bottom.bold':null,'chart.title.bottom.italic':null,'chart.title.bottom.pos':null,'chart.background.color':'white','chart.background.gradient':false,'chart.scale.decimals':0,'chart.scale.point':'.','chart.scale.thousand':',','chart.scale.units.pre':'','chart.scale.units.post':'','chart.scale.point':'.','chart.scale.thousand':',','chart.labels.count':5,'chart.labels.centered':false,'chart.labels.offset.radius':0,'chart.labels.offset.angle':0,'chart.labels.specific':null,'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.value':false,'chart.labels.value.y.pos':0.5,'chart.labels.value.units.pre':'','chart.labels.value.units.post':'','chart.labels.value.bounding':true,'chart.labels.value.bounding.fill':'white','chart.labels.value.bounding.stroke':'black','chart.labels.value.font':null,'chart.labels.value.size':null,'chart.labels.value.color':null,'chart.labels.value.italic':null,'chart.labels.value.bold':null,'chart.labels.value.decimals':null,'chart.colors.red.start':0.9*this.max,'chart.colors.red.color':'#DC3912','chart.colors.red.width':10,'chart.colors.yellow.color':'#FF9900','chart.colors.yellow.width':10,'chart.colors.green.end':0.7*this.max,'chart.colors.green.color':'rgba(0,0,0,0)','chart.colors.green.width':10,'chart.colors.ranges':null,'chart.needle.size':null,'chart.needle.tail':false,'chart.needle.colors':['#D5604D','red','green','yellow'],'chart.needle.type':'triangle','chart.needle.width':7,'chart.border.outer':'#ccc','chart.border.inner':'#f1f1f1','chart.border.outline':'black','chart.border.gradient':false,'chart.centerpin.color':'blue','chart.centerpin.radius':null,'chart.tickmarks.small':25,'chart.tickmarks.small.color':'black','chart.tickmarks.medium':0,'chart.tickmarks.medium.color':'black','chart.tickmarks.large':5,'chart.tickmarks.large.color':'black','chart.adjustable':false,'chart.shadow':true,'chart.shadow.color':'gray','chart.shadow.offsetx':0,'chart.shadow.offsety':0,'chart.shadow.blur':15,'chart.clearto':'rgba(0,0,0,0)'}
6
- if(!this.canvas.__rgraph_aa_translated__){this.context.translate(0.5,0.5);this.canvas.__rgraph_aa_translated__=true;}
7
- var RG=RGraph,ca=this.canvas,co=ca.getContext('2d'),prop=this.properties,pa2=RG.path2,win=window,doc=document,ma=Math
8
- if(RG.Effects&&typeof RG.Effects.decorate==='function'){RG.Effects.decorate(this);}
9
- this.set=this.Set=function(name)
10
- {var value=typeof arguments[1]==='undefined'?null:arguments[1];if(arguments.length===1&&typeof name==='object'){RG.parseObjectStyleConfig(this,name);return this;}
11
- if(name.substr(0,6)!='chart.'){name='chart.'+name;}
12
- while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
13
- if(name=='chart.title')name='chart.title.top';if(name=='chart.title.font')name='chart.title.top.font';if(name=='chart.title.size')name='chart.title.top.size';if(name=='chart.title.color')name='chart.title.top.color';if(name=='chart.title.bold')name='chart.title.top.bold';if(name=='chart.title.italic')name='chart.title.top.italic';if(name=='chart.needle.color'){name='chart.needle.colors';}
14
- if(name=='chart.labels.offset'){name='chart.labels.offset.radius';}
15
- prop[name]=value;return this;};this.get=this.Get=function(name)
16
- {if(name.substr(0,6)!='chart.'){name='chart.'+name;}
17
- while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
18
- if(name=='chart.needle.color'){name='chart.needle.colors';}
19
- if(name=='chart.labels.offset'){name='chart.labels.offset.radius';}
20
- return prop[name];};this.draw=this.Draw=function()
21
- {RG.fireCustomEvent(this,'onbeforedraw');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.centerx=((ca.width-this.marginLeft-this.marginRight)/2)+this.marginLeft;this.centery=((ca.height-this.marginTop-this.marginBottom)/2)+this.marginTop;this.radius=Math.min(((ca.width-this.marginLeft-this.marginRight)/2),((ca.height-this.marginTop-this.marginBottom)/2));this.startAngle=prop['chart.angles.start']?prop['chart.angles.start']:(RG.HALFPI/3)+RG.HALFPI;this.endAngle=prop['chart.angles.end']?prop['chart.angles.end']:RG.TWOPI+RG.HALFPI-(RG.HALFPI/3);this.coordsText=[];if(typeof(prop['chart.centerx'])=='number')this.centerx=prop['chart.centerx'];if(typeof(prop['chart.centery'])=='number')this.centery=prop['chart.centery'];if(typeof(prop['chart.radius'])=='number')this.radius=prop['chart.radius'];if(!this.colorsParsed){this.parseColors();this.colorsParsed=true;}
22
- this.centerpinRadius=0.16*this.radius;if(typeof(prop['chart.centerpin.radius'])=='number'){this.centerpinRadius=prop['chart.centerpin.radius'];}
23
- if(prop['chart.contextmenu']){RG.ShowContext(this);}
24
- this.drawBackGround();this.drawGradient();this.drawColorBands();this.drawSmallTickmarks();this.drawMediumTickmarks();this.drawBigTickmarks();this.drawLabels();this.drawTopTitle();this.drawBottomTitle();if(typeof(this.value)=='object'){for(var i=0;i<this.value.length;++i){this.drawNeedle(this.value[i],prop['chart.needle.colors'][i],i);}}else{this.drawNeedle(this.value,prop['chart.needle.colors'][0],0);}
25
- this.DrawCenterpin();if(prop['chart.resizable']){RG.AllowResizing(this);}
26
- RG.installEventListeners(this);if(this.firstDraw){this.firstDraw=false;RG.fireCustomEvent(this,'onfirstdraw');this.firstDrawFunc();}
27
- RG.fireCustomEvent(this,'ondraw');return this;};this.exec=function(func)
28
- {func(this);return this;};this.drawBackGround=this.DrawBackGround=function()
29
- {if(prop['chart.shadow']){RG.setShadow(this,prop['chart.shadow.color'],prop['chart.shadow.offsetx'],prop['chart.shadow.offsety'],prop['chart.shadow.blur']);}
30
- co.beginPath();co.fillStyle=prop['chart.background.color'];co.arc(this.centerx,this.centery,this.radius,0,RG.TWOPI,0);co.fill();RG.noShadow(this);var grad=co.createRadialGradient(this.centerx+50,this.centery-50,0,this.centerx+50,this.centery-50,150);grad.addColorStop(0,'#eee');grad.addColorStop(1,'white');var borderWidth=prop['chart.border.width'];co.beginPath();co.fillStyle=prop['chart.background.color'];co.arc(this.centerx,this.centery,this.radius,0,RG.TWOPI,0);co.fill();co.beginPath();co.fillStyle=prop['chart.border.outer'];co.arc(this.centerx,this.centery,this.radius,0,RG.TWOPI,0);co.fill();co.beginPath();co.fillStyle=prop['chart.border.inner'];co.arc(this.centerx,this.centery,this.radius-borderWidth,0,RG.TWOPI,0);co.fill();co.beginPath();co.fillStyle=prop['chart.background.color'];co.arc(this.centerx,this.centery,this.radius-borderWidth-4,0,RG.TWOPI,0);co.fill();co.beginPath();co.fillStyle=prop['chart.background.color'];co.arc(this.centerx,this.centery,this.radius-borderWidth-4,0,RG.TWOPI,0);co.fill();if(prop['chart.background.gradient']){co.beginPath();co.fillStyle=RG.RadialGradient(this,this.centerx-this.radius,this.centery-this.radius,0,this.centerx-(this.radius/2),this.centery-(this.radius/2),this.radius,'rgba(255,255,255,0.2)','rgba(0,0,0,0.1)');co.arc(this.centerx,this.centery,this.radius-borderWidth-4,0,RG.TWOPI,0);co.fill();}
31
- co.beginPath();co.strokeStyle=prop['chart.border.outline'];co.arc(this.centerx,this.centery,this.radius,0,RG.TWOPI,0);co.stroke();};this.drawSmallTickmarks=this.DrawSmallTickmarks=function()
32
- {var numTicks=prop['chart.tickmarks.small'];co.lineWidth=1;for(var i=0;i<=numTicks;++i){co.beginPath();co.strokeStyle=prop['chart.tickmarks.small.color'];var a=(((this.endAngle-this.startAngle)/numTicks)*i)+this.startAngle;co.arc(this.centerx,this.centery,this.radius-prop['chart.border.width']-10,a,a+0.00001,0);co.arc(this.centerx,this.centery,this.radius-prop['chart.border.width']-10-5,a,a+0.00001,0);co.stroke();}};this.drawMediumTickmarks=this.DrawMediumTickmarks=function()
33
- {if(prop['chart.tickmarks.medium']){var numTicks=prop['chart.tickmarks.medium'];co.lineWidth=3;co.lineCap='round';co.strokeStyle=prop['chart.tickmarks.medium.color'];for(var i=0;i<=numTicks;++i){co.beginPath();var a=(((this.endAngle-this.startAngle)/numTicks)*i)+this.startAngle+(((this.endAngle-this.startAngle)/(2*numTicks)));if(a>this.startAngle&&a<this.endAngle){co.arc(this.centerx,this.centery,this.radius-prop['chart.border.width']-10,a,a+0.00001,0);co.arc(this.centerx,this.centery,this.radius-prop['chart.border.width']-10-6,a,a+0.00001,0);}
34
- co.stroke();}}};this.drawLargeTickmarks=this.drawBigTickmarks=this.DrawBigTickmarks=function()
35
- {var numTicks=prop['chart.tickmarks.large'];co.lineWidth=3;co.lineCap='round';for(var i=0;i<=numTicks;++i){co.beginPath();co.strokeStyle=prop['chart.tickmarks.large.color'];var a=(((this.endAngle-this.startAngle)/numTicks)*i)+this.startAngle;co.arc(this.centerx,this.centery,this.radius-prop['chart.border.width']-10,a,a+0.00001,0);co.arc(this.centerx,this.centery,this.radius-prop['chart.border.width']-10-10,a,a+0.00001,0);co.stroke();}};this.drawCenterpin=this.DrawCenterpin=function()
36
- {var offset=6;var grad=co.createRadialGradient(this.centerx+offset,this.centery-offset,0,this.centerx+offset,this.centery-offset,25);grad.addColorStop(0,'#ddf');grad.addColorStop(1,prop['chart.centerpin.color']);co.beginPath();co.fillStyle=grad;co.arc(this.centerx,this.centery,this.centerpinRadius,0,RG.TWOPI,0);co.fill();};this.drawLabels=this.DrawLabels=function()
37
- {co.fillStyle=prop['chart.text.color'];var font=prop['chart.text.font'],size=prop['chart.text.size'],num=prop['chart.labels.specific']?(prop['chart.labels.specific'].length-1):prop['chart.labels.count'],offsetx=prop['chart.labels.offsetx'],offsety=prop['chart.labels.offsety'],offseta=prop['chart.labels.offset.angle'];var textConf=RG.getTextConf({object:this,prefix:'chart.labels'});co.beginPath();if(num){for(var i=0;i<=num;++i){var hyp=(this.radius-25-prop['chart.border.width'])-prop['chart.labels.offset.radius'];var a=(this.endAngle-this.startAngle)/num
38
- a=this.startAngle+(i*a);a-=RG.HALFPI;a+=offseta;var x=this.centerx-(ma.sin(a)*hyp);var y=this.centery+(ma.cos(a)*hyp);var hAlign=x>this.centerx?'right':'left';var vAlign=y>this.centery?'bottom':'top';if(a==RG.HALFPI){vAlign='center';}else if(a==RG.PI){hAlign='center';}else if(a==(RG.HALFPI+RG.PI)){vAlign='center';}
39
- if(prop['chart.labels.centered']){hAlign='center';vAlign='center';}
40
- var value=(((this.max-this.min)*(i/num))+this.min);RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:x+offsetx,y:y+offsety,text:prop['chart.labels.specific']?prop['chart.labels.specific'][i]:RG.numberFormat({object:this,number:value.toFixed(prop['chart.scale.decimals']),unitspre:prop['chart.scale.units.pre'],unitspost:prop['chart.scale.units.post'],point:prop['chart.scale.point'],thousand:prop['chart.scale.thousand']}),halign:hAlign,valign:vAlign,tag:prop['chart.labels.specific']?'labels.specific':'labels'});}}
41
- co.fill();if(prop['chart.labels.value']){var x=this.centerx,y=this.centery+(prop['chart.labels.value.y.pos']*this.radius),units_pre=typeof(prop['chart.labels.value.units.pre'])=='string'?prop['chart.labels.value.units.pre']:prop['chart.scale.units.pre'],units_post=typeof(prop['chart.labels.value.units.post'])=='string'?prop['chart.labels.value.units.post']:prop['chart.scale.units.post'],bounding=prop['chart.labels.value.bounding'],boundingFill=prop['chart.labels.value.bounding.fill'],boundingStroke=prop['chart.labels.value.bounding.stroke'],decimals=typeof prop['chart.labels.value.decimals']==='number'?prop['chart.labels.value.decimals']:prop['chart.scale.decimals'];var textConf=RG.getTextConf({object:this,prefix:'chart.labels.value'});if(typeof this.value==='number'){var value=parseFloat(prop['chart.value.text.actual']?this.valueOriginal:this.value);var text=RG.numberFormat({object:this,number:value.toFixed(decimals),unitspre:units_pre,unitspost:units_post});}else{var text=[];for(var i=0;i<this.value.length;++i){text[i]=RG.numberFormat({object:this,number:this.value[i].toFixed(decimals),unitspre:units_pre,unitspost:units_post});}
42
- text=text.join(', ');}
43
- RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:x,y:y,text:text,halign:'center',valign:'center',bounding:bounding,'bounding.fill':boundingFill,'bounding.stroke':boundingStroke,tag:'value.text'});}};this.drawTopTitle=this.DrawTopTitle=function()
44
- {var x=this.centerx;var y=this.centery-25;if(typeof(prop['chart.title.top.pos'])=='number'){y=this.centery-(this.radius*prop['chart.title.top.pos']);}
45
- var textConf=RG.getTextConf({object:this,prefix:'chart.title.top'});if(prop['chart.title.top']){co.fillStyle=prop['chart.title.top.color'];RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:x,y:y,text:String(prop['chart.title.top']),halign:'center',valign:'bottom',tag:'title.top'});}};this.drawBottomTitle=this.DrawBottomTitle=function()
46
- {var x=this.centerx;var y=this.centery+this.centerpinRadius+10;if(typeof(prop['chart.title.bottom.pos'])=='number'){y=this.centery+(this.radius*prop['chart.title.bottom.pos']);}
47
- if(prop['chart.title.bottom']){co.fillStyle=prop['chart.title.bottom.color'];var textConf=RG.getTextConf({object:this,prefix:'chart.title.bottom'});RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:x,y:y,text:String(prop['chart.title.bottom']),halign:'center',valign:'top',tag:'title.bottom'});}};this.drawNeedle=this.DrawNeedle=function(value,color,index)
48
- {var type=prop['chart.needle.type'];co.lineWidth=0.5;co.strokeStyle='gray';co.fillStyle=color;var angle=(this.endAngle-this.startAngle)*((value-this.min)/(this.max-this.min));angle+=this.startAngle;if(typeof(prop['chart.needle.size'])=='object'&&prop['chart.needle.size']&&typeof(prop['chart.needle.size'][index])=='number'){var size=prop['chart.needle.size'][index];}else if(typeof(prop['chart.needle.size'])=='number'){var size=prop['chart.needle.size'];}else{var size=this.radius-25-prop['chart.border.width'];}
49
- if(type=='line'){co.beginPath();co.lineWidth=prop['chart.needle.width'];co.strokeStyle=color;co.arc(this.centerx,this.centery,size,angle,angle+0.0001,false);co.lineTo(this.centerx,this.centery);if(prop['chart.needle.tail']){co.arc(this.centerx,this.centery,this.radius*0.2,angle+RG.PI,angle+0.00001+RG.PI,false);}
50
- co.lineTo(this.centerx,this.centery);co.stroke();}else{co.beginPath();co.arc(this.centerx,this.centery,size,angle,angle+0.00001,false);co.arc(this.centerx,this.centery,this.centerpinRadius*0.5,angle+RG.HALFPI,angle+0.00001+RG.HALFPI,false);if(prop['chart.needle.tail']){co.arc(this.centerx,this.centery,this.radius*0.2,angle+RG.PI,angle+0.00001+RG.PI,false);}
51
- co.arc(this.centerx,this.centery,this.centerpinRadius*0.5,angle-RG.HALFPI,angle-0.00001-RG.HALFPI,false);co.stroke();co.fill();this.angle=angle;}};this.drawColorBands=this.DrawColorBands=function()
52
- {if(RG.isArray(prop['chart.colors.ranges'])){var ranges=prop['chart.colors.ranges'];for(var i=0;i<ranges.length;++i){co.fillStyle=ranges[i][2];co.lineWidth=0;co.beginPath();co.arc(this.centerx,this.centery,this.radius-10-prop['chart.border.width'],(((ranges[i][0]-this.min)/(this.max-this.min))*(this.endAngle-this.startAngle))+this.startAngle,(((ranges[i][1]-this.min)/(this.max-this.min))*(this.endAngle-this.startAngle))+this.startAngle,false);co.arc(this.centerx,this.centery,this.radius-10-prop['chart.border.width']-(typeof ranges[i][3]==='number'?ranges[i][3]:10),(((ranges[i][1]-this.min)/(this.max-this.min))*(this.endAngle-this.startAngle))+this.startAngle,(((ranges[i][0]-this.min)/(this.max-this.min))*(this.endAngle-this.startAngle))+this.startAngle,true);co.closePath();co.fill();}
53
- return;}
54
- co.strokeStyle=prop['chart.colors.green.color'];co.fillStyle=prop['chart.colors.green.color'];var greenStart=this.startAngle;var greenEnd=this.startAngle+(this.endAngle-this.startAngle)*((prop['chart.colors.green.end']-this.min)/(this.max-this.min))
55
- co.beginPath();co.arc(this.centerx,this.centery,this.radius-10-prop['chart.border.width'],greenStart,greenEnd,false);co.arc(this.centerx,this.centery,this.radius-(10+prop['chart.colors.green.width'])-prop['chart.border.width'],greenEnd,greenStart,true);co.fill();co.strokeStyle=prop['chart.colors.yellow.color'];co.fillStyle=prop['chart.colors.yellow.color'];var yellowStart=greenEnd;var yellowEnd=this.startAngle+(this.endAngle-this.startAngle)*((prop['chart.colors.red.start']-this.min)/(this.max-this.min))
56
- co.beginPath();co.arc(this.centerx,this.centery,this.radius-10-prop['chart.border.width'],yellowStart,yellowEnd,false);co.arc(this.centerx,this.centery,this.radius-(10+prop['chart.colors.yellow.width'])-prop['chart.border.width'],yellowEnd,yellowStart,true);co.fill();co.strokeStyle=prop['chart.colors.red.color'];co.fillStyle=prop['chart.colors.red.color'];var redStart=yellowEnd;var redEnd=this.startAngle+(this.endAngle-this.startAngle)*((this.max-this.min)/(this.max-this.min))
57
- co.beginPath();co.arc(this.centerx,this.centery,this.radius-10-prop['chart.border.width'],redStart,redEnd,false);co.arc(this.centerx,this.centery,this.radius-(10+prop['chart.colors.red.width'])-prop['chart.border.width'],redEnd,redStart,true);co.fill();};this.getShape=function(e){};this.getValue=function(e)
58
- {var mouseXY=RG.getMouseXY(e);var mouseX=mouseXY[0];var mouseY=mouseXY[1];var angle=RG.getAngleByXY(this.centerx,this.centery,mouseX,mouseY);if(angle>=0&&angle<=RG.HALFPI){angle+=RG.TWOPI;}
59
- var value=((angle-this.startAngle)/(this.endAngle-this.startAngle))*(this.max-this.min);value=value+this.min;if(value<this.min){value=this.min}
60
- if(value>this.max){value=this.max}
61
- return value;};this.getObjectByXY=function(e)
62
- {var mouseXY=RGraph.getMouseXY(e);if(mouseXY[0]>(this.centerx-this.radius)&&mouseXY[0]<(this.centerx+this.radius)&&mouseXY[1]>(this.centery-this.radius)&&mouseXY[1]<(this.centery+this.radius)&&RG.getHypLength(this.centerx,this.centery,mouseXY[0],mouseXY[1])<=this.radius){return this;}};this.drawGradient=this.DrawGradient=function()
63
- {if(prop['chart.border.gradient']){co.beginPath();var grad=co.createRadialGradient(this.centerx,this.centery,this.radius,this.centerx,this.centery,this.radius-15);grad.addColorStop(0,'gray');grad.addColorStop(1,'white');co.fillStyle=grad;co.arc(this.centerx,this.centery,this.radius,0,RG.TWOPI,false)
64
- co.arc(this.centerx,this.centery,this.radius-15,RG.TWOPI,0,true)
65
- co.fill();}};this.adjusting_mousemove=this.Adjusting_mousemove=function(e)
66
- {if(prop['chart.adjustable']&&RG.Registry.get('chart.adjusting')&&RG.Registry.get('chart.adjusting').uid==this.uid){this.value=this.getValue(e);RG.redrawCanvas(this.canvas);RG.fireCustomEvent(this,'onadjust');}};this.getAngle=function(value)
67
- {if(value>this.max||value<this.min){return null;}
68
- var angle=(((value-this.min)/(this.max-this.min))*(this.endAngle-this.startAngle))+this.startAngle;return angle;};this.parseColors=function()
69
- {if(this.original_colors.length===0){this.original_colors['chart.background.color']=RG.arrayClone(prop['chart.background.color']);this.original_colors['chart.colors.red.color']=RG.arrayClone(prop['chart.colors.red.color']);this.original_colors['chart.colors.yellow.color']=RG.arrayClone(prop['chart.colors.yellow.color']);this.original_colors['chart.colors.green.color']=RG.arrayClone(prop['chart.colors.green.color']);this.original_colors['chart.border.inner']=RG.arrayClone(prop['chart.border.inner']);this.original_colors['chart.border.outer']=RG.arrayClone(prop['chart.border.outer']);this.original_colors['chart.colors.ranges']=RG.arrayClone(prop['chart.colors.ranges']);this.original_colors['chart.needle.colors']=RG.arrayClone(prop['chart.needle.colors']);}
70
- prop['chart.background.color']=this.parseSingleColorForGradient(prop['chart.background.color']);prop['chart.colors.red.color']=this.parseSingleColorForGradient(prop['chart.colors.red.color']);prop['chart.colors.yellow.color']=this.parseSingleColorForGradient(prop['chart.colors.yellow.color']);prop['chart.colors.green.color']=this.parseSingleColorForGradient(prop['chart.colors.green.color']);prop['chart.border.inner']=this.parseSingleColorForGradient(prop['chart.border.inner']);prop['chart.border.outer']=this.parseSingleColorForGradient(prop['chart.border.outer']);if(prop['chart.colors.ranges']){var ranges=prop['chart.colors.ranges'];for(var i=0;i<ranges.length;++i){ranges[i][2]=this.parseSingleColorForGradient(ranges[i][2],this.radius-30);}}
71
- if(prop['chart.needle.colors']){var colors=prop['chart.needle.colors'];for(var i=0;i<colors.length;++i){colors[i]=this.parseSingleColorForGradient(colors[i]);}}};this.reset=function()
72
- {};this.parseSingleColorForGradient=function(color)
73
- {var radiusStart=arguments[1]||0;if(!color||typeof(color)!='string'){return color;}
74
- if(color.match(/^gradient\((.*)\)$/i)){if(color.match(/^gradient\(({.*})\)$/i)){return RGraph.parseJSONGradient({object:this,def:RegExp.$1});}
75
- var parts=RegExp.$1.split(':');var grad=co.createRadialGradient(this.centerx,this.centery,radiusStart,this.centerx,this.centery,this.radius);var diff=1/(parts.length-1);grad.addColorStop(0,RG.trim(parts[0]));for(var j=1;j<parts.length;++j){grad.addColorStop(j*diff,RG.trim(parts[j]));}}
76
- return grad?grad:color;};this.on=function(type,func)
77
- {if(type.substr(0,2)!=='on'){type='on'+type;}
78
- if(typeof this[type]!=='function'){this[type]=func;}else{RG.addCustomEventListener(this,type,func);}
79
- return this;};this.firstDrawFunc=function()
80
- {};this.grow=function()
81
- {var obj=this,opt=arguments[0]?arguments[0]:{},callback=arguments[1]?arguments[1]:function(){},frames=opt.frames||30,frame=0;if(typeof this.value==='string'){this.value=RG.stringsToNumbers(this.value);}
82
- if(typeof this.value==='number'){var origValue=Number(this.currentValue);if(this.currentValue==null){this.currentValue=this.min;origValue=this.min;}
83
- var newValue=this.value,diff=newValue-origValue;var iterator=function()
84
- {obj.value=((frame/frames)*diff)+origValue;if(obj.value>obj.max)obj.value=obj.max;if(obj.value<obj.min)obj.value=obj.min;RG.redrawCanvas(obj.canvas);if(frame++<frames){RG.Effects.updateCanvas(iterator);}else{callback(obj);}};iterator();}else{if(this.currentValue==null){this.currentValue=[];for(var i=0;i<this.value.length;++i){this.currentValue[i]=this.min;}
85
- origValue=RG.arrayClone(this.currentValue);}
86
- var origValue=RG.arrayClone(this.currentValue);var newValue=RG.arrayClone(this.value);var diff=[];for(var i=0,len=newValue.length;i<len;++i){diff[i]=newValue[i]-Number(this.currentValue[i]);}
87
- var iterator=function()
88
- {frame++;for(var i=0,len=obj.value.length;i<len;++i){obj.value[i]=((frame/frames)*diff[i])+origValue[i];if(obj.value[i]>obj.max)obj.value[i]=obj.max;if(obj.value[i]<obj.min)obj.value[i]=obj.min;}
89
- RG.redrawCanvas(obj.canvas);if(frame<frames){RG.Effects.updateCanvas(iterator);}else{callback(obj);}};iterator();}
90
- 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
+ // The line chart constructor
16
+ //
17
+ RGraph.Gauge = function (conf)
18
+ {
19
+ var id = conf.id,
20
+ canvas = document.getElementById(id),
21
+ min = conf.min,
22
+ max = conf.max,
23
+ value = conf.value;
24
+
25
+ this.id = id;
26
+ this.canvas = canvas;
27
+ this.context = this.canvas.getContext ? this.canvas.getContext("2d", {alpha: (typeof id === 'object' && id.alpha === false) ? false : true}) : null;
28
+ this.canvas.__object__ = this;
29
+ this.type = 'gauge';
30
+ this.min = RGraph.stringsToNumbers(min);
31
+ this.max = RGraph.stringsToNumbers(max);
32
+ this.value = RGraph.stringsToNumbers(value);
33
+ this.isRGraph = true;
34
+ this.isrgraph = true;
35
+ this.rgraph = true;
36
+ this.currentValue = null;
37
+ this.uid = RGraph.createUID();
38
+ this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.createUID();
39
+ this.colorsParsed = false;
40
+ this.coordsText = [];
41
+ this.original_colors = [];
42
+ this.firstDraw = true; // After the first draw this will be false
43
+ this.stopAnimationRequested = false;// Used to control the animations
44
+
45
+
46
+
47
+ //
48
+ // Range checking.
49
+ //
50
+ // As of 4.63, it now saves the original value
51
+ //
52
+ this.valueOriginal = this.value;
53
+
54
+ if (typeof this.value === 'object') {
55
+ for (var i=0; i<this.value.length; ++i) {
56
+ if (this.value[i] > this.max) this.value[i] = max;
57
+ if (this.value[i] < this.min) this.value[i] = min;
58
+ }
59
+ } else {
60
+ if (this.value > this.max) this.value = max;
61
+ if (this.value < this.min) this.value = min;
62
+ }
63
+
64
+
65
+ // Coniguration properties
66
+ this.properties =
67
+ {
68
+ anglesStart: null,
69
+ anglesEnd: null,
70
+
71
+ centerx: null,
72
+ centery: null,
73
+ radius: null,
74
+
75
+ marginLeft: 35,
76
+ marginRight: 35,
77
+ marginTop: 35,
78
+ marginBottom: 35,
79
+
80
+ borderWidth: 10,
81
+
82
+ textFont: 'Arial, Verdana, sans-serif',
83
+ textSize: 12,
84
+ textColor: '#666',
85
+ textBold: false,
86
+ textItalic: false,
87
+ textAccessible: false,
88
+ textAccessibleOverflow: 'visible',
89
+ textAccessiblePointerevents: false,
90
+ text: null,
91
+
92
+ titleTop: '',
93
+ titleTopFont: null,
94
+ titleTopSize: 16,
95
+ titleTopColor: 'black',
96
+ titleTopBold: true,
97
+ titleTopItalic: null,
98
+ titleTopPos: null,
99
+ titleTopOffsetx: 0,
100
+ titleTopOffsety: 0,
101
+
102
+ titleTopSubtitle: null,
103
+ titleTopSubtitleFont: null,
104
+ titleTopSubtitleSize: null,
105
+ titleTopSubtitleColor: '#666',
106
+ titleTopSubtitleBold: null,
107
+ titleTopSubtitleItalic: null,
108
+ titleTopSubtitlePos: null,
109
+ titleTopSubtitleOffsetx: 0,
110
+ titleTopSubtitleOffsety: 0,
111
+
112
+ titleBottom: '',
113
+ titleBottomFont: null,
114
+ titleBottomSize: null,
115
+ titleBottomColor: null,
116
+ titleBottomBold: null,
117
+ titleBottomItalic: null,
118
+ titleBottomPos: null,
119
+ titleBottomOffsetx: 0,
120
+ titleBottomOffsety: 0,
121
+
122
+ backgroundColor: 'white',
123
+ backgroundGradient: false,
124
+
125
+ scaleDecimals: 0,
126
+ scalePoint: '.',
127
+ scaleThousand: ',',
128
+ scaleUnitsPre: '',
129
+ scaleUnitsPost: '',
130
+ scalePoint: '.',
131
+ scaleThousand: ',',
132
+
133
+ labelsCount: 5,
134
+ labelsCentered: false,
135
+ labelsOffsetRadius: 0,
136
+ labelsOffsetAngle: 0,
137
+ labelsSpecific: null,
138
+ labelsSpecificFormattedDecimals: 0,
139
+ labelsSpecificFormattedPoint: '.',
140
+ labelsSpecificFormattedThousand: ',',
141
+ labelsSpecificFormattedUnitsPre: '',
142
+ labelsSpecificFormattedUnitsPost: '',
143
+ labelsOffsetx: 0,
144
+ labelsOffsety: 0,
145
+ labelsFont: null,
146
+ labelsSize: null,
147
+ labelsColor: null,
148
+ labelsBold: null,
149
+ labelsItalic: null,
150
+ labelsValue: false,
151
+ labelsValueYPos: 0.5,
152
+ labelsValueUnitsPre: '',
153
+ labelsValueUnitsPost: '',
154
+ labelsValueBounding: true,
155
+ labelsValueBoundingFill: 'white',
156
+ labelsValueBoundingStroke: 'black',
157
+ labelsValueFont: null,
158
+ labelsValueSize: null,
159
+ labelsValueColor: null,
160
+ labelsValueItalic: null,
161
+ labelsValueBold: null,
162
+ labelsValueDecimals: null,
163
+ labelsValuePoint: null,
164
+ labelsValueThousand: null,
165
+
166
+
167
+ colorsRedStart: 0.9 * this.max,
168
+ colorsRedColor: '#DC3912',
169
+ colorsRedWidth: 10,
170
+ colorsYellowColor: '#FF9900',
171
+ colorsYellowWidth: 10,
172
+ colorsGreenEnd: 0.7 * this.max,
173
+ colorsGreenColor: 'rgba(0,0,0,0)',
174
+ colorsGreenWidth: 10,
175
+ colorsRanges: null,
176
+
177
+ needleSize: null,
178
+ needleTail: false,
179
+ needleColors: ['#D5604D', 'red', 'green', 'yellow'],
180
+ needleType: 'triangle',
181
+ needleWidth: 7,
182
+
183
+ borderOuter: '#ccc',
184
+ borderInner: '#f1f1f1',
185
+ borderOutline: 'black',
186
+ borderGradient: false,
187
+
188
+ centerpinColor: 'blue',
189
+ centerpinRadius: null,
190
+
191
+ tickmarksSmall: 25,
192
+ tickmarksSmallColor: 'black',
193
+ tickmarksMedium: 0,
194
+ tickmarksMediumColor: 'black',
195
+ tickmarksLarge: 5,
196
+ tickmarksLargeColor: 'black',
197
+
198
+ adjustable: false,
199
+
200
+ annotatable: false,
201
+ annotatableLinewidth: 1,
202
+ annotatableColor: 'black',
203
+
204
+ shadow: true,
205
+ shadowColor: 'gray',
206
+ shadowOffsetx: 0,
207
+ shadowOffsety: 0,
208
+ shadowBlur: 15,
209
+
210
+ clearto: 'rgba(0,0,0,0)'
211
+ }
212
+
213
+
214
+
215
+
216
+ // Easy access to properties and the path function
217
+ var properties = this.properties;
218
+ this.path = RGraph.pathObjectFunction;
219
+
220
+
221
+
222
+ //
223
+ // "Decorate" the object with the generic effects if the effects library has been included
224
+ //
225
+ if (RGraph.Effects && typeof RGraph.Effects.decorate === 'function') {
226
+ RGraph.Effects.decorate(this);
227
+ }
228
+
229
+
230
+
231
+ // Add the responsive method. This method resides in the common file.
232
+ this.responsive = RGraph.responsive;
233
+
234
+
235
+
236
+
237
+ //
238
+ // An all encompassing accessor
239
+ //
240
+ // @param string name The name of the property
241
+ // @param mixed value The value of the property
242
+ //
243
+ this.set = function (name)
244
+ {
245
+ var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
246
+
247
+ // the number of arguments is only one and it's an
248
+ // object - parse it for configuration data and return.
249
+ if (arguments.length === 1 && typeof arguments[0] === 'object') {
250
+ for (i in arguments[0]) {
251
+ if (typeof i === 'string') {
252
+ this.set(i, arguments[0][i]);
253
+ }
254
+ }
255
+
256
+ return this;
257
+ }
258
+
259
+ properties[name] = value;
260
+
261
+ return this;
262
+ };
263
+
264
+
265
+
266
+
267
+
268
+
269
+
270
+
271
+ //
272
+ // An all encompassing accessor
273
+ //
274
+ // @param string name The name of the property
275
+ //
276
+ this.get = function (name)
277
+ {
278
+ return properties[name];
279
+ };
280
+
281
+
282
+
283
+
284
+
285
+
286
+
287
+
288
+ //
289
+ // The function you call to draw the line chart
290
+ //
291
+ // @param bool An optional bool used internally to ditinguish whether the
292
+ // line chart is being called by the bar chart
293
+ //
294
+ this.draw = function ()
295
+ {
296
+ //
297
+ // Fire the onbeforedraw event
298
+ //
299
+ RGraph.fireCustomEvent(this, 'onbeforedraw');
300
+
301
+
302
+
303
+ // Translate half a pixel for antialiasing purposes - but only if it hasn't been
304
+ // done already
305
+ //
306
+ // MUST be the first thing done!
307
+ //
308
+ if (!this.canvas.__rgraph_aa_translated__) {
309
+ this.context.translate(0.5,0.5);
310
+
311
+ this.canvas.__rgraph_aa_translated__ = true;
312
+ }
313
+
314
+ //
315
+ // Store the value (for animation primarily
316
+ //
317
+ this.currentValue = this.value;
318
+
319
+
320
+
321
+ //
322
+ // Make the margins easy to access
323
+ //
324
+ this.marginLeft = properties.marginLeft;
325
+ this.marginRight = properties.marginRight;
326
+ this.marginTop = properties.marginTop;
327
+ this.marginBottom = properties.marginBottom;
328
+
329
+ this.centerx = ((this.canvas.width - this.marginLeft - this.marginRight) / 2) + this.marginLeft;
330
+ this.centery = ((this.canvas.height - this.marginTop - this.marginBottom) / 2) + this.marginTop;
331
+ this.radius = Math.min(
332
+ ((this.canvas.width - this.marginLeft - this.marginRight) / 2),
333
+ ((this.canvas.height - this.marginTop - this.marginBottom) / 2)
334
+ );
335
+ this.startAngle = properties.anglesStart ? properties.anglesStart : (RGraph.HALFPI / 3) + RGraph.HALFPI;
336
+ this.endAngle = properties.anglesEnd ? properties.anglesEnd : RGraph.TWOPI + RGraph.HALFPI - (RGraph.HALFPI / 3);
337
+
338
+
339
+ //
340
+ // Reset this so it doesn't keep growing
341
+ //
342
+ this.coordsText = [];
343
+
344
+
345
+
346
+ //
347
+ // You can now override the positioning and radius if you so wish.
348
+ //
349
+ if (typeof properties.centerx == 'number') this.centerx = properties.centerx;
350
+ if (typeof properties.centery == 'number') this.centery = properties.centery;
351
+ if (typeof properties.radius == 'number') this.radius = properties.radius;
352
+
353
+ //
354
+ // Parse the colors. This allows for simple gradient syntax
355
+ //
356
+ if (!this.colorsParsed) {
357
+ this.parseColors();
358
+
359
+ // Don't want to do this again
360
+ this.colorsParsed = true;
361
+ }
362
+
363
+
364
+ // This has to be in the constructor
365
+ this.centerpinRadius = 0.16 * this.radius;
366
+
367
+ if (typeof properties.centerpinRadius == 'number') {
368
+ this.centerpinRadius = properties.centerpinRadius;
369
+ }
370
+
371
+
372
+
373
+ //
374
+ // Setup the context menu if required
375
+ //
376
+ if (properties.contextmenu) {
377
+ RGraph.showContext(this);
378
+ }
379
+
380
+
381
+
382
+ // DRAW THE CHART HERE
383
+ this.drawBackGround();
384
+ this.drawGradient();
385
+ this.drawColorBands();
386
+ this.drawSmallTickmarks();
387
+ this.drawMediumTickmarks();
388
+ this.drawLargeTickmarks();
389
+ this.drawLabels();
390
+ this.drawTopTitle();
391
+ this.drawBottomTitle();
392
+
393
+ if (typeof this.value == 'object') {
394
+ for (var i=0; i<this.value.length; ++i) {
395
+ this.drawNeedle(this.value[i], properties.needleColors[i], i);
396
+ }
397
+ } else {
398
+ this.drawNeedle(this.value, properties.needleColors[0], 0);
399
+ }
400
+
401
+ this.drawCenterpin();
402
+
403
+
404
+
405
+
406
+ //
407
+ // Add custom text thats specified
408
+ //
409
+ RGraph.addCustomText(this);
410
+
411
+
412
+
413
+
414
+
415
+
416
+
417
+
418
+ //
419
+ // This installs the event listeners
420
+ //
421
+ RGraph.installEventListeners(this);
422
+
423
+
424
+ //
425
+ // Fire the onfirstdraw event
426
+ //
427
+ if (this.firstDraw) {
428
+ this.firstDraw = false;
429
+ RGraph.fireCustomEvent(this, 'onfirstdraw');
430
+ this.firstDrawFunc();
431
+ }
432
+
433
+
434
+
435
+
436
+ //
437
+ // Fire the RGraph draw event
438
+ //
439
+ RGraph.fireCustomEvent(this, 'ondraw');
440
+
441
+
442
+
443
+
444
+
445
+
446
+
447
+
448
+
449
+
450
+ //
451
+ // Install any inline responsive configuration. This
452
+ // should be last in the draw function - even after
453
+ // the draw events.
454
+ //
455
+ RGraph.installInlineResponsive(this);
456
+
457
+
458
+
459
+
460
+
461
+
462
+
463
+
464
+
465
+
466
+
467
+
468
+ return this;
469
+ };
470
+
471
+
472
+
473
+
474
+
475
+
476
+
477
+
478
+ //
479
+ // Used in chaining. Runs a function there and then - not waiting for
480
+ // the events to fire (eg the onbeforedraw event)
481
+ //
482
+ // @param function func The function to execute
483
+ //
484
+ this.exec = function (func)
485
+ {
486
+ func(this);
487
+
488
+ return this;
489
+ };
490
+
491
+
492
+
493
+
494
+
495
+
496
+
497
+
498
+ //
499
+ // Draw the background
500
+ //
501
+ this.drawBackGround = function ()
502
+ {
503
+ // Shadow //////////////////////////////////////////////
504
+ if (properties.shadow) {
505
+ RGraph.setShadow(
506
+ this,
507
+ properties.shadowColor,
508
+ properties.shadowOffsetx,
509
+ properties.shadowOffsety,
510
+ properties.shadowBlur
511
+ );
512
+ }
513
+
514
+ this.context.beginPath();
515
+ this.context.fillStyle = properties.backgroundColor;
516
+ //this.context.moveTo(this.centerx, this.centery)
517
+ this.context.arc(this.centerx, this.centery, this.radius, 0, RGraph.TWOPI, 0);
518
+ this.context.fill();
519
+
520
+ // Turn off the shadow
521
+ RGraph.noShadow(this);
522
+ // Shadow //////////////////////////////////////////////
523
+
524
+
525
+ var grad = this.context.createRadialGradient(this.centerx + 50, this.centery - 50, 0, this.centerx + 50, this.centery - 50, 150);
526
+ grad.addColorStop(0, '#eee');
527
+ grad.addColorStop(1, 'white');
528
+
529
+ var borderWidth = properties.borderWidth;
530
+
531
+ this.context.beginPath();
532
+ this.context.fillStyle = properties.backgroundColor;
533
+ this.context.arc(this.centerx, this.centery, this.radius, 0, RGraph.TWOPI, 0);
534
+ this.context.fill();
535
+
536
+ //
537
+ // Draw the gray circle
538
+ //
539
+ this.context.beginPath();
540
+ this.context.fillStyle = properties.borderOuter;
541
+ this.context.arc(this.centerx, this.centery, this.radius, 0, RGraph.TWOPI, 0);
542
+ this.context.fill();
543
+
544
+ //
545
+ // Draw the light gray inner border
546
+ //
547
+ this.context.beginPath();
548
+ this.context.fillStyle = properties.borderInner;
549
+ this.context.arc(this.centerx, this.centery, this.radius - borderWidth, 0, RGraph.TWOPI, 0);
550
+ this.context.fill();
551
+
552
+
553
+
554
+ // Draw the white circle inner border
555
+ this.context.beginPath();
556
+ this.context.fillStyle = properties.backgroundColor;
557
+ this.context.arc(this.centerx, this.centery, this.radius - borderWidth - 4, 0, RGraph.TWOPI, 0);
558
+ this.context.fill();
559
+
560
+
561
+
562
+ // Draw the circle background. Can be any colour now.
563
+ this.context.beginPath();
564
+ this.context.fillStyle = properties.backgroundColor;
565
+ this.context.arc(this.centerx, this.centery, this.radius - borderWidth - 4, 0, RGraph.TWOPI, 0);
566
+ this.context.fill();
567
+
568
+ if (properties.backgroundGradient) {
569
+
570
+ // Draw a partially transparent gradient that sits on top of the background
571
+ this.context.beginPath();
572
+ this.context.fillStyle = RGraph.radialGradient({
573
+ object: this,
574
+ x1: this.centerx - this.radius,
575
+ y1: this.centery - this.radius,
576
+ r1: 0,
577
+ x2: this.centerx - (this.radius / 2),
578
+ y2: this.centery - (this.radius / 2),
579
+ r2: this.radius,
580
+ colors: [
581
+ 'rgba(255,255,255,0.2)',
582
+ 'rgba(0,0,0,0.1)'
583
+ ]
584
+ });
585
+ this.context.arc(this.centerx, this.centery, this.radius - borderWidth - 4, 0, RGraph.TWOPI, 0);
586
+ this.context.fill();
587
+ }
588
+
589
+
590
+
591
+ // Draw a black border around the chart
592
+ this.context.beginPath();
593
+ this.context.strokeStyle = properties.borderOutline;
594
+ this.context.arc(this.centerx, this.centery, this.radius, 0, RGraph.TWOPI, 0);
595
+ this.context.stroke();
596
+ };
597
+
598
+
599
+
600
+
601
+
602
+
603
+
604
+
605
+ //
606
+ // This function draws the smaller tickmarks
607
+ //
608
+ this.drawSmallTickmarks = function ()
609
+ {
610
+ var numTicks = properties.tickmarksSmall;
611
+ this.context.lineWidth = 1;
612
+
613
+ for (var i=0; i<=numTicks; ++i) {
614
+ this.context.beginPath();
615
+ this.context.strokeStyle = properties.tickmarksSmallColor;
616
+ var a = (((this.endAngle - this.startAngle) / numTicks) * i) + this.startAngle;
617
+ this.context.arc(this.centerx, this.centery, this.radius - properties.borderWidth - 10, a, a + 0.00001, 0);
618
+ this.context.arc(this.centerx, this.centery, this.radius - properties.borderWidth - 10 - 5, a, a + 0.00001, 0);
619
+ this.context.stroke();
620
+ }
621
+ };
622
+
623
+
624
+
625
+
626
+
627
+
628
+
629
+
630
+ //
631
+ // This function draws the medium sized tickmarks
632
+ //
633
+ this.drawMediumTickmarks = function ()
634
+ {
635
+ if (properties.tickmarksMedium) {
636
+
637
+ var numTicks = properties.tickmarksMedium;
638
+ this.context.lineWidth = 3;
639
+ this.context.lineCap = 'round';
640
+ this.context.strokeStyle = properties.tickmarksMediumColor;
641
+
642
+ for (var i=0; i<=numTicks; ++i) {
643
+ this.context.beginPath();
644
+ var a = (((this.endAngle - this.startAngle) / numTicks) * i) + this.startAngle + (((this.endAngle - this.startAngle) / (2 * numTicks)));
645
+
646
+ if (a > this.startAngle && a< this.endAngle) {
647
+ this.context.arc(this.centerx, this.centery, this.radius - properties.borderWidth - 10, a, a + 0.00001, 0);
648
+ this.context.arc(this.centerx, this.centery, this.radius - properties.borderWidth - 10 - 6, a, a + 0.00001, 0);
649
+ }
650
+ this.context.stroke();
651
+ }
652
+ }
653
+ };
654
+
655
+
656
+
657
+
658
+
659
+
660
+
661
+
662
+ //
663
+ // This function draws the large, bold tickmarks
664
+ //
665
+ this.drawLargeTickmarks = function ()
666
+ {
667
+ var numTicks = properties.tickmarksLarge;
668
+
669
+ this.context.lineWidth = 3;
670
+ this.context.lineCap = 'round';
671
+
672
+ for (var i=0; i<=numTicks; ++i) {
673
+ this.context.beginPath();
674
+ this.context.strokeStyle = properties.tickmarksLargeColor;
675
+ var a = (((this.endAngle - this.startAngle) / numTicks) * i) + this.startAngle;
676
+ this.context.arc(this.centerx, this.centery, this.radius - properties.borderWidth - 10, a, a + 0.00001, 0);
677
+ this.context.arc(this.centerx, this.centery, this.radius - properties.borderWidth - 10 - 10, a, a + 0.00001, 0);
678
+ this.context.stroke();
679
+ }
680
+ };
681
+
682
+
683
+
684
+
685
+
686
+
687
+
688
+
689
+ //
690
+ // This function draws the centerpin
691
+ //
692
+ this.drawCenterpin = function ()
693
+ {
694
+ var offset = 6;
695
+
696
+ var grad = this.context.createRadialGradient(this.centerx + offset, this.centery - offset, 0, this.centerx + offset, this.centery - offset, 25);
697
+ grad.addColorStop(0, '#ddf');
698
+ grad.addColorStop(1, properties.centerpinColor);
699
+
700
+ this.context.beginPath();
701
+ this.context.fillStyle = grad;
702
+ this.context.arc(this.centerx, this.centery, this.centerpinRadius, 0, RGraph.TWOPI, 0);
703
+ this.context.fill();
704
+ };
705
+
706
+
707
+
708
+
709
+
710
+
711
+
712
+
713
+ //
714
+ // This function draws the labels
715
+ //
716
+ this.drawLabels = function ()
717
+ {
718
+ this.context.fillStyle = properties.textColor;
719
+
720
+ var font = properties.textFont,
721
+ size = properties.textSize,
722
+ num = properties.labelsSpecific ? (properties.labelsSpecific.length - 1) : properties.labelsCount,
723
+ offsetx = properties.labelsOffsetx,
724
+ offsety = properties.labelsOffsety,
725
+ offseta = properties.labelsOffsetAngle;
726
+
727
+ var textConf = RGraph.getTextConf({
728
+ object: this,
729
+ prefix: 'labels'
730
+ });
731
+
732
+
733
+ //
734
+ // String based labels
735
+ //
736
+ if (typeof properties.labelsSpecific === 'string') {
737
+
738
+ // Reset the number of labels to show
739
+ num = properties.labelsCount - 1;
740
+
741
+ if (properties.labelsSpecific && properties.labelsSpecific.length) {
742
+ //
743
+ // If the labelsSpecific option is a string then turn it
744
+ // into an array.
745
+ if (typeof properties.labelsSpecific === 'string' ) {
746
+ properties.labelsSpecific = RGraph.arrayPad({
747
+ array: [],
748
+ length: properties.labelsCount,
749
+ value: properties.labelsSpecific
750
+ });
751
+ }
752
+
753
+
754
+ //
755
+ // Label substitution
756
+ //
757
+ for (var i=0; i<properties.labelsSpecific.length; ++i) {
758
+ properties.labelsSpecific[i] = RGraph.labelSubstitution({
759
+ object: this,
760
+ text: properties.labelsSpecific[i],
761
+ index: i,
762
+ value: this.value,
763
+ decimals: properties.labelsSpecificFormattedDecimals || 0,
764
+ unitsPre: properties.labelsSpecificFormattedUnitsPre || '',
765
+ unitsPost: properties.labelsSpecificFormattedUnitsPost || '',
766
+ thousand: properties.labelsSpecificFormattedThousand || ',',
767
+ point: properties.labelsSpecificFormattedPoint || '.'
768
+ });
769
+ }
770
+ }
771
+ }
772
+
773
+
774
+
775
+
776
+ this.context.beginPath();
777
+ if (num) {
778
+ for (var i=0; i<=num; ++i) {
779
+ var hyp = (this.radius - 25 - properties.borderWidth) - properties.labelsOffsetRadius;
780
+ var a = (this.endAngle - this.startAngle) / num
781
+ a = this.startAngle + (i * a);
782
+ a -= RGraph.HALFPI;
783
+ a += offseta;
784
+
785
+
786
+ var x = this.centerx - (Math.sin(a) * hyp);
787
+ var y = this.centery + (Math.cos(a) * hyp);
788
+
789
+ var hAlign = x > this.centerx ? 'right' : 'left';
790
+ var vAlign = y > this.centery ? 'bottom' : 'top';
791
+
792
+ // This handles the label alignment when the label is on a PI/HALFPI boundary
793
+ if (a == RGraph.HALFPI) {
794
+ vAlign = 'center';
795
+ } else if (a == RGraph.PI) {
796
+ hAlign = 'center';
797
+ } else if (a == (RGraph.HALFPI + RGraph.PI) ) {
798
+ vAlign = 'center';
799
+ }
800
+
801
+ //
802
+ // Can now force center alignment
803
+ //
804
+ if (properties.labelsCentered) {
805
+ hAlign = 'center';
806
+ vAlign = 'center';
807
+ }
808
+
809
+ var value = (((this.max - this.min) * (i / num)) + this.min);
810
+
811
+
812
+ RGraph.text({
813
+
814
+ object: this,
815
+
816
+ font: textConf.font,
817
+ size: textConf.size,
818
+ color: textConf.color,
819
+ bold: textConf.bold,
820
+ italic: textConf.italic,
821
+
822
+ x: x + offsetx,
823
+ y: y + offsety,
824
+ text: properties.labelsSpecific ? properties.labelsSpecific[i] : RGraph.numberFormat({
825
+ object: this,
826
+ number: value.toFixed(properties.scaleDecimals),
827
+ unitspre: properties.scaleUnitsPre,
828
+ unitspost: properties.scaleUnitsPost,
829
+ point: properties.scalePoint,
830
+ thousand: properties.scaleThousand
831
+ }),
832
+ halign: hAlign,
833
+ valign: vAlign,
834
+ tag: properties.labelsSpecific ? 'labels.specific' : 'labels',
835
+ cssClass: properties.labelsSpecific
836
+ ? RGraph.getLabelsCSSClassName({
837
+ object: this,
838
+ name: 'labelsClass',
839
+ index: i
840
+ })
841
+ : ''
842
+ });
843
+ }
844
+ }
845
+ this.context.fill();
846
+
847
+
848
+
849
+
850
+
851
+ //
852
+ // Draw the textual value if requested
853
+ //
854
+ if (properties.labelsValue) {
855
+
856
+ var x = this.centerx,
857
+ y = this.centery + (properties.labelsValueYPos * this.radius),
858
+ units_pre = typeof properties.labelsValueUnitsPre == 'string' ? properties.labelsValueUnitsPre : properties.scaleUnitsPre,
859
+ units_post = typeof properties.labelsValueUnitsPost == 'string' ? properties.labelsValueUnitsPost : properties.scaleUnitsPost,
860
+ bounding = properties.labelsValueBounding,
861
+ boundingFill = properties.labelsValueBoundingFill,
862
+ boundingStroke = properties.labelsValueBoundingStroke,
863
+ decimals = typeof properties.labelsValueDecimals === 'number' ? properties.labelsValueDecimals : properties.scaleDecimals,
864
+ point = typeof properties.labelsValuePoint === 'string' ? properties.labelsValuePoint : properties.scalePoint,
865
+ thousand = typeof properties.labelsValueThousand === 'string' ? properties.labelsValueThousand : properties.scaleThousand;
866
+
867
+ var textConf = RGraph.getTextConf({
868
+ object: this,
869
+ prefix: 'labelsValue'
870
+ });
871
+
872
+
873
+ if (typeof this.value === 'number') {
874
+
875
+ var value = parseFloat(properties.valueTextActual ? this.valueOriginal : this.value);
876
+
877
+ var text = RGraph.numberFormat({
878
+ object: this,
879
+ number: value.toFixed(decimals),
880
+ unitspre: units_pre,
881
+ unitspost: units_post,
882
+ point: point,
883
+ thousand: thousand
884
+ });
885
+
886
+ } else {
887
+
888
+ var text = [];
889
+
890
+ for (var i=0; i<this.value.length; ++i) {
891
+ text[i] = RGraph.numberFormat({
892
+ object: this,
893
+ number: this.value[i].toFixed(decimals),
894
+ unitspre: units_pre,
895
+ unitspost: units_post,
896
+ point: point,
897
+ thousand: thousand
898
+ });
899
+ }
900
+
901
+ text = text.join(', ');
902
+ }
903
+
904
+ RGraph.text({
905
+
906
+ object: this,
907
+
908
+ font: textConf.font,
909
+ size: textConf.size,
910
+ color: textConf.color,
911
+ bold: textConf.bold,
912
+ italic: textConf.italic,
913
+
914
+ x: x,
915
+ y: y,
916
+ text: text,
917
+ halign: 'center',
918
+ valign: 'center',
919
+ bounding: bounding,
920
+ 'bounding.fill': boundingFill,
921
+ 'bounding.stroke': boundingStroke,
922
+ tag: 'value.text'
923
+ });
924
+ }
925
+ };
926
+
927
+
928
+
929
+
930
+
931
+
932
+
933
+
934
+ //
935
+ // This function draws the top title
936
+ //
937
+ this.drawTopTitle = function ()
938
+ {
939
+ var x = this.centerx;
940
+ var y = this.centery - 25;
941
+
942
+ if (typeof properties.titleTopSubtitle === 'string') {
943
+ y -= 20.
944
+ }
945
+
946
+
947
+
948
+
949
+ // Move the Y coord up if there's a subtitle
950
+ if (typeof properties.titleTopSubtitle === 'string' || typeof properties.titleTopSubtitle === 'number') {
951
+ var titleTopSubtitleDim = RGraph.measureText({
952
+ bold: properties.titleTopSubtitleBold,
953
+ italic: properties.titleTopSubtitleItalic,
954
+ size: properties.titleTopSubtitleSize,
955
+ font: properties.titleTopSubtitleFont,
956
+ text: 'Mg'
957
+ });
958
+
959
+ y -= titleTopSubtitleDim[1];
960
+ }
961
+
962
+
963
+
964
+
965
+ // Totally override the calculated positioning
966
+ if (typeof properties.titleTopPos == 'number') {
967
+ y = this.centery - (this.radius * properties.titleTopPos);
968
+ }
969
+
970
+ var textConf = RGraph.getTextConf({
971
+ object: this,
972
+ prefix: 'titleTop'
973
+ });
974
+
975
+ if (properties.titleTop) {
976
+
977
+ if (typeof properties.titleTopOffsetx === 'number') x += properties.titleTopOffsetx;
978
+ if (typeof properties.titleTopOffsety === 'number') y += properties.titleTopOffsety;
979
+
980
+ this.context.fillStyle = properties.titleTopColor;
981
+
982
+ RGraph.text({
983
+ object: this,
984
+ font: textConf.font,
985
+ size: textConf.size,
986
+ color: textConf.color,
987
+ bold: textConf.bold,
988
+ italic: textConf.italic,
989
+ x: x,
990
+ y: y,
991
+ text: String(properties.titleTop),
992
+ halign: 'center',
993
+ valign: 'bottom',
994
+ tag: 'title.top',
995
+ marker: false
996
+ });
997
+ }
998
+
999
+ // Draw the subtitle
1000
+ var text = properties.titleTopSubtitle;
1001
+
1002
+ if (typeof text === 'string') {
1003
+
1004
+ // Get the size of the title
1005
+ var titleSize = textConf.size;
1006
+
1007
+ var textConf = RGraph.getTextConf({
1008
+ object: this,
1009
+ prefix: 'titleTopSubtitle'
1010
+ });
1011
+
1012
+ // Draw the subtitle
1013
+ var ret = RGraph.text({
1014
+ object: this,
1015
+ font: textConf.font,
1016
+ size: textConf.size,
1017
+ color: textConf.color,
1018
+ bold: textConf.bold,
1019
+ italic: textConf.italic,
1020
+ x: x + properties.titleTopSubtitleOffsetx,
1021
+ y: y + 5 + properties.titleTopSubtitleOffsety,
1022
+ text: text,
1023
+ valign: 'top',
1024
+ halign: 'center',
1025
+ tag: 'subtitle.top',
1026
+ marker: false
1027
+ });
1028
+ }
1029
+ };
1030
+
1031
+
1032
+
1033
+
1034
+
1035
+
1036
+
1037
+
1038
+ //
1039
+ // This function draws the bottom title
1040
+ //
1041
+ this.drawBottomTitle = function ()
1042
+ {
1043
+ var x = this.centerx;
1044
+ var y = this.centery + this.centerpinRadius + 10;
1045
+
1046
+ // Totally override the calculated positioning
1047
+ if (typeof properties.titleBottomPos == 'number') {
1048
+ y = this.centery + (this.radius * properties.titleBottomPos);
1049
+ }
1050
+
1051
+ if (properties.titleBottom) {
1052
+
1053
+ if (typeof properties.titleBottomOffsetx === 'number') x += properties.titleBottomOffsetx;
1054
+ if (typeof properties.titleBottomOffsety === 'number') y += properties.titleBottomOffsety;
1055
+
1056
+ this.context.fillStyle = properties.titleBottomColor;
1057
+
1058
+ var textConf = RGraph.getTextConf({
1059
+ object: this,
1060
+ prefix: 'titleBottom'
1061
+ });
1062
+
1063
+ RGraph.text({
1064
+
1065
+ object: this,
1066
+
1067
+ font: textConf.font,
1068
+ size: textConf.size,
1069
+ color: textConf.color,
1070
+ bold: textConf.bold,
1071
+ italic: textConf.italic,
1072
+
1073
+ x: x,
1074
+ y: y,
1075
+ text: String(properties.titleBottom),
1076
+ halign: 'center',
1077
+ valign: 'top',
1078
+ tag: 'title.bottom'
1079
+ });
1080
+ }
1081
+ };
1082
+
1083
+
1084
+
1085
+
1086
+
1087
+
1088
+
1089
+
1090
+ //
1091
+ // This function draws the Needle
1092
+ //
1093
+ // @param number value The value to draw the needle for
1094
+ //
1095
+ this.drawNeedle = function (value, color, index)
1096
+ {
1097
+ var type = properties.needleType;
1098
+
1099
+ this.context.lineWidth = 0.5;
1100
+ this.context.strokeStyle = 'gray';
1101
+ this.context.fillStyle = color;
1102
+
1103
+ var angle = (this.endAngle - this.startAngle) * ((value - this.min) / (this.max - this.min));
1104
+ angle += this.startAngle;
1105
+
1106
+
1107
+ // Work out the size of the needle
1108
+ if ( typeof properties.needleSize == 'object'
1109
+ && properties.needleSize
1110
+ && typeof properties.needleSize[index] == 'number') {
1111
+
1112
+ var size = properties.needleSize[index];
1113
+
1114
+ } else if (typeof properties.needleSize == 'number') {
1115
+ var size = properties.needleSize;
1116
+
1117
+ } else {
1118
+ var size = this.radius - 25 - properties.borderWidth;
1119
+ }
1120
+
1121
+
1122
+
1123
+ if (type == 'line') {
1124
+
1125
+ this.context.beginPath();
1126
+
1127
+ this.context.lineWidth = properties.needleWidth;
1128
+ this.context.strokeStyle = color;
1129
+
1130
+ this.context.arc(this.centerx,
1131
+ this.centery,
1132
+ size,
1133
+ angle,
1134
+ angle + 0.0001,
1135
+ false
1136
+ );
1137
+
1138
+ this.context.lineTo(this.centerx, this.centery);
1139
+
1140
+ if (properties.needleTail) {
1141
+ this.context.arc(this.centerx, this.centery, this.radius * 0.2 , angle + RGraph.PI, angle + 0.00001 + RGraph.PI, false);
1142
+ }
1143
+
1144
+ this.context.lineTo(this.centerx, this.centery);
1145
+
1146
+ this.context.stroke();
1147
+ //this.context.fill();
1148
+
1149
+ } else {
1150
+
1151
+ this.context.beginPath();
1152
+ this.context.arc(this.centerx, this.centery, size, angle, angle + 0.00001, false);
1153
+ this.context.arc(this.centerx, this.centery, this.centerpinRadius * 0.5, angle + RGraph.HALFPI, angle + 0.00001 + RGraph.HALFPI, false);
1154
+
1155
+ if (properties.needleTail) {
1156
+ this.context.arc(this.centerx, this.centery, this.radius * 0.2 , angle + RGraph.PI, angle + 0.00001 + RGraph.PI, false);
1157
+ }
1158
+
1159
+ this.context.arc(this.centerx, this.centery, this.centerpinRadius * 0.5, angle - RGraph.HALFPI, angle - 0.00001 - RGraph.HALFPI, false);
1160
+ this.context.stroke();
1161
+ this.context.fill();
1162
+
1163
+ //
1164
+ // Store the angle in an object variable
1165
+ //
1166
+ this.angle = angle;
1167
+ }
1168
+ };
1169
+
1170
+
1171
+
1172
+
1173
+
1174
+
1175
+
1176
+
1177
+ //
1178
+ // This draws the green background to the tickmarks
1179
+ //
1180
+ this.drawColorBands = function ()
1181
+ {
1182
+ if (RGraph.isArray(properties.colorsRanges)) {
1183
+
1184
+ var ranges = properties.colorsRanges;
1185
+
1186
+ for (var i=0; i<ranges.length; ++i) {
1187
+
1188
+ this.context.fillStyle = ranges[i][2];
1189
+ this.context.lineWidth = 0;
1190
+
1191
+ this.context.beginPath();
1192
+ this.context.arc(
1193
+ this.centerx,
1194
+ this.centery,
1195
+ this.radius - 10 - properties.borderWidth,
1196
+ (((ranges[i][0] - this.min) / (this.max - this.min)) * (this.endAngle - this.startAngle)) + this.startAngle,
1197
+ (((ranges[i][1] - this.min) / (this.max - this.min)) * (this.endAngle - this.startAngle)) + this.startAngle,
1198
+ false
1199
+ );
1200
+
1201
+ this.context.arc(
1202
+ this.centerx,
1203
+ this.centery,
1204
+ this.radius - 10 - properties.borderWidth - (typeof ranges[i][3] === 'number' ? ranges[i][3] : 10),
1205
+ (((ranges[i][1] - this.min) / (this.max - this.min)) * (this.endAngle - this.startAngle)) + this.startAngle,
1206
+ (((ranges[i][0] - this.min) / (this.max - this.min)) * (this.endAngle - this.startAngle)) + this.startAngle,
1207
+ true
1208
+ );
1209
+ this.context.closePath();
1210
+ this.context.fill();
1211
+ }
1212
+
1213
+ return;
1214
+ }
1215
+
1216
+ //
1217
+ // Draw the GREEN region
1218
+ //
1219
+ this.context.strokeStyle = properties.colorsGreenColor;
1220
+ this.context.fillStyle = properties.colorsGreenColor;
1221
+
1222
+ var greenStart = this.startAngle;
1223
+ var greenEnd = this.startAngle + (this.endAngle - this.startAngle) * ((properties.colorsGreenEnd - this.min) / (this.max - this.min))
1224
+
1225
+ this.context.beginPath();
1226
+ this.context.arc(this.centerx, this.centery, this.radius - 10 - properties.borderWidth, greenStart, greenEnd, false);
1227
+ this.context.arc(this.centerx, this.centery, this.radius - (10 + properties.colorsGreenWidth) - properties.borderWidth, greenEnd, greenStart, true);
1228
+ this.context.fill();
1229
+
1230
+
1231
+
1232
+
1233
+
1234
+ //
1235
+ // Draw the YELLOW region
1236
+ //
1237
+ this.context.strokeStyle = properties.colorsYellowColor;
1238
+ this.context.fillStyle = properties.colorsYellowColor;
1239
+
1240
+ var yellowStart = greenEnd;
1241
+ var yellowEnd = this.startAngle + (this.endAngle - this.startAngle) * ((properties.colorsRedStart - this.min) / (this.max - this.min))
1242
+
1243
+ this.context.beginPath();
1244
+ this.context.arc(this.centerx, this.centery, this.radius - 10 - properties.borderWidth, yellowStart, yellowEnd, false);
1245
+ this.context.arc(this.centerx, this.centery, this.radius - (10 + properties.colorsYellowWidth) - properties.borderWidth, yellowEnd, yellowStart, true);
1246
+ this.context.fill();
1247
+
1248
+
1249
+
1250
+
1251
+
1252
+ //
1253
+ // Draw the RED region
1254
+ //
1255
+ this.context.strokeStyle = properties.colorsRedColor;
1256
+ this.context.fillStyle = properties.colorsRedColor;
1257
+
1258
+ var redStart = yellowEnd;
1259
+ var redEnd = this.startAngle + (this.endAngle - this.startAngle) * ((this.max - this.min) / (this.max - this.min))
1260
+
1261
+ this.context.beginPath();
1262
+ this.context.arc(this.centerx, this.centery, this.radius - 10 - properties.borderWidth, redStart, redEnd, false);
1263
+ this.context.arc(this.centerx, this.centery, this.radius - (10 + properties.colorsRedWidth) - properties.borderWidth, redEnd, redStart, true);
1264
+ this.context.fill();
1265
+ };
1266
+
1267
+
1268
+
1269
+
1270
+
1271
+
1272
+
1273
+
1274
+ //
1275
+ // A placeholder function
1276
+ //
1277
+ // @param object The event object
1278
+ //
1279
+ this.getShape = function (e) {};
1280
+
1281
+
1282
+
1283
+
1284
+
1285
+
1286
+
1287
+
1288
+ //
1289
+ // A getValue method
1290
+ //
1291
+ // @param object e An event object
1292
+ //
1293
+ this.getValue = function (e)
1294
+ {
1295
+ var mouseXY = RGraph.getMouseXY(e);
1296
+ var mouseX = mouseXY[0];
1297
+ var mouseY = mouseXY[1];
1298
+
1299
+ var angle = RGraph.getAngleByXY(this.centerx, this.centery, mouseX, mouseY);
1300
+
1301
+ if (angle >= 0 && angle <= RGraph.HALFPI) {
1302
+ angle += RGraph.TWOPI;
1303
+ }
1304
+
1305
+ var value = ((angle - this.startAngle) / (this.endAngle - this.startAngle)) * (this.max - this.min);
1306
+ value = value + this.min;
1307
+
1308
+ if (value < this.min) {
1309
+ value = this.min
1310
+ }
1311
+
1312
+ if (value > this.max) {
1313
+ value = this.max
1314
+ }
1315
+
1316
+ return value;
1317
+ };
1318
+
1319
+
1320
+
1321
+
1322
+
1323
+
1324
+
1325
+
1326
+ //
1327
+ // The getObjectByXY() worker method. Don't call this call:
1328
+ //
1329
+ // RGraph.ObjectRegistry.getObjectByXY(e)
1330
+ //
1331
+ // @param object e The event object
1332
+ //
1333
+ this.getObjectByXY = function (e)
1334
+ {
1335
+ var mouseXY = RGraph.getMouseXY(e);
1336
+
1337
+ if (
1338
+ mouseXY[0] > (this.centerx - this.radius)
1339
+ && mouseXY[0] < (this.centerx + this.radius)
1340
+ && mouseXY[1] > (this.centery - this.radius)
1341
+ && mouseXY[1] < (this.centery + this.radius)
1342
+ && RGraph.getHypLength(this.centerx, this.centery, mouseXY[0], mouseXY[1]) <= this.radius
1343
+ ) {
1344
+
1345
+ return this;
1346
+ }
1347
+ };
1348
+
1349
+
1350
+
1351
+
1352
+
1353
+
1354
+
1355
+
1356
+ //
1357
+ // This draws the gradient that goes around the Gauge chart
1358
+ //
1359
+ this.drawGradient = function ()
1360
+ {
1361
+ if (properties.borderGradient) {
1362
+
1363
+ this.context.beginPath();
1364
+
1365
+ var grad = this.context.createRadialGradient(this.centerx, this.centery, this.radius, this.centerx, this.centery, this.radius - 15);
1366
+ grad.addColorStop(0, 'gray');
1367
+ grad.addColorStop(1, 'white');
1368
+
1369
+ this.context.fillStyle = grad;
1370
+ this.context.arc(this.centerx, this.centery, this.radius, 0, RGraph.TWOPI, false)
1371
+ this.context.arc(this.centerx, this.centery, this.radius - 15, RGraph.TWOPI,0, true)
1372
+ this.context.fill();
1373
+ }
1374
+ };
1375
+
1376
+
1377
+
1378
+
1379
+
1380
+
1381
+
1382
+
1383
+ //
1384
+ // This method handles the adjusting calculation for when the mouse is moved
1385
+ //
1386
+ // @param object e The event object
1387
+ //
1388
+ this.adjusting_mousemove = function (e)
1389
+ {
1390
+ //
1391
+ // Handle adjusting for the Bar
1392
+ //
1393
+ if (properties.adjustable && RGraph.Registry.get('adjusting') && RGraph.Registry.get('adjusting').uid == this.uid) {
1394
+ this.value = this.getValue(e);
1395
+ //RGraph.clear(this.canvas);
1396
+ RGraph.redrawCanvas(this.canvas);
1397
+ RGraph.fireCustomEvent(this, 'onadjust');
1398
+ }
1399
+ };
1400
+
1401
+
1402
+
1403
+
1404
+
1405
+
1406
+
1407
+
1408
+ //
1409
+ // This method returns an appropriate angle for the given value (in RADIANS)
1410
+ //
1411
+ // @param number value The value to get the angle for
1412
+ //
1413
+ this.getAngle = function (value)
1414
+ {
1415
+ // Higher than max
1416
+ if (value > this.max || value < this.min) {
1417
+ return null;
1418
+ }
1419
+
1420
+ //var value = ((angle - this.startAngle) / (this.endAngle - this.startAngle)) * (this.max - this.min);
1421
+ //value = value + this.min;
1422
+
1423
+ var angle = (((value - this.min) / (this.max - this.min)) * (this.endAngle - this.startAngle)) + this.startAngle;
1424
+
1425
+ return angle;
1426
+ };
1427
+
1428
+
1429
+
1430
+
1431
+
1432
+
1433
+
1434
+
1435
+ //
1436
+ // This allows for easy specification of gradients. Could optimise this not to repeatedly call parseSingleColors()
1437
+ //
1438
+ this.parseColors = function ()
1439
+ {
1440
+ // Save the original colors so that they can be restored when the canvas is reset
1441
+ if (this.original_colors.length === 0) {
1442
+ this.original_colors.backgroundColor = RGraph.arrayClone(properties.backgroundColor);
1443
+ this.original_colors.colorsRedColor = RGraph.arrayClone(properties.colorsRedColor);
1444
+ this.original_colors.colorsYellowColor = RGraph.arrayClone(properties.colorsYellowColor);
1445
+ this.original_colors.colorsGreenColor = RGraph.arrayClone(properties.colorsGreenColor);
1446
+ this.original_colors.borderInner = RGraph.arrayClone(properties.borderInner);
1447
+ this.original_colors.borderOuter = RGraph.arrayClone(properties.borderOuter);
1448
+ this.original_colors.colorsRanges = RGraph.arrayClone(properties.colorsRanges);
1449
+ this.original_colors.needleColors = RGraph.arrayClone(properties.needleColors);
1450
+ }
1451
+
1452
+ properties.backgroundColor = this.parseSingleColorForGradient(properties.backgroundColor);
1453
+ properties.colorsRedColor = this.parseSingleColorForGradient(properties.colorsRedColor);
1454
+ properties.colorsYellowColor = this.parseSingleColorForGradient(properties.colorsYellowColor);
1455
+ properties.colorsGreenColor = this.parseSingleColorForGradient(properties.colorsGreenColor);
1456
+ properties.borderInner = this.parseSingleColorForGradient(properties.borderInner);
1457
+ properties.borderOuter = this.parseSingleColorForGradient(properties.borderOuter);
1458
+
1459
+ // Parse the colorRanges value
1460
+ if (properties.colorsRanges) {
1461
+
1462
+ var ranges = properties.colorsRanges;
1463
+
1464
+ for (var i=0; i<ranges.length; ++i) {
1465
+ ranges[i][2] = this.parseSingleColorForGradient(ranges[i][2], this.radius - 30);
1466
+ }
1467
+ }
1468
+
1469
+ // Parse the needleColors value
1470
+ if (properties.needleColors) {
1471
+
1472
+ var colors = properties.needleColors;
1473
+
1474
+ for (var i=0; i<colors.length; ++i) {
1475
+ colors[i] = this.parseSingleColorForGradient(colors[i]);
1476
+ }
1477
+ }
1478
+ };
1479
+
1480
+
1481
+
1482
+
1483
+
1484
+
1485
+
1486
+
1487
+ //
1488
+ // Use this function to reset the object to the post-constructor state. Eg reset colors if
1489
+ // need be etc
1490
+ //
1491
+ this.reset = function ()
1492
+ {
1493
+ };
1494
+
1495
+
1496
+
1497
+
1498
+
1499
+
1500
+
1501
+
1502
+ //
1503
+ // This parses a single color value
1504
+ //
1505
+ // @param string color The color to look for a gradient in
1506
+ // @param radius OPTIONAL The start radius to start the gradient at.
1507
+ // If not suppllied the centerx value is used
1508
+ //
1509
+ this.parseSingleColorForGradient = function (color)
1510
+ {
1511
+ var radiusStart = arguments[1] || 0;
1512
+
1513
+ if (!color || typeof color != 'string') {
1514
+ return color;
1515
+ }
1516
+
1517
+ if (color.match(/^gradient\((.*)\)$/i)) {
1518
+
1519
+
1520
+ // Allow for JSON gradients
1521
+ if (color.match(/^gradient\(({.*})\)$/i)) {
1522
+ return RGraph.parseJSONGradient({object: this, def: RegExp.$1});
1523
+ }
1524
+
1525
+ var parts = RegExp.$1.split(':');
1526
+
1527
+ // Create the gradient
1528
+ var grad = this.context.createRadialGradient(
1529
+ this.centerx,
1530
+ this.centery,
1531
+ radiusStart,
1532
+ this.centerx,
1533
+ this.centery,
1534
+ this.radius
1535
+ );
1536
+
1537
+ var diff = 1 / (parts.length - 1);
1538
+
1539
+ grad.addColorStop(0, RGraph.trim(parts[0]));
1540
+
1541
+ for (var j=1; j<parts.length; ++j) {
1542
+ grad.addColorStop(j * diff, RGraph.trim(parts[j]));
1543
+ }
1544
+ }
1545
+
1546
+ return grad ? grad : color;
1547
+ };
1548
+
1549
+
1550
+
1551
+
1552
+
1553
+
1554
+
1555
+
1556
+ //
1557
+ // Using a function to add events makes it easier to facilitate method chaining
1558
+ //
1559
+ // @param string type The type of even to add
1560
+ // @param function func
1561
+ //
1562
+ this.on = function (type, func)
1563
+ {
1564
+ if (type.substr(0,2) !== 'on') {
1565
+ type = 'on' + type;
1566
+ }
1567
+
1568
+ if (typeof this[type] !== 'function') {
1569
+ this[type] = func;
1570
+ } else {
1571
+ RGraph.addCustomEventListener(this, type, func);
1572
+ }
1573
+
1574
+ return this;
1575
+ };
1576
+
1577
+
1578
+
1579
+
1580
+
1581
+
1582
+
1583
+
1584
+ //
1585
+ // This function runs once only
1586
+ // (put at the end of the file (before any effects))
1587
+ //
1588
+ this.firstDrawFunc = function ()
1589
+ {
1590
+ };
1591
+
1592
+
1593
+
1594
+
1595
+
1596
+
1597
+
1598
+
1599
+ //
1600
+ // Gauge Grow
1601
+ //
1602
+ // This effect gradually increases the represented value
1603
+ //
1604
+ // @param object Options for the effect. You can pass frames here
1605
+ // @param function An optional callback function
1606
+ //
1607
+ this.grow = function ()
1608
+ {
1609
+ // Cancel any stop request if one is pending
1610
+ this.cancelStopAnimation();
1611
+
1612
+ var obj = this,
1613
+ opt = arguments[0] ? arguments[0] : {},
1614
+ callback = arguments[1] ? arguments[1] : function () {},
1615
+ frames = opt.frames || 30,
1616
+ frame = 0;
1617
+
1618
+ // Don't want any strings
1619
+ if (typeof this.value === 'string') {
1620
+ this.value = RGraph.stringsToNumbers(this.value);
1621
+ }
1622
+
1623
+ // Single pointer
1624
+ if (typeof this.value === 'number') {
1625
+
1626
+ var origValue = Number(this.currentValue);
1627
+
1628
+ if (this.currentValue == null) {
1629
+ this.currentValue = this.min;
1630
+ origValue = this.min;
1631
+ }
1632
+
1633
+ var newValue = this.value,
1634
+ diff = newValue - origValue;
1635
+
1636
+
1637
+
1638
+ var iterator = function ()
1639
+ {
1640
+ if (obj.stopAnimationRequested) {
1641
+
1642
+ // Reset the flag
1643
+ obj.stopAnimationRequested = false;
1644
+
1645
+ return;
1646
+ }
1647
+
1648
+ obj.value = ((frame / frames) * diff) + origValue;
1649
+
1650
+ if (obj.value > obj.max) obj.value = obj.max;
1651
+ if (obj.value < obj.min) obj.value = obj.min;
1652
+
1653
+ //RGraph.clear(obj.canvas);
1654
+ RGraph.redrawCanvas(obj.canvas);
1655
+
1656
+ if (frame++ < frames) {
1657
+ RGraph.Effects.updateCanvas(iterator);
1658
+ } else {
1659
+ callback(obj);
1660
+ }
1661
+ };
1662
+
1663
+ iterator();
1664
+
1665
+
1666
+
1667
+ //
1668
+ // Multiple pointers
1669
+ //
1670
+ } else {
1671
+
1672
+ if (this.currentValue == null) {
1673
+ this.currentValue = [];
1674
+
1675
+ for (var i=0; i<this.value.length; ++i) {
1676
+ this.currentValue[i] = this.min;
1677
+ }
1678
+
1679
+ origValue = RGraph.arrayClone(this.currentValue);
1680
+ }
1681
+
1682
+ var origValue = RGraph.arrayClone(this.currentValue);
1683
+ var newValue = RGraph.arrayClone(this.value);
1684
+ var diff = [];
1685
+
1686
+ for (var i=0,len=newValue.length; i<len; ++i) {
1687
+ diff[i] = newValue[i] - Number(this.currentValue[i]);
1688
+ }
1689
+
1690
+
1691
+
1692
+ var iterator = function ()
1693
+ {
1694
+ if (obj.stopAnimationRequested) {
1695
+
1696
+ // Reset the flag
1697
+ obj.stopAnimationRequested = false;
1698
+
1699
+ return;
1700
+ }
1701
+
1702
+ frame++;
1703
+
1704
+ for (var i=0,len=obj.value.length; i<len; ++i) {
1705
+
1706
+ obj.value[i] = ((frame / frames) * diff[i]) + origValue[i];
1707
+
1708
+ if (obj.value[i] > obj.max) obj.value[i] = obj.max;
1709
+ if (obj.value[i] < obj.min) obj.value[i] = obj.min;
1710
+ }
1711
+
1712
+ //RGraph.clear(obj.canvas);
1713
+ RGraph.redrawCanvas(obj.canvas);
1714
+
1715
+
1716
+ if (frame < frames) {
1717
+ RGraph.Effects.updateCanvas(iterator);
1718
+ } else {
1719
+ callback(obj);
1720
+ }
1721
+ };
1722
+
1723
+ iterator();
1724
+ }
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
+ // Register the object
1759
+ //
1760
+ RGraph.register(this);
1761
+
1762
+
1763
+
1764
+
1765
+
1766
+
1767
+
1768
+
1769
+ //
1770
+ // This is the 'end' of the constructor so if the first argument
1771
+ // contains configuration data - handle that.
1772
+ //
1773
+ RGraph.parseObjectStyleConfig(this, conf.options);
1774
+ };