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,75 +1,1281 @@
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.Meter=function(conf)
3
- {if(typeof conf==='object'&&typeof conf.value!=='undefined'&&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='meter';this.min=RGraph.stringsToNumbers(min);this.max=RGraph.stringsToNumbers(max);this.value=RGraph.stringsToNumbers(value);this.centerx=null;this.centery=null;this.radius=null;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.properties={'chart.background.image.url':null,'chart.background.image.offsetx':0,'chart.background.image.offsety':0,'chart.background.image.stretch':true,'chart.background.color':'white','chart.gutter.left':15,'chart.gutter.right':15,'chart.gutter.top':15,'chart.gutter.bottom':20,'chart.linewidth':1,'chart.linewidth.segments':0,'chart.strokestyle':null,'chart.border':true,'chart.border.color':'black','chart.text.font':'Segoe UI, Arial, Verdana, sans-serif','chart.text.size':12,'chart.text.color':'black','chart.text.valign':'center','chart.text.accessible':false,'chart.text.accessible.overflow':'visible','chart.text.accessible.pointerevents':true,'chart.value.text.decimals':0,'chart.value.text.units.pre':'','chart.value.text.units.post':'','chart.title':'','chart.title.background':null,'chart.title.hpos':null,'chart.title.vpos':null,'chart.title.color':'black','chart.title.bold':true,'chart.title.font':null,'chart.title.x':null,'chart.title.y':null,'chart.title.halign':null,'chart.title.valign':null,'chart.green.start':((this.max-this.min)*0.35)+this.min,'chart.green.end':this.max,'chart.green.color':'#207A20','chart.yellow.start':((this.max-this.min)*0.1)+this.min,'chart.yellow.end':((this.max-this.min)*0.35)+this.min,'chart.yellow.color':'#D0AC41','chart.red.start':this.min,'chart.red.end':((this.max-this.min)*0.1)+this.min,'chart.red.color':'#9E1E1E','chart.colors.ranges':null,'chart.units.pre':'','chart.units.post':'','chart.contextmenu':null,'chart.zoom.factor':1.5,'chart.zoom.fade.in':true,'chart.zoom.fade.out':true,'chart.zoom.hdir':'right','chart.zoom.vdir':'down','chart.zoom.frames':25,'chart.zoom.delay':16.666,'chart.zoom.shadow':true,'chart.zoom.background':true,'chart.zoom.action':'zoom','chart.annotatable':false,'chart.annotate.color':'black','chart.shadow':false,'chart.shadow.color':'rgba(0,0,0,0.5)','chart.shadow.blur':3,'chart.shadow.offsetx':3,'chart.shadow.offsety':3,'chart.resizable':false,'chart.resize.handle.adjust':[0,0],'chart.resize.handle.background':null,'chart.tickmarks.small.num':100,'chart.tickmarks.big.num':10,'chart.tickmarks.small.color':'#bbb','chart.tickmarks.big.color':'black','chart.scale.decimals':0,'chart.scale.point':'.','chart.scale.thousand':',','chart.radius':null,'chart.centerx':null,'chart.centery':null,'chart.labels':true,'chart.labels.count':10,'chart.labels.specific':null,'chart.segment.radius.start':0,'chart.needle.radius':null,'chart.needle.tail':false,'chart.needle.head':true,'chart.needle.color':'black','chart.needle.image.url':null,'chart.needle.image.offsetx':0,'chart.needle.image.offsety':0,'chart.adjustable':false,'chart.angles.start':RGraph.PI,'chart.angles.end':RGraph.TWOPI,'chart.centerpin.stroke':'black','chart.centerpin.fill':'white','chart.clearto':'rgba(0,0,0,0)'}
6
- if(!this.canvas){alert('[METER] No canvas support');return;}
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=arguments[1]||null;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.value'){this.value=value;return;}
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.value'){return this.value;}
19
- return prop[name];};this.draw=this.Draw=function()
20
- {RG.FireCustomEvent(this,'onbeforedraw');if(this.value>this.max)this.value=this.max;if(this.value<this.min)this.value=this.min;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.gutterBottom;this.radius=Math.min((ca.width-this.gutterLeft-this.gutterRight)/2,(ca.height-this.gutterTop-this.gutterBottom));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;}
21
- this.drawBackground();this.drawLabels();this.drawNeedle();this.drawReadout();RG.DrawTitle(this,prop['chart.title'],this.gutterTop,null,prop['chart.title.size']?prop['chart.title.size']:prop['chart.text.size']+2);if(prop['chart.contextmenu']){RG.ShowContext(this);}
22
- if(prop['chart.resizable']){RG.AllowResizing(this);}
23
- RG.InstallEventListeners(this);if(this.firstDraw){RG.fireCustomEvent(this,'onfirstdraw');this.firstDraw=false;this.firstDrawFunc();}
24
- RG.FireCustomEvent(this,'ondraw');return this;};this.exec=function(func)
25
- {func(this);return this;};this.drawBackground=this.DrawBackground=function()
26
- {if(typeof prop['chart.background.image.url']==='string'&&!this.__background_image__){var x=0+prop['chart.background.image.offsetx'];var y=0+prop['chart.background.image.offsety'];var img=new Image();this.__background_image__=img;img.src=prop['chart.background.image.url'];img.onload=function()
27
- {if(prop['chart.background.image.stretch']){co.drawImage(this,x,y,ca.width,ca.height);}else{co.drawImage(this,x,y);}
28
- RG.redraw();}}else if(this.__background_image__){var x=0+prop['chart.background.image.offsetx'];var y=0+prop['chart.background.image.offsety'];if(prop['chart.background.image.stretch']){co.drawImage(this.__background_image__,x,y,ca.width,ca.height);}else{co.drawImage(this.__background_image__,x,y);}}
29
- co.beginPath();co.fillStyle=prop['chart.background.color'];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.moveTo(this.centerx,this.centery);co.arc(this.centerx,this.centery,this.radius,prop['chart.angles.start'],prop['chart.angles.end'],false);co.fill();RG.NoShadow(this);if(prop['chart.shadow']){co.beginPath();var r=(this.radius*0.06)>40?40:(this.radius*0.06);co.arc(this.centerx,this.centery,r,0,RG.TWOPI,0);co.fill();RG.NoShadow(this);}
31
- if(prop['chart.tickmarks.small.num']){for(var i=0;i<(prop['chart.angles.end']-prop['chart.angles.start']);i+=(RG.PI/prop['chart.tickmarks.small.num'])){co.beginPath();co.strokeStyle=prop['chart.tickmarks.small.color'];co.arc(this.centerx,this.centery,this.radius,prop['chart.angles.start']+i,prop['chart.angles.start']+i+0.00001,0);co.arc(this.centerx,this.centery,this.radius-5,prop['chart.angles.start']+i,prop['chart.angles.start']+i+0.00001,0);co.stroke();}
32
- co.beginPath();co.fillStyle=prop['chart.background.color'];co.arc(this.centerx,this.centery,this.radius-4,prop['chart.angles.start'],prop['chart.angles.end'],false);co.closePath();co.fill();}
33
- if(prop['chart.tickmarks.big.num']){var colors=['white','white',prop['chart.tickmarks.big.color']];for(var j=0;j<colors.length;++j){for(var i=0;i<(prop['chart.angles.end']-prop['chart.angles.start']);i+=((prop['chart.angles.end']-prop['chart.angles.start'])/prop['chart.tickmarks.big.num'])){co.beginPath();co.strokeStyle=colors[j];co.arc(this.centerx,this.centery,this.radius,prop['chart.angles.start']+i,prop['chart.angles.start']+i+0.001,0);co.arc(this.centerx,this.centery,this.radius-5,prop['chart.angles.start']+i,prop['chart.angles.start']+i+0.0001,0);co.stroke();}}}
34
- co.beginPath();co.fillStyle=prop['chart.background.color'];co.moveTo(this.centerx,this.centery);co.arc(this.centerx,this.centery,this.radius-7,prop['chart.angles.start'],prop['chart.angles.end'],false);co.closePath();co.fill();var ranges=prop['chart.colors.ranges'];if(RG.is_array(prop['chart.colors.ranges'])){var ranges=prop['chart.colors.ranges'];for(var i=0;i<ranges.length;++i){co.strokeStyle=prop['chart.strokestyle']?prop['chart.strokestyle']:ranges[i][2];co.fillStyle=ranges[i][2];co.lineWidth=prop['chart.linewidth.segments'];co.beginPath();co.arc(this.centerx,this.centery,this.radius*0.85,(((ranges[i][0]-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],(((ranges[i][1]-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],false);if(prop['chart.segment.radius.start']>0){co.arc(this.centerx,this.centery,prop['chart.segment.radius.start'],(((ranges[i][1]-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],(((ranges[i][0]-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],true);}else{co.lineTo(this.centerx,this.centery);}
35
- co.closePath();co.stroke();co.fill();}
36
- co.beginPath();}else{co.lineWidth=prop['chart.linewidth'];co.strokeStyle=prop['chart.strokestyle']?prop['chart.strokestyle']:prop['chart.green.color'];co.fillStyle=prop['chart.green.color'];co.lineWidth=prop['chart.linewidth.segments'];co.beginPath();co.arc(this.centerx,this.centery,this.radius*0.85,(((prop['chart.green.start']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-this.properties['chart.angles.start']))+prop['chart.angles.start'],(((prop['chart.green.end']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],false);if(prop['chart.segment.radius.start']>0){co.arc(this.centerx,this.centery,prop['chart.segment.radius.start'],(((prop['chart.green.end']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],(((prop['chart.green.start']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],true);}else{co.lineTo(this.centerx,this.centery);}
37
- co.closePath();co.stroke();co.fill();co.strokeStyle=prop['chart.strokestyle']?prop['chart.strokestyle']:prop['chart.yellow.color'];co.fillStyle=prop['chart.yellow.color'];co.lineWidth=prop['chart.linewidth.segments'];co.beginPath();co.arc(this.centerx,this.centery,this.radius*0.85,(((prop['chart.yellow.start']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],(((prop['chart.yellow.end']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],false);if(prop['chart.segment.radius.start']>0){co.arc(this.centerx,this.centery,prop['chart.segment.radius.start'],(((prop['chart.yellow.end']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],(((prop['chart.yellow.start']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],true);}else{co.lineTo(this.centerx,this.centery);}
38
- co.closePath();co.stroke();co.fill();co.strokeStyle=prop['chart.strokestyle']?prop['chart.strokestyle']:prop['chart.red.color'];co.fillStyle=prop['chart.red.color'];co.lineWidth=prop['chart.linewidth.segments'];co.beginPath();co.arc(this.centerx,this.centery,this.radius*0.85,(((prop['chart.red.start']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],(((prop['chart.red.end']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],false);if(prop['chart.segment.radius.start']>0){co.arc(this.centerx,this.centery,prop['chart.segment.radius.start'],(((prop['chart.red.end']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],(((prop['chart.red.start']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],true);}else{co.lineTo(this.centerx,this.centery);}
39
- co.closePath();co.stroke();co.fill();co.lineWidth=1;}
40
- if(prop['chart.border']){co.strokeStyle=prop['chart.border.color'];co.lineWidth=prop['chart.linewidth'];co.beginPath();co.moveTo(this.centerx,this.centery);co.arc(this.centerx,this.centery,this.radius,prop['chart.angles.start'],prop['chart.angles.end'],false);co.closePath();}
41
- co.stroke();co.lineWidth=1;};this.drawNeedle=this.DrawNeedle=function()
42
- {var a=(((this.value-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'];if(typeof prop['chart.needle.image.url']==='string'&&!this.__needle_image__){var img=new Image();this.__needle_image__=img;img.src=prop['chart.needle.image.url'];img.onload=function()
43
- {co.save();RG.rotateCanvas(ca,this.centerx,this.centery,a);co.drawImage(this,this.centerx+prop['chart.needle.image.offsetx'],this.centery+prop['chart.needle.image.offsety']);co.restore();RG.redraw();}}else if(this.__needle_image__){co.save();RG.rotateCanvas(ca,this.centerx,this.centery,a);co.drawImage(this.__needle_image__,this.centerx+prop['chart.needle.image.offsetx'],this.centery+prop['chart.needle.image.offsety']);co.restore();}
44
- var needleRadius=typeof(prop['chart.needle.radius'])=='number'?prop['chart.needle.radius']:this.radius*0.7;co.fillStyle='black';co.lineWidth=this.radius>=200?7:3;co.lineCap='round';co.beginPath();co.strokeStyle=prop['chart.needle.color'];if(typeof(prop['chart.needle.linewidth'])=='number')co.lineWidth=prop['chart.needle.linewidth'];co.arc(this.centerx,this.centery,needleRadius,a,a+0.001,false);co.lineTo(this.centerx,this.centery);co.stroke();if(prop['chart.needle.head']){co.fillStyle=prop['chart.needle.color'];co.beginPath();co.lineWidth=1;co.arc(this.centerx,this.centery,needleRadius+15,a,a+0.001,0);co.arc(this.centerx,this.centery,needleRadius-15,a+0.087,a+0.087999,0);co.arc(this.centerx,this.centery,needleRadius-15,a-0.087,a-0.087999,1);co.fill();}
45
- if(prop['chart.needle.tail']){co.beginPath();co.strokeStyle=prop['chart.needle.color'];if(typeof(prop['chart.needle.linewidth'])=='number')co.lineWidth=prop['chart.needle.linewidth'];var a=((this.value-this.min)/(this.max-this.min)*(this.properties['chart.angles.end']-this.properties['chart.angles.start']))+this.properties['chart.angles.start']+RG.PI;co.arc(this.centerx,this.centery,25,a,a+0.001,false);co.lineTo(this.centerx,this.centery);co.stroke();}
46
- var r=(this.radius*0.06)>40?40:(this.radius*0.06);co.beginPath();co.fillStyle=prop['chart.centerpin.stroke'];co.arc(this.centerx,this.centery,r,0+0.001,RG.TWOPI,0);co.fill();co.fillStyle=prop['chart.centerpin.fill'];co.beginPath();co.arc(this.centerx,this.centery,r-2,0+0.001,RG.TWOPI,0);co.fill();};this.drawLabels=this.DrawLabels=function()
47
- {if(!prop['chart.labels']){return;}
48
- var radius=this.radius,text_size=prop['chart.text.size'],text_font=prop['chart.text.font'],units_post=prop['chart.units.post'],units_pre=prop['chart.units.pre'],centerx=this.centerx,centery=this.centery,min=this.min,max=this.max,decimals=prop['chart.scale.decimals'],numLabels=prop['chart.labels.count'],specific=prop['chart.labels.specific']
49
- if(specific){for(var i=0;i<specific.length;++i){var angle=this.getAngle(specific[i][1]),angle_degrees=angle*(180/RG.PI),text=specific[i][0].toString(),coords=RG.getRadiusEndPoint(this.centerx,this.centery,angle,this.radius*0.925)
50
- RG.text2(this,{'font':text_font,'size':text_size,'x':coords[0],'y':coords[1],'text':text,'halign':'center','valign':'center','angle':angle_degrees+90,'bounding':false,'tag':'labels-specific',color:'black'});}
51
- return;}
52
- co.fillStyle=prop['chart.text.color'];co.lineWidth=1;co.beginPath();for(var i=0;i<=numLabels;++i){var angle=((prop['chart.angles.end']-prop['chart.angles.start'])*(i/numLabels))+prop['chart.angles.start'];var coords=RG.getRadiusEndPoint(centerx,centery,angle+(((i==0||i==numLabels)&&prop['chart.border'])?(i==0?0.05:-0.05):0),(this.radius*0.925)-(prop['chart.text.valign']==='bottom'?15:0));var angleStart=prop['chart.angles.start'],angleEnd=prop['chart.angles.end'],angleRange=angleEnd-angleStart,angleStart_degrees=angleStart*(180/RG.PI),angleEnd_degrees=angleEnd*(180/RG.PI),angleRange_degrees=angleRange*(180/RG.PI)
53
- valign=prop['chart.text.valign'];if(prop['chart.border']){if(i==0){halign='left';}else if(i==numLabels){halign='right';}else{halign='center'}}else{halign='center';}
54
- var value=((this.max-this.min)*(i/numLabels))+this.min;RG.text2(this,{'font':text_font,'size':text_size,'x':coords[0],'y':coords[1],'text':RG.numberFormat(this,(value).toFixed(value===0?0:decimals),units_pre,units_post),'halign':halign,'valign':valign,'angle':((angleRange_degrees*(1/numLabels)*i)+angleStart_degrees)-270,'bounding':false,'boundingFill':(i==0||i==numLabels)?'white':null,'tag':'scale'});}};this.drawReadout=this.DrawReadout=function()
55
- {if(prop['chart.value.text']){co.beginPath();co.fillStyle=prop['chart.text.color'];RG.Text2(this,{'font':prop['chart.text.font'],'size':prop['chart.text.size'],'x':this.centerx,'y':this.centery-prop['chart.text.size']-15,'text':prop['chart.value.text.units.pre']+(this.value).toFixed(prop['chart.value.text.decimals'])+prop['chart.value.text.units.post'],'halign':'center','valign':'bottom','bounding':true,'boundingFill':'white','tag':'value.text'});co.stroke();co.fill();}};this.getShape=function(e){};this.getValue=function(e)
56
- {var mouseXY=RG.getMouseXY(e);var angle=RG.getAngleByXY(this.centerx,this.centery,mouseXY[0],mouseXY[1]);var radius=RG.getHypLength(this.centerx,this.centery,mouseXY[0],mouseXY[1]);if(radius>this.radius){return null;}
57
- if(angle<RG.HALFPI){angle+=RG.TWOPI;}
58
- var value=(((angle-prop['chart.angles.start'])/(prop['chart.angles.end']-prop['chart.angles.start']))*(this.max-this.min))+this.min;value=Math.max(value,this.min);value=Math.min(value,this.max);return value;};this.getObjectByXY=function(e)
59
- {var mouseXY=RGraph.getMouseXY(e);var radius=RG.getHypLength(this.centerx,this.centery,mouseXY[0],mouseXY[1]);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)&&radius<=this.radius){return this;}};this.adjusting_mousemove=this.Adjusting_mousemove=function(e)
60
- {if(prop['chart.adjustable']&&RG.Registry.Get('chart.adjusting')&&RG.Registry.Get('chart.adjusting').uid==this.uid){this.value=this.getValue(e);RG.clear(this.canvas);RG.redrawCanvas(this.canvas);RG.fireCustomEvent(this,'onadjust');}};this.getAngle=function(value)
61
- {if(value>this.max||value<this.min){return null;}
62
- var angle=(((value-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'];return angle;};this.parseColors=function()
63
- {if(this.original_colors.length===0){this.original_colors['chart.green.color']=RG.array_clone(prop['chart.green.color']);this.original_colors['chart.yellow.color']=RG.array_clone(prop['chart.yellow.color']);this.original_colors['chart.red.color']=RG.array_clone(prop['chart.red.color']);this.original_colors['chart.colors.ranges']=RG.array_clone(prop['chart.colors.ranges']);}
64
- prop['chart.green.color']=this.parseSingleColorForGradient(prop['chart.green.color']);prop['chart.yellow.color']=this.parseSingleColorForGradient(prop['chart.yellow.color']);prop['chart.red.color']=this.parseSingleColorForGradient(prop['chart.red.color']);var ranges=prop['chart.colors.ranges'];if(ranges&&ranges.length){for(var i=0;i<ranges.length;++i){ranges[i][2]=this.parseSingleColorForGradient(ranges[i][2]);}}};this.reset=function()
65
- {};this.parseSingleColorForGradient=function(color)
66
- {if(!color||typeof(color)!='string'){return color;}
67
- if(color.match(/^gradient\((.*)\)$/i)){var parts=RegExp.$1.split(':');var grad=co.createRadialGradient(this.centerx,this.centery,prop['chart.segment.radius.start'],this.centerx,this.centery,this.radius*0.85);var diff=1/(parts.length-1);for(var j=0;j<parts.length;++j){grad.addColorStop(j*diff,RG.trim(parts[j]));}}
68
- return grad?grad:color;};this.on=function(type,func)
69
- {if(type.substr(0,2)!=='on'){type='on'+type;}
70
- if(typeof this[type]!=='function'){this[type]=func;}else{RG.addCustomEventListener(this,type,func);}
71
- return this;};this.firstDrawFunc=function()
72
- {};this.grow=function()
73
- {var obj=this;obj.currentValue=obj.currentValue||obj.min;var opt=arguments[0]||{};var frames=opt.frames||30;var frame=0;var diff=obj.value-obj.currentValue;var step=diff/frames;var callback=arguments[1]||function(){};var initial=obj.currentValue;function iterator()
74
- {obj.value=initial+(frame++ *step);RG.clear(obj.canvas);RG.redrawCanvas(obj.canvas);if(frame<=frames){RG.Effects.updateCanvas(iterator);}else{callback(obj);}}
75
- iterator();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 bar chart constructor
17
+ *
18
+ * @param string canvas The canvas ID
19
+ * @param min integer The minimum value
20
+ * @param max integer The maximum value
21
+ * @param value integer The indicated value
22
+ */
23
+ RGraph.Meter = function (conf)
24
+ {
25
+ /**
26
+ * Allow for object config style
27
+ */
28
+ if ( typeof conf === 'object'
29
+ && typeof conf.value !== 'undefined'
30
+ && typeof conf.id === 'string') {
31
+
32
+ var id = conf.id
33
+ var canvas = document.getElementById(id);
34
+ var min = conf.min;
35
+ var max = conf.max;
36
+ var value = conf.value;
37
+ var parseConfObjectForOptions = true; // Set this so the config is parsed (at the end of the constructor)
38
+
39
+ } else {
40
+
41
+ var id = conf;
42
+ var canvas = document.getElementById(id);
43
+ var min = arguments[1];
44
+ var max = arguments[2];
45
+ var value = arguments[3];
46
+ }
47
+
48
+
49
+
50
+
51
+ // id, min, max, value
52
+ // Get the canvas and context objects
53
+ this.id = id;
54
+ this.canvas = canvas;
55
+ this.context = this.canvas.getContext ? this.canvas.getContext("2d", {alpha: (typeof id === 'object' && id.alpha === false) ? false : true}) : null;
56
+ this.canvas.__object__ = this;
57
+ this.type = 'meter';
58
+ this.min = RGraph.stringsToNumbers(min);
59
+ this.max = RGraph.stringsToNumbers(max);
60
+ this.value = RGraph.stringsToNumbers(value);
61
+ this.centerx = null;
62
+ this.centery = null;
63
+ this.radius = null;
64
+ this.isRGraph = true;
65
+ this.currentValue = null;
66
+ this.uid = RGraph.CreateUID();
67
+ this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.CreateUID();
68
+ this.colorsParsed = false;
69
+ this.coordsText = [];
70
+ this.original_colors = [];
71
+ this.firstDraw = true; // After the first draw this will be false
72
+
73
+
74
+ /**
75
+ * Compatibility with older browsers
76
+ */
77
+ //RGraph.OldBrowserCompat(this.context);
78
+
79
+
80
+ // Various config type stuff
81
+ this.properties =
82
+ {
83
+ 'chart.background.image.url': null,
84
+ 'chart.background.image.offsetx': 0,
85
+ 'chart.background.image.offsety': 0,
86
+ 'chart.background.image.stretch': true,
87
+ 'chart.background.color': 'white',
88
+ 'chart.gutter.left': 15,
89
+ 'chart.gutter.right': 15,
90
+ 'chart.gutter.top': 15,
91
+ 'chart.gutter.bottom': 20,
92
+ 'chart.linewidth': 1,
93
+ 'chart.linewidth.segments': 0,
94
+ 'chart.strokestyle': null,
95
+ 'chart.border': true,
96
+ 'chart.border.color': 'black',
97
+ 'chart.text.font': 'Segoe UI, Arial, Verdana, sans-serif',
98
+ 'chart.text.size': 12,
99
+ 'chart.text.color': 'black',
100
+ 'chart.text.valign': 'center',
101
+ 'chart.text.accessible': false,
102
+ 'chart.text.accessible.overflow': 'visible',
103
+ 'chart.text.accessible.pointerevents': true,
104
+ 'chart.value.text.decimals': 0,
105
+ 'chart.value.text.units.pre': '',
106
+ 'chart.value.text.units.post': '',
107
+ 'chart.title': '',
108
+ 'chart.title.background': null,
109
+ 'chart.title.hpos': null,
110
+ 'chart.title.vpos': null,
111
+ 'chart.title.color': 'black',
112
+ 'chart.title.bold': true,
113
+ 'chart.title.font': null,
114
+ 'chart.title.x': null,
115
+ 'chart.title.y': null,
116
+ 'chart.title.halign': null,
117
+ 'chart.title.valign': null,
118
+ 'chart.green.start': ((this.max - this.min) * 0.35) + this.min,
119
+ 'chart.green.end': this.max,
120
+ 'chart.green.color': '#207A20',
121
+ 'chart.yellow.start': ((this.max - this.min) * 0.1) + this.min,
122
+ 'chart.yellow.end': ((this.max - this.min) * 0.35) + this.min,
123
+ 'chart.yellow.color': '#D0AC41',
124
+ 'chart.red.start': this.min,
125
+ 'chart.red.end': ((this.max - this.min) * 0.1) + this.min,
126
+ 'chart.red.color': '#9E1E1E',
127
+ 'chart.colors.ranges': null,
128
+ 'chart.units.pre': '',
129
+ 'chart.units.post': '',
130
+ 'chart.contextmenu': null,
131
+ 'chart.zoom.factor': 1.5,
132
+ 'chart.zoom.fade.in': true,
133
+ 'chart.zoom.fade.out': true,
134
+ 'chart.zoom.hdir': 'right',
135
+ 'chart.zoom.vdir': 'down',
136
+ 'chart.zoom.frames': 25,
137
+ 'chart.zoom.delay': 16.666,
138
+ 'chart.zoom.shadow': true,
139
+ 'chart.zoom.background': true,
140
+ 'chart.zoom.action': 'zoom',
141
+ 'chart.annotatable': false,
142
+ 'chart.annotate.color': 'black',
143
+ 'chart.shadow': false,
144
+ 'chart.shadow.color': 'rgba(0,0,0,0.5)',
145
+ 'chart.shadow.blur': 3,
146
+ 'chart.shadow.offsetx': 3,
147
+ 'chart.shadow.offsety': 3,
148
+ 'chart.resizable': false,
149
+ 'chart.resize.handle.adjust': [0,0],
150
+ 'chart.resize.handle.background': null,
151
+ 'chart.tickmarks.small.num': 100,
152
+ 'chart.tickmarks.big.num': 10,
153
+ 'chart.tickmarks.small.color': '#bbb',
154
+ 'chart.tickmarks.big.color': 'black',
155
+ 'chart.scale.decimals': 0,
156
+ 'chart.scale.point': '.',
157
+ 'chart.scale.thousand': ',',
158
+ 'chart.radius': null,
159
+ 'chart.centerx': null,
160
+ 'chart.centery': null,
161
+ 'chart.labels': true,
162
+ 'chart.labels.count': 10,
163
+ 'chart.labels.specific': null,
164
+ 'chart.segment.radius.start': 0,
165
+ 'chart.needle.radius': null,
166
+ 'chart.needle.tail': false,
167
+ 'chart.needle.head': true,
168
+ 'chart.needle.color': 'black',
169
+ 'chart.needle.image.url': null,
170
+ 'chart.needle.image.offsetx': 0,
171
+ 'chart.needle.image.offsety': 0,
172
+ 'chart.adjustable': false,
173
+ 'chart.angles.start': RGraph.PI,
174
+ 'chart.angles.end': RGraph.TWOPI,
175
+ 'chart.centerpin.stroke': 'black',
176
+ 'chart.centerpin.fill': 'white',
177
+ 'chart.clearto': 'rgba(0,0,0,0)'
178
+ }
179
+
180
+
181
+ // Check for support
182
+ if (!this.canvas) {
183
+ alert('[METER] No canvas support');
184
+ return;
185
+ }
186
+
187
+
188
+
189
+ /*
190
+ * Translate half a pixel for antialiasing purposes - but only if it hasn't beeen
191
+ * done already
192
+ */
193
+ if (!this.canvas.__rgraph_aa_translated__) {
194
+ this.context.translate(0.5,0.5);
195
+
196
+ this.canvas.__rgraph_aa_translated__ = true;
197
+ }
198
+
199
+
200
+
201
+
202
+ // Short variable names
203
+ var RG = RGraph,
204
+ ca = this.canvas,
205
+ co = ca.getContext('2d'),
206
+ prop = this.properties,
207
+ pa2 = RG.path2,
208
+ win = window,
209
+ doc = document,
210
+ ma = Math
211
+
212
+
213
+
214
+ /**
215
+ * "Decorate" the object with the generic effects if the effects library has been included
216
+ */
217
+ if (RG.Effects && typeof RG.Effects.decorate === 'function') {
218
+ RG.Effects.decorate(this);
219
+ }
220
+
221
+
222
+
223
+ /**
224
+ * A setter
225
+ *
226
+ * @param name string The name of the property to set
227
+ * @param value mixed The value of the property
228
+ */
229
+ this.set =
230
+ this.Set = function (name)
231
+ {
232
+ var value = arguments[1] || null;
233
+
234
+ /**
235
+ * the number of arguments is only one and it's an
236
+ * object - parse it for configuration data and return.
237
+ */
238
+ if (arguments.length === 1 && typeof name === 'object') {
239
+ RG.parseObjectStyleConfig(this, name);
240
+ return this;
241
+ }
242
+
243
+
244
+
245
+
246
+
247
+ /**
248
+ * This should be done first - prepend the propertyy name with "chart." if necessary
249
+ */
250
+ if (name.substr(0,6) != 'chart.') {
251
+ name = 'chart.' + name;
252
+ }
253
+
254
+
255
+
256
+
257
+ // Convert uppercase letters to dot+lower case letter
258
+ while(name.match(/([A-Z])/)) {
259
+ name = name.replace(/([A-Z])/, '.' + RegExp.$1.toLowerCase());
260
+ }
261
+
262
+
263
+
264
+
265
+ if (name == 'chart.value') {
266
+ this.value = value;
267
+ return;
268
+ }
269
+
270
+
271
+
272
+
273
+
274
+
275
+ prop[name] = value;
276
+
277
+ return this;
278
+ };
279
+
280
+
281
+
282
+
283
+ /**
284
+ * A getter
285
+ *
286
+ * @param name string The name of the property to get
287
+ */
288
+ this.get =
289
+ this.Get = function (name)
290
+ {
291
+ /**
292
+ * This should be done first - prepend the property name with "chart." if necessary
293
+ */
294
+ if (name.substr(0,6) != 'chart.') {
295
+ name = 'chart.' + name;
296
+ }
297
+
298
+ // Convert uppercase letters to dot+lower case letter
299
+ while(name.match(/([A-Z])/)) {
300
+ name = name.replace(/([A-Z])/, '.' + RegExp.$1.toLowerCase());
301
+ }
302
+
303
+ if (name == 'chart.value') {
304
+ return this.value;
305
+ }
306
+
307
+ return prop[name];
308
+ };
309
+
310
+
311
+
312
+
313
+ /**
314
+ * The function you call to draw the bar chart
315
+ */
316
+ this.draw =
317
+ this.Draw = function ()
318
+ {
319
+ /**
320
+ * Fire the onbeforedraw event
321
+ */
322
+ RG.FireCustomEvent(this, 'onbeforedraw');
323
+
324
+ /**
325
+ * Constrain the value to be within the min and max
326
+ */
327
+ if (this.value > this.max) this.value = this.max;
328
+ if (this.value < this.min) this.value = this.min;
329
+
330
+ /**
331
+ * Set the current value
332
+ */
333
+ this.currentValue = this.value;
334
+
335
+ /**
336
+ * This is new in May 2011 and facilitates indiviual gutter settings,
337
+ * eg chart.gutter.left
338
+ */
339
+ this.gutterLeft = prop['chart.gutter.left'];
340
+ this.gutterRight = prop['chart.gutter.right'];
341
+ this.gutterTop = prop['chart.gutter.top'];
342
+ this.gutterBottom = prop['chart.gutter.bottom'];
343
+
344
+ this.centerx = ((ca.width - this.gutterLeft - this.gutterRight) / 2) + this.gutterLeft;
345
+ this.centery = ca.height - this.gutterBottom;
346
+ this.radius = Math.min(
347
+ (ca.width - this.gutterLeft - this.gutterRight) / 2,
348
+ (ca.height - this.gutterTop - this.gutterBottom)
349
+ );
350
+
351
+ /**
352
+ * Stop this growing uncontrollably
353
+ */
354
+ this.coordsText = [];
355
+
356
+
357
+
358
+ /**
359
+ * Custom centerx, centery and radius
360
+ */
361
+ if (typeof(prop['chart.centerx']) == 'number') this.centerx = prop['chart.centerx'];
362
+ if (typeof(prop['chart.centery']) == 'number') this.centery = prop['chart.centery'];
363
+ if (typeof(prop['chart.radius']) == 'number') this.radius = prop['chart.radius'];
364
+
365
+
366
+ /**
367
+ * Parse the colors for gradients. Its down here so that the center X/Y can be used
368
+ */
369
+ if (!this.colorsParsed) {
370
+
371
+ this.parseColors();
372
+
373
+ // Don't want to do this again
374
+ this.colorsParsed = true;
375
+ }
376
+
377
+
378
+ this.drawBackground();
379
+ this.drawLabels();
380
+ this.drawNeedle();
381
+ this.drawReadout();
382
+
383
+ /**
384
+ * Draw the title
385
+ */
386
+ RG.DrawTitle(this, prop['chart.title'], this.gutterTop, null, prop['chart.title.size'] ? prop['chart.title.size'] : prop['chart.text.size'] + 2);
387
+
388
+ /**
389
+ * Setup the context menu if required
390
+ */
391
+ if (prop['chart.contextmenu']) {
392
+ RG.ShowContext(this);
393
+ }
394
+
395
+
396
+ /**
397
+ * This function enables resizing
398
+ */
399
+ if (prop['chart.resizable']) {
400
+ RG.AllowResizing(this);
401
+ }
402
+
403
+
404
+ /**
405
+ * This installs the event listeners
406
+ */
407
+ RG.InstallEventListeners(this);
408
+
409
+
410
+
411
+ /**
412
+ * Fire the onfirstdraw event
413
+ */
414
+ if (this.firstDraw) {
415
+ RG.fireCustomEvent(this, 'onfirstdraw');
416
+ this.firstDraw = false;
417
+ this.firstDrawFunc();
418
+ }
419
+
420
+
421
+
422
+
423
+ /**
424
+ * Fire the RGraph ondraw event
425
+ */
426
+ RG.FireCustomEvent(this, 'ondraw');
427
+
428
+
429
+
430
+ return this;
431
+ };
432
+
433
+
434
+
435
+ /**
436
+ * Used in chaining. Runs a function there and then - not waiting for
437
+ * the events to fire (eg the onbeforedraw event)
438
+ *
439
+ * @param function func The function to execute
440
+ */
441
+ this.exec = function (func)
442
+ {
443
+ func(this);
444
+
445
+ return this;
446
+ };
447
+
448
+
449
+
450
+
451
+ /**
452
+ * Draws the background of the chart
453
+ */
454
+ this.drawBackground =
455
+ this.DrawBackground = function ()
456
+ {
457
+ /**
458
+ * First draw the background image if it's defined
459
+ */
460
+ if (typeof prop['chart.background.image.url'] === 'string' && !this.__background_image__) {
461
+
462
+ var x = 0 + prop['chart.background.image.offsetx'];
463
+ var y = 0 + prop['chart.background.image.offsety'];
464
+ var img = new Image();
465
+
466
+ this.__background_image__ = img;
467
+ img.src = prop['chart.background.image.url'];
468
+
469
+ img.onload = function ()
470
+ {
471
+ if (prop['chart.background.image.stretch']) {
472
+ co.drawImage(this, x,y,ca.width, ca.height);
473
+ } else {
474
+ co.drawImage(this, x,y);
475
+ }
476
+ RG.redraw();
477
+ }
478
+
479
+ } else if (this.__background_image__) {
480
+
481
+ var x = 0 + prop['chart.background.image.offsetx'];
482
+ var y = 0 + prop['chart.background.image.offsety'];
483
+
484
+ if (prop['chart.background.image.stretch']) {
485
+ co.drawImage(this.__background_image__, x,y,ca.width, ca.height);
486
+ } else {
487
+ co.drawImage(this.__background_image__, x,y);
488
+ }
489
+ }
490
+
491
+
492
+
493
+ /**
494
+ * Draw the white background
495
+ */
496
+ co.beginPath();
497
+
498
+ co.fillStyle = prop['chart.background.color'];
499
+
500
+ if (prop['chart.shadow']) {
501
+ RG.SetShadow(this, prop['chart.shadow.color'],prop['chart.shadow.offsetx'],prop['chart.shadow.offsety'], prop['chart.shadow.blur']);
502
+ }
503
+ co.moveTo(this.centerx,this.centery);
504
+ co.arc(this.centerx,
505
+ this.centery,
506
+ this.radius,
507
+ prop['chart.angles.start'],
508
+ prop['chart.angles.end'],
509
+ false);
510
+
511
+ co.fill();
512
+
513
+ RG.NoShadow(this);
514
+
515
+
516
+ // Draw the shadow
517
+ if (prop['chart.shadow']) {
518
+
519
+ co.beginPath();
520
+ var r = (this.radius * 0.06) > 40 ? 40 : (this.radius * 0.06);
521
+ co.arc(this.centerx, this.centery, r, 0, RG.TWOPI, 0);
522
+ co.fill();
523
+
524
+ RG.NoShadow(this);
525
+ }
526
+
527
+
528
+
529
+ // First, draw the grey tickmarks
530
+ if (prop['chart.tickmarks.small.num']) {
531
+ for (var i=0; i<(prop['chart.angles.end'] - prop['chart.angles.start']); i+=(RG.PI / prop['chart.tickmarks.small.num'])) {
532
+ co.beginPath();
533
+ co.strokeStyle = prop['chart.tickmarks.small.color'];
534
+ co.arc(this.centerx, this.centery, this.radius, prop['chart.angles.start'] + i, prop['chart.angles.start'] + i + 0.00001, 0);
535
+ co.arc(this.centerx, this.centery, this.radius - 5, prop['chart.angles.start'] + i, prop['chart.angles.start'] + i + 0.00001, 0);
536
+ co.stroke();
537
+ }
538
+
539
+ // Draw the semi-circle that makes the tickmarks
540
+ co.beginPath();
541
+ co.fillStyle = prop['chart.background.color'];
542
+ co.arc(this.centerx, this.centery, this.radius - 4, prop['chart.angles.start'], prop['chart.angles.end'], false);
543
+ co.closePath();
544
+ co.fill();
545
+ }
546
+
547
+
548
+ // Second, draw the darker tickmarks. First run draws them in white to get rid of the existing tickmark,
549
+ // then the second run draws them in the requested color
550
+
551
+
552
+ if (prop['chart.tickmarks.big.num']) {
553
+ var colors = ['white','white',prop['chart.tickmarks.big.color']];
554
+ for (var j=0; j<colors.length; ++j) {
555
+ for (var i=0; i<(prop['chart.angles.end'] - prop['chart.angles.start']); i+=((prop['chart.angles.end'] - prop['chart.angles.start']) / prop['chart.tickmarks.big.num'])) {
556
+ co.beginPath();
557
+ co.strokeStyle = colors[j];
558
+ co.arc(this.centerx, this.centery, this.radius, prop['chart.angles.start'] + i, prop['chart.angles.start'] + i + 0.001, 0);
559
+ co.arc(this.centerx, this.centery, this.radius - 5, prop['chart.angles.start'] + i, prop['chart.angles.start'] + i + 0.0001, 0);
560
+ co.stroke();
561
+ }
562
+ }
563
+ }
564
+
565
+ // Draw the white circle that makes the tickmarks
566
+ co.beginPath();
567
+ co.fillStyle = prop['chart.background.color'];
568
+ co.moveTo(this.centerx, this.centery);
569
+ co.arc(this.centerx, this.centery, this.radius - 7, prop['chart.angles.start'], prop['chart.angles.end'], false);
570
+ co.closePath();
571
+ co.fill();
572
+
573
+ /**
574
+ * Color ranges - either green/yellow/red or an arbitrary number of ranges
575
+ */
576
+ var ranges = prop['chart.colors.ranges'];
577
+
578
+ if (RG.is_array(prop['chart.colors.ranges'])) {
579
+
580
+ var ranges = prop['chart.colors.ranges'];
581
+
582
+ for (var i=0; i<ranges.length; ++i) {
583
+
584
+ co.strokeStyle = prop['chart.strokestyle'] ? prop['chart.strokestyle'] : ranges[i][2];
585
+ co.fillStyle = ranges[i][2];
586
+ co.lineWidth = prop['chart.linewidth.segments'];
587
+
588
+ co.beginPath();
589
+ co.arc(this.centerx,
590
+ this.centery,
591
+ this.radius * 0.85,
592
+ (((ranges[i][0] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
593
+ (((ranges[i][1] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
594
+ false);
595
+
596
+ if (prop['chart.segment.radius.start'] > 0) {
597
+ co.arc(this.centerx,
598
+ this.centery,
599
+ prop['chart.segment.radius.start'],
600
+ (((ranges[i][1] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
601
+ (((ranges[i][0] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
602
+ true);
603
+ } else {
604
+ co.lineTo(this.centerx, this.centery);
605
+ }
606
+
607
+ co.closePath();
608
+ co.stroke();
609
+ co.fill();
610
+ }
611
+
612
+ // Stops the last line from being changed to a big linewidth.
613
+ co.beginPath();
614
+
615
+ } else {
616
+ co.lineWidth = prop['chart.linewidth'];
617
+
618
+ // Draw the green area
619
+ co.strokeStyle = prop['chart.strokestyle'] ? prop['chart.strokestyle'] : prop['chart.green.color'];
620
+ co.fillStyle = prop['chart.green.color'];
621
+ co.lineWidth = prop['chart.linewidth.segments'];
622
+
623
+ co.beginPath();
624
+ co.arc(this.centerx,
625
+ this.centery,
626
+ this.radius * 0.85,
627
+ (((prop['chart.green.start'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - this.properties['chart.angles.start'])) + prop['chart.angles.start'],
628
+ (((prop['chart.green.end'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
629
+ false);
630
+
631
+ if (prop['chart.segment.radius.start'] > 0) {
632
+
633
+ co.arc(this.centerx,
634
+ this.centery,
635
+ prop['chart.segment.radius.start'],
636
+ (((prop['chart.green.end'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
637
+ (((prop['chart.green.start'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
638
+ true);
639
+ } else {
640
+ co.lineTo(this.centerx, this.centery);
641
+ }
642
+
643
+ co.closePath();
644
+ co.stroke();
645
+ co.fill();
646
+
647
+ // Draw the yellow area
648
+ co.strokeStyle = prop['chart.strokestyle'] ? prop['chart.strokestyle'] : prop['chart.yellow.color'];
649
+ co.fillStyle = prop['chart.yellow.color'];
650
+ co.lineWidth = prop['chart.linewidth.segments'];
651
+ co.beginPath();
652
+ co.arc(this.centerx,
653
+ this.centery,
654
+ this.radius * 0.85,
655
+ (((prop['chart.yellow.start'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
656
+ (((prop['chart.yellow.end'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
657
+ false);
658
+
659
+ if (prop['chart.segment.radius.start'] > 0) {
660
+ co.arc(this.centerx,
661
+ this.centery,
662
+ prop['chart.segment.radius.start'],
663
+ (((prop['chart.yellow.end'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
664
+ (((prop['chart.yellow.start'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
665
+ true);
666
+ } else {
667
+ co.lineTo(this.centerx, this.centery);
668
+ }
669
+
670
+ co.closePath();
671
+ co.stroke();
672
+ co.fill();
673
+
674
+ // Draw the red area
675
+ co.strokeStyle = prop['chart.strokestyle'] ? prop['chart.strokestyle'] : prop['chart.red.color'];
676
+ co.fillStyle = prop['chart.red.color'];
677
+ co.lineWidth = prop['chart.linewidth.segments'];
678
+
679
+ co.beginPath();
680
+ co.arc(this.centerx,
681
+ this.centery,this.radius * 0.85,
682
+ (((prop['chart.red.start'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
683
+ (((prop['chart.red.end'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
684
+ false);
685
+
686
+ if (prop['chart.segment.radius.start'] > 0) {
687
+ co.arc(this.centerx,
688
+ this.centery,
689
+ prop['chart.segment.radius.start'],
690
+ (((prop['chart.red.end'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
691
+ (((prop['chart.red.start'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
692
+ true);
693
+ } else {
694
+ co.lineTo(this.centerx, this.centery);
695
+ }
696
+
697
+ co.closePath();
698
+ co.stroke();
699
+ co.fill();
700
+
701
+ // Revert the linewidth
702
+ co.lineWidth = 1;
703
+ }
704
+
705
+ // Draw the outline
706
+ if (prop['chart.border']) {
707
+ co.strokeStyle = prop['chart.border.color'];
708
+ co.lineWidth = prop['chart.linewidth'];
709
+
710
+ co.beginPath();
711
+ co.moveTo(this.centerx, this.centery);
712
+ co.arc(this.centerx,
713
+ this.centery,
714
+ this.radius,
715
+ prop['chart.angles.start'],
716
+ prop['chart.angles.end'],
717
+ false);
718
+ co.closePath();
719
+ }
720
+
721
+ co.stroke();
722
+
723
+ // Reset the linewidth back to 1
724
+ co.lineWidth = 1;
725
+ };
726
+
727
+
728
+
729
+
730
+ /**
731
+ * Draws the pointer
732
+ */
733
+ this.drawNeedle =
734
+ this.DrawNeedle = function ()
735
+ {
736
+ /**
737
+ * The angle that the needle is at
738
+ */
739
+ var a = (((this.value - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'];
740
+
741
+ /**
742
+ * First draw the background image if it's defined
743
+ */
744
+ if (typeof prop['chart.needle.image.url'] === 'string' && !this.__needle_image__) {
745
+
746
+ var img = new Image();
747
+
748
+ this.__needle_image__ = img;
749
+ img.src = prop['chart.needle.image.url'];
750
+
751
+ img.onload = function ()
752
+ {
753
+ co.save();
754
+ RG.rotateCanvas(ca, this.centerx, this.centery, a);
755
+ co.drawImage(this,
756
+ this.centerx + prop['chart.needle.image.offsetx'],
757
+ this.centery + prop['chart.needle.image.offsety']);
758
+ co.restore();
759
+
760
+ RG.redraw();
761
+ }
762
+
763
+ } else if (this.__needle_image__) {
764
+
765
+ co.save();
766
+ RG.rotateCanvas(ca, this.centerx, this.centery, a);
767
+ co.drawImage(this.__needle_image__,
768
+ this.centerx + prop['chart.needle.image.offsetx'],
769
+ this.centery + prop['chart.needle.image.offsety']);
770
+ co.restore();
771
+ }
772
+
773
+
774
+
775
+
776
+
777
+
778
+
779
+
780
+ // Allow customising the needle radius
781
+ var needleRadius = typeof(prop['chart.needle.radius']) == 'number' ? prop['chart.needle.radius'] : this.radius * 0.7;
782
+
783
+ // First draw the circle at the bottom
784
+ co.fillStyle = 'black';
785
+ co.lineWidth = this.radius >= 200 ? 7 : 3;
786
+ co.lineCap = 'round';
787
+
788
+ // Now, draw the arm of the needle
789
+ co.beginPath();
790
+ co.strokeStyle = prop['chart.needle.color'];
791
+ if (typeof(prop['chart.needle.linewidth']) == 'number') co.lineWidth = prop['chart.needle.linewidth'];
792
+
793
+
794
+ co.arc(this.centerx, this.centery, needleRadius, a, a + 0.001, false);
795
+ co.lineTo(this.centerx, this.centery);
796
+ co.stroke();
797
+
798
+ // Draw the triangular needle head
799
+ if (prop['chart.needle.head']) {
800
+
801
+ co.fillStyle = prop['chart.needle.color'];
802
+ co.beginPath();
803
+ co.lineWidth = 1;
804
+ //co.moveTo(this.centerx, this.centery);
805
+ co.arc(this.centerx, this.centery, needleRadius + 15, a, a + 0.001, 0);
806
+ co.arc(this.centerx, this.centery, needleRadius - 15, a + 0.087, a + 0.087999, 0);
807
+ co.arc(this.centerx, this.centery, needleRadius - 15, a - 0.087, a - 0.087999, 1);
808
+ co.fill();
809
+ }
810
+
811
+ // Draw the tail if requested
812
+ if (prop['chart.needle.tail']) {
813
+ co.beginPath();
814
+ co.strokeStyle = prop['chart.needle.color'];
815
+ if (typeof(prop['chart.needle.linewidth']) == 'number') co.lineWidth = prop['chart.needle.linewidth'];
816
+
817
+ var a = ((this.value - this.min) / (this.max - this.min) * (this.properties['chart.angles.end'] - this.properties['chart.angles.start'])) + this.properties['chart.angles.start'] + RG.PI;
818
+ co.arc(this.centerx, this.centery, 25, a, a + 0.001, false);
819
+ co.lineTo(this.centerx, this.centery);
820
+ co.stroke();
821
+ }
822
+
823
+ // Draw the center circle (the stroke)
824
+ var r = (this.radius * 0.06) > 40 ? 40 : (this.radius * 0.06);
825
+
826
+ co.beginPath();
827
+ co.fillStyle = prop['chart.centerpin.stroke'];
828
+ co.arc(this.centerx, this.centery, r, 0 + 0.001, RG.TWOPI, 0);
829
+ co.fill();
830
+
831
+
832
+
833
+
834
+
835
+
836
+
837
+
838
+
839
+
840
+
841
+
842
+
843
+
844
+ // Draw the centre bit of the circle (the fill)
845
+ co.fillStyle = prop['chart.centerpin.fill'];
846
+ co.beginPath();
847
+ co.arc(this.centerx, this.centery, r - 2, 0 + 0.001, RG.TWOPI, 0);
848
+ co.fill();
849
+ };
850
+
851
+
852
+
853
+
854
+ /**
855
+ * Draws the labels
856
+ */
857
+ this.drawLabels =
858
+ this.DrawLabels = function ()
859
+ {
860
+ if (!prop['chart.labels']) {
861
+ return;
862
+ }
863
+
864
+ var radius = this.radius,
865
+ text_size = prop['chart.text.size'],
866
+ text_font = prop['chart.text.font'],
867
+ units_post = prop['chart.units.post'],
868
+ units_pre = prop['chart.units.pre'],
869
+ centerx = this.centerx,
870
+ centery = this.centery,
871
+ min = this.min,
872
+ max = this.max,
873
+ decimals = prop['chart.scale.decimals'],
874
+ numLabels = prop['chart.labels.count'],
875
+ specific = prop['chart.labels.specific']
876
+
877
+
878
+
879
+
880
+ //
881
+ // Draw the specific labels if they're specifid
882
+ //
883
+ if (specific) {
884
+ for (var i=0; i<specific.length; ++i) {
885
+
886
+ var angle = this.getAngle(specific[i][1]),
887
+ angle_degrees = angle * (180 / RG.PI),
888
+ text = specific[i][0].toString(),
889
+ coords = RG.getRadiusEndPoint(this.centerx, this.centery, angle, this.radius * 0.925)
890
+
891
+
892
+ RG.text2(this, {
893
+ 'font':text_font,
894
+ 'size':text_size,
895
+ 'x': coords[0],
896
+ 'y': coords[1],
897
+ 'text':text,
898
+ 'halign':'center',
899
+ 'valign':'center',
900
+ 'angle':angle_degrees + 90,
901
+ 'bounding': false,
902
+ 'tag': 'labels-specific',
903
+ color: 'black'
904
+ });
905
+ }
906
+
907
+ return;
908
+ }
909
+
910
+
911
+
912
+
913
+ co.fillStyle = prop['chart.text.color'];
914
+ co.lineWidth = 1;
915
+
916
+ co.beginPath();
917
+
918
+ for (var i=0; i<=numLabels; ++i) {
919
+
920
+ var angle = ((prop['chart.angles.end'] - prop['chart.angles.start']) * (i / numLabels)) + prop['chart.angles.start'];
921
+ var coords = RG.getRadiusEndPoint(centerx, centery, angle + (((i == 0 || i == numLabels) && prop['chart.border']) ? (i == 0 ? 0.05 : -0.05) : 0), (this.radius * 0.925) - (prop['chart.text.valign'] === 'bottom' ? 15 : 0));
922
+
923
+ var angleStart = prop['chart.angles.start'],
924
+ angleEnd = prop['chart.angles.end'],
925
+ angleRange = angleEnd - angleStart,
926
+ angleStart_degrees = angleStart * (180 / RG.PI),
927
+ angleEnd_degrees = angleEnd * (180 / RG.PI),
928
+ angleRange_degrees = angleRange * (180 / RG.PI)
929
+
930
+ // Vertical alignment
931
+ valign = prop['chart.text.valign'];
932
+
933
+ // Horizontal alignment
934
+ if (prop['chart.border']) {
935
+ if (i == 0) {
936
+ halign = 'left';
937
+ } else if (i == numLabels) {
938
+ halign = 'right';
939
+ } else {
940
+ halign = 'center'
941
+ }
942
+ } else {
943
+ halign = 'center';
944
+ }
945
+
946
+ var value = ((this.max - this.min) * (i / numLabels)) + this.min;
947
+
948
+ RG.text2(this, {
949
+ 'font':text_font,
950
+ 'size':text_size,
951
+ 'x':coords[0],
952
+ 'y':coords[1],
953
+ 'text':RG.numberFormat(this, (value).toFixed(value === 0 ? 0 : decimals),units_pre,units_post),
954
+ 'halign':halign,
955
+ 'valign':valign,
956
+ 'angle':((angleRange_degrees * (1 / numLabels) * i) + angleStart_degrees) - 270,
957
+ 'bounding':false,
958
+ 'boundingFill':(i == 0 || i == numLabels) ? 'white': null,
959
+ 'tag': 'scale'
960
+ });
961
+ }
962
+ };
963
+
964
+
965
+
966
+
967
+ /**
968
+ * This function draws the text readout if specified
969
+ */
970
+ this.drawReadout =
971
+ this.DrawReadout = function ()
972
+ {
973
+ if (prop['chart.value.text']) {
974
+ co.beginPath();
975
+ co.fillStyle = prop['chart.text.color'];
976
+ RG.Text2(this, {'font':prop['chart.text.font'],
977
+ 'size':prop['chart.text.size'],
978
+ 'x':this.centerx,
979
+ 'y':this.centery - prop['chart.text.size'] - 15,
980
+ 'text': prop['chart.value.text.units.pre'] + (this.value).toFixed(prop['chart.value.text.decimals']) + prop['chart.value.text.units.post'],
981
+ 'halign':'center',
982
+ 'valign':'bottom',
983
+ 'bounding':true,
984
+ 'boundingFill':'white',
985
+ 'tag': 'value.text'
986
+ });
987
+
988
+ co.stroke();
989
+ co.fill();
990
+ }
991
+ };
992
+
993
+
994
+
995
+
996
+ /**
997
+ * A placeholder function
998
+ *
999
+ * @param object The event object
1000
+ */
1001
+ this.getShape = function (e) {};
1002
+
1003
+
1004
+
1005
+
1006
+ /**
1007
+ * This function returns the pertinent value for a particular click (or other mouse event)
1008
+ *
1009
+ * @param obj e The event object
1010
+ */
1011
+ this.getValue = function (e)
1012
+ {
1013
+ var mouseXY = RG.getMouseXY(e);
1014
+ var angle = RG.getAngleByXY(this.centerx, this.centery, mouseXY[0], mouseXY[1]);
1015
+
1016
+ // Work out the radius
1017
+ var radius = RG.getHypLength(this.centerx, this.centery, mouseXY[0], mouseXY[1]);
1018
+ if (radius > this.radius) {
1019
+ return null;
1020
+ }
1021
+
1022
+
1023
+ if (angle < RG.HALFPI) {
1024
+ angle += RG.TWOPI;
1025
+ }
1026
+
1027
+ var value = (((angle - prop['chart.angles.start']) / (prop['chart.angles.end'] - prop['chart.angles.start'])) * (this.max - this.min)) + this.min;
1028
+
1029
+ value = Math.max(value, this.min);
1030
+ value = Math.min(value, this.max);
1031
+
1032
+ return value;
1033
+ };
1034
+
1035
+
1036
+
1037
+
1038
+ /**
1039
+ * The getObjectByXY() worker method. Don't call this call:
1040
+ *
1041
+ * RGraph.ObjectRegistry.getObjectByXY(e)
1042
+ *
1043
+ * @param object e The event object
1044
+ */
1045
+ this.getObjectByXY = function (e)
1046
+ {
1047
+ var mouseXY = RGraph.getMouseXY(e);
1048
+
1049
+ // Work out the radius
1050
+ var radius = RG.getHypLength(this.centerx, this.centery, mouseXY[0], mouseXY[1]);
1051
+
1052
+ if (
1053
+ mouseXY[0] > (this.centerx - this.radius)
1054
+ && mouseXY[0] < (this.centerx + this.radius)
1055
+ && mouseXY[1] > (this.centery - this.radius)
1056
+ && mouseXY[1] < (this.centery + this.radius)
1057
+ && radius <= this.radius
1058
+ ) {
1059
+
1060
+ return this;
1061
+ }
1062
+ };
1063
+
1064
+
1065
+
1066
+
1067
+ /**
1068
+ * This method handles the adjusting calculation for when the mouse is moved
1069
+ *
1070
+ * @param object e The event object
1071
+ */
1072
+ this.adjusting_mousemove =
1073
+ this.Adjusting_mousemove = function (e)
1074
+ {
1075
+ /**
1076
+ * Handle adjusting for the Bar
1077
+ */
1078
+ if (prop['chart.adjustable'] && RG.Registry.Get('chart.adjusting') && RG.Registry.Get('chart.adjusting').uid == this.uid) {
1079
+ this.value = this.getValue(e);
1080
+ RG.clear(this.canvas);
1081
+ RG.redrawCanvas(this.canvas);
1082
+ RG.fireCustomEvent(this, 'onadjust');
1083
+ }
1084
+ };
1085
+
1086
+
1087
+
1088
+
1089
+ /**
1090
+ * This method returns the appropriate angle for a value
1091
+ *
1092
+ * @param number value The value
1093
+ */
1094
+ this.getAngle = function (value)
1095
+ {
1096
+ // Higher than max
1097
+ if (value > this.max || value < this.min) {
1098
+ return null;
1099
+ }
1100
+
1101
+ var angle = (((value - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'];
1102
+
1103
+ return angle;
1104
+ };
1105
+
1106
+
1107
+
1108
+
1109
+ /**
1110
+ * This allows for easy specification of gradients
1111
+ */
1112
+ this.parseColors = function ()
1113
+ {
1114
+ // Save the original colors so that they can be restored when the canvas is reset
1115
+ if (this.original_colors.length === 0) {
1116
+ this.original_colors['chart.green.color'] = RG.array_clone(prop['chart.green.color']);
1117
+ this.original_colors['chart.yellow.color'] = RG.array_clone(prop['chart.yellow.color']);
1118
+ this.original_colors['chart.red.color'] = RG.array_clone(prop['chart.red.color']);
1119
+ this.original_colors['chart.colors.ranges'] = RG.array_clone(prop['chart.colors.ranges']);
1120
+ }
1121
+
1122
+ // Parse the basic colors
1123
+ prop['chart.green.color'] = this.parseSingleColorForGradient(prop['chart.green.color']);
1124
+ prop['chart.yellow.color'] = this.parseSingleColorForGradient(prop['chart.yellow.color']);
1125
+ prop['chart.red.color'] = this.parseSingleColorForGradient(prop['chart.red.color']);
1126
+
1127
+ // Parse chart.colors.ranges
1128
+ var ranges = prop['chart.colors.ranges'];
1129
+ if (ranges && ranges.length) {
1130
+ for (var i=0; i<ranges.length; ++i) {
1131
+ ranges[i][2] = this.parseSingleColorForGradient(ranges[i][2]);
1132
+ }
1133
+ }
1134
+ };
1135
+
1136
+
1137
+
1138
+
1139
+ /**
1140
+ * Use this function to reset the object to the post-constructor state. Eg reset colors if
1141
+ * need be etc
1142
+ */
1143
+ this.reset = function ()
1144
+ {
1145
+ };
1146
+
1147
+
1148
+
1149
+
1150
+ /**
1151
+ * This parses a single color value
1152
+ */
1153
+ this.parseSingleColorForGradient = function (color)
1154
+ {
1155
+ if (!color || typeof(color) != 'string') {
1156
+ return color;
1157
+ }
1158
+
1159
+ if (color.match(/^gradient\((.*)\)$/i)) {
1160
+
1161
+ var parts = RegExp.$1.split(':');
1162
+
1163
+ // Create the gradient
1164
+ var grad = co.createRadialGradient(this.centerx, this.centery, prop['chart.segment.radius.start'], this.centerx, this.centery, this.radius * 0.85);
1165
+
1166
+ var diff = 1 / (parts.length - 1);
1167
+
1168
+ for (var j=0; j<parts.length; ++j) {
1169
+ grad.addColorStop(j * diff, RG.trim(parts[j]));
1170
+ }
1171
+ }
1172
+
1173
+ return grad ? grad : color;
1174
+ };
1175
+
1176
+
1177
+
1178
+
1179
+ /**
1180
+ * Using a function to add events makes it easier to facilitate method chaining
1181
+ *
1182
+ * @param string type The type of even to add
1183
+ * @param function func
1184
+ */
1185
+ this.on = function (type, func)
1186
+ {
1187
+ if (type.substr(0,2) !== 'on') {
1188
+ type = 'on' + type;
1189
+ }
1190
+
1191
+ if (typeof this[type] !== 'function') {
1192
+ this[type] = func;
1193
+ } else {
1194
+ RG.addCustomEventListener(this, type, func);
1195
+ }
1196
+
1197
+ return this;
1198
+ };
1199
+
1200
+
1201
+
1202
+
1203
+ /**
1204
+ * This function runs once only
1205
+ * (put at the end of the file (before any effects))
1206
+ */
1207
+ this.firstDrawFunc = function ()
1208
+ {
1209
+ };
1210
+
1211
+
1212
+
1213
+
1214
+ /**
1215
+ * Meter Grow
1216
+ *
1217
+ * This effect gradually increases the represented value
1218
+ *
1219
+ * @param An object of options - eg: {frames: 60}
1220
+ * @param function An optional callback function
1221
+ */
1222
+ this.grow = function ()
1223
+ {
1224
+ var obj = this;
1225
+
1226
+ obj.currentValue = obj.currentValue || obj.min;
1227
+
1228
+ var opt = arguments[0] || {};
1229
+ var frames = opt.frames || 30;
1230
+ var frame = 0;
1231
+ var diff = obj.value - obj.currentValue;
1232
+ var step = diff / frames;
1233
+ var callback = arguments[1] || function () {};
1234
+ var initial = obj.currentValue;
1235
+
1236
+
1237
+
1238
+ function iterator ()
1239
+ {
1240
+ obj.value = initial + (frame++ * step);
1241
+
1242
+ RG.clear(obj.canvas);
1243
+ RG.redrawCanvas(obj.canvas);
1244
+
1245
+ if (frame <= frames) {
1246
+ RG.Effects.updateCanvas(iterator);
1247
+ } else {
1248
+ callback(obj);
1249
+ }
1250
+ }
1251
+
1252
+ iterator();
1253
+
1254
+ return this;
1255
+ };
1256
+
1257
+
1258
+
1259
+
1260
+
1261
+ RG.att(ca);
1262
+
1263
+
1264
+
1265
+
1266
+ /**
1267
+ * Register the object
1268
+ */
1269
+ RG.register(this);
1270
+
1271
+
1272
+
1273
+
1274
+ /**
1275
+ * This is the 'end' of the constructor so if the first argument
1276
+ * contains configuration data - handle that.
1277
+ */
1278
+ if (parseConfObjectForOptions) {
1279
+ RG.parseObjectStyleConfig(this, conf.options);
1280
+ }
1281
+ };