rgraph-rails 1.0.7 → 1.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/lib/rgraph-rails/version.rb +1 -1
  4. data/license.txt +4 -16
  5. data/vendor/assets/javascripts/RGraph.bar.js +3734 -241
  6. data/vendor/assets/javascripts/RGraph.bipolar.js +2005 -115
  7. data/vendor/assets/javascripts/RGraph.common.annotate.js +395 -35
  8. data/vendor/assets/javascripts/RGraph.common.context.js +595 -30
  9. data/vendor/assets/javascripts/RGraph.common.core.js +5282 -405
  10. data/vendor/assets/javascripts/RGraph.common.csv.js +276 -19
  11. data/vendor/assets/javascripts/RGraph.common.deprecated.js +450 -35
  12. data/vendor/assets/javascripts/RGraph.common.dynamic.js +1395 -86
  13. data/vendor/assets/javascripts/RGraph.common.effects.js +1545 -90
  14. data/vendor/assets/javascripts/RGraph.common.key.js +753 -54
  15. data/vendor/assets/javascripts/RGraph.common.resizing.js +563 -37
  16. data/vendor/assets/javascripts/RGraph.common.sheets.js +352 -29
  17. data/vendor/assets/javascripts/RGraph.common.tooltips.js +450 -32
  18. data/vendor/assets/javascripts/RGraph.common.zoom.js +219 -14
  19. data/vendor/assets/javascripts/RGraph.drawing.background.js +570 -35
  20. data/vendor/assets/javascripts/RGraph.drawing.circle.js +544 -35
  21. data/vendor/assets/javascripts/RGraph.drawing.image.js +755 -52
  22. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +645 -41
  23. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +633 -37
  24. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +514 -36
  25. data/vendor/assets/javascripts/RGraph.drawing.poly.js +559 -39
  26. data/vendor/assets/javascripts/RGraph.drawing.rect.js +548 -35
  27. data/vendor/assets/javascripts/RGraph.drawing.text.js +664 -36
  28. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +812 -50
  29. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +856 -51
  30. data/vendor/assets/javascripts/RGraph.fuel.js +964 -58
  31. data/vendor/assets/javascripts/RGraph.funnel.js +984 -55
  32. data/vendor/assets/javascripts/RGraph.gantt.js +1354 -77
  33. data/vendor/assets/javascripts/RGraph.gauge.js +1421 -87
  34. data/vendor/assets/javascripts/RGraph.hbar.js +2562 -146
  35. data/vendor/assets/javascripts/RGraph.hprogress.js +1401 -80
  36. data/vendor/assets/javascripts/RGraph.line.js +4226 -244
  37. data/vendor/assets/javascripts/RGraph.meter.js +1280 -74
  38. data/vendor/assets/javascripts/RGraph.modaldialog.js +301 -19
  39. data/vendor/assets/javascripts/RGraph.odo.js +1264 -71
  40. data/vendor/assets/javascripts/RGraph.pie.js +2288 -137
  41. data/vendor/assets/javascripts/RGraph.radar.js +1847 -110
  42. data/vendor/assets/javascripts/RGraph.rose.js +1977 -108
  43. data/vendor/assets/javascripts/RGraph.rscatter.js +1432 -80
  44. data/vendor/assets/javascripts/RGraph.scatter.js +3036 -168
  45. data/vendor/assets/javascripts/RGraph.semicircularprogress.js +1120 -60
  46. data/vendor/assets/javascripts/RGraph.svg.bar.js +1067 -0
  47. data/vendor/assets/javascripts/RGraph.svg.common.ajax.js +247 -0
  48. data/vendor/assets/javascripts/RGraph.svg.common.core.js +3363 -0
  49. data/vendor/assets/javascripts/RGraph.svg.common.csv.js +277 -0
  50. data/vendor/assets/javascripts/RGraph.svg.common.fx.js +1304 -0
  51. data/vendor/assets/javascripts/RGraph.svg.common.sheets.js +353 -0
  52. data/vendor/assets/javascripts/RGraph.svg.common.tooltips.js +233 -0
  53. data/vendor/assets/javascripts/RGraph.svg.hbar.js +1141 -0
  54. data/vendor/assets/javascripts/RGraph.svg.line.js +1486 -0
  55. data/vendor/assets/javascripts/RGraph.svg.pie.js +781 -0
  56. data/vendor/assets/javascripts/RGraph.svg.radar.js +1326 -0
  57. data/vendor/assets/javascripts/RGraph.svg.semicircularprogress.js +817 -0
  58. data/vendor/assets/javascripts/RGraph.thermometer.js +1135 -62
  59. data/vendor/assets/javascripts/RGraph.vprogress.js +1470 -83
  60. data/vendor/assets/javascripts/RGraph.waterfall.js +1347 -80
  61. metadata +15 -3
@@ -1,88 +1,1422 @@
1
+ // version: 2017-01-02
2
+ /**
3
+ * o--------------------------------------------------------------------------------o
4
+ * | This file is part of the RGraph package - you can learn more at: |
5
+ * | |
6
+ * | http://www.rgraph.net |
7
+ * | |
8
+ * | RGraph is licensed under the Open Source MIT license. That means that it's |
9
+ * | totally free to use! |
10
+ * o--------------------------------------------------------------------------------o
11
+ */
1
12
 
