rgraph-rails 1.0.7 → 1.0.8

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