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