rgraph-rails 5.00 → 6.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/publish-geml.yaml +46 -0
  3. data/.gitignore +1 -0
  4. data/README.md +4 -5
  5. data/lib/rgraph-rails/version.rb +1 -1
  6. data/rgraph-rails.gemspec +4 -4
  7. data/vendor/assets/javascripts/RGraph.activity.js +1691 -0
  8. data/vendor/assets/javascripts/RGraph.bar.js +4253 -236
  9. data/vendor/assets/javascripts/RGraph.bipolar.js +3958 -162
  10. data/vendor/assets/javascripts/RGraph.common.annotate.js +414 -35
  11. data/vendor/assets/javascripts/RGraph.common.context.js +635 -30
  12. data/vendor/assets/javascripts/RGraph.common.core.js +10485 -419
  13. data/vendor/assets/javascripts/RGraph.common.csv.js +508 -27
  14. data/vendor/assets/javascripts/RGraph.common.dynamic.js +1693 -90
  15. data/vendor/assets/javascripts/RGraph.common.effects.js +1629 -89
  16. data/vendor/assets/javascripts/RGraph.common.key.js +1003 -53
  17. data/vendor/assets/javascripts/RGraph.common.moment.js +5670 -0
  18. data/vendor/assets/javascripts/RGraph.common.sheets.js +541 -31
  19. data/vendor/assets/javascripts/RGraph.common.sheets.php +351 -0
  20. data/vendor/assets/javascripts/RGraph.common.starburst.js +382 -0
  21. data/vendor/assets/javascripts/RGraph.common.table.js +386 -0
  22. data/vendor/assets/javascripts/RGraph.common.tooltips.js +1433 -32
  23. data/vendor/assets/javascripts/RGraph.drawing.background.js +660 -35
  24. data/vendor/assets/javascripts/RGraph.drawing.circle.js +618 -34
  25. data/vendor/assets/javascripts/RGraph.drawing.image.js +857 -52
  26. data/vendor/assets/javascripts/RGraph.drawing.line.js +712 -0
  27. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +760 -38
  28. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +740 -37
  29. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +573 -36
  30. data/vendor/assets/javascripts/RGraph.drawing.poly.js +667 -36
  31. data/vendor/assets/javascripts/RGraph.drawing.rect.js +638 -34
  32. data/vendor/assets/javascripts/RGraph.drawing.text.js +672 -37
  33. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +653 -52
  34. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +714 -51
  35. data/vendor/assets/javascripts/RGraph.fuel.js +1149 -59
  36. data/vendor/assets/javascripts/RGraph.funnel.js +1277 -56
  37. data/vendor/assets/javascripts/RGraph.gantt.js +1646 -82
  38. data/vendor/assets/javascripts/RGraph.gauge.js +1773 -89
  39. data/vendor/assets/javascripts/RGraph.hbar.js +3869 -159
  40. data/vendor/assets/javascripts/RGraph.horseshoe.js +970 -0
  41. data/vendor/assets/javascripts/RGraph.hprogress.js +1829 -81
  42. data/vendor/assets/javascripts/RGraph.line.js +5293 -244
  43. data/vendor/assets/javascripts/RGraph.meter.js +1570 -77
  44. data/vendor/assets/javascripts/RGraph.modaldialog.js +300 -19
  45. data/vendor/assets/javascripts/RGraph.odo.js +1553 -68
  46. data/vendor/assets/javascripts/RGraph.pie.js +3273 -129
  47. data/vendor/assets/javascripts/RGraph.radar.js +2333 -108
  48. data/vendor/assets/javascripts/RGraph.rose.js +2685 -114
  49. data/vendor/assets/javascripts/RGraph.rscatter.js +1920 -80
  50. data/vendor/assets/javascripts/RGraph.scatter.js +4215 -171
  51. data/vendor/assets/javascripts/RGraph.segmented.js +1006 -0
  52. data/vendor/assets/javascripts/RGraph.semicircularprogress.js +1980 -59
  53. data/vendor/assets/javascripts/RGraph.svg.activity.js +1696 -0
  54. data/vendor/assets/javascripts/RGraph.svg.bar.js +2575 -77
  55. data/vendor/assets/javascripts/RGraph.svg.bipolar.js +3533 -106
  56. data/vendor/assets/javascripts/RGraph.svg.common.ajax.js +240 -21
  57. data/vendor/assets/javascripts/RGraph.svg.common.core.js +7105 -299
  58. data/vendor/assets/javascripts/RGraph.svg.common.csv.js +408 -28
  59. data/vendor/assets/javascripts/RGraph.svg.common.fx.js +1291 -68
  60. data/vendor/assets/javascripts/RGraph.svg.common.key.js +451 -20
  61. data/vendor/assets/javascripts/RGraph.svg.common.sheets.js +543 -31
  62. data/vendor/assets/javascripts/RGraph.svg.common.table.js +391 -0
  63. data/vendor/assets/javascripts/RGraph.svg.common.tooltips.js +1072 -23
  64. data/vendor/assets/javascripts/RGraph.svg.funnel.js +1151 -32
  65. data/vendor/assets/javascripts/RGraph.svg.gauge.js +1429 -34
  66. data/vendor/assets/javascripts/RGraph.svg.hbar.js +2692 -65
  67. data/vendor/assets/javascripts/RGraph.svg.horseshoe.js +969 -0
  68. data/vendor/assets/javascripts/RGraph.svg.line.js +2855 -86
  69. data/vendor/assets/javascripts/RGraph.svg.pie.js +1630 -58
  70. data/vendor/assets/javascripts/RGraph.svg.radar.js +1772 -58
  71. data/vendor/assets/javascripts/RGraph.svg.rose.js +2419 -83
  72. data/vendor/assets/javascripts/RGraph.svg.scatter.js +2280 -65
  73. data/vendor/assets/javascripts/RGraph.svg.segmented.js +930 -0
  74. data/vendor/assets/javascripts/RGraph.svg.semicircularprogress.js +1612 -29
  75. data/vendor/assets/javascripts/RGraph.svg.waterfall.js +1525 -50
  76. data/vendor/assets/javascripts/RGraph.thermometer.js +1411 -64
  77. data/vendor/assets/javascripts/RGraph.vprogress.js +1915 -81
  78. data/vendor/assets/javascripts/RGraph.waterfall.js +1896 -89
  79. data/vendor/assets/javascripts/financial-data.js +1067 -0
  80. metadata +37 -16
  81. data/.travis.yml +0 -11
  82. data/vendor/assets/javascripts/RGraph.common.deprecated.js +0 -35
  83. data/vendor/assets/javascripts/RGraph.common.resizing.js +0 -38
  84. data/vendor/assets/javascripts/RGraph.common.zoom.js +0 -15
  85. data/vendor/assets/javascripts/RGraph.cornergauge.js +0 -71
@@ -1,78 +1,1571 @@
1
+ 'version:2023-09-16 (6.14)';
2
+ //
3
+ // o--------------------------------------------------------------------------------o
4
+ // | This file is part of the RGraph package - you can learn more at: |
5
+ // | |
6
+ // | https://www.rgraph.net |
7
+ // | |
8
+ // | RGraph is licensed under the Open Source MIT license. That means that it's |
9
+ // | totally free to use and there are no restrictions on what you can do with it! |
10
+ // o--------------------------------------------------------------------------------o
1
11
 