2
- RGraph=window.RGraph||{isRGraph:true};RGraph.Gauge=function(conf)
3
- {if(typeof conf==='object'&&typeof conf.id==='string'){var id=conf.id
4
- var canvas=document.getElementById(id);var min=conf.min;var max=conf.max;var value=conf.value;var parseConfObjectForOptions=true;}else{var id=conf;var canvas=document.getElementById(id);var min=arguments[1];var max=arguments[2];var value=arguments[3];}
5
- 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;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;}
6
- this.properties={'chart.angles.start':null,'chart.angles.end':null,'chart.centerx':null,'chart.centery':null,'chart.radius':null,'chart.gutter.left':15,'chart.gutter.right':15,'chart.gutter.top':15,'chart.gutter.bottom':15,'chart.border.width':10,'chart.title.top':'','chart.title.top.font':'Segoe UI, Arial, Verdana, sans-serif','chart.title.top.size':14,'chart.title.top.color':'#333','chart.title.top.bold':false,'chart.title.top.pos':null,'chart.title.bottom':'','chart.title.bottom.font':'Segoe UI, Arial, Verdana, sans-serif','chart.title.bottom.size':14,'chart.title.bottom.color':'#333','chart.title.bottom.bold':false,'chart.title.bottom.pos':null,'chart.text.font':'Segoe UI, Arial, Verdana, sans-serif','chart.text.color':'#666','chart.text.size':12,'chart.text.accessible':true,'chart.text.accessible.overflow':'visible','chart.text.accessible.pointerevents':true,'chart.background.color':'white','chart.background.gradient':false,'chart.scale.decimals':0,'chart.scale.point':'.','chart.scale.thousand':',','chart.units.pre':'','chart.units.post':'','chart.value.text':false,'chart.value.text.y.pos':0.5,'chart.value.text.units.pre':null,'chart.value.text.units.post':null,'chart.value.text.color':'black','chart.value.text.bounding':true,'chart.value.text.bounding.fill':'white','chart.value.text.bounding.stroke':'black','chart.red.start':0.9*this.max,'chart.red.color':'#DC3912','chart.red.width':10,'chart.yellow.color':'#FF9900','chart.yellow.width':10,'chart.green.end':0.7*this.max,'chart.green.color':'rgba(0,0,0,0)','chart.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.centerpin.color':'blue','chart.centerpin.radius':null,'chart.zoom.background':true,'chart.zoom.action':'zoom','chart.tickmarks.small':25,'chart.tickmarks.small.color':'black','chart.tickmarks.medium':0,'chart.tickmarks.medium.color':'black','chart.tickmarks.big':5,'chart.tickmarks.big.color':'black','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.border.gradient':false,'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)'}
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
- 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.needle.color'){name='chart.needle.colors';}
15
- if(name=='chart.labels.offset'){name='chart.labels.offset.radius';}
16
- prop[name]=value;return this;};this.get=this.Get=function(name)
17
- {if(name.substr(0,6)!='chart.'){name='chart.'+name;}
18
- while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
19
- if(name=='chart.needle.color'){name='chart.needle.colors';}
20
- if(name=='chart.labels.offset'){name='chart.labels.offset.radius';}
21
- return prop[name];};this.draw=this.Draw=function()
22
- {RG.FireCustomEvent(this,'onbeforedraw');this.currentValue=this.value;this.gutterLeft=prop['chart.gutter.left'];this.gutterRight=prop['chart.gutter.right'];this.gutterTop=prop['chart.gutter.top'];this.gutterBottom=prop['chart.gutter.bottom'];this.centerx=((ca.width-this.gutterLeft-this.gutterRight)/2)+this.gutterLeft;this.centery=((ca.height-this.gutterTop-this.gutterBottom)/2)+this.gutterTop;this.radius=Math.min(((ca.width-this.gutterLeft-this.gutterRight)/2),((ca.height-this.gutterTop-this.gutterBottom)/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;}
23
- this.centerpinRadius=0.16*this.radius;if(typeof(prop['chart.centerpin.radius'])=='number'){this.centerpinRadius=prop['chart.centerpin.radius'];}
24
- if(prop['chart.contextmenu']){RG.ShowContext(this);}
25
- 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);}
26
- this.DrawCenterpin();if(prop['chart.resizable']){RG.AllowResizing(this);}
27
- RG.InstallEventListeners(this);if(this.firstDraw){RG.fireCustomEvent(this,'onfirstdraw');this.firstDraw=false;this.firstDrawFunc();}
28
- RG.FireCustomEvent(this,'ondraw');return this;};this.exec=function(func)
29
- {func(this);return this;};this.drawBackGround=this.DrawBackGround=function()
30
- {if(prop['chart.shadow']){RG.SetShadow(this,prop['chart.shadow.color'],prop['chart.shadow.offsetx'],prop['chart.shadow.offsety'],prop['chart.shadow.blur']);}
31
- 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.centery,0,this.centerx,this.centery,this.radius,'rgba(255,255,255,0.6)','rgba(255,255,255,0.1)');co.arc(this.centerx,this.centery,this.radius-borderWidth-4,0,RG.TWOPI,0);co.fill();}
32
- 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()
33
- {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()
34
- {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);}
35
- co.stroke();}}};this.drawBigTickmarks=this.DrawBigTickmarks=function()
36
- {var numTicks=prop['chart.tickmarks.big'];co.lineWidth=3;co.lineCap='round';for(var i=0;i<=numTicks;++i){co.beginPath();co.strokeStyle=prop['chart.tickmarks.big.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()
37
- {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()
38
- {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']
39
- 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
40
- 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';}
41
- if(prop['chart.labels.centered']){hAlign='center';vAlign='center';}
42
- var value=(((this.max-this.min)*(i/num))+this.min);RG.text2(this,{'font':font,'size':size,'x':x+offsetx,'y':y+offsety,'text':prop['chart.labels.specific']?prop['chart.labels.specific'][i]:RG.numberFormat(this,value.toFixed(value===0?0:prop['chart.scale.decimals']),prop['chart.units.pre'],prop['chart.units.post']),'halign':hAlign,'valign':vAlign,'tag':prop['chart.labels.specific']?'labels.specific':'labels'});}}
43
- co.fill();if(prop['chart.value.text']){var x=this.centerx;var y=this.centery+(prop['chart.value.text.y.pos']*this.radius);var units_pre=typeof(prop['chart.value.text.units.pre'])=='string'?prop['chart.value.text.units.pre']:prop['chart.units.pre'];var units_post=typeof(prop['chart.value.text.units.post'])=='string'?prop['chart.value.text.units.post']:prop['chart.units.post'];var color=prop['chart.value.text.color'];var bounding=prop['chart.value.text.bounding'];var boundingFill=prop['chart.value.text.bounding.fill'];var boundingStroke=prop['chart.value.text.bounding.stroke'];co.fillStyle=color;RG.text2(this,{'font':font,'size':size+2,'x':x,'y':y,'text':RG.numberFormat(this,this.value.toFixed(prop['chart.value.text.decimals']),units_pre,units_post),'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
- if(prop['chart.title.top']){co.fillStyle=prop['chart.title.top.color'];RG.Text2(this,{'font':prop['chart.title.top.font'],'size':prop['chart.title.top.size'],'x':x,'y':y,'text':String(prop['chart.title.top']),'halign':'center','valign':'bottom','bold':prop['chart.title.top.bold'],'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'];RG.Text2(this,{'font':prop['chart.title.bottom.font'],'size':prop['chart.title.bottom.size'],'x':x,'y':y,'text':String(prop['chart.title.bottom']),'halign':'center','valign':'top','bold':prop['chart.title.bottom.bold'],'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.is_array(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-20-prop['chart.border.width'],(((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.green.color'];co.fillStyle=prop['chart.green.color'];var greenStart=this.startAngle;var greenEnd=this.startAngle+(this.endAngle-this.startAngle)*((prop['chart.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.green.width'])-prop['chart.border.width'],greenEnd,greenStart,true);co.fill();co.strokeStyle=prop['chart.yellow.color'];co.fillStyle=prop['chart.yellow.color'];var yellowStart=greenEnd;var yellowEnd=this.startAngle+(this.endAngle-this.startAngle)*((prop['chart.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.yellow.width'])-prop['chart.border.width'],yellowEnd,yellowStart,true);co.fill();co.strokeStyle=prop['chart.red.color'];co.fillStyle=prop['chart.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.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.array_clone(prop['chart.background.color']);this.original_colors['chart.red.color']=RG.array_clone(prop['chart.red.color']);this.original_colors['chart.yellow.color']=RG.array_clone(prop['chart.yellow.color']);this.original_colors['chart.green.color']=RG.array_clone(prop['chart.green.color']);this.original_colors['chart.border.inner']=RG.array_clone(prop['chart.border.inner']);this.original_colors['chart.border.outer']=RG.array_clone(prop['chart.border.outer']);this.original_colors['chart.colors.ranges']=RG.array_clone(prop['chart.colors.ranges']);this.original_colors['chart.needle.colors']=RG.array_clone(prop['chart.needle.colors']);}
70
- prop['chart.background.color']=this.parseSingleColorForGradient(prop['chart.background.color']);prop['chart.red.color']=this.parseSingleColorForGradient(prop['chart.red.color']);prop['chart.yellow.color']=this.parseSingleColorForGradient(prop['chart.yellow.color']);prop['chart.green.color']=this.parseSingleColorForGradient(prop['chart.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)){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]));}}
75
- return grad?grad:color;};this.on=function(type,func)
76
- {if(type.substr(0,2)!=='on'){type='on'+type;}
77
- if(typeof this[type]!=='function'){this[type]=func;}else{RG.addCustomEventListener(this,type,func);}
78
- return this;};this.firstDrawFunc=function()
79
- {};this.grow=function()
80
- {var obj=this;var opt=arguments[0]?arguments[0]:{};var callback=arguments[1]?arguments[1]:function(){};var frames=opt.frames||30;var frame=0;if(typeof obj.value==='number'){var origValue=Number(obj.currentValue);if(obj.currentValue==null){obj.currentValue=obj.min;origValue=obj.min;}
81
- var newValue=obj.value;var diff=newValue-origValue;var iterator=function()
82
- {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(obj.currentValue==null){obj.currentValue=[];for(var i=0;i<obj.value.length;++i){obj.currentValue[i]=obj.min;}
83
- origValue=RG.array_clone(obj.currentValue);}
84
- var origValue=RG.array_clone(obj.currentValue);var newValue=RG.array_clone(obj.value);var diff=[];for(var i=0,len=newValue.length;i<len;++i){diff[i]=newValue[i]-Number(obj.currentValue[i]);}
85
- var iterator=function()
86
- {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;}
87
- RG.redrawCanvas(obj.canvas);if(frame<frames){RG.Effects.updateCanvas(iterator);}else{callback(obj);}};iterator();}
88
- return this;};RG.att(ca);RG.Register(this);if(parseConfObjectForOptions){RG.parseObjectStyleConfig(this,conf.options);}};
13
+ RGraph = window.RGraph || {isRGraph: true};
14
+
15
+ /**
16
+ * The line chart constructor
17
+ *
18
+ * @param object canvas The canvas ID
19
+ * @param array data The chart data
20
+ * @param array ... Other lines to plot
21
+ */
22
+ RGraph.Gauge = function (conf)
23
+ {
24
+ /**
25
+ * Allow for object config style
26
+ */
27
+ if ( typeof conf === 'object'
28
+ && typeof conf.id === 'string') {
29
+
30
+ var id = conf.id
31
+ var canvas = document.getElementById(id);
32
+ var min = conf.min;
33
+ var max = conf.max;
34
+ var value = conf.value;
35
+ var parseConfObjectForOptions = true; // Set this so the config is parsed (at the end of the constructor)
36
+
37
+ } else {
38
+
39
+ var id = conf;
40
+ var canvas = document.getElementById(id);
41
+ var min = arguments[1];
42
+ var max = arguments[2];
43
+ var value = arguments[3];
44
+ }
45
+
46
+ // id, min, max, value
47
+ this.id = id;
48
+ this.canvas = canvas;
49
+ this.context = this.canvas.getContext ? this.canvas.getContext("2d", {alpha: (typeof id === 'object' && id.alpha === false) ? false : true}) : null;
50
+ this.canvas.__object__ = this;
51
+ this.type = 'gauge';
52
+ this.min = RGraph.stringsToNumbers(min);
53
+ this.max = RGraph.stringsToNumbers(max);
54
+ this.value = RGraph.stringsToNumbers(value);
55
+ this.isRGraph = true;
56
+ this.currentValue = null;
57
+ this.uid = RGraph.CreateUID();
58
+ this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.CreateUID();
59
+ this.colorsParsed = false;
60
+ this.coordsText = [];
61
+ this.original_colors = [];
62
+ this.firstDraw = true; // After the first draw this will be false
63
+
64
+ /**
65
+ * Range checking
66
+ */
67
+ if (typeof(this.value) == 'object') {
68
+ for (var i=0; i<this.value.length; ++i) {
69
+ if (this.value[i] > this.max) this.value[i] = max;
70
+ if (this.value[i] < this.min) this.value[i] = min;
71
+ }
72
+ } else {
73
+ if (this.value > this.max) this.value = max;
74
+ if (this.value < this.min) this.value = min;
75
+ }
76
+
77
+
78
+
79
+ /**
80
+ * Compatibility with older browsers
81
+ */
82
+ //RGraph.OldBrowserCompat(this.context);
83
+
84
+
85
+ // Various config type stuff
86
+ this.properties =
87
+ {
88
+ 'chart.angles.start': null,
89
+ 'chart.angles.end': null,
90
+ 'chart.centerx': null,
91
+ 'chart.centery': null,
92
+ 'chart.radius': null,
93
+ 'chart.gutter.left': 15,
94
+ 'chart.gutter.right': 15,
95
+ 'chart.gutter.top': 15,
96
+ 'chart.gutter.bottom': 15,
97
+ 'chart.border.width': 10,
98
+ 'chart.title.top': '',
99
+ 'chart.title.top.font':'Segoe UI, Arial, Verdana, sans-serif',
100
+ 'chart.title.top.size':14,
101
+ 'chart.title.top.color':'#333',
102
+ 'chart.title.top.bold':false,
103
+ 'chart.title.top.pos': null,
104
+ 'chart.title.bottom': '',
105
+ 'chart.title.bottom.font':'Segoe UI, Arial, Verdana, sans-serif',
106
+ 'chart.title.bottom.size':14,
107
+ 'chart.title.bottom.color':'#333',
108
+ 'chart.title.bottom.bold':false,
109
+ 'chart.title.bottom.pos':null,
110
+ 'chart.text.font': 'Segoe UI, Arial, Verdana, sans-serif',
111
+ 'chart.text.color': '#666',
112
+ 'chart.text.size': 12,
113
+ 'chart.text.accessible': true,
114
+ 'chart.text.accessible.overflow': 'visible',
115
+ 'chart.text.accessible.pointerevents': true,
116
+ 'chart.background.color': 'white',
117
+ 'chart.background.gradient': false,
118
+ 'chart.scale.decimals': 0,
119
+ 'chart.scale.point': '.',
120
+ 'chart.scale.thousand': ',',
121
+ 'chart.units.pre': '',
122
+ 'chart.units.post': '',
123
+
124
+ 'chart.value.text': false,
125
+ 'chart.value.text.y.pos': 0.5,
126
+ 'chart.value.text.units.pre': null,
127
+ 'chart.value.text.units.post': null,
128
+ 'chart.value.text.color': 'black',
129
+ 'chart.value.text.bounding': true,
130
+ 'chart.value.text.bounding.fill': 'white',
131
+ 'chart.value.text.bounding.stroke': 'black',
132
+
133
+ 'chart.red.start': 0.9 * this.max,
134
+ 'chart.red.color': '#DC3912',
135
+ 'chart.red.width': 10,
136
+ 'chart.yellow.color': '#FF9900',
137
+ 'chart.yellow.width': 10,
138
+ 'chart.green.end': 0.7 * this.max,
139
+ 'chart.green.color': 'rgba(0,0,0,0)',
140
+ 'chart.green.width': 10,
141
+ 'chart.colors.ranges': null,
142
+ 'chart.needle.size': null,
143
+ 'chart.needle.tail': false,
144
+ 'chart.needle.colors': ['#D5604D', 'red', 'green', 'yellow'],
145
+ 'chart.needle.type': 'triangle',
146
+ 'chart.needle.width': 7,
147
+ 'chart.border.outer': '#ccc',
148
+ 'chart.border.inner': '#f1f1f1',
149
+ 'chart.border.outline': 'black',
150
+ 'chart.centerpin.color': 'blue',
151
+ 'chart.centerpin.radius': null,
152
+ 'chart.zoom.background': true,
153
+ 'chart.zoom.action': 'zoom',
154
+ 'chart.tickmarks.small': 25,
155
+ 'chart.tickmarks.small.color': 'black',
156
+ 'chart.tickmarks.medium': 0,
157
+ 'chart.tickmarks.medium.color': 'black',
158
+ 'chart.tickmarks.big': 5,
159
+ 'chart.tickmarks.big.color': 'black',
160
+
161
+ 'chart.labels.count': 5,
162
+ 'chart.labels.centered': false,
163
+ 'chart.labels.offset.radius': 0,
164
+ 'chart.labels.offset.angle': 0,
165
+ 'chart.labels.specific': null,
166
+ 'chart.labels.offsetx': 0,
167
+ 'chart.labels.offsety': 0,
168
+
169
+ 'chart.border.gradient': false,
170
+ 'chart.adjustable': false,
171
+ 'chart.shadow': true,
172
+ 'chart.shadow.color': 'gray',
173
+ 'chart.shadow.offsetx': 0,
174
+ 'chart.shadow.offsety': 0,
175
+ 'chart.shadow.blur': 15,
176
+ 'chart.clearto': 'rgba(0,0,0,0)'
177
+ }
178
+
179
+
180
+
181
+
182
+ /*
183
+ * Translate half a pixel for antialiasing purposes - but only if it hasn't beeen
184
+ * done already
185
+ */
186
+ if (!this.canvas.__rgraph_aa_translated__) {
187
+ this.context.translate(0.5,0.5);
188
+
189
+ this.canvas.__rgraph_aa_translated__ = true;
190
+ }
191
+
192
+
193
+
194
+
195
+
196
+ // Short variable names
197
+ var RG = RGraph,
198
+ ca = this.canvas,
199
+ co = ca.getContext('2d'),
200
+ prop = this.properties,
201
+ pa2 = RG.path2,
202
+ win = window,
203
+ doc = document,
204
+ ma = Math
205
+
206
+
207
+
208
+ /**
209
+ * "Decorate" the object with the generic effects if the effects library has been included
210
+ */
211
+ if (RG.Effects && typeof RG.Effects.decorate === 'function') {
212
+ RG.Effects.decorate(this);
213
+ }
214
+
215
+
216
+
217
+
218
+ /**
219
+ * An all encompassing accessor
220
+ *
221
+ * @param string name The name of the property
222
+ * @param mixed value The value of the property
223
+ */
224
+ this.set =
225
+ this.Set = function (name)
226
+ {
227
+ var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
228
+
229
+ /**
230
+ * the number of arguments is only one and it's an
231
+ * object - parse it for configuration data and return.
232
+ */
233
+ if (arguments.length === 1 && typeof name === 'object') {
234
+ RG.parseObjectStyleConfig(this, name);
235
+ return this;
236
+ }
237
+
238
+
239
+
240
+
241
+
242
+ /**
243
+ * This should be done first - prepend the propertyy name with "chart." if necessary
244
+ */
245
+ if (name.substr(0,6) != 'chart.') {
246
+ name = 'chart.' + name;
247
+ }
248
+
249
+
250
+
251
+
252
+ // Convert uppercase letters to dot+lower case letter
253
+ while(name.match(/([A-Z])/)) {
254
+ name = name.replace(/([A-Z])/, '.' + RegExp.$1.toLowerCase());
255
+ }
256
+
257
+
258
+
259
+
260
+
261
+ /**
262
+ * Title compatibility
263
+ */
264
+ if (name == 'chart.title') name = 'chart.title.top';
265
+ if (name == 'chart.title.font') name = 'chart.title.top.font';
266
+ if (name == 'chart.title.size') name = 'chart.title.top.size';
267
+ if (name == 'chart.title.color') name = 'chart.title.top.color';
268
+ if (name == 'chart.title.bold') name = 'chart.title.top.bold';
269
+
270
+ // BC
271
+ if (name == 'chart.needle.color') {
272
+ name = 'chart.needle.colors';
273
+ }
274
+
275
+ // name change
276
+ if (name == 'chart.labels.offset') {
277
+ name = 'chart.labels.offset.radius';
278
+ }
279
+
280
+
281
+
282
+
283
+
284
+
285
+ prop[name] = value;
286
+
287
+ return this;
288
+ };
289
+
290
+
291
+
292
+
293
+ /**
294
+ * An all encompassing accessor
295
+ *
296
+ * @param string name The name of the property
297
+ */
298
+ this.get =
299
+ this.Get = function (name)
300
+ {
301
+ /**
302
+ * This should be done first - prepend the property name with "chart." if necessary
303
+ */
304
+ if (name.substr(0,6) != 'chart.') {
305
+ name = 'chart.' + name;
306
+ }
307
+
308
+ // Convert uppercase letters to dot+lower case letter
309
+ while(name.match(/([A-Z])/)) {
310
+ name = name.replace(/([A-Z])/, '.' + RegExp.$1.toLowerCase());
311
+ }
312
+
313
+ // BC
314
+ if (name == 'chart.needle.color') {
315
+ name = 'chart.needle.colors';
316
+ }
317
+
318
+ // name change
319
+ if (name == 'chart.labels.offset') {
320
+ name = 'chart.labels.offset.radius';
321
+ }
322
+
323
+ return prop[name];
324
+ };
325
+
326
+
327
+
328
+
329
+ /**
330
+ * The function you call to draw the line chart
331
+ *
332
+ * @param bool An optional bool used internally to ditinguish whether the
333
+ * line chart is being called by the bar chart
334
+ */
335
+ this.draw =
336
+ this.Draw = function ()
337
+ {
338
+ /**
339
+ * Fire the onbeforedraw event
340
+ */
341
+ RG.FireCustomEvent(this, 'onbeforedraw');
342
+
343
+
344
+
345
+ /**
346
+ * Store the value (for animation primarily
347
+ */
348
+ this.currentValue = this.value;
349
+
350
+
351
+ /**
352
+ * This is new in May 2011 and facilitates indiviual gutter settings,
353
+ * eg chart.gutter.left
354
+ */
355
+ this.gutterLeft = prop['chart.gutter.left'];
356
+ this.gutterRight = prop['chart.gutter.right'];
357
+ this.gutterTop = prop['chart.gutter.top'];
358
+ this.gutterBottom = prop['chart.gutter.bottom'];
359
+
360
+ this.centerx = ((ca.width - this.gutterLeft - this.gutterRight) / 2) + this.gutterLeft;
361
+ this.centery = ((ca.height - this.gutterTop - this.gutterBottom) / 2) + this.gutterTop;
362
+ this.radius = Math.min(
363
+ ((ca.width - this.gutterLeft - this.gutterRight) / 2),
364
+ ((ca.height - this.gutterTop - this.gutterBottom) / 2)
365
+ );
366
+ this.startAngle = prop['chart.angles.start'] ? prop['chart.angles.start'] : (RG.HALFPI / 3) + RG.HALFPI;
367
+ this.endAngle = prop['chart.angles.end'] ? prop['chart.angles.end'] : RG.TWOPI + RG.HALFPI - (RG.HALFPI / 3);
368
+
369
+
370
+ /**
371
+ * Reset this so it doesn't keep growing
372
+ */
373
+ this.coordsText = [];
374
+
375
+
376
+
377
+ /**
378
+ * You can now override the positioning and radius if you so wish.
379
+ */
380
+ if (typeof(prop['chart.centerx']) == 'number') this.centerx = prop['chart.centerx'];
381
+ if (typeof(prop['chart.centery']) == 'number') this.centery = prop['chart.centery'];
382
+ if (typeof(prop['chart.radius']) == 'number') this.radius = prop['chart.radius'];
383
+
384
+ /**
385
+ * Parse the colors. This allows for simple gradient syntax
386
+ */
387
+ if (!this.colorsParsed) {
388
+ this.parseColors();
389
+
390
+ // Don't want to do this again
391
+ this.colorsParsed = true;
392
+ }
393
+
394
+
395
+ // This has to be in the constructor
396
+ this.centerpinRadius = 0.16 * this.radius;
397
+
398
+ if (typeof(prop['chart.centerpin.radius']) == 'number') {
399
+ this.centerpinRadius = prop['chart.centerpin.radius'];
400
+ }
401
+
402
+
403
+
404
+ /**
405
+ * Setup the context menu if required
406
+ */
407
+ if (prop['chart.contextmenu']) {
408
+ RG.ShowContext(this);
409
+ }
410
+
411
+
412
+
413
+ // DRAW THE CHART HERE
414
+ this.DrawBackGround();
415
+ this.DrawGradient();
416
+ this.DrawColorBands();
417
+ this.DrawSmallTickmarks();
418
+ this.DrawMediumTickmarks();
419
+ this.DrawBigTickmarks();
420
+ this.DrawLabels();
421
+ this.DrawTopTitle();
422
+ this.DrawBottomTitle();
423
+
424
+ if (typeof(this.value) == 'object') {
425
+ for (var i=0; i<this.value.length; ++i) {
426
+ this.DrawNeedle(this.value[i], prop['chart.needle.colors'][i], i);
427
+ }
428
+ } else {
429
+ this.DrawNeedle(this.value, prop['chart.needle.colors'][0], 0);
430
+ }
431
+
432
+ this.DrawCenterpin();
433
+
434
+ /**
435
+ * This function enables resizing
436
+ */
437
+ if (prop['chart.resizable']) {
438
+ RG.AllowResizing(this);
439
+ }
440
+
441
+
442
+ /**
443
+ * This installs the event listeners
444
+ */
445
+ RG.InstallEventListeners(this);
446
+
447
+
448
+ /**
449
+ * Fire the onfirstdraw event
450
+ */
451
+ if (this.firstDraw) {
452
+ RG.fireCustomEvent(this, 'onfirstdraw');
453
+ this.firstDraw = false;
454
+ this.firstDrawFunc();
455
+ }
456
+
457
+
458
+
459
+
460
+ /**
461
+ * Fire the RGraph ondraw event
462
+ */
463
+ RG.FireCustomEvent(this, 'ondraw');
464
+
465
+ return this;
466
+ };
467
+
468
+
469
+
470
+ /**
471
+ * Used in chaining. Runs a function there and then - not waiting for
472
+ * the events to fire (eg the onbeforedraw event)
473
+ *
474
+ * @param function func The function to execute
475
+ */
476
+ this.exec = function (func)
477
+ {
478
+ func(this);
479
+
480
+ return this;
481
+ };
482
+
483
+
484
+
485
+
486
+ /**
487
+ * Draw the background
488
+ */
489
+ this.drawBackGround =
490
+ this.DrawBackGround = function ()
491
+ {
492
+ // Shadow //////////////////////////////////////////////
493
+ if (prop['chart.shadow']) {
494
+ RG.SetShadow(this, prop['chart.shadow.color'], prop['chart.shadow.offsetx'], prop['chart.shadow.offsety'], prop['chart.shadow.blur']);
495
+ }
496
+
497
+ co.beginPath();
498
+ co.fillStyle = prop['chart.background.color'];
499
+ //co.moveTo(this.centerx, this.centery)
500
+ co.arc(this.centerx, this.centery, this.radius, 0, RG.TWOPI, 0);
501
+ co.fill();
502
+
503
+ // Turn off the shadow
504
+ RG.NoShadow(this);
505
+ // Shadow //////////////////////////////////////////////
506
+
507
+
508
+ var grad = co.createRadialGradient(this.centerx + 50, this.centery - 50, 0, this.centerx + 50, this.centery - 50, 150);
509
+ grad.addColorStop(0, '#eee');
510
+ grad.addColorStop(1, 'white');
511
+
512
+ var borderWidth = prop['chart.border.width'];
513
+
514
+ co.beginPath();
515
+ co.fillStyle = prop['chart.background.color'];
516
+ co.arc(this.centerx, this.centery, this.radius, 0, RG.TWOPI, 0);
517
+ co.fill();
518
+
519
+ /**
520
+ * Draw the gray circle
521
+ */
522
+ co.beginPath();
523
+ co.fillStyle = prop['chart.border.outer'];
524
+ co.arc(this.centerx, this.centery, this.radius, 0, RG.TWOPI, 0);
525
+ co.fill();
526
+
527
+ /**
528
+ * Draw the light gray inner border
529
+ */
530
+ co.beginPath();
531
+ co.fillStyle = prop['chart.border.inner'];
532
+ co.arc(this.centerx, this.centery, this.radius - borderWidth, 0, RG.TWOPI, 0);
533
+ co.fill();
534
+
535
+
536
+
537
+ // Draw the white circle inner border
538
+ co.beginPath();
539
+ co.fillStyle = prop['chart.background.color'];
540
+ co.arc(this.centerx, this.centery, this.radius - borderWidth - 4, 0, RG.TWOPI, 0);
541
+ co.fill();
542
+
543
+
544
+
545
+ // Draw the circle background. Can be any colour now.
546
+ co.beginPath();
547
+ co.fillStyle = prop['chart.background.color'];
548
+ co.arc(this.centerx, this.centery, this.radius - borderWidth - 4, 0, RG.TWOPI, 0);
549
+ co.fill();
550
+
551
+ if (prop['chart.background.gradient']) {
552
+
553
+ // Draw a partially transparent gradient that sits on top of the background
554
+ co.beginPath();
555
+ co.fillStyle = RG.RadialGradient(this,
556
+ this.centerx,
557
+ this.centery,
558
+ 0,
559
+ this.centerx,
560
+ this.centery,
561
+ this.radius,
562
+ 'rgba(255,255,255,0.6)',
563
+ 'rgba(255,255,255,0.1)');
564
+ co.arc(this.centerx, this.centery, this.radius - borderWidth - 4, 0, RG.TWOPI, 0);
565
+ co.fill();
566
+ }
567
+
568
+
569
+
570
+ // Draw a black border around the chart
571
+ co.beginPath();
572
+ co.strokeStyle = prop['chart.border.outline'];
573
+ co.arc(this.centerx, this.centery, this.radius, 0, RG.TWOPI, 0);
574
+ co.stroke();
575
+ };
576
+
577
+
578
+
579
+
580
+ /**
581
+ * This function draws the smaller tickmarks
582
+ */
583
+ this.drawSmallTickmarks =
584
+ this.DrawSmallTickmarks = function ()
585
+ {
586
+ var numTicks = prop['chart.tickmarks.small'];
587
+ co.lineWidth = 1;
588
+
589
+ for (var i=0; i<=numTicks; ++i) {
590
+ co.beginPath();
591
+ co.strokeStyle = prop['chart.tickmarks.small.color'];
592
+ var a = (((this.endAngle - this.startAngle) / numTicks) * i) + this.startAngle;
593
+ co.arc(this.centerx, this.centery, this.radius - prop['chart.border.width'] - 10, a, a + 0.00001, 0);
594
+ co.arc(this.centerx, this.centery, this.radius - prop['chart.border.width'] - 10 - 5, a, a + 0.00001, 0);
595
+ co.stroke();
596
+ }
597
+ };
598
+
599
+
600
+
601
+
602
+ /**
603
+ * This function draws the medium sized tickmarks
604
+ */
605
+ this.drawMediumTickmarks =
606
+ this.DrawMediumTickmarks = function ()
607
+ {
608
+ if (prop['chart.tickmarks.medium']) {
609
+
610
+ var numTicks = prop['chart.tickmarks.medium'];
611
+ co.lineWidth = 3;
612
+ co.lineCap = 'round';
613
+ co.strokeStyle = prop['chart.tickmarks.medium.color'];
614
+
615
+ for (var i=0; i<=numTicks; ++i) {
616
+ co.beginPath();
617
+ var a = (((this.endAngle - this.startAngle) / numTicks) * i) + this.startAngle + (((this.endAngle - this.startAngle) / (2 * numTicks)));
618
+
619
+ if (a > this.startAngle && a< this.endAngle) {
620
+ co.arc(this.centerx, this.centery, this.radius - prop['chart.border.width'] - 10, a, a + 0.00001, 0);
621
+ co.arc(this.centerx, this.centery, this.radius - prop['chart.border.width'] - 10 - 6, a, a + 0.00001, 0);
622
+ }
623
+ co.stroke();
624
+ }
625
+ }
626
+ };
627
+
628
+
629
+
630
+
631
+ /**
632
+ * This function draws the large, bold tickmarks
633
+ */
634
+ this.drawBigTickmarks =
635
+ this.DrawBigTickmarks = function ()
636
+ {
637
+ var numTicks = prop['chart.tickmarks.big'];
638
+ co.lineWidth = 3;
639
+ co.lineCap = 'round';
640
+
641
+ for (var i=0; i<=numTicks; ++i) {
642
+ co.beginPath();
643
+ co.strokeStyle = prop['chart.tickmarks.big.color'];
644
+ var a = (((this.endAngle - this.startAngle) / numTicks) * i) + this.startAngle;
645
+ co.arc(this.centerx, this.centery, this.radius - prop['chart.border.width'] - 10, a, a + 0.00001, 0);
646
+ co.arc(this.centerx, this.centery, this.radius - prop['chart.border.width'] - 10 - 10, a, a + 0.00001, 0);
647
+ co.stroke();
648
+ }
649
+ };
650
+
651
+
652
+
653
+
654
+ /**
655
+ * This function draws the centerpin
656
+ */
657
+ this.drawCenterpin =
658
+ this.DrawCenterpin = function ()
659
+ {
660
+ var offset = 6;
661
+
662
+ var grad = co.createRadialGradient(this.centerx + offset, this.centery - offset, 0, this.centerx + offset, this.centery - offset, 25);
663
+ grad.addColorStop(0, '#ddf');
664
+ grad.addColorStop(1, prop['chart.centerpin.color']);
665
+
666
+ co.beginPath();
667
+ co.fillStyle = grad;
668
+ co.arc(this.centerx, this.centery, this.centerpinRadius, 0, RG.TWOPI, 0);
669
+ co.fill();
670
+ };
671
+
672
+
673
+
674
+
675
+ /**
676
+ * This function draws the labels
677
+ */
678
+ this.drawLabels =
679
+ this.DrawLabels = function ()
680
+ {
681
+ co.fillStyle = prop['chart.text.color'];
682
+
683
+ var font = prop['chart.text.font'],
684
+ size = prop['chart.text.size'],
685
+ num = prop['chart.labels.specific'] ? (prop['chart.labels.specific'].length - 1) : prop['chart.labels.count'],
686
+ offsetx = prop['chart.labels.offsetx'],
687
+ offsety = prop['chart.labels.offsety'],
688
+ offseta = prop['chart.labels.offset.angle']
689
+
690
+ co.beginPath();
691
+ if (num) {
692
+ for (var i=0; i<=num; ++i) {
693
+ var hyp = (this.radius - 25 - prop['chart.border.width']) - prop['chart.labels.offset.radius'];
694
+ var a = (this.endAngle - this.startAngle) / num
695
+ a = this.startAngle + (i * a);
696
+ a -= RG.HALFPI;
697
+ a += offseta;
698
+
699
+
700
+ var x = this.centerx - (ma.sin(a) * hyp);
701
+ var y = this.centery + (ma.cos(a) * hyp);
702
+
703
+ var hAlign = x > this.centerx ? 'right' : 'left';
704
+ var vAlign = y > this.centery ? 'bottom' : 'top';
705
+
706
+ // This handles the label alignment when the label is on a PI/HALFPI boundary
707
+ if (a == RG.HALFPI) {
708
+ vAlign = 'center';
709
+ } else if (a == RG.PI) {
710
+ hAlign = 'center';
711
+ } else if (a == (RG.HALFPI + RG.PI) ) {
712
+ vAlign = 'center';
713
+ }
714
+
715
+ /**
716
+ * Can now force center alignment
717
+ */
718
+ if (prop['chart.labels.centered']) {
719
+ hAlign = 'center';
720
+ vAlign = 'center';
721
+ }
722
+
723
+ var value = (((this.max - this.min) * (i / num)) + this.min);
724
+
725
+
726
+ RG.text2(this, {
727
+ 'font':font,
728
+ 'size':size,
729
+ 'x':x + offsetx,
730
+ 'y':y + offsety,
731
+ 'text':prop['chart.labels.specific'] ? prop['chart.labels.specific'][i] : RG.numberFormat(this, value.toFixed(value === 0 ? 0 : prop['chart.scale.decimals']), prop['chart.units.pre'], prop['chart.units.post']),
732
+ 'halign':hAlign,
733
+ 'valign':vAlign,
734
+ 'tag': prop['chart.labels.specific'] ? 'labels.specific' : 'labels'
735
+ });
736
+ }
737
+ }
738
+ co.fill();
739
+
740
+
741
+ /**
742
+ * Draw the textual value if requested
743
+ */
744
+ if (prop['chart.value.text']) {
745
+
746
+ var x = this.centerx;
747
+ var y = this.centery + (prop['chart.value.text.y.pos'] * this.radius);
748
+
749
+ var units_pre = typeof(prop['chart.value.text.units.pre']) == 'string' ? prop['chart.value.text.units.pre'] : prop['chart.units.pre'];
750
+ var units_post = typeof(prop['chart.value.text.units.post']) == 'string' ? prop['chart.value.text.units.post'] : prop['chart.units.post'];
751
+ var color = prop['chart.value.text.color'];
752
+ var bounding = prop['chart.value.text.bounding'];
753
+ var boundingFill = prop['chart.value.text.bounding.fill'];
754
+ var boundingStroke = prop['chart.value.text.bounding.stroke'];
755
+
756
+ co.fillStyle = color;
757
+
758
+ RG.text2(this, {
759
+ 'font':font,
760
+ 'size':size + 2,
761
+ 'x':x,
762
+ 'y':y,
763
+ 'text':RG.numberFormat(this, this.value.toFixed(prop['chart.value.text.decimals']), units_pre, units_post),
764
+ 'halign':'center',
765
+ 'valign':'center',
766
+ 'bounding':bounding,
767
+ 'bounding.fill':boundingFill,
768
+ 'bounding.stroke': boundingStroke,
769
+ 'tag': 'value.text'
770
+ });
771
+ }
772
+ };
773
+
774
+
775
+
776
+
777
+ /**
778
+ * This function draws the top title
779
+ */
780
+ this.drawTopTitle =
781
+ this.DrawTopTitle = function ()
782
+ {
783
+ var x = this.centerx;
784
+ var y = this.centery - 25;
785
+
786
+ // Totally override the calculated positioning
787
+ if (typeof(prop['chart.title.top.pos']) == 'number') {
788
+ y = this.centery - (this.radius * prop['chart.title.top.pos']);
789
+ }
790
+
791
+ if (prop['chart.title.top']) {
792
+ co.fillStyle = prop['chart.title.top.color'];
793
+ RG.Text2(this, {'font':prop['chart.title.top.font'],
794
+ 'size':prop['chart.title.top.size'],
795
+ 'x':x,
796
+ 'y':y,
797
+ 'text':String(prop['chart.title.top']),
798
+ 'halign':'center',
799
+ 'valign':'bottom',
800
+ 'bold':prop['chart.title.top.bold'],
801
+ 'tag': 'title.top'
802
+ });
803
+ }
804
+ };
805
+
806
+
807
+
808
+
809
+ /**
810
+ * This function draws the bottom title
811
+ */
812
+ this.drawBottomTitle =
813
+ this.DrawBottomTitle = function ()
814
+ {
815
+ var x = this.centerx;
816
+ var y = this.centery + this.centerpinRadius + 10;
817
+
818
+ // Totally override the calculated positioning
819
+ if (typeof(prop['chart.title.bottom.pos']) == 'number') {
820
+ y = this.centery + (this.radius * prop['chart.title.bottom.pos']);
821
+ }
822
+
823
+ if (prop['chart.title.bottom']) {
824
+ co.fillStyle = prop['chart.title.bottom.color'];
825
+
826
+ RG.Text2(this, {'font':prop['chart.title.bottom.font'],
827
+ 'size':prop['chart.title.bottom.size'],
828
+ 'x':x,
829
+ 'y':y,
830
+ 'text':String(prop['chart.title.bottom']),
831
+ 'halign':'center',
832
+ 'valign':'top',
833
+ 'bold':prop['chart.title.bottom.bold'],
834
+ 'tag': 'title.bottom'
835
+ });
836
+ }
837
+ };
838
+
839
+
840
+
841
+
842
+ /**
843
+ * This function draws the Needle
844
+ *
845
+ * @param number value The value to draw the needle for
846
+ */
847
+ this.drawNeedle =
848
+ this.DrawNeedle = function (value, color, index)
849
+ {
850
+ var type = prop['chart.needle.type'];
851
+
852
+ co.lineWidth = 0.5;
853
+ co.strokeStyle = 'gray';
854
+ co.fillStyle = color;
855
+
856
+ var angle = (this.endAngle - this.startAngle) * ((value - this.min) / (this.max - this.min));
857
+ angle += this.startAngle;
858
+
859
+
860
+ // Work out the size of the needle
861
+ if ( typeof(prop['chart.needle.size']) == 'object'
862
+ && prop['chart.needle.size']
863
+ && typeof(prop['chart.needle.size'][index]) == 'number') {
864
+
865
+ var size = prop['chart.needle.size'][index];
866
+
867
+ } else if (typeof(prop['chart.needle.size']) == 'number') {
868
+ var size = prop['chart.needle.size'];
869
+
870
+ } else {
871
+ var size = this.radius - 25 - prop['chart.border.width'];
872
+ }
873
+
874
+
875
+
876
+ if (type == 'line') {
877
+
878
+ co.beginPath();
879
+
880
+ co.lineWidth = prop['chart.needle.width'];
881
+ co.strokeStyle = color;
882
+
883
+ co.arc(this.centerx,
884
+ this.centery,
885
+ size,
886
+ angle,
887
+ angle + 0.0001,
888
+ false);
889
+
890
+ co.lineTo(this.centerx, this.centery);
891
+
892
+ if (prop['chart.needle.tail']) {
893
+ co.arc(this.centerx, this.centery, this.radius * 0.2 , angle + RG.PI, angle + 0.00001 + RG.PI, false);
894
+ }
895
+
896
+ co.lineTo(this.centerx, this.centery);
897
+
898
+ co.stroke();
899
+ //co.fill();
900
+
901
+ } else {
902
+
903
+ co.beginPath();
904
+ co.arc(this.centerx, this.centery, size, angle, angle + 0.00001, false);
905
+ co.arc(this.centerx, this.centery, this.centerpinRadius * 0.5, angle + RG.HALFPI, angle + 0.00001 + RG.HALFPI, false);
906
+
907
+ if (prop['chart.needle.tail']) {
908
+ co.arc(this.centerx, this.centery, this.radius * 0.2 , angle + RG.PI, angle + 0.00001 + RG.PI, false);
909
+ }
910
+
911
+ co.arc(this.centerx, this.centery, this.centerpinRadius * 0.5, angle - RG.HALFPI, angle - 0.00001 - RG.HALFPI, false);
912
+ co.stroke();
913
+ co.fill();
914
+
915
+ /**
916
+ * Store the angle in an object variable
917
+ */
918
+ this.angle = angle;
919
+ }
920
+ };
921
+
922
+
923
+
924
+
925
+ /**
926
+ * This draws the green background to the tickmarks
927
+ */
928
+ this.drawColorBands =
929
+ this.DrawColorBands = function ()
930
+ {
931
+ if (RG.is_array(prop['chart.colors.ranges'])) {
932
+
933
+ var ranges = prop['chart.colors.ranges'];
934
+
935
+ for (var i=0; i<ranges.length; ++i) {
936
+
937
+ //co.strokeStyle = prop['chart.strokestyle'] ? prop['chart.strokestyle'] : ranges[i][2];
938
+ co.fillStyle = ranges[i][2];
939
+ co.lineWidth = 0;//prop['chart.linewidth.segments'];
940
+
941
+ co.beginPath();
942
+ co.arc(this.centerx,
943
+ this.centery,
944
+ this.radius - 10 - prop['chart.border.width'],
945
+ (((ranges[i][0] - this.min) / (this.max - this.min)) * (this.endAngle - this.startAngle)) + this.startAngle,
946
+ (((ranges[i][1] - this.min) / (this.max - this.min)) * (this.endAngle - this.startAngle)) + this.startAngle,
947
+ false);
948
+
949
+ co.arc(this.centerx,
950
+ this.centery,
951
+ this.radius - 20 - prop['chart.border.width'],
952
+ (((ranges[i][1] - this.min) / (this.max - this.min)) * (this.endAngle - this.startAngle)) + this.startAngle,
953
+ (((ranges[i][0] - this.min) / (this.max - this.min)) * (this.endAngle - this.startAngle)) + this.startAngle,
954
+ true);
955
+ co.closePath();
956
+ co.fill();
957
+ }
958
+
959
+ return;
960
+ }
961
+
962
+
963
+
964
+
965
+ /**
966
+ * Draw the GREEN region
967
+ */
968
+ co.strokeStyle = prop['chart.green.color'];
969
+ co.fillStyle = prop['chart.green.color'];
970
+
971
+ var greenStart = this.startAngle;
972
+ var greenEnd = this.startAngle + (this.endAngle - this.startAngle) * ((prop['chart.green.end'] - this.min) / (this.max - this.min))
973
+
974
+ co.beginPath();
975
+ co.arc(this.centerx, this.centery, this.radius - 10 - prop['chart.border.width'], greenStart, greenEnd, false);
976
+ co.arc(this.centerx, this.centery, this.radius - (10 + prop['chart.green.width']) - prop['chart.border.width'], greenEnd, greenStart, true);
977
+ co.fill();
978
+
979
+
980
+
981
+
982
+
983
+ /**
984
+ * Draw the YELLOW region
985
+ */
986
+ co.strokeStyle = prop['chart.yellow.color'];
987
+ co.fillStyle = prop['chart.yellow.color'];
988
+
989
+ var yellowStart = greenEnd;
990
+ var yellowEnd = this.startAngle + (this.endAngle - this.startAngle) * ((prop['chart.red.start'] - this.min) / (this.max - this.min))
991
+
992
+ co.beginPath();
993
+ co.arc(this.centerx, this.centery, this.radius - 10 - prop['chart.border.width'], yellowStart, yellowEnd, false);
994
+ co.arc(this.centerx, this.centery, this.radius - (10 + prop['chart.yellow.width']) - prop['chart.border.width'], yellowEnd, yellowStart, true);
995
+ co.fill();
996
+
997
+
998
+
999
+
1000
+
1001
+ /**
1002
+ * Draw the RED region
1003
+ */
1004
+ co.strokeStyle = prop['chart.red.color'];
1005
+ co.fillStyle = prop['chart.red.color'];
1006
+
1007
+ var redStart = yellowEnd;
1008
+ var redEnd = this.startAngle + (this.endAngle - this.startAngle) * ((this.max - this.min) / (this.max - this.min))
1009
+
1010
+ co.beginPath();
1011
+ co.arc(this.centerx, this.centery, this.radius - 10 - prop['chart.border.width'], redStart, redEnd, false);
1012
+ co.arc(this.centerx, this.centery, this.radius - (10 + prop['chart.red.width']) - prop['chart.border.width'], redEnd, redStart, true);
1013
+ co.fill();
1014
+ };
1015
+
1016
+
1017
+
1018
+
1019
+ /**
1020
+ * A placeholder function
1021
+ *
1022
+ * @param object The event object
1023
+ */
1024
+ this.getShape = function (e) {};
1025
+
1026
+
1027
+
1028
+
1029
+ /**
1030
+ * A getValue method
1031
+ *
1032
+ * @param object e An event object
1033
+ */
1034
+ this.getValue = function (e)
1035
+ {
1036
+ var mouseXY = RG.getMouseXY(e);
1037
+ var mouseX = mouseXY[0];
1038
+ var mouseY = mouseXY[1];
1039
+
1040
+ var angle = RG.getAngleByXY(this.centerx, this.centery, mouseX, mouseY);
1041
+
1042
+ if (angle >= 0 && angle <= RG.HALFPI) {
1043
+ angle += RG.TWOPI;
1044
+ }
1045
+
1046
+ var value = ((angle - this.startAngle) / (this.endAngle - this.startAngle)) * (this.max - this.min);
1047
+ value = value + this.min;
1048
+
1049
+ if (value < this.min) {
1050
+ value = this.min
1051
+ }
1052
+
1053
+ if (value > this.max) {
1054
+ value = this.max
1055
+ }
1056
+
1057
+ return value;
1058
+ };
1059
+
1060
+
1061
+
1062
+
1063
+ /**
1064
+ * The getObjectByXY() worker method. Don't call this call:
1065
+ *
1066
+ * RGraph.ObjectRegistry.getObjectByXY(e)
1067
+ *
1068
+ * @param object e The event object
1069
+ */
1070
+ this.getObjectByXY = function (e)
1071
+ {
1072
+ var mouseXY = RGraph.getMouseXY(e);
1073
+
1074
+ if (
1075
+ mouseXY[0] > (this.centerx - this.radius)
1076
+ && mouseXY[0] < (this.centerx + this.radius)
1077
+ && mouseXY[1] > (this.centery - this.radius)
1078
+ && mouseXY[1] < (this.centery + this.radius)
1079
+ && RG.getHypLength(this.centerx, this.centery, mouseXY[0], mouseXY[1]) <= this.radius
1080
+ ) {
1081
+
1082
+ return this;
1083
+ }
1084
+ };
1085
+
1086
+
1087
+
1088
+
1089
+ /**
1090
+ * This draws the gradient that goes around the Gauge chart
1091
+ */
1092
+ this.drawGradient =
1093
+ this.DrawGradient = function ()
1094
+ {
1095
+ if (prop['chart.border.gradient']) {
1096
+
1097
+ co.beginPath();
1098
+
1099
+ var grad = co.createRadialGradient(this.centerx, this.centery, this.radius, this.centerx, this.centery, this.radius - 15);
1100
+ grad.addColorStop(0, 'gray');
1101
+ grad.addColorStop(1, 'white');
1102
+
1103
+ co.fillStyle = grad;
1104
+ co.arc(this.centerx, this.centery, this.radius, 0, RG.TWOPI, false)
1105
+ co.arc(this.centerx, this.centery, this.radius - 15, RG.TWOPI,0, true)
1106
+ co.fill();
1107
+ }
1108
+ };
1109
+
1110
+
1111
+
1112
+
1113
+ /**
1114
+ * This method handles the adjusting calculation for when the mouse is moved
1115
+ *
1116
+ * @param object e The event object
1117
+ */
1118
+ this.adjusting_mousemove =
1119
+ this.Adjusting_mousemove = function (e)
1120
+ {
1121
+ /**
1122
+ * Handle adjusting for the Bar
1123
+ */
1124
+ if (prop['chart.adjustable'] && RG.Registry.Get('chart.adjusting') && RG.Registry.Get('chart.adjusting').uid == this.uid) {
1125
+ this.value = this.getValue(e);
1126
+ //RG.Clear(this.canvas);
1127
+ RG.redrawCanvas(this.canvas);
1128
+ RG.fireCustomEvent(this, 'onadjust');
1129
+ }
1130
+ };
1131
+
1132
+
1133
+
1134
+
1135
+ /**
1136
+ * This method returns an appropriate angle for the given value (in RADIANS)
1137
+ *
1138
+ * @param number value The value to get the angle for
1139
+ */
1140
+ this.getAngle = function (value)
1141
+ {
1142
+ // Higher than max
1143
+ if (value > this.max || value < this.min) {
1144
+ return null;
1145
+ }
1146
+
1147
+ //var value = ((angle - this.startAngle) / (this.endAngle - this.startAngle)) * (this.max - this.min);
1148
+ //value = value + this.min;
1149
+
1150
+ var angle = (((value - this.min) / (this.max - this.min)) * (this.endAngle - this.startAngle)) + this.startAngle;
1151
+
1152
+ return angle;
1153
+ };
1154
+
1155
+
1156
+
1157
+
1158
+ /**
1159
+ * This allows for easy specification of gradients. Could optimise this not to repeatedly call parseSingleColors()
1160
+ */
1161
+ this.parseColors = function ()
1162
+ {
1163
+ // Save the original colors so that they can be restored when the canvas is reset
1164
+ if (this.original_colors.length === 0) {
1165
+ this.original_colors['chart.background.color'] = RG.array_clone(prop['chart.background.color']);
1166
+ this.original_colors['chart.red.color'] = RG.array_clone(prop['chart.red.color']);
1167
+ this.original_colors['chart.yellow.color'] = RG.array_clone(prop['chart.yellow.color']);
1168
+ this.original_colors['chart.green.color'] = RG.array_clone(prop['chart.green.color']);
1169
+ this.original_colors['chart.border.inner'] = RG.array_clone(prop['chart.border.inner']);
1170
+ this.original_colors['chart.border.outer'] = RG.array_clone(prop['chart.border.outer']);
1171
+ this.original_colors['chart.colors.ranges'] = RG.array_clone(prop['chart.colors.ranges']);
1172
+ this.original_colors['chart.needle.colors'] = RG.array_clone(prop['chart.needle.colors']);
1173
+ }
1174
+
1175
+ prop['chart.background.color'] = this.parseSingleColorForGradient(prop['chart.background.color']);
1176
+ prop['chart.red.color'] = this.parseSingleColorForGradient(prop['chart.red.color']);
1177
+ prop['chart.yellow.color'] = this.parseSingleColorForGradient(prop['chart.yellow.color']);
1178
+ prop['chart.green.color'] = this.parseSingleColorForGradient(prop['chart.green.color']);
1179
+ prop['chart.border.inner'] = this.parseSingleColorForGradient(prop['chart.border.inner']);
1180
+ prop['chart.border.outer'] = this.parseSingleColorForGradient(prop['chart.border.outer']);
1181
+
1182
+ // Parse the chart.color.ranges value
1183
+ if (prop['chart.colors.ranges']) {
1184
+
1185
+ var ranges = prop['chart.colors.ranges'];
1186
+
1187
+ for (var i=0; i<ranges.length; ++i) {
1188
+ ranges[i][2] = this.parseSingleColorForGradient(ranges[i][2], this.radius - 30);
1189
+ }
1190
+ }
1191
+
1192
+ // Parse the chart.needle.colors value
1193
+ if (prop['chart.needle.colors']) {
1194
+
1195
+ var colors = prop['chart.needle.colors'];
1196
+
1197
+ for (var i=0; i<colors.length; ++i) {
1198
+ colors[i] = this.parseSingleColorForGradient(colors[i]);
1199
+ }
1200
+ }
1201
+ };
1202
+
1203
+
1204
+
1205
+
1206
+ /**
1207
+ * Use this function to reset the object to the post-constructor state. Eg reset colors if
1208
+ * need be etc
1209
+ */
1210
+ this.reset = function ()
1211
+ {
1212
+ };
1213
+
1214
+
1215
+
1216
+
1217
+ /**
1218
+ * This parses a single color value
1219
+ *
1220
+ * @param string color The color to look for a gradient in
1221
+ * @param radius OPTIONAL The start radius to start the gradient at.
1222
+ * If not suppllied the centerx value is used
1223
+ */
1224
+ this.parseSingleColorForGradient = function (color)
1225
+ {
1226
+ var radiusStart = arguments[1] || 0;
1227
+
1228
+ if (!color || typeof(color) != 'string') {
1229
+ return color;
1230
+ }
1231
+
1232
+ if (color.match(/^gradient\((.*)\)$/i)) {
1233
+
1234
+ var parts = RegExp.$1.split(':');
1235
+
1236
+ // Create the gradient
1237
+ var grad = co.createRadialGradient(this.centerx,
1238
+ this.centery,
1239
+ radiusStart,
1240
+ this.centerx,
1241
+ this.centery,
1242
+ this.radius
1243
+ );
1244
+
1245
+ var diff = 1 / (parts.length - 1);
1246
+
1247
+ grad.addColorStop(0, RG.trim(parts[0]));
1248
+
1249
+ for (var j=1; j<parts.length; ++j) {
1250
+ grad.addColorStop(j * diff, RG.trim(parts[j]));
1251
+ }
1252
+ }
1253
+
1254
+ return grad ? grad : color;
1255
+ };
1256
+
1257
+
1258
+
1259
+
1260
+ /**
1261
+ * Using a function to add events makes it easier to facilitate method chaining
1262
+ *
1263
+ * @param string type The type of even to add
1264
+ * @param function func
1265
+ */
1266
+ this.on = function (type, func)
1267
+ {
1268
+ if (type.substr(0,2) !== 'on') {
1269
+ type = 'on' + type;
1270
+ }
1271
+
1272
+ if (typeof this[type] !== 'function') {
1273
+ this[type] = func;
1274
+ } else {
1275
+ RG.addCustomEventListener(this, type, func);
1276
+ }
1277
+
1278
+ return this;
1279
+ };
1280
+
1281
+
1282
+
1283
+
1284
+ /**
1285
+ * This function runs once only
1286
+ * (put at the end of the file (before any effects))
1287
+ */
1288
+ this.firstDrawFunc = function ()
1289
+ {
1290
+ };
1291
+
1292
+
1293
+
1294
+
1295
+ /**
1296
+ * Gauge Grow
1297
+ *
1298
+ * This effect gradually increases the represented value
1299
+ *
1300
+ * @param object Options for the effect. You can pass frames here
1301
+ * @param function An optional callback function
1302
+ */
1303
+ this.grow = function ()
1304
+ {
1305
+ var obj = this;
1306
+ var opt = arguments[0] ? arguments[0] : {};
1307
+ var callback = arguments[1] ? arguments[1] : function () {};
1308
+ var frames = opt.frames || 30;
1309
+ var frame = 0;
1310
+
1311
+ // Single pointer
1312
+ if (typeof obj.value === 'number') {
1313
+
1314
+ var origValue = Number(obj.currentValue);
1315
+
1316
+ if (obj.currentValue == null) {
1317
+ obj.currentValue = obj.min;
1318
+ origValue = obj.min;
1319
+ }
1320
+
1321
+ var newValue = obj.value;
1322
+ var diff = newValue - origValue;
1323
+
1324
+
1325
+ var iterator = function ()
1326
+ {
1327
+ obj.value = ((frame / frames) * diff) + origValue;
1328
+
1329
+ if (obj.value > obj.max) obj.value = obj.max;
1330
+ if (obj.value < obj.min) obj.value = obj.min;
1331
+
1332
+ //RGraph.clear(obj.canvas);
1333
+ RG.redrawCanvas(obj.canvas);
1334
+
1335
+ if (frame++ < frames) {
1336
+ RG.Effects.updateCanvas(iterator);
1337
+ } else {
1338
+ callback(obj);
1339
+ }
1340
+ };
1341
+
1342
+ iterator();
1343
+
1344
+
1345
+
1346
+ /**
1347
+ * Multiple pointers
1348
+ */
1349
+ } else {
1350
+
1351
+ if (obj.currentValue == null) {
1352
+ obj.currentValue = [];
1353
+
1354
+ for (var i=0; i<obj.value.length; ++i) {
1355
+ obj.currentValue[i] = obj.min;
1356
+ }
1357
+
1358
+ origValue = RG.array_clone(obj.currentValue);
1359
+ }
1360
+
1361
+ var origValue = RG.array_clone(obj.currentValue);
1362
+ var newValue = RG.array_clone(obj.value);
1363
+ var diff = [];
1364
+
1365
+ for (var i=0,len=newValue.length; i<len; ++i) {
1366
+ diff[i] = newValue[i] - Number(obj.currentValue[i]);
1367
+ }
1368
+
1369
+
1370
+
1371
+ var iterator = function ()
1372
+ {
1373
+ frame++;
1374
+
1375
+ for (var i=0,len=obj.value.length; i<len; ++i) {
1376
+
1377
+ obj.value[i] = ((frame / frames) * diff[i]) + origValue[i];
1378
+
1379
+ if (obj.value[i] > obj.max) obj.value[i] = obj.max;
1380
+ if (obj.value[i] < obj.min) obj.value[i] = obj.min;
1381
+ }
1382
+
1383
+ //RG.clear(obj.canvas);
1384
+ RG.redrawCanvas(obj.canvas);
1385
+
1386
+
1387
+ if (frame < frames) {
1388
+ RG.Effects.updateCanvas(iterator);
1389
+ } else {
1390
+ callback(obj);
1391
+ }
1392
+ };
1393
+
1394
+ iterator();
1395
+ }
1396
+
1397
+ return this;
1398
+ };
1399
+
1400
+
1401
+
1402
+ RG.att(ca);
1403
+
1404
+
1405
+
1406
+
1407
+ /**
1408
+ * Register the object
1409
+ */
1410
+ RG.Register(this);
1411
+
1412
+
1413
+
1414
+
1415
+ /**
1416
+ * This is the 'end' of the constructor so if the first argument
1417
+ * contains configuration data - handle that.
1418
+ */
1419
+ if (parseConfObjectForOptions) {
1420
+ RG.parseObjectStyleConfig(this, conf.options);
1421
+ }
1422
+ };