2
- RGraph=window.RGraph||{isRGraph:true};RGraph.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.propertyNameAliases={};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.margin.left':15,'chart.margin.right':15,'chart.margin.top':15,'chart.margin.bottom':20,'chart.linewidth':1,'chart.linewidth.segments':0,'chart.colors.stroke':null,'chart.border':true,'chart.border.color':'black','chart.text.font':'Arial, Verdana, sans-serif','chart.text.size':12,'chart.text.color':'black','chart.text.bold':false,'chart.text.italic':false,'chart.text.valign':'center','chart.text.accessible':false,'chart.text.accessible.overflow':'visible','chart.text.accessible.pointerevents':false,'chart.labels':true,'chart.labels.count':10,'chart.labels.specific':null,'chart.labels.radius.offset':0,'chart.labels.font':null,'chart.labels.size':null,'chart.labels.color':null,'chart.labels.bold':null,'chart.labels.italic':null,'chart.labels.value.text':false,'chart.labels.value.text.font':null,'chart.labels.value.text.size':null,'chart.labels.value.text.bold':null,'chart.labels.value.text.italic':null,'chart.labels.value.text.color':null,'chart.labels.value.text.decimals':0,'chart.labels.value.text.units.pre':'','chart.labels.value.text.units.post':'','chart.labels.value.text.background':true,'chart.labels.value.text.background.fill':'rgba(255,255,255,0.75)','chart.labels.value.text.background.stroke':'rgba(0,0,0,0)','chart.labels.value.text.specific':null,'chart.labels.value.text.accessible':true,'chart.title':'','chart.title.background':null,'chart.title.hpos':null,'chart.title.vpos':null,'chart.title.color':null,'chart.title.bold':null,'chart.title.font':null,'chart.title.italic':null,'chart.title.size':null,'chart.title.x':null,'chart.title.y':null,'chart.title.halign':null,'chart.title.valign':null,'chart.colors.green.start':((this.max-this.min)*0.35)+this.min,'chart.colors.green.end':this.max,'chart.colors.green.color':'#207A20','chart.colors.yellow.start':((this.max-this.min)*0.1)+this.min,'chart.colors.yellow.end':((this.max-this.min)*0.35)+this.min,'chart.colors.yellow.color':'#D0AC41','chart.colors.red.start':this.min,'chart.colors.red.end':((this.max-this.min)*0.1)+this.min,'chart.colors.red.color':'#9E1E1E','chart.colors.ranges':null,'chart.contextmenu':null,'chart.annotatable':false,'chart.annotatable.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.resizable.handle.adjust':[0,0],'chart.resizable.handle.background':null,'chart.tickmarks.small.count':100,'chart.tickmarks.small.color':'#bbb','chart.tickmarks.large.count':10,'chart.tickmarks.large.color':'black','chart.scale.units.pre':'','chart.scale.units.post':'','chart.scale.decimals':0,'chart.scale.point':'.','chart.scale.thousand':',','chart.radius':null,'chart.centerx':null,'chart.centery':null,'chart.segments.radius.start':0,'chart.needle.radius':null,'chart.needle.type':'normal','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.marginLeft=prop['chart.margin.left'];this.marginRight=prop['chart.margin.right'];this.marginTop=prop['chart.margin.top'];this.marginBottom=prop['chart.margin.bottom'];this.centerx=((ca.width-this.marginLeft-this.marginRight)/2)+this.marginLeft;this.centery=ca.height-this.marginBottom;this.radius=Math.min((ca.width-this.marginLeft-this.marginRight)/2,(ca.height-this.marginTop-this.marginBottom));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.marginTop,null,typeof prop['chart.title.size']==='boolean'?prop['chart.title.size']:prop['chart.text.size']);if(prop['chart.contextmenu']){RG.showContext(this);}
22
- if(prop['chart.resizable']){RG.allowResizing(this);}
23
- RG.installEventListeners(this);if(this.firstDraw){this.firstDraw=false;RG.fireCustomEvent(this,'onfirstdraw');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.count']){for(var i=0;i<(prop['chart.angles.end']-prop['chart.angles.start']);i+=(RG.PI/prop['chart.tickmarks.small.count'])){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.large.count']){var colors=['white','white',prop['chart.tickmarks.large.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.large.count'])){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.isArray(prop['chart.colors.ranges'])){var ranges=prop['chart.colors.ranges'];for(var i=0;i<ranges.length;++i){co.strokeStyle=prop['chart.colors.stroke']?prop['chart.colors.stroke']: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.segments.radius.start']>0){co.arc(this.centerx,this.centery,prop['chart.segments.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.colors.stroke']?prop['chart.colors.stroke']:prop['chart.colors.green.color'];co.fillStyle=prop['chart.colors.green.color'];co.lineWidth=prop['chart.linewidth.segments'];co.beginPath();co.arc(this.centerx,this.centery,this.radius*0.85,(((prop['chart.colors.green.start']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],(((prop['chart.colors.green.end']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],false);if(prop['chart.segments.radius.start']>0){co.arc(this.centerx,this.centery,prop['chart.segments.radius.start'],(((prop['chart.colors.green.end']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],(((prop['chart.colors.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.colors.stroke']?prop['chart.colors.stroke']:prop['chart.colors.yellow'];co.fillStyle=prop['chart.colors.yellow.color'];co.lineWidth=prop['chart.linewidth.segments'];co.beginPath();co.arc(this.centerx,this.centery,this.radius*0.85,(((prop['chart.colors.yellow.start']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],(((prop['chart.colors.yellow.end']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],false);if(prop['chart.segments.radius.start']>0){co.arc(this.centerx,this.centery,prop['chart.segments.radius.start'],(((prop['chart.colors.yellow.end']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],(((prop['chart.colors.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.colors.stroke']?prop['chart.colors.stroke']:prop['chart.colors.red.color'];co.fillStyle=prop['chart.colors.red.color'];co.lineWidth=prop['chart.linewidth.segments'];co.beginPath();co.arc(this.centerx,this.centery,this.radius*0.85,(((prop['chart.colors.red.start']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],(((prop['chart.colors.red.end']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],false);if(prop['chart.segments.radius.start']>0){co.arc(this.centerx,this.centery,prop['chart.segments.radius.start'],(((prop['chart.colors.red.end']-this.min)/(this.max-this.min))*(prop['chart.angles.end']-prop['chart.angles.start']))+prop['chart.angles.start'],(((prop['chart.colors.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;if(prop['chart.needle.type']==='pointer'){var r=(this.radius*0.06)>40?40:(this.radius*0.06);co.beginPath();co.fillStyle=prop['chart.needle.color'];co.moveTo(this.centerx,this.centery);co.arc(this.centerx,this.centery,r,0,RG.TWOPI,false);co.fill();co.beginPath();co.arc(this.centerx,this.centery,r,a+RG.HALFPI,a+RG.HALFPI+0.0001,false);co.arc(this.centerx,this.centery,needleRadius,a,a+0.001,false);co.arc(this.centerx,this.centery,r,a-RG.HALFPI,a-RG.HALFPI+0.001,false);co.fill();}else{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_italic=prop['chart.text.italic'],units_post=prop['chart.scale.units.post'],units_pre=prop['chart.scale.units.pre'],point=prop['chart.scale.point'],thousand=prop['chart.scale.thousand'],centerx=this.centerx,centery=this.centery,min=this.min,max=this.max,decimals=prop['chart.scale.decimals'],numLabels=prop['chart.labels.count'],offset=prop['chart.labels.radius.offset'],specific=prop['chart.labels.specific'];var textConf=RG.getTextConf({object:this,prefix:'chart.labels'});if(specific){for(var i=0;i<specific.length;++i){if(typeof specific[i]==='string'||typeof specific[i]==='number'){var angle=this.getAngle((((this.max-this.min)/specific.length)/2)+(((this.max-this.min)/specific.length)*i)+this.min),angle_degrees=angle*(180/RG.PI),text=specific[i].toString(),coords=RG.getRadiusEndPoint(this.centerx,this.centery,angle,(this.radius*0.925)+offset);}else{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)+offset);}
49
- RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:coords[0],y:coords[1],text:text,halign:'center',valign:'center',angle:angle_degrees+90,bounding:false,tag:'labels-specific'});}
50
- return;}
51
- 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)+prop['chart.labels.radius.offset']));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)
52
- 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';}
53
- var value=((this.max-this.min)*(i/numLabels))+this.min;RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:coords[0],y:coords[1],text:RG.numberFormat({object:this,number:(value).toFixed(value===0?0:decimals),unitspre:units_pre,unitspost:units_post,point:point,thousand:thousand}),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()
54
- {if(prop['chart.labels.value.text']){var text=(prop['chart.labels.value.text.units.pre']||'')
55
- +(this.value).toFixed(prop['chart.labels.value.text.decimals'])
56
- +(prop['chart.labels.value.text.units.post']||'');if(typeof prop['chart.labels.value.text.specific']==='string'){text=prop['chart.labels.value.text.specific'];}
57
- var textConf=RG.getTextConf({object:this,prefix:'chart.labels.value.text'});RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:this.centerx,y:this.centery-textConf.size-15,text:text,halign:'center',valign:'bottom',bounding:prop['chart.labels.value.text.background'],boundingFill:prop['chart.labels.value.text.background.fill'],boundingStroke:prop['chart.labels.value.text.background.stroke'],accessible:prop['chart.labels.value.text.accessible'],tag:'value.text'});}};this.getShape=function(e){};this.getValue=function(e)
58
- {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;}
59
- if(angle<RG.HALFPI){angle+=RG.TWOPI;}
60
- 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)
61
- {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)
62
- {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)
63
- {if(value>this.max||value<this.min){return null;}
64
- 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()
65
- {if(this.original_colors.length===0){this.original_colors['chart.colors.green.color']=RG.arrayClone(prop['chart.colors.green.color']);this.original_colors['chart.colors.yellow.color']=RG.arrayClone(prop['chart.colors.yellow.color']);this.original_colors['chart.colors.red.color']=RG.arrayClone(prop['chart.colors.red.color']);this.original_colors['chart.colors.ranges']=RG.arrayClone(prop['chart.colors.ranges']);}
66
- prop['chart.colors.green.color']=this.parseSingleColorForGradient(prop['chart.colors.green.color']);prop['chart.colors.yellow.color']=this.parseSingleColorForGradient(prop['chart.colors.yellow.color']);prop['chart.colors.red.color']=this.parseSingleColorForGradient(prop['chart.colors.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()
67
- {};this.parseSingleColorForGradient=function(color)
68
- {if(!color||typeof(color)!='string'){return color;}
69
- if(color.match(/^gradient\((.*)\)$/i)){if(color.match(/^gradient\(({.*})\)$/i)){return RGraph.parseJSONGradient({object:this,def:RegExp.$1,radial:true});}
70
- var parts=RegExp.$1.split(':');var grad=co.createRadialGradient(this.centerx,this.centery,prop['chart.segments.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]));}}
71
- return grad?grad:color;};this.on=function(type,func)
72
- {if(type.substr(0,2)!=='on'){type='on'+type;}
73
- if(typeof this[type]!=='function'){this[type]=func;}else{RG.addCustomEventListener(this,type,func);}
74
- return this;};this.firstDrawFunc=function()
75
- {};this.grow=function()
76
- {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()
77
- {obj.value=initial+(frame++ *step);RG.clear(obj.canvas);RG.redrawCanvas(obj.canvas);if(frame<=frames){RG.Effects.updateCanvas(iterator);}else{callback(obj);}}
78
- iterator();return this;};RG.register(this);if(parseConfObjectForOptions){RG.parseObjectStyleConfig(this,conf.options);}};
12
+ RGraph = window.RGraph || {isrgraph:true,isRGraph:true,rgraph:true};
13
+
14
+ //
15
+ // The bar chart constructor
16
+ //
17
+ RGraph.Meter = function (conf)
18
+ {
19
+ var id = conf.id
20
+ var canvas = document.getElementById(id);
21
+ var min = conf.min;
22
+ var max = conf.max;
23
+ var value = conf.value;
24
+
25
+ // id, min, max, value
26
+ // Get the canvas and context objects
27
+ this.id = id;
28
+ this.canvas = canvas;
29
+ this.context = this.canvas.getContext ? this.canvas.getContext("2d", {alpha: (typeof id === 'object' && id.alpha === false) ? false : true}) : null;
30
+ this.canvas.__object__ = this;
31
+ this.type = 'meter';
32
+ this.min = RGraph.stringsToNumbers(min);
33
+ this.max = RGraph.stringsToNumbers(max);
34
+ this.value = RGraph.stringsToNumbers(value);
35
+ this.centerx = null;
36
+ this.centery = null;
37
+ this.radius = null;
38
+ this.isRGraph = true;
39
+ this.isrgraph = true;
40
+ this.rgraph = true;
41
+ this.currentValue = null;
42
+ this.uid = RGraph.createUID();
43
+ this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.createUID();
44
+ this.colorsParsed = false;
45
+ this.coordsText = [];
46
+ this.original_colors = [];
47
+ this.firstDraw = true; // After the first draw this will be false
48
+ this.stopAnimationRequested = false;// Used to control the animations
49
+
50
+
51
+ // Various config type stuff
52
+ this.properties =
53
+ {
54
+ backgroundImageUrl: null,
55
+ backgroundImageOffsetx: 0,
56
+ backgroundImageOffsety: 0,
57
+ backgroundImageStretch: true,
58
+ backgroundColor: 'white',
59
+
60
+ marginLeft: 35,
61
+ marginRight: 35,
62
+ marginTop: 35,
63
+ marginBottom: 35,
64
+
65
+ linewidth: 1,
66
+ linewidthSegments: 0,
67
+
68
+ colorsStroke: null,
69
+
70
+ border: true,
71
+ borderColor: 'black',
72
+
73
+ textFont: 'Arial, Verdana, sans-serif',
74
+ textSize: 12,
75
+ textColor: 'black',
76
+ textBold: false,
77
+ textItalic: false,
78
+ textValign: 'center',
79
+ textAccessible: false,
80
+ textAccessibleOverflow: 'visible',
81
+ textAccessiblePointerevents: false,
82
+ text: null,
83
+
84
+ labels: true,
85
+ labelsCount: 10,
86
+ labelsSpecific: null,
87
+ labelsRadiusOffset: 0,
88
+ labelsOffsetRadius: null,
89
+ labelsFont: null,
90
+ labelsSize: null,
91
+ labelsColor: null,
92
+ labelsBold: null,
93
+ labelsItalic: null,
94
+ labelsValue: false,
95
+ labelsValueFont: null,
96
+ labelsValueSize: null,
97
+ labelsValueBold: null,
98
+ labelsValueItalic: null,
99
+ labelsValueColor: null,
100
+ labelsValueDecimals: 0,
101
+ labelsValuePoint: '.',
102
+ labelsValueThousand: ',',
103
+ labelsValueUnitsPre: '',
104
+ labelsValueUnitsPost: '',
105
+ labelsValueBackground: true,
106
+ labelsValueBackgroundFill: 'rgba(255,255,255,0.75)',
107
+ labelsValueBackgroundStroke: 'rgba(0,0,0,0)',
108
+ labelsValueSpecific: null,
109
+ labelsValueAccessible: true,
110
+ labelsValueOffsetx: 0,
111
+ labelsValueOffsety: 0,
112
+
113
+ title: '',
114
+ titleColor: null,
115
+ titleBold: null,
116
+ titleFont: null,
117
+ titleItalic: null,
118
+ titleSize: null,
119
+ titleX: null,
120
+ titleY: null,
121
+ titleHalign: null,
122
+ titleValign: null,
123
+ titleOffsetx: 0,
124
+ titleOffsety: 0,
125
+ titleSubtitle: '',
126
+ titleSubtitleSize: null,
127
+ titleSubtitleColor: '#aaa',
128
+ titleSubtitleFont: null,
129
+ titleSubtitleBold: null,
130
+ titleSubtitleItalic: null,
131
+ titleSubtitleOffsetx: 0,
132
+ titleSubtitleOffsety: 0,
133
+
134
+ colorsGreenStart: ((this.max - this.min) * 0.35) + this.min,
135
+ colorsGreenEnd: this.max,
136
+ colorsGreenColor: '#207A20',
137
+ colorsYellowStart: ((this.max - this.min) * 0.1) + this.min,
138
+ colorsYellowEnd: ((this.max - this.min) * 0.35) + this.min,
139
+ colorsYellowColor: '#D0AC41',
140
+ colorsRedStart: this.min,
141
+ colorsRedEnd: ((this.max - this.min) * 0.1) + this.min,
142
+ colorsRedColor: '#9E1E1E',
143
+ colorsRanges: null,
144
+
145
+ contextmenu: null,
146
+
147
+ annotatable: false,
148
+ annotatableColor: 'black',
149
+
150
+ shadow: false,
151
+ shadowColor: 'rgba(0,0,0,0.5)',
152
+ shadowBlur: 3,
153
+ shadowOffsetx: 3,
154
+ shadowOffsety: 3,
155
+
156
+ resizable: false,
157
+ resizableHandleAdjust: [0,0],
158
+ resizableHandleBackground: null,
159
+
160
+ tickmarksSmallCount: 100,
161
+ tickmarksSmallColor: '#bbb',
162
+ tickmarksLargeCount: 10,
163
+ tickmarksLargeColor: 'black',
164
+
165
+ scaleUnitsPre: '',
166
+ scaleUnitsPost: '',
167
+ scaleDecimals: 0,
168
+ scalePoint: '.',
169
+ scaleThousand: ',',
170
+
171
+ radius: null,
172
+ centerx: null,
173
+ centery: null,
174
+
175
+ segmentsRadiusStart: 0,
176
+
177
+ needleRadius: null,
178
+ needleType: 'normal',
179
+ needleTail: false,
180
+ needleHead: true,
181
+ needleHeadLength: 30,
182
+ needleHeadWidth: 0.088,
183
+ needleColor: 'black',
184
+ needleImageUrl: null,
185
+ needleImageOffsetx: 0,
186
+ needleImageOffsety: 0,
187
+
188
+ adjustable: false,
189
+
190
+ anglesStart: RGraph.PI,
191
+ anglesEnd: RGraph.TWOPI,
192
+
193
+ centerpinStroke: 'black',
194
+ centerpinFill: 'white',
195
+
196
+ clearto: 'rgba(0,0,0,0)'
197
+ }
198
+
199
+
200
+ // Check for support
201
+ if (!this.canvas) {
202
+ alert('[METER] No canvas support');
203
+ return;
204
+ }
205
+
206
+
207
+
208
+
209
+ // Easy access to properties and the path function
210
+ var properties = this.properties;
211
+ this.path = RGraph.pathObjectFunction;
212
+
213
+
214
+
215
+ //
216
+ // "Decorate" the object with the generic effects if the effects library has been included
217
+ //
218
+ if (RGraph.Effects && typeof RGraph.Effects.decorate === 'function') {
219
+ RGraph.Effects.decorate(this);
220
+ }
221
+
222
+
223
+
224
+ // Add the responsive method. This method resides in the common file.
225
+ this.responsive = RGraph.responsive;
226
+
227
+
228
+ //
229
+ // A setter
230
+ //
231
+ this.set = function (name)
232
+ {
233
+ // BC for the labeslsValueText properties
234
+ if (name.substr(0, 15) === 'labelsValueText') {
235
+ name = name.replace(/^labelsValueText/, 'labelsValue');
236
+ }
237
+
238
+ var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
239
+
240
+ // the number of arguments is only one and it's an
241
+ // object - parse it for configuration data and return.
242
+ if (arguments.length === 1 && typeof arguments[0] === 'object') {
243
+ for (i in arguments[0]) {
244
+ if (typeof i === 'string') {
245
+ this.set(i, arguments[0][i]);
246
+ }
247
+ }
248
+
249
+ return this;
250
+ }
251
+
252
+ properties[name] = value;
253
+
254
+ return this;
255
+ };
256
+
257
+
258
+
259
+
260
+
261
+
262
+
263
+
264
+ //
265
+ // A getter
266
+ //
267
+ // @param name string The name of the property to get
268
+ //
269
+ this.get = function (name)
270
+ {
271
+ return properties[name];
272
+ };
273
+
274
+
275
+
276
+
277
+
278
+
279
+
280
+
281
+ //
282
+ // The function you call to draw the bar chart
283
+ //
284
+ this.draw = function ()
285
+ {
286
+ //
287
+ // Fire the onbeforedraw event
288
+ //
289
+ RGraph.fireCustomEvent(this, 'onbeforedraw');
290
+
291
+
292
+
293
+ // Translate half a pixel for antialiasing purposes - but only if it hasn't been
294
+ // done already
295
+ //
296
+ // MUST be the first thing done!
297
+ //
298
+ if (!this.canvas.__rgraph_aa_translated__) {
299
+ this.context.translate(0.5,0.5);
300
+
301
+ this.canvas.__rgraph_aa_translated__ = true;
302
+ }
303
+
304
+
305
+ //
306
+ // Constrain the value to be within the min and max
307
+ //
308
+ if (this.value > this.max) this.value = this.max;
309
+ if (this.value < this.min) this.value = this.min;
310
+
311
+ //
312
+ // Set the current value
313
+ //
314
+ this.currentValue = this.value;
315
+
316
+
317
+
318
+ //
319
+ // Make the margins easy to access
320
+ //
321
+ this.marginLeft = properties.marginLeft;
322
+ this.marginRight = properties.marginRight;
323
+ this.marginTop = properties.marginTop;
324
+ this.marginBottom = properties.marginBottom;
325
+
326
+ this.centerx = ((this.canvas.width - this.marginLeft - this.marginRight) / 2) + this.marginLeft;
327
+ this.centery = this.canvas.height - this.marginBottom;
328
+ this.radius = Math.min(
329
+ (this.canvas.width - this.marginLeft - this.marginRight) / 2,
330
+ (this.canvas.height - this.marginTop - this.marginBottom)
331
+ );
332
+
333
+ //
334
+ // Stop this growing uncontrollably
335
+ //
336
+ this.coordsText = [];
337
+
338
+
339
+
340
+ //
341
+ // Custom centerx, centery and radius
342
+ //
343
+ if (typeof properties.centerx === 'number') this.centerx = properties.centerx;
344
+ if (typeof properties.centery === 'number') this.centery = properties.centery;
345
+ if (typeof properties.radius === 'number') this.radius = properties.radius;
346
+
347
+
348
+ //
349
+ // Parse the colors for gradients. Its down here so that the center X/Y can be used
350
+ //
351
+ if (!this.colorsParsed) {
352
+
353
+ this.parseColors();
354
+
355
+ // Don't want to do this again
356
+ this.colorsParsed = true;
357
+ }
358
+
359
+
360
+ this.drawBackground();
361
+ this.drawLabels();
362
+ this.drawNeedle();
363
+ this.drawReadout();
364
+
365
+ //
366
+ // Draw the title
367
+ //
368
+ RGraph.drawTitle(this);
369
+
370
+ //
371
+ // Setup the context menu if required
372
+ //
373
+ if (properties.contextmenu) {
374
+ RGraph.showContext(this);
375
+ }
376
+
377
+
378
+
379
+
380
+ //
381
+ // Add custom text thats specified
382
+ //
383
+ RGraph.addCustomText(this);
384
+
385
+
386
+
387
+
388
+
389
+
390
+
391
+
392
+ //
393
+ // This installs the event listeners
394
+ //
395
+ RGraph.installEventListeners(this);
396
+
397
+
398
+
399
+ //
400
+ // Fire the onfirstdraw event
401
+ //
402
+ if (this.firstDraw) {
403
+ this.firstDraw = false;
404
+ RGraph.fireCustomEvent(this, 'onfirstdraw');
405
+ this.firstDrawFunc();
406
+ }
407
+
408
+
409
+
410
+
411
+ //
412
+ // Fire the RGraph draw event
413
+ //
414
+ RGraph.fireCustomEvent(this, 'ondraw');
415
+
416
+
417
+
418
+
419
+
420
+
421
+
422
+
423
+ //
424
+ // Install any inline responsive configuration. This
425
+ // should be last in the draw function - even after
426
+ // the draw events.
427
+ //
428
+ RGraph.installInlineResponsive(this);
429
+
430
+
431
+
432
+
433
+
434
+
435
+
436
+
437
+
438
+
439
+
440
+ return this;
441
+ };
442
+
443
+
444
+
445
+
446
+
447
+
448
+
449
+
450
+ //
451
+ // Used in chaining. Runs a function there and then - not waiting for
452
+ // the events to fire (eg the onbeforedraw event)
453
+ //
454
+ // @param function func The function to execute
455
+ //
456
+ this.exec = function (func)
457
+ {
458
+ func(this);
459
+
460
+ return this;
461
+ };
462
+
463
+
464
+
465
+
466
+
467
+
468
+
469
+
470
+ //
471
+ // Draws the background of the chart
472
+ //
473
+ this.drawBackground = function ()
474
+ {
475
+ //
476
+ // First draw the background image if it's defined
477
+ //
478
+ if (typeof properties.backgroundImageUrl === 'string' && !this.__background_image__) {
479
+
480
+ var x = 0 + properties.backgroundImageOffsetx;
481
+ var y = 0 + properties.backgroundImageOffsety;
482
+ var img = new Image();
483
+
484
+ this.__background_image__ = img;
485
+ img.src = properties.backgroundImageUrl;
486
+ var obj = this;
487
+
488
+ img.onload = function ()
489
+ {
490
+ if (properties.backgroundImageStretch) {
491
+ obj.context.drawImage(this, x,y,obj.canvas.width, obj.canvas.height);
492
+ } else {
493
+ obj.context.drawImage(this, x,y);
494
+ }
495
+ RGraph.redraw();
496
+ }
497
+
498
+ } else if (this.__background_image__) {
499
+
500
+ var x = 0 + properties.backgroundImageOffsetx;
501
+ var y = 0 + properties.backgroundImageOffsety;
502
+
503
+ if (properties.backgroundImageStretch) {
504
+ this.context.drawImage(this.__background_image__, x,y,this.canvas.width, this.canvas.height);
505
+ } else {
506
+ this.context.drawImage(this.__background_image__, x,y);
507
+ }
508
+ }
509
+
510
+
511
+
512
+ //
513
+ // Draw the white background
514
+ //
515
+ this.context.beginPath();
516
+
517
+ this.context.fillStyle = properties.backgroundColor;
518
+
519
+ if (properties.shadow) {
520
+ RGraph.setShadow(
521
+ this,
522
+ properties.shadowColor,
523
+ properties.shadowOffsetx,
524
+ properties.shadowOffsety,
525
+ properties.shadowBlur
526
+ );
527
+ }
528
+
529
+ this.context.moveTo(this.centerx,this.centery);
530
+ this.context.arc(
531
+ this.centerx,
532
+ this.centery,
533
+ this.radius,
534
+ properties.anglesStart,
535
+ properties.anglesEnd,
536
+ false
537
+ );
538
+
539
+ this.context.fill();
540
+
541
+ RGraph.noShadow(this);
542
+
543
+
544
+ // Draw the shadow
545
+ if (properties.shadow) {
546
+
547
+ this.context.beginPath();
548
+ var r = (this.radius * 0.06) > 40 ? 40 : (this.radius * 0.06);
549
+ this.context.arc(this.centerx, this.centery, r, 0, RGraph.TWOPI, 0);
550
+ this.context.fill();
551
+
552
+ RGraph.noShadow(this);
553
+ }
554
+
555
+
556
+
557
+ // First, draw the grey tickmarks
558
+ if (properties.tickmarksSmallCount) {
559
+ for (var i=0; i<(properties.anglesEnd - properties.anglesStart); i+=(RGraph.PI / properties.tickmarksSmallCount)) {
560
+ this.context.beginPath();
561
+ this.context.strokeStyle = properties.tickmarksSmallColor;
562
+ this.context.arc(this.centerx, this.centery, this.radius, properties.anglesStart + i, properties.anglesStart + i + 0.00001, 0);
563
+ this.context.arc(this.centerx, this.centery, this.radius - 5, properties.anglesStart + i, properties.anglesStart + i + 0.00001, 0);
564
+ this.context.stroke();
565
+ }
566
+
567
+ // Draw the semi-circle that makes the tickmarks
568
+ this.context.beginPath();
569
+ this.context.fillStyle = properties.backgroundColor;
570
+ this.context.arc(this.centerx, this.centery, this.radius - 4, properties.anglesStart, properties.anglesEnd, false);
571
+ this.context.closePath();
572
+ this.context.fill();
573
+ }
574
+
575
+
576
+ // Second, draw the darker tickmarks. First run draws them in white to get rid of the existing tickmark,
577
+ // then the second run draws them in the requested color
578
+
579
+
580
+ if (properties.tickmarksLargeCount) {
581
+
582
+ var colors = ['white','white',properties.tickmarksLargeColor];
583
+
584
+ for (var j=0; j<colors.length; ++j) {
585
+ for (var i=0; i<(properties.anglesEnd - properties.anglesStart); i+=((properties.anglesEnd - properties.anglesStart) / properties.tickmarksLargeCount)) {
586
+ this.context.beginPath();
587
+ this.context.strokeStyle = colors[j];
588
+ this.context.arc(this.centerx, this.centery, this.radius, properties.anglesStart + i, properties.anglesStart + i + 0.001, 0);
589
+ this.context.arc(this.centerx, this.centery, this.radius - 5, properties.anglesStart + i, properties.anglesStart + i + 0.0001, 0);
590
+ this.context.stroke();
591
+ }
592
+ }
593
+ }
594
+
595
+ // Draw the white circle that makes the tickmarks
596
+ this.context.beginPath();
597
+ this.context.fillStyle = properties.backgroundColor;
598
+ this.context.moveTo(this.centerx, this.centery);
599
+ this.context.arc(
600
+ this.centerx,
601
+ this.centery,
602
+ this.radius - 7,
603
+ properties.anglesStart,
604
+ properties.anglesEnd,
605
+ false
606
+ );
607
+ this.context.closePath();
608
+ this.context.fill();
609
+
610
+ //
611
+ // Color ranges - either green/yellow/red or an arbitrary number of ranges
612
+ //
613
+ var ranges = properties.colorsRanges;
614
+
615
+ if (RGraph.isArray(properties.colorsRanges)) {
616
+
617
+ var ranges = properties.colorsRanges;
618
+
619
+ for (var i=0; i<ranges.length; ++i) {
620
+
621
+ this.context.strokeStyle = properties.colorsStroke ? properties.colorsStroke : ranges[i][2];
622
+ this.context.fillStyle = ranges[i][2];
623
+ this.context.lineWidth = properties.linewidthSegments;
624
+
625
+ this.context.beginPath();
626
+ this.context.arc(
627
+ this.centerx,
628
+ this.centery,
629
+ this.radius * 0.85,
630
+ (((ranges[i][0] - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart,
631
+ (((ranges[i][1] - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart,
632
+ false
633
+ );
634
+
635
+ if (properties.segmentsRadiusStart > 0) {
636
+ this.context.arc(
637
+ this.centerx,
638
+ this.centery,
639
+ properties.segmentsRadiusStart,
640
+ (((ranges[i][1] - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart,
641
+ (((ranges[i][0] - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart,
642
+ true
643
+ );
644
+ } else {
645
+ this.context.lineTo(this.centerx, this.centery);
646
+ }
647
+
648
+ this.context.closePath();
649
+ this.context.stroke();
650
+ this.context.fill();
651
+ }
652
+
653
+ // Stops the last line from being changed to a big linewidth.
654
+ this.context.beginPath();
655
+
656
+ } else {
657
+ this.context.lineWidth = properties.linewidth;
658
+
659
+ // Draw the green area
660
+ this.context.strokeStyle = properties.colorsStroke ? properties.colorsStroke : properties.colorsGreenColor;
661
+ this.context.fillStyle = properties.colorsGreenColor;
662
+ this.context.lineWidth = properties.linewidthSegments;
663
+
664
+ this.context.beginPath();
665
+ this.context.arc(
666
+ this.centerx,
667
+ this.centery,
668
+ this.radius * 0.85,
669
+ (((properties.colorsGreenStart - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart,
670
+ (((properties.colorsGreenEnd - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart,
671
+ false
672
+ );
673
+
674
+ if (properties.segmentsRadiusStart > 0) {
675
+
676
+ this.context.arc(
677
+ this.centerx,
678
+ this.centery,
679
+ properties.segmentsRadiusStart,
680
+ (((properties.colorsGreenEnd - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart,
681
+ (((properties.colorsGreenStart - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart,
682
+ true
683
+ );
684
+ } else {
685
+ this.context.lineTo(this.centerx, this.centery);
686
+ }
687
+
688
+ this.context.closePath();
689
+ this.context.stroke();
690
+ this.context.fill();
691
+
692
+ // Draw the yellow area
693
+ this.context.strokeStyle = properties.colorsStroke ? properties.colorsStroke : properties.colorsYellow;
694
+ this.context.fillStyle = properties.colorsYellowColor;
695
+ this.context.lineWidth = properties.linewidthSegments;
696
+ this.context.beginPath();
697
+ this.context.arc(
698
+ this.centerx,
699
+ this.centery,
700
+ this.radius * 0.85,
701
+ (((properties.colorsYellowStart - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart,
702
+ (((properties.colorsYellowEnd - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart,
703
+ false
704
+ );
705
+
706
+ if (properties.segmentsRadiusStart > 0) {
707
+ this.context.arc(
708
+ this.centerx,
709
+ this.centery,
710
+ properties.segmentsRadiusStart,
711
+ (((properties.colorsYellowEnd - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart,
712
+ (((properties.colorsYellowStart - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart,
713
+ true
714
+ );
715
+ } else {
716
+ this.context.lineTo(this.centerx, this.centery);
717
+ }
718
+
719
+ this.context.closePath();
720
+ this.context.stroke();
721
+ this.context.fill();
722
+
723
+ // Draw the red area
724
+ this.context.strokeStyle = properties.colorsStroke ? properties.colorsStroke : properties.colorsRedColor;
725
+ this.context.fillStyle = properties.colorsRedColor;
726
+ this.context.lineWidth = properties.linewidthSegments;
727
+
728
+ this.context.beginPath();
729
+ this.context.arc(
730
+ this.centerx,
731
+ this.centery,this.radius * 0.85,
732
+ (((properties.colorsRedStart - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart,
733
+ (((properties.colorsRedEnd - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart,
734
+ false
735
+ );
736
+
737
+ if (properties.segmentsRadiusStart > 0) {
738
+ this.context.arc(
739
+ this.centerx,
740
+ this.centery,
741
+ properties.segmentsRadiusStart,
742
+ (((properties.colorsRedEnd - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart,
743
+ (((properties.colorsRedStart - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart,
744
+ true
745
+ );
746
+ } else {
747
+ this.context.lineTo(this.centerx, this.centery);
748
+ }
749
+
750
+ this.context.closePath();
751
+ this.context.stroke();
752
+ this.context.fill();
753
+
754
+ // Revert the linewidth
755
+ this.context.lineWidth = 1;
756
+ }
757
+
758
+ // Draw the outline
759
+ if (properties.border) {
760
+ this.context.strokeStyle = properties.borderColor;
761
+ this.context.lineWidth = properties.linewidth;
762
+
763
+ this.context.beginPath();
764
+ this.context.moveTo(this.centerx, this.centery);
765
+ this.context.arc(
766
+ this.centerx,
767
+ this.centery,
768
+ this.radius,
769
+ properties.anglesStart,
770
+ properties.anglesEnd,
771
+ false
772
+ );
773
+ this.context.closePath();
774
+ }
775
+
776
+ this.context.stroke();
777
+
778
+ // Reset the linewidth back to 1
779
+ this.context.lineWidth = 1;
780
+ };
781
+
782
+
783
+
784
+
785
+
786
+
787
+
788
+
789
+ //
790
+ // Draws the pointer
791
+ //
792
+ this.drawNeedle = function ()
793
+ {
794
+ //
795
+ // The angle that the needle is at
796
+ //
797
+ var a = (((this.value - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart;
798
+
799
+ //
800
+ // First draw the background image if it's defined
801
+ //
802
+ if (typeof properties.needleImageUrl === 'string' && !this.__needle_image__) {
803
+
804
+ var img = new Image();
805
+
806
+ this.__needle_image__ = img;
807
+ img.src = properties.needleImageUrl;
808
+ var obj = this;
809
+
810
+ img.onload = function ()
811
+ {
812
+ obj.context.save();
813
+ RGraph.rotateCanvas(obj.canvas, obj.centerx, obj.centery, a);
814
+ obj.context.drawImage(
815
+ this,
816
+ obj.centerx + properties.needleImageOffsetx,
817
+ obj.centery + properties.needleImageOffsety
818
+ );
819
+ obj.context.restore();
820
+
821
+ RGraph.redraw();
822
+ }
823
+
824
+ } else if (this.__needle_image__) {
825
+
826
+ this.context.save();
827
+ RGraph.rotateCanvas(this.canvas, this.centerx, this.centery, a);
828
+ this.context.drawImage(
829
+ this.__needle_image__,
830
+ this.centerx + properties.needleImageOffsetx,
831
+ this.centery + properties.needleImageOffsety
832
+ );
833
+ this.context.restore();
834
+ }
835
+
836
+
837
+ // Allow customising the needle radius
838
+ var needleRadius = typeof properties.needleRadius === 'number' ? properties.needleRadius : this.radius * 0.7;
839
+
840
+
841
+
842
+ //
843
+ // Draw a simple pointer as for the needle
844
+ //
845
+ if (properties.needleType === 'pointer') {
846
+
847
+ // Draw the center circle (the stroke)
848
+ var r = (this.radius * 0.06) > 40 ? 40 : (this.radius * 0.06);
849
+
850
+ // Draw the black circle at the bottom of the needle
851
+ this.context.beginPath();
852
+
853
+ this.context.fillStyle = properties.needleColor;
854
+
855
+ this.context.moveTo(this.centerx,this.centery);
856
+
857
+ this.context.arc(
858
+ this.centerx,
859
+ this.centery,
860
+ r,
861
+ 0,
862
+ RGraph.TWOPI,
863
+ false
864
+ );
865
+
866
+ this.context.fill();
867
+ this.context.beginPath();
868
+
869
+ // This moves the "pen" to the outer edge of the needle
870
+ this.context.arc(
871
+ this.centerx,
872
+ this.centery,
873
+ r,
874
+ a + RGraph.HALFPI,
875
+ a + RGraph.HALFPI + 0.0001,
876
+ false
877
+ );
878
+
879
+ // Draw a line up to the tip of the needle
880
+ this.context.arc(
881
+ this.centerx,
882
+ this.centery,
883
+ needleRadius,
884
+ a,
885
+ a + 0.001,
886
+ false
887
+ );
888
+
889
+ // Draw a line back down to the other side of the circle
890
+ this.context.arc(
891
+ this.centerx,
892
+ this.centery,
893
+ r,
894
+ a - RGraph.HALFPI,
895
+ a - RGraph.HALFPI + 0.001,
896
+ false
897
+ );
898
+
899
+
900
+ this.context.fill();
901
+
902
+
903
+ } else {
904
+
905
+
906
+ // First draw the circle at the bottom
907
+ this.context.fillStyle = 'black';
908
+ this.context.lineWidth = this.radius >= 200 ? 7 : 3;
909
+ this.context.lineCap = 'round';
910
+
911
+ // Now, draw the arm of the needle
912
+ this.context.beginPath();
913
+ this.context.strokeStyle = properties.needleColor;
914
+ if (typeof properties.needleLinewidth == 'number') this.context.lineWidth = properties.needleLinewidth;
915
+
916
+
917
+ this.context.arc(this.centerx, this.centery, needleRadius, a, a + 0.001, false);
918
+ this.context.lineTo(this.centerx, this.centery);
919
+ this.context.stroke();
920
+
921
+ // Draw the triangular needle head
922
+
923
+ if (properties.needleHead) {
924
+ this.context.fillStyle = properties.needleColor;
925
+ this.context.beginPath();
926
+ this.context.lineWidth = 1;
927
+ //this.context.moveTo(this.centerx, this.centery);
928
+ this.context.arc(this.centerx, this.centery, needleRadius + 15, a, a + 0.001, 0);
929
+ this.context.arc(this.centerx, this.centery, needleRadius - properties.needleHeadLength + 15, a + properties.needleHeadWidth, a + properties.needleHeadWidth, 0);
930
+ this.context.arc(this.centerx, this.centery, needleRadius - properties.needleHeadLength + 15, a - properties.needleHeadWidth, a - properties.needleHeadWidth, 1);
931
+ this.context.fill();
932
+ }
933
+
934
+ // Draw the tail if requested
935
+ if (properties.needleTail) {
936
+ this.context.beginPath();
937
+ this.context.strokeStyle = properties.needleColor;
938
+ if (typeof properties.needleLinewidth == 'number') this.context.lineWidth = properties.needleLinewidth;
939
+
940
+ var a = ((this.value - this.min) / (this.max - this.min) * (this.properties.anglesEnd - this.properties.anglesStart)) + this.properties.anglesStart + RGraph.PI;
941
+ this.context.arc(this.centerx, this.centery, 25, a, a + 0.001, false);
942
+ this.context.lineTo(this.centerx, this.centery);
943
+ this.context.stroke();
944
+ }
945
+
946
+ // Draw the center circle (the stroke)
947
+ var r = (this.radius * 0.06) > 40 ? 40 : (this.radius * 0.06);
948
+
949
+ this.context.beginPath();
950
+ this.context.fillStyle = properties.centerpinStroke;
951
+ this.context.arc(this.centerx, this.centery, r, 0 + 0.001, RGraph.TWOPI, 0);
952
+ this.context.fill();
953
+
954
+
955
+
956
+ // Draw the centre bit of the circle (the fill)
957
+ this.context.fillStyle = properties.centerpinFill;
958
+ this.context.beginPath();
959
+ this.context.arc(this.centerx, this.centery, r - 2, 0 + 0.001, RGraph.TWOPI, 0);
960
+ this.context.fill();
961
+ }
962
+ };
963
+
964
+
965
+
966
+
967
+
968
+
969
+
970
+
971
+ //
972
+ // Draws the labels
973
+ //
974
+ this.drawLabels = function ()
975
+ {
976
+ if (!properties.labels) {
977
+ return;
978
+ }
979
+
980
+ var radius = this.radius,
981
+ text_italic = properties.textItalic,
982
+ units_post = properties.scaleUnitsPost,
983
+ units_pre = properties.scaleUnitsPre,
984
+ point = properties.scalePoint,
985
+ thousand = properties.scaleThousand,
986
+ centerx = this.centerx,
987
+ centery = this.centery,
988
+ min = this.min,
989
+ max = this.max,
990
+ decimals = properties.scaleDecimals,
991
+ numLabels = properties.labelsCount,
992
+ offset = properties.labelsRadiusOffset,
993
+ specific = properties.labelsSpecific;
994
+
995
+ // Allows for new name of property
996
+ if (typeof properties.labelsOffsetRadius === 'number') {
997
+ offset = properties.labelsOffsetRadius;
998
+ }
999
+
1000
+
1001
+ var textConf = RGraph.getTextConf({
1002
+ object: this,
1003
+ prefix: 'labels'
1004
+ });
1005
+
1006
+
1007
+ //
1008
+ // Draw the specific labels if they're specific
1009
+ //
1010
+ if (specific) {
1011
+
1012
+ for (var i=0; i<specific.length; ++i) {
1013
+
1014
+ if (typeof specific[i] === 'string' || typeof specific[i] === 'number') {
1015
+
1016
+ var angle = this.getAngle(
1017
+ (((this.max - this.min) / specific.length) / 2) + (((this.max - this.min) / specific.length) * i) + this.min
1018
+ ),
1019
+ angle_degrees = angle * (180 / RGraph.PI),
1020
+ text = specific[i].toString(),
1021
+ coords = RGraph.getRadiusEndPoint(
1022
+ this.centerx,
1023
+ this.centery,
1024
+ angle,
1025
+ (this.radius * 0.925) + offset
1026
+ );
1027
+
1028
+ } else {
1029
+
1030
+ var angle = this.getAngle(specific[i][1]),
1031
+ angle_degrees = angle * (180 / RGraph.PI),
1032
+ text = specific[i][0].toString(),
1033
+ coords = RGraph.getRadiusEndPoint(
1034
+ this.centerx,
1035
+ this.centery,
1036
+ angle,
1037
+ (this.radius * 0.925) + offset
1038
+ );
1039
+ }
1040
+
1041
+ RGraph.text({
1042
+
1043
+ object: this,
1044
+
1045
+ font: textConf.font,
1046
+ size: textConf.size,
1047
+ color: textConf.color,
1048
+ bold: textConf.bold,
1049
+ italic: textConf.italic,
1050
+
1051
+ x: coords[0],
1052
+ y: coords[1],
1053
+ text: text,
1054
+ halign: 'center',
1055
+ valign: 'center',
1056
+ angle: angle_degrees + 90,
1057
+ bounding: false,
1058
+ tag: 'labels-specific'
1059
+ });
1060
+ }
1061
+
1062
+ return;
1063
+ }
1064
+
1065
+
1066
+
1067
+
1068
+ this.context.fillStyle = properties.textColor;
1069
+ this.context.lineWidth = 1;
1070
+
1071
+ this.context.beginPath();
1072
+
1073
+ for (var i=0; i<=numLabels; ++i) {
1074
+
1075
+ var angle = ((properties.anglesEnd - properties.anglesStart) * (i / numLabels)) + properties.anglesStart;
1076
+ var coords = RGraph.getRadiusEndPoint(
1077
+ centerx,
1078
+ centery,
1079
+ angle + (((i == 0 || i == numLabels) && properties.border) ? (i == 0 ? 0.05 : -0.05) : 0),
1080
+ ((this.radius * 0.925) - (properties.textValign === 'bottom' ? 15 : 0) + offset
1081
+ ));
1082
+
1083
+ var angleStart = properties.anglesStart,
1084
+ angleEnd = properties.anglesEnd,
1085
+ angleRange = angleEnd - angleStart,
1086
+ angleStart_degrees = angleStart * (180 / RGraph.PI),
1087
+ angleEnd_degrees = angleEnd * (180 / RGraph.PI),
1088
+ angleRange_degrees = angleRange * (180 / RGraph.PI)
1089
+
1090
+ // Vertical alignment
1091
+ valign = properties.textValign;
1092
+
1093
+ // Horizontal alignment
1094
+ if (properties.border) {
1095
+ if (i == 0) {
1096
+ halign = 'left';
1097
+ } else if (i == numLabels) {
1098
+ halign = 'right';
1099
+ } else {
1100
+ halign = 'center'
1101
+ }
1102
+ } else {
1103
+ halign = 'center';
1104
+ }
1105
+
1106
+ var value = ((this.max - this.min) * (i / numLabels)) + this.min;
1107
+
1108
+ RGraph.text({
1109
+
1110
+ object: this,
1111
+
1112
+ font: textConf.font,
1113
+ size: textConf.size,
1114
+ color: textConf.color,
1115
+ bold: textConf.bold,
1116
+ italic: textConf.italic,
1117
+
1118
+ x: coords[0],
1119
+ y: coords[1],
1120
+ text: RGraph.numberFormat({
1121
+ object: this,
1122
+ number: (value).toFixed(value === 0 ? 0 : decimals),
1123
+ unitspre: units_pre,
1124
+ unitspost: units_post,
1125
+ point: point,
1126
+ thousand: thousand
1127
+ }),
1128
+ halign: halign,
1129
+ valign: valign,
1130
+ angle: ((angleRange_degrees * (1 / numLabels) * i) + angleStart_degrees) - 270,
1131
+ bounding: false,
1132
+ boundingFill: (i == 0 || i == numLabels) ? 'white': null,
1133
+ tag: 'scale'
1134
+ });
1135
+ }
1136
+ };
1137
+
1138
+
1139
+
1140
+
1141
+
1142
+
1143
+
1144
+
1145
+ //
1146
+ // This function draws the text readout if specified
1147
+ //
1148
+ this.drawReadout = function ()
1149
+ {
1150
+ if (properties.labelsValue) {
1151
+
1152
+ // The text label
1153
+ var text = RGraph.numberFormat({
1154
+ object: this,
1155
+ number: this.value.toFixed(this.value === 0 ? 0 : properties.labelsValueDecimals),
1156
+ unitspre: properties.labelsValueUnitsPre,
1157
+ unitspost: properties.labelsValueUnitsPost,
1158
+ point: properties.labelsValuePoint,
1159
+ thousand: properties.labelsValueThousand
1160
+ });
1161
+
1162
+ // Allow for a specific label
1163
+ if (typeof properties.labelsValueSpecific === 'string') {
1164
+ text = properties.labelsValueSpecific;
1165
+ }
1166
+
1167
+ var textConf = RGraph.getTextConf({
1168
+ object: this,
1169
+ prefix: 'labelsValue'
1170
+ });
1171
+
1172
+ RGraph.text({
1173
+
1174
+ object: this,
1175
+
1176
+ font: textConf.font,
1177
+ size: textConf.size,
1178
+ color: textConf.color,
1179
+ bold: textConf.bold,
1180
+ italic: textConf.italic,
1181
+
1182
+ x: this.centerx + properties.labelsValueOffsetx,
1183
+ y: this.centery - textConf.size - 15 + properties.labelsValueOffsety,
1184
+
1185
+ text: text,
1186
+
1187
+ halign: 'center',
1188
+ valign: 'bottom',
1189
+
1190
+ bounding: properties.labelsValueBackground,
1191
+ boundingFill: properties.labelsValueBackgroundFill,
1192
+ boundingStroke: properties.labelsValueBackgroundStroke,
1193
+ accessible: properties.labelsValueAccessible,
1194
+ tag: 'value.text'
1195
+ });
1196
+ }
1197
+ };
1198
+
1199
+
1200
+
1201
+
1202
+
1203
+
1204
+
1205
+
1206
+ //
1207
+ // A placeholder function
1208
+ //
1209
+ // @param object The event object
1210
+ //
1211
+ this.getShape = function (e) {};
1212
+
1213
+
1214
+
1215
+
1216
+
1217
+
1218
+
1219
+
1220
+ //
1221
+ // This function returns the pertinent value for a particular click (or other mouse event)
1222
+ //
1223
+ // @param obj e The event object
1224
+ //
1225
+ this.getValue = function (e)
1226
+ {
1227
+ var mouseXY = RGraph.getMouseXY(e);
1228
+ var angle = RGraph.getAngleByXY(this.centerx, this.centery, mouseXY[0], mouseXY[1]);
1229
+
1230
+ // Work out the radius
1231
+ var radius = RGraph.getHypLength(this.centerx, this.centery, mouseXY[0], mouseXY[1]);
1232
+ if (radius > this.radius) {
1233
+ return null;
1234
+ }
1235
+
1236
+
1237
+ if (angle < RGraph.HALFPI) {
1238
+ angle += RGraph.TWOPI;
1239
+ }
1240
+
1241
+ var value = (((angle - properties.anglesStart) / (properties.anglesEnd - properties.anglesStart)) * (this.max - this.min)) + this.min;
1242
+
1243
+ value = Math.max(value, this.min);
1244
+ value = Math.min(value, this.max);
1245
+
1246
+ return value;
1247
+ };
1248
+
1249
+
1250
+
1251
+
1252
+
1253
+
1254
+
1255
+
1256
+ //
1257
+ // The getObjectByXY() worker method. Don't call this call:
1258
+ //
1259
+ // RGraph.ObjectRegistry.getObjectByXY(e)
1260
+ //
1261
+ // @param object e The event object
1262
+ //
1263
+ this.getObjectByXY = function (e)
1264
+ {
1265
+ var mouseXY = RGraph.getMouseXY(e);
1266
+
1267
+ // Work out the radius
1268
+ var radius = RGraph.getHypLength(this.centerx, this.centery, mouseXY[0], mouseXY[1]);
1269
+
1270
+ if (
1271
+ mouseXY[0] > (this.centerx - this.radius)
1272
+ && mouseXY[0] < (this.centerx + this.radius)
1273
+ && mouseXY[1] > (this.centery - this.radius)
1274
+ && mouseXY[1] < (this.centery + this.radius)
1275
+ && radius <= this.radius
1276
+ ) {
1277
+
1278
+ return this;
1279
+ }
1280
+ };
1281
+
1282
+
1283
+
1284
+
1285
+
1286
+
1287
+
1288
+
1289
+ //
1290
+ // This method handles the adjusting calculation for when the mouse is moved
1291
+ //
1292
+ // @param object e The event object
1293
+ //
1294
+ this.adjusting_mousemove = function (e)
1295
+ {
1296
+ //
1297
+ // Handle adjusting for the Bar
1298
+ //
1299
+ if (properties.adjustable && RGraph.Registry.get('adjusting') && RGraph.Registry.get('adjusting').uid == this.uid) {
1300
+ this.value = this.getValue(e);
1301
+ RGraph.clear(this.canvas);
1302
+ RGraph.redrawCanvas(this.canvas);
1303
+ RGraph.fireCustomEvent(this, 'onadjust');
1304
+ }
1305
+ };
1306
+
1307
+
1308
+
1309
+
1310
+
1311
+
1312
+
1313
+
1314
+ //
1315
+ // This method returns the appropriate angle for a value
1316
+ //
1317
+ // @param number value The value
1318
+ //
1319
+ this.getAngle = function (value)
1320
+ {
1321
+ // Higher than max
1322
+ if (value > this.max || value < this.min) {
1323
+ return null;
1324
+ }
1325
+
1326
+ var angle = (((value - this.min) / (this.max - this.min)) * (properties.anglesEnd - properties.anglesStart)) + properties.anglesStart;
1327
+
1328
+ return angle;
1329
+ };
1330
+
1331
+
1332
+
1333
+
1334
+
1335
+
1336
+
1337
+
1338
+ //
1339
+ // This allows for easy specification of gradients
1340
+ //
1341
+ this.parseColors = function ()
1342
+ {
1343
+ // Save the original colors so that they can be restored when the canvas is reset
1344
+ if (this.original_colors.length === 0) {
1345
+ this.original_colors.colorsGreenColor = RGraph.arrayClone(properties.colorsGreenColor);
1346
+ this.original_colors.colorsYellowColor = RGraph.arrayClone(properties.colorsYellowColor);
1347
+ this.original_colors.colorsRedColor = RGraph.arrayClone(properties.colorsRedColor);
1348
+ this.original_colors.colorsRanges = RGraph.arrayClone(properties.colorsRanges);
1349
+ }
1350
+
1351
+ // Parse the basic colors
1352
+ properties.colorsGreenColor = this.parseSingleColorForGradient(properties.colorsGreenColor);
1353
+ properties.colorsYellowColor = this.parseSingleColorForGradient(properties.colorsYellowColor);
1354
+ properties.colorsRedColor = this.parseSingleColorForGradient(properties.colorsRedColor);
1355
+
1356
+ // Parse colorsRanges
1357
+ var ranges = properties.colorsRanges;
1358
+
1359
+ if (ranges && ranges.length) {
1360
+ for (var i=0; i<ranges.length; ++i) {
1361
+ ranges[i][2] = this.parseSingleColorForGradient(ranges[i][2]);
1362
+ }
1363
+ }
1364
+ };
1365
+
1366
+
1367
+
1368
+
1369
+
1370
+
1371
+
1372
+
1373
+ //
1374
+ // Use this function to reset the object to the post-constructor state. Eg reset colors if
1375
+ // need be etc
1376
+ //
1377
+ this.reset = function ()
1378
+ {
1379
+ };
1380
+
1381
+
1382
+
1383
+
1384
+
1385
+
1386
+
1387
+
1388
+ //
1389
+ // This parses a single color value
1390
+ //
1391
+ this.parseSingleColorForGradient = function (color)
1392
+ {
1393
+ if (!color || typeof color != 'string') {
1394
+ return color;
1395
+ }
1396
+
1397
+ if (color.match(/^gradient\((.*)\)$/i)) {
1398
+
1399
+ // Allow for JSON gradients
1400
+ if (color.match(/^gradient\(({.*})\)$/i)) {
1401
+ return RGraph.parseJSONGradient({
1402
+ object: this,
1403
+ def: RegExp.$1,radial:true
1404
+ });
1405
+ }
1406
+
1407
+ var parts = RegExp.$1.split(':');
1408
+
1409
+ // Create the gradient
1410
+ var grad = this.context.createRadialGradient(this.centerx, this.centery, properties.segmentsRadiusStart, this.centerx, this.centery, this.radius * 0.85);
1411
+
1412
+ var diff = 1 / (parts.length - 1);
1413
+
1414
+ for (var j=0; j<parts.length; ++j) {
1415
+ grad.addColorStop(j * diff, RGraph.trim(parts[j]));
1416
+ }
1417
+ }
1418
+
1419
+ return grad ? grad : color;
1420
+ };
1421
+
1422
+
1423
+
1424
+
1425
+
1426
+
1427
+
1428
+
1429
+ //
1430
+ // Using a function to add events makes it easier to facilitate method chaining
1431
+ //
1432
+ // @param string type The type of even to add
1433
+ // @param function func
1434
+ //
1435
+ this.on = function (type, func)
1436
+ {
1437
+ if (type.substr(0,2) !== 'on') {
1438
+ type = 'on' + type;
1439
+ }
1440
+
1441
+ if (typeof this[type] !== 'function') {
1442
+ this[type] = func;
1443
+ } else {
1444
+ RGraph.addCustomEventListener(this, type, func);
1445
+ }
1446
+
1447
+ return this;
1448
+ };
1449
+
1450
+
1451
+
1452
+
1453
+
1454
+
1455
+
1456
+
1457
+ //
1458
+ // This function runs once only
1459
+ // (put at the end of the file (before any effects))
1460
+ //
1461
+ this.firstDrawFunc = function ()
1462
+ {
1463
+ };
1464
+
1465
+
1466
+
1467
+
1468
+
1469
+
1470
+
1471
+
1472
+ //
1473
+ // Meter Grow
1474
+ //
1475
+ // This effect gradually increases the represented value
1476
+ //
1477
+ // @param An object of options - eg: {frames: 60}
1478
+ // @param function An optional callback function
1479
+ //
1480
+ this.grow = function ()
1481
+ {
1482
+ // Cancel any stop request if one is pending
1483
+ this.cancelStopAnimation();
1484
+
1485
+ var obj = this;
1486
+
1487
+ obj.currentValue = obj.currentValue || obj.min;
1488
+
1489
+ var opt = arguments[0] || {};
1490
+ var frames = opt.frames || 30;
1491
+ var frame = 0;
1492
+ var diff = obj.value - obj.currentValue;
1493
+ var step = diff / frames;
1494
+ var callback = arguments[1] || function () {};
1495
+ var initial = obj.currentValue;
1496
+
1497
+
1498
+
1499
+ function iterator ()
1500
+ {
1501
+ if (obj.stopAnimationRequested) {
1502
+
1503
+ // Reset the flag
1504
+ obj.stopAnimationRequested = false;
1505
+
1506
+ return;
1507
+ }
1508
+
1509
+ obj.value = initial + (frame++ * step);
1510
+
1511
+ RGraph.clear(obj.canvas);
1512
+ RGraph.redrawCanvas(obj.canvas);
1513
+
1514
+ if (frame <= frames) {
1515
+ RGraph.Effects.updateCanvas(iterator);
1516
+ } else {
1517
+ callback(obj);
1518
+ }
1519
+ }
1520
+
1521
+ iterator();
1522
+
1523
+ return this;
1524
+ };
1525
+
1526
+
1527
+
1528
+
1529
+
1530
+
1531
+
1532
+
1533
+ //
1534
+ // Couple of functions that allow you to control the
1535
+ // animation effect
1536
+ //
1537
+ this.stopAnimation = function ()
1538
+ {
1539
+ this.stopAnimationRequested = true;
1540
+ };
1541
+
1542
+ this.cancelStopAnimation = function ()
1543
+ {
1544
+ this.stopAnimationRequested = false;
1545
+ };
1546
+
1547
+
1548
+
1549
+
1550
+
1551
+
1552
+
1553
+
1554
+ //
1555
+ // Register the object
1556
+ //
1557
+ RGraph.register(this);
1558
+
1559
+
1560
+
1561
+
1562
+
1563
+
1564
+
1565
+
1566
+ //
1567
+ // This is the 'end' of the constructor so if the first argument
1568
+ // contains configuration data - handle that.
1569
+ //
1570
+ RGraph.parseObjectStyleConfig(this, conf.options);
1571
+ };