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,83 +1,1647 @@
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.Gantt=function(conf)
3
- {if(typeof conf==='object'&&typeof conf.data==='object'&&typeof conf.id==='string'){var id=conf.id
4
- var canvas=document.getElementById(id);var data=conf.data;var parseConfObjectForOptions=true;}else{var id=conf;var canvas=document.getElementById(id);var data=arguments[1];}
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='gantt';this.isRGraph=true;this.uid=RGraph.CreateUID();this.canvas.uid=this.canvas.uid?this.canvas.uid:RGraph.CreateUID();this.data=data;this.colorsParsed=false;this.coordsText=[];this.original_colors=[];this.firstDraw=true;this.propertyNameAliases={};this.properties={'chart.background.bars.count':null,'chart.background.bars.color1':'rgba(0,0,0,0)','chart.background.bars.color2':'rgba(0,0,0,0)','chart.background.grid':true,'chart.background.grid.linewidth':1,'chart.background.grid.color':'#ddd','chart.background.grid.hsize':20,'chart.background.grid.vsize':20,'chart.background.grid.hlines':true,'chart.background.grid.vlines':true,'chart.background.grid.border':true,'chart.background.grid.align':true,'chart.background.grid.autofit':true,'chart.background.grid.autofit.align':true,'chart.background.grid.hlines.count':null,'chart.background.grid.vlines.count':null,'chart.background.vbars':[],'chart.background.hbars':[],'chart.text.size':12,'chart.text.font':'Arial, Verdana, sans-serif','chart.text.color':'black','chart.text.bold':false,'chart.text.italic':false,'chart.text.accessible':true,'chart.text.accessible.overflow':'visible','chart.text.accessible.pointerevents':false,'chart.margin.left':75,'chart.margin.right':25,'chart.margin.top':35,'chart.margin.bottom':25,'chart.labels.inbar':null,'chart.labels.inbar.bgcolor':null,'chart.labels.inbar.align':'left','chart.labels.inbar.size':null,'chart.labels.inbar.font':null,'chart.labels.inbar.color':null,'chart.labels.inbar.bold':null,'chart.labels.inbar.italic':null,'chart.labels.inbar.above':false,'chart.labels.complete':true,'chart.labels.complete.font':null,'chart.labels.complete.size':null,'chart.labels.complete.color':null,'chart.labels.complete.bold':null,'chart.labels.complete.italic':null,'chart.vmargin':2,'chart.title':'','chart.title.background':null,'chart.title.x':null,'chart.title.y':null,'chart.title.bold':null,'chart.title.italic':null,'chart.title.font':null,'chart.title.size':null,'chart.title.color':null,'chart.title.halign':null,'chart.title.valign':null,'chart.yaxis.labels.font':null,'chart.yaxis.labels.size':null,'chart.yaxis.labels.color':null,'chart.yaxis.labels.bold':null,'chart.yaxis.labels.italic':null,'chart.yaxis.title':'','chart.yaxis.title.bold':null,'chart.yaxis.title.italic':null,'chart.yaxis.title.font':null,'chart.yaxis.title.size':null,'chart.yaxis.title.color':null,'chart.yaxis.title.pos':null,'chart.yaxis.title.position':'right','chart.yaxis.title.x':null,'chart.yaxis.title.y':null,'chart.xaxis.labels':[],'chart.xaxis.labels.font':null,'chart.xaxis.labels.size':null,'chart.xaxis.labels.color':null,'chart.xaxis.labels.bold':null,'chart.xaxis.labels.italic':null,'chart.xaxis.labels.align':'bottom','chart.xaxis.title':'','chart.xaxis.title.x':null,'chart.xaxis.title.y':null,'chart.xaxis.title.bold':null,'chart.xaxis.title.color':null,'chart.xaxis.title.font':null,'chart.xaxis.title.size':null,'chart.xaxis.title.italic':null,'chart.xaxis.scale.min':0,'chart.xaxis.scale.max':0,'chart.colors.default':'white','chart.borders':true,'chart.coords':[],'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.contextmenu':null,'chart.annotatable':false,'chart.annotatable.color':'black','chart.resizable':false,'chart.resizable.handle.adjust':[0,0],'chart.resizable.handle.background':null,'chart.adjustable':false,'chart.adjustable.only':null,'chart.events.click':null,'chart.events.mousemove':null,'chart.clearto':'rgba(0,0,0,0)'}
6
- if(!data){alert('[GANTT] The Gantt chart event data is now supplied as the second argument to the constructor - please update your code');}else{for(var i=0,idx=0;i<data.length;++i){if(typeof data[i].start==='string')data[i].start=parseFloat(data[i].start);if(typeof data[i].duration==='string')data[i].duration=parseFloat(data[i].duration);if(typeof data[i].complete==='string')data[i].complete=parseFloat(data[i].complete);if(typeof data[i].linewidth==='string')data[i].linewidth=parseFloat(data[i].linewidth);}}
7
- for(var i=0,idx=0;i<data.length;++i){if(RGraph.isArray(this.data[i][0])){for(var j=0;j<this.data[i].length;++j){this['$'+(idx++)]={};}}else{this['$'+(idx++)]={};}}
8
- if(!this.canvas.__rgraph_aa_translated__){this.context.translate(0.5,0.5);this.canvas.__rgraph_aa_translated__=true;}
9
- var RG=RGraph,ca=this.canvas,co=ca.getContext('2d'),prop=this.properties,pa2=RG.path2,win=window,doc=document,ma=Math
10
- if(RG.Effects&&typeof RG.Effects.decorate==='function'){RG.Effects.decorate(this);}
11
- this.set=this.Set=function(name)
12
- {var value=typeof arguments[1]==='undefined'?null:arguments[1];if(arguments.length===1&&typeof name==='object'){RG.parseObjectStyleConfig(this,name);return this;}
13
- if(name.substr(0,6)!='chart.'){name='chart.'+name;}
14
- while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
15
- if(name=='chart.margin'){name='chart.vmargin'}
16
- if(name=='chart.events'){alert('[GANTT] The chart.events property is deprecated - supply the events data as an argument to the constructor instead');this.data=value;}
17
- prop[name]=value;return this;};this.get=this.Get=function(name)
18
- {if(name.substr(0,6)!='chart.'){name='chart.'+name;}
19
- while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
20
- if(name=='chart.margin'){name='chart.vmargin'}
21
- return prop[name.toLowerCase()];};this.draw=this.Draw=function()
22
- {RG.fireCustomEvent(this,'onbeforedraw');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.coordsText=[];if(!this.colorsParsed){this.parseColors();this.colorsParsed=true;}
23
- this.graphArea=ca.width-this.marginLeft-this.marginRight;this.graphHeight=ca.height-this.marginTop-this.marginBottom;this.numEvents=this.data.length
24
- this.barHeight=this.graphHeight/this.numEvents;this.halfBarHeight=this.barHeight/2;if(RG.isNull(prop['chart.background.grid.hlines.count'])){this.set('chart.background.grid.hlines.count',this.data.length);}
25
- RG.Background.draw(this);this.drawLabels();this.drawEvents();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.drawLabels=this.DrawLabels=function()
30
- {var labels=prop['chart.xaxis.labels'],labelsColor=prop['chart.xaxis.labels.color']||prop['chart.text.color'],labelSpace=(this.graphArea)/labels.length,x=this.marginLeft+(labelSpace/2),y=this.marginTop-(prop['chart.text.size']/2)-5,font=prop['chart.text.font'],size=prop['chart.text.size'];co.beginPath();co.fillStyle=prop['chart.text.color'];co.strokeStyle='black'
31
- if(prop['chart.xaxis.labels.align']=='bottom'){y=ca.height-this.marginBottom+size+2;}
32
- var textConf=RG.getTextConf({object:this,prefix:'chart.xaxis.labels'});for(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:x+(i*labelSpace),y:y,text:String(labels[i]),halign:'center',valign:'center',tag:'labels.horizontal'});}
33
- for(var i=0,len=this.data.length;i<len;++i){var ev=this.data[i],x=this.marginLeft,y=this.marginTop+this.halfBarHeight+(i*this.barHeight);co.fillStyle=labelsColor||prop['chart.text.color'];var label=RG.isArray(ev)?String(ev[0].label):String(ev.label);var textConf=RG.getTextConf({object:this,prefix:'chart.yaxis.labels'});if(label){RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:x-5,y:y,text:label,halign:'right',valign:'center',tag:'labels.vertical'});}}};this.drawEvents=this.DrawEvents=function()
34
- {var events=this.data;this.coords=[];if(prop['chart.background.vbars']){for(i=0,len=prop['chart.background.vbars'].length;i<len;++i){if(prop['chart.background.vbars'][i][0]+prop['chart.background.vbars'][i][1]>prop['chart.xaxis.scale.max']){prop['chart.background.vbars'][i][1]=364-prop['chart.background.vbars'][i][0];}
35
- var barX=this.marginLeft+(((prop['chart.background.vbars'][i][0]-prop['chart.xaxis.scale.min'])/(prop['chart.xaxis.scale.max']-prop['chart.xaxis.scale.min']))*this.graphArea),barY=this.marginTop,width=(this.graphArea/(prop['chart.xaxis.scale.max']-prop['chart.xaxis.scale.min']))*prop['chart.background.vbars'][i][1],height=ca.height-this.marginTop-this.marginBottom;if((barX+width)>(ca.width-this.marginRight)){width=ca.width-this.marginRight-barX;}
36
- co.fillStyle=prop['chart.background.vbars'][i][2];co.fillRect(barX,barY,width,height);}}
37
- if(prop['chart.background.hbars']){for(i=0,len=prop['chart.background.hbars'].length;i<len;++i){if(prop['chart.background.hbars'][i]){var barX=this.marginLeft,barY=((ca.height-this.marginTop-this.marginBottom)/this.data.length)*i+this.marginTop,width=this.graphArea,height=this.barHeight
38
- co.fillStyle=prop['chart.background.hbars'][i];co.fillRect(barX,barY,width,height);}}}
39
- var sequentialIndex=0;for(i=0;i<events.length;++i){if(typeof events[i].start==='number'){this.DrawSingleEvent(events[i],i,sequentialIndex++);}else{for(var j=0;j<events[i].length;++j){var subindex=j;this.DrawSingleEvent(events[i][j],i,sequentialIndex++,subindex);}}}};this.getShape=this.getBar=function(e)
40
- {e=RG.fixEventObject(e);var mouseXY=RG.getMouseXY(e),mouseX=mouseXY[0],mouseY=mouseXY[1];for(var i=0,len=this.coords.length;i<len;i++){var left=this.coords[i][0],top=this.coords[i][1],width=this.coords[i][2],height=this.coords[i][3];if(mouseX>=left&&mouseX<=(left+width)&&mouseY>=top&&mouseY<=(top+height)){var tooltip=RG.parseTooltipText(prop['chart.tooltips'],i);var ret={0:this,object:this,1:left,x:left,2:top,y:top,3:width,width:width,4:height,height:height,5:i,index:this.coords[i][4].index,subindex:(this.coords[i][4]&&typeof this.coords[i][4].subindex==='number'?this.coords[i][4].subindex:null),sequentialIndex:this.coords[i][5],tooltip:tooltip};return ret;}}};this.drawSingleEvent=this.DrawSingleEvent=function(ev,index,sequentialIndex)
41
- {ev.index=index;if(typeof arguments[3]==='number'){ev.subindex=arguments[3]}
42
- var min=prop['chart.xaxis.scale.min'];co.beginPath();co.strokeStyle='black';co.fillStyle=ev.color?ev.color:prop['chart.colors.default'];var barStartX=this.marginLeft+(((ev.start-min)/(prop['chart.xaxis.scale.max']-min))*this.graphArea),barStartY=this.marginTop+(index*this.barHeight),barWidth=(ev.duration/(prop['chart.xaxis.scale.max']-min))*this.graphArea;if((barStartX+barWidth)>(ca.width-this.marginRight)){barWidth=ca.width-this.marginRight-barStartX;}
43
- this.coords.push([barStartX,barStartY+prop['chart.vmargin'],barWidth,this.barHeight-(2*prop['chart.vmargin']),ev,sequentialIndex,]);if(prop['chart.borders']||typeof ev.border==='number'){co.strokeStyle=typeof(ev.border)==='string'?ev.border:'black';co.lineWidth=(typeof(ev.linewidth)==='number'?ev.linewidth:1);if(ev.linewidth!==0){co.strokeRect(barStartX,barStartY+prop['chart.vmargin'],barWidth,this.barHeight-(2*prop['chart.vmargin']));}}
44
- if(RG.isNull(ev.complete)){co.fillStyle=ev.color?ev.color:prop['chart.colors.default'];}else{co.fillStyle=ev.background?ev.background:prop['chart.colors.default'];}
45
- co.fillRect(barStartX,barStartY+prop['chart.vmargin'],barWidth,this.barHeight-(2*prop['chart.vmargin']));var complete=(ev.complete/100)*barWidth;if(typeof(ev.complete)==='number'){co.fillStyle=ev.color?ev.color:'#0c0';co.fillRect(barStartX,barStartY+prop['chart.vmargin'],(ev.complete/100)*barWidth,this.barHeight-(2*prop['chart.vmargin']));if(prop['chart.labels.complete']){co.beginPath();var textConf=RG.getTextConf({object:this,prefix:'chart.labels.complete'});RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:barStartX+barWidth+5,y:barStartY+this.halfBarHeight,text:String(ev.complete)+'%',valign:'center',tag:'labels.complete'});}}
46
- if(prop['chart.labels.inbar']&&prop['chart.labels.inbar'][sequentialIndex]){var label=String(prop['chart.labels.inbar'][sequentialIndex]),halign=prop['chart.labels.inbar.align']=='left'?'left':'center';halign=prop['chart.labels.inbar.align']=='right'?'right':halign;if(halign=='right'){var x=(barStartX+barWidth)-5;}else if(halign=='center'){var x=barStartX+(barWidth/2);}else{var x=barStartX+5;}
47
- if(prop['chart.labels.inbar.above']){x=barStartX+barWidth+5;halign='left';}
48
- var textConf=RG.getTextConf({object:this,prefix:'chart.labels.inbar'});co.fillStyle=prop['chart.labels.inbar.color'];RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,x:x,y:barStartY+this.halfBarHeight,text:label,valign:'center',halign:halign,bounding:typeof(prop['chart.labels.inbar.bgcolor'])=='string',boundingFill:typeof(prop['chart.labels.inbar.bgcolor'])==='string'?prop['chart.labels.inbar.bgcolor']:null,tag:'labels.inbar'});}};this.highlight=this.Highlight=function(shape)
49
- {if(typeof prop['chart.highlight.style']==='function'){(prop['chart.highlight.style'])(shape);}else{RG.Highlight.Rect(this,shape);}};this.getObjectByXY=function(e)
50
- {var mouseXY=RG.getMouseXY(e);if(mouseXY[0]>this.marginLeft&&mouseXY[0]<(ca.width-this.marginRight)&&mouseXY[1]>this.marginTop&&mouseXY[1]<(ca.height-this.marginBottom)){return this;}};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 bar=RG.Registry.get('chart.adjusting.gantt');if(bar){var mouseXY=RG.getMouseXY(e),obj=RG.Registry.get('chart.adjusting.gantt')['object'],index=bar['index'],subindex=bar['subindex'],diff=((mouseXY[0]-RG.Registry.get('chart.adjusting.gantt')['mousex'])/(ca.width-obj.marginLeft-obj.marginRight))*prop['chart.xaxis.scale.max'],eventStart=RG.Registry.get('chart.adjusting.gantt')['event_start'],duration=RG.Registry.get('chart.adjusting.gantt')['event_duration'],event=typeof subindex==='number'?obj.data[index][subindex]:obj.data[index]
52
- if(bar['mode']==='move'){diff=ma.round(diff);if(RG.isNull(subindex)){event.start=eventStart+diff;if(eventStart+diff<0){obj.data[index].start=0;}else if((eventStart+diff+obj.data[index].duration)>prop['chart.xaxis.scale.max']){obj.data[index].start=prop['chart.xaxis.scale.max']-obj.data[index].duration;}}else{var index=RG.Registry.get('chart.adjusting.gantt').index,subindex=RG.Registry.get('chart.adjusting.gantt').subindex,event=this.data[index][subindex];event.start=eventStart+diff;if((eventStart+diff)<0){event.start=0;}else if((eventStart+diff+event.duration)>prop['chart.xaxis.scale.max']){event.start=prop['chart.xaxis.scale.max']-event.duration;}}}else if(bar['mode']=='resize'){if(mouseXY[0]>(ca.width-obj.marginRight)){mouseXY[0]=ca.width-obj.marginRight;}
53
- var diff=((mouseXY[0]-RG.Registry.get('chart.adjusting.gantt')['mousex'])/(ca.width-obj.marginLeft-obj.marginRight))*prop['chart.xaxis.scale.max'];diff=ma.round(diff);if(RG.isNull(subindex)){obj.data[index].duration=duration+diff;if(obj.data[index].duration<0){obj.data[index].duration=1;}}else{obj.data[index][subindex].duration=duration+diff;if(obj.data[index][subindex].duration<0){obj.data[index][subindex].duration=1;}}}
54
- RG.resetColorsToOriginalValues(this);RG.redrawCanvas(ca);RG.fireCustomEvent(obj,'onadjust');}}};this.getXCoord=function(value)
55
- {var min=prop['chart.xaxis.scale.min'],max=prop['chart.xaxis.scale.max'],graphArea=ca.width-this.marginLeft-this.marginRight;if(value>max||value<min){return null;}
56
- var x=(((value-min)/(max-min))*graphArea)+this.marginLeft;return x;};this.getValue=function(arg)
57
- {if(arg.length==2){var mouseXY=arg;}else{var mouseXY=RGraph.getMouseXY(arg);}
58
- var mouseX=mouseXY[0],mouseY=mouseXY[1];var value=(mouseX-this.marginLeft)/(ca.width-this.marginLeft-this.marginRight);value*=(prop['chart.xaxis.scale.max']-prop['chart.xaxis.scale.min']);if(value<prop['chart.xaxis.scale.min']||value>prop['chart.xaxis.scale.max']){value=null;}
59
- return value;};this.parseColors=function()
60
- {if(this.original_colors.length===0){this.original_colors['data']=RG.arrayClone(this.data);this.original_colors['chart.background.bars.color1']=RG.arrayClone(prop['chart.background.bars.color1']);this.original_colors['chart.background.bars.color2']=RG.arrayClone(prop['chart.background.bars.color2']);this.original_colors['chart.background.grid.color']=RG.arrayClone(prop['chart.background.grid.color']);this.original_colors['chart.colors.default']=RG.arrayClone(prop['chart.colors.default']);this.original_colors['chart.highlight.stroke']=RG.arrayClone(prop['chart.highlight.stroke']);this.original_colors['chart.highlight.fill']=RG.arrayClone(prop['chart.highlight.fill']);}
61
- for(var i=0,sequentialIndex=0;i<this.data.length;++i){if(RG.isArray(this.data[i])&&typeof this.data[i][0]==='object'&&typeof this.data[i][0].start==='number'){for(var j=0,len=this.data[i].length;j<len;j+=1,sequentialIndex+=1){this.data[i][j].background=this.parseSingleColorForGradient(this.data[i][j].background,{start:this.data[i][j].start,duration:this.data[i][j].duration});this.data[i][j].color=this.parseSingleColorForGradient(this.data[i][j].color,{start:this.data[i][j].start,duration:this.data[i][j].duration});}}else{if(typeof this.data[i].background==='string'){this.data[i].background=this.parseSingleColorForGradient(this.data[i].background,{start:this.data[i].start,duration:this.data[i].duration});}
62
- if(typeof this.data[i].color==='string'){this.data[i].color=this.parseSingleColorForGradient(this.data[i].color,{start:this.data[i].start,duration:this.data[i].duration});}
63
- ++sequentialIndex;}}
64
- prop['chart.background.bars.color1']=this.parseSingleColorForGradient(prop['chart.background.bars.color1']);prop['chart.background.bars.color2']=this.parseSingleColorForGradient(prop['chart.background.bars.color2']);prop['chart.background.grid.color']=this.parseSingleColorForGradient(prop['chart.background.grid.color']);prop['chart.background.color']=this.parseSingleColorForGradient(prop['chart.background.color']);prop['chart.colors.default']=this.parseSingleColorForGradient(prop['chart.colors.default']);prop['chart.highlight.stroke']=this.parseSingleColorForGradient(prop['chart.highlight.stroke']);prop['chart.highlight.fill']=this.parseSingleColorForGradient(prop['chart.highlight.fill']);};this.reset=function()
65
- {};this.parseSingleColorForGradient=function(color)
66
- {var opts=arguments[1]||{};if(!color||typeof(color)!='string'){return color;}
67
- if(color.match(/^gradient\((.*)\)$/i)){if(color.match(/^gradient\(({.*})\)$/i)){return RGraph.parseJSONGradient({object:this,def:RegExp.$1});}
68
- var parts=RegExp.$1.split(':'),value=(opts.start+opts.duration)>prop['chart.xaxis.scale.max']?prop['chart.xaxis.scale.max']:(opts.start+opts.duration);var grad=co.createLinearGradient(typeof opts.start==='number'?this.getXCoord(opts.start):this.marginLeft,0,typeof opts.start==='number'?this.getXCoord(value):ca.width-this.marginRight,0);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]));}}
69
- return grad?grad:color;};this.on=function(type,func)
70
- {if(type.substr(0,2)!=='on'){type='on'+type;}
71
- if(typeof this[type]!=='function'){this[type]=func;}else{RG.addCustomEventListener(this,type,func);}
72
- return this;};this.firstDrawFunc=function()
73
- {};this.grow=function()
74
- {var obj=this,opt=arguments[0]||{},callback=arguments[1]?arguments[1]:function(){},canvas=obj.canvas,context=obj.context,numFrames=opt.frames||30,frame=0;original_events=RG.arrayClone(obj.data);function iterator()
75
- {RG.clear(obj.canvas);RG.redrawCanvas(obj.canvas);if(frame<=numFrames){for(var i=0,len=obj.data.length;i<len;++i){if(typeof obj.data[i]==='object'&&obj.data[i][0]&&typeof obj.data[i][0]==='object'){for(var j=0;j<obj.data[i].length;++j){obj.data[i][j].duration=(frame/numFrames)*original_events[i][j].duration;}}else{obj.data[i].duration=(frame/numFrames)*original_events[i].duration;}}
76
- obj.reset();frame++;RGraph.Effects.updateCanvas(iterator);}else{callback(obj);}}
77
- iterator();return this;};this.resetColorsToOriginalValues=function()
78
- {for(var i=0;i<this.original_colors['data'].length;++i){if(this.original_colors['data'][i].background){this.data[i].background=RG.arrayClone(this.original_colors['data'][i].background);}
79
- if(this.original_colors['data'][i].color){this.data[i].color=RG.arrayClone(this.original_colors['data'][i].color);}
80
- if(typeof this.original_colors['data'][i][0]==='object'&&typeof this.original_colors['data'][i][0].start==='number'){for(var j=0,len2=this.original_colors['data'][i].length;j<len2;++j){this.data[i][j].background=RG.arrayClone(this.original_colors['data'][i][j].background);this.data[i][j].color=RG.arrayClone(this.original_colors['data'][i][j].color);}}}};this.reset=function()
81
- {this.resetColorsToOriginalValues();this.colorsParsed=false;this.coordsText=[];this.original_colors=[];this.firstDraw=true;this.coords=[];};this.sequentialIndex2Grouped=function(){alert('[RGRAPH] Something went badly wrong - contact support');};this.isAdjustable=function(shape)
82
- {if(RG.isNull(prop['chart.adjustable.only'])){return true;}else if(RG.isArray(prop['chart.adjustable.only'])&&prop['chart.adjustable.only'][shape.sequentialIndex]){return true;}
83
- return false;};RG.Register(this);if(parseConfObjectForOptions){RG.parseObjectStyleConfig(this,conf.options);}};
12
+ RGraph = window.RGraph || {isrgraph:true,isRGraph:true,rgraph:true};
13
+
14
+ //
15
+ // The gantt chart constructor
16
+ //
17
+ RGraph.Gantt = function (conf)
18
+ {
19
+ var id = conf.id
20
+ var canvas = document.getElementById(id);
21
+ var data = conf.data;
22
+
23
+ this.id = id;
24
+ this.canvas = canvas;
25
+ this.context = this.canvas.getContext ? this.canvas.getContext("2d", {alpha: (typeof id === 'object' && id.alpha === false) ? false : true}) : null;
26
+ this.canvas.__object__ = this;
27
+ this.type = 'gantt';
28
+ this.isRGraph = true;
29
+ this.isrgraph = true;
30
+ this.rgraph = true;
31
+ this.uid = RGraph.createUID();
32
+ this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.createUID();
33
+ this.data = data;
34
+ this.original_data = RGraph.arrayClone(data);
35
+ this.colorsParsed = false;
36
+ this.coordsText = [];
37
+ this.original_colors = [];
38
+ this.firstDraw = true; // After the first draw this will be false
39
+ this.stopAnimationRequested = false;// Used to control the animations
40
+
41
+
42
+ // Set some defaults
43
+ this.properties =
44
+ {
45
+ backgroundBarsCount: null,
46
+ backgroundBarsColor1: 'rgba(0,0,0,0)',
47
+ backgroundBarsColor2: 'rgba(0,0,0,0)',
48
+ backgroundGrid: true,
49
+ backgroundGridLinewidth: 1,
50
+ backgroundGridColor: '#ddd',
51
+ backgroundGridHsize: 20,
52
+ backgroundGridVsize: 20,
53
+ backgroundGridHlines: true,
54
+ backgroundGridVlines: true,
55
+ backgroundGridBorder: true,
56
+ backgroundGridAlign: true,
57
+ backgroundGridAutofit:true,
58
+ backgroundGridAutofitAlign:true,
59
+ backgroundGridHlinesCount: null,
60
+ backgroundGridVlinesCount: null,
61
+ backgroundVbars: [],
62
+ backgroundHbars: [],
63
+
64
+ textSize: 12,
65
+ textFont: 'Arial, Verdana, sans-serif',
66
+ textColor: 'black',
67
+ textBold: false,
68
+ textItalic: false,
69
+ textAccessible: false,
70
+ textAccessibleOverflow: 'visible',
71
+ textAccessiblePointerevents: false,
72
+ text: null,
73
+
74
+ marginLeft: 75,
75
+ marginRight: 35,
76
+ marginTop: 35,
77
+ marginBottom: 35,
78
+ marginInner: 2,
79
+
80
+ labelsInbar: null,
81
+ labelsInbarBgcolor: null,
82
+ labelsInbarAlign: 'left',
83
+ labelsInbarSize: null,
84
+ labelsInbarFont: null,
85
+ labelsInbarColor: null,
86
+ labelsInbarBold: null,
87
+ labelsInbarItalic: null,
88
+ labelsInbarAbove: false,
89
+ labelsInbarOffsetx: 0,
90
+ labelsInbarOffsety: 0,
91
+ labelsComplete: true,
92
+ labelsCompleteFont: null,
93
+ labelsCompleteSize: null,
94
+ labelsCompleteColor: null,
95
+ labelsCompleteBold: null,
96
+ labelsCompleteItalic: null,
97
+ labelsCompleteOffsetx: 0,
98
+ labelsCompleteOffsety: 0,
99
+
100
+ title: '',
101
+ titleX: null,
102
+ titleY: null,
103
+ titleBold: null,
104
+ titleItalic: null,
105
+ titleFont: null,
106
+ titleSize: null,
107
+ titleColor: null,
108
+ titleHalign: null,
109
+ titleValign: null,
110
+ titleOffsetx: 0,
111
+ titleOffsety: 0,
112
+ titleSubtitle: '',
113
+ titleSubtitleSize: null,
114
+ titleSubtitleColor: '#aaa',
115
+ titleSubtitleFont: null,
116
+ titleSubtitleBold: null,
117
+ titleSubtitleItalic: null,
118
+ titleSubtitleOffsetx: 0,
119
+ titleSubtitleOffsety: 0,
120
+
121
+ xaxis: false,
122
+ xaxisLinewidth: 1,
123
+ xaxisColor: 'black',
124
+ xaxisTickmarks: true,
125
+ xaxisTickmarksLength: 3,
126
+ xaxisTickmarksLastLeft: null,
127
+ xaxisTickmarksLastRight: null,
128
+ xaxisTickmarksCount: null,
129
+ xaxisLabels: null,
130
+ xaxisLabelsSize: null,
131
+ xaxisLabelsFont: null,
132
+ xaxisLabelsItalic: null,
133
+ xaxisLabelsBold: null,
134
+ xaxisLabelsColor: null,
135
+ xaxisLabelsOffsetx: 0,
136
+ xaxisLabelsOffsety: 0,
137
+ xaxisLabelsHalign: null,
138
+ xaxisLabelsValign: null,
139
+ xaxisLabelsPosition: 'section',
140
+ xaxisPosition: 'bottom',
141
+ xaxisLabelsAngle: 0,
142
+ xaxisTitle: null,
143
+ xaxisTitleBold: null,
144
+ xaxisTitleSize: null,
145
+ xaxisTitleFont: null,
146
+ xaxisTitleColor: null,
147
+ xaxisTitleItalic: null,
148
+ xaxisTitlePos: null,
149
+ xaxisTitleOffsetx: 0,
150
+ xaxisTitleOffsety: 0,
151
+ xaxisTitleX: null,
152
+ xaxisTitleY: null,
153
+ xaxisTitleHalign: null,
154
+ xaxisTitleValign: null,
155
+ xaxisScaleMin: 0,
156
+ xaxisScaleMax: 0,
157
+
158
+ yaxis: false,
159
+ yaxisColor: 'black',
160
+ yaxisLinewidth: 1,
161
+ yaxisTickmarks: false,
162
+ yaxisTickmarksLength: null,
163
+ yaxisTickmarksCount: null,
164
+ yaxisTickmarksLastTop: null,
165
+ yaxisTickmarksLastBottom: null,
166
+ yaxisScale: false,
167
+ yaxisLabelsPosition: 'section',
168
+ yaxisLabels: null, // This is populated when the chart is first drawn
169
+ yaxisLabelsFont: null,
170
+ yaxisLabelsSize: null,
171
+ yaxisLabelsColor: null,
172
+ yaxisLabelsBold: null,
173
+ yaxisLabelsItalic: null,
174
+ yaxisLabelsOffsety: 0,
175
+ yaxisLabelsOffsetx: 0,
176
+ yaxisLabelsValign: 'center',
177
+ yaxisLabelsHalign: 'right',
178
+ yaxisTitle: '',
179
+ yaxisTitleBold: null,
180
+ yaxisTitleItalic: null,
181
+ yaxisTitleFont: null,
182
+ yaxisTitleSize: null,
183
+ yaxisTitleColor: null,
184
+ yaxisTitlePos: null,
185
+ yaxisTitleOffsetx: null,
186
+ yaxisTitleOffsety: null,
187
+ yaxisTitleX: null,
188
+ yaxisTitleY: null,
189
+ yaxisTitleHalign: null,
190
+ yaxisTitleValign: null,
191
+ yaxisTitleAccessible: null,
192
+
193
+ colorsDefault: 'white',
194
+
195
+ borders: true,
196
+
197
+ coords: [],
198
+
199
+ tooltips: null,
200
+ tooltipsEffect: 'slide',
201
+ tooltipsCssClass: 'RGraph_tooltip',
202
+ tooltipsCss: null,
203
+ tooltipsHighlight: true,
204
+ tooltipsEvent: 'click',
205
+ tooltipsFormattedThousand: ',',
206
+ tooltipsFormattedPoint: '.',
207
+ tooltipsFormattedDecimals: 0,
208
+ tooltipsFormattedUnitsPre: '',
209
+ tooltipsFormattedUnitsPost: '',
210
+ tooltipsFormattedTableHeaders: null,
211
+ tooltipsFormattedTableData: null,
212
+ tooltipsPointer: true,
213
+ tooltipsPointerOffsetx: 0,
214
+ tooltipsPointerOffsety: 0,
215
+ tooltipsPositionStatic: true,
216
+ tooltipsHotspotIgnore: null,
217
+
218
+ highlightStroke: 'rgba(0,0,0,0)',
219
+ highlightFill: 'rgba(255,255,255,0.7)',
220
+
221
+ contextmenu: null,
222
+
223
+ annotatable: false,
224
+ annotatableColor: 'black',
225
+ annotatableLinewidth: 1,
226
+
227
+ adjustable: false,
228
+ adjustableOnly: null,
229
+
230
+ clearto: 'rgba(0,0,0,0)'
231
+ }
232
+
233
+
234
+ //
235
+ // Create the dollar objects so that functions can be added to them
236
+ //
237
+ if (!data) {
238
+ alert('[GANTT] The Gantt chart event data is now supplied as the second argument to the constructor - please update your code');
239
+ } else {
240
+ // Go through the data converting relevant args to numbers
241
+ for (var i=0,idx=0; i<data.length; ++i) {
242
+ if (typeof data[i].start === 'string') data[i].start = parseFloat(data[i].start);
243
+ if (typeof data[i].duration === 'string') data[i].duration = parseFloat(data[i].duration);
244
+ if (typeof data[i].complete === 'string') data[i].complete = parseFloat(data[i].complete);
245
+ if (typeof data[i].linewidth === 'string') data[i].linewidth = parseFloat(data[i].linewidth);
246
+ }
247
+ }
248
+
249
+ // Linearize the data (DON'T use RGraph.arrayLinearize() here)
250
+
251
+ // Initialise this
252
+ this.properties.yaxisLabels = [];
253
+
254
+ for (var i=0,idx=0; i<data.length; ++i) {
255
+ if (RGraph.isArray(this.data[i])) {
256
+ for (var j=0; j<this.data[i].length; ++j) {
257
+ this.data[i][j].index = j;
258
+ this.data[i][j].dataset = i;
259
+ this['$' + (idx++)] = this.data[i][j];
260
+
261
+ // Populate the label property
262
+ if (this.data[i][j].label) {
263
+ this.properties.yaxisLabels[i] = this.data[i][j].label;
264
+ }
265
+ }
266
+ } else {
267
+
268
+ this.data[i].index = 0;
269
+ this.data[i].dataset = i;
270
+ this['$' + (idx++)] = this.data[i];
271
+
272
+ // Populate the label property
273
+ this.properties.yaxisLabels[i] = this.data[i].label;
274
+ }
275
+ }
276
+
277
+
278
+
279
+
280
+ // Easy access to properties and the path function
281
+ var properties = this.properties;
282
+ this.path = RGraph.pathObjectFunction;
283
+
284
+
285
+
286
+ //
287
+ // "Decorate" the object with the generic effects if the effects library has been included
288
+ //
289
+ if (RGraph.Effects && typeof RGraph.Effects.decorate === 'function') {
290
+ RGraph.Effects.decorate(this);
291
+ }
292
+
293
+
294
+
295
+ // Add the responsive method. This method resides in the common file.
296
+ this.responsive = RGraph.responsive;
297
+
298
+
299
+
300
+
301
+
302
+
303
+
304
+
305
+ //
306
+ // A setter
307
+ //
308
+ this.set = function (name)
309
+ {
310
+ var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
311
+
312
+ // the number of arguments is only one and it's an
313
+ // object - parse it for configuration data and return.
314
+ if (arguments.length === 1 && typeof arguments[0] === 'object') {
315
+ for (i in arguments[0]) {
316
+ if (typeof i === 'string') {
317
+ this.set(i, arguments[0][i]);
318
+ }
319
+ }
320
+
321
+ return this;
322
+ }
323
+
324
+ properties[name] = value;
325
+
326
+ return this;
327
+ };
328
+
329
+
330
+
331
+
332
+
333
+
334
+
335
+
336
+ //
337
+ // A peudo getter
338
+ //
339
+ // @param name string The name of the property to get
340
+ //
341
+ this.get = function (name)
342
+ {
343
+ return properties[name];
344
+ };
345
+
346
+
347
+
348
+
349
+
350
+
351
+
352
+
353
+ //
354
+ // Draws the chart
355
+ //
356
+ this.draw = function ()
357
+ {
358
+ //
359
+ // Fire the onbeforedraw event
360
+ //
361
+ RGraph.fireCustomEvent(this, 'onbeforedraw');
362
+
363
+
364
+
365
+ // Translate half a pixel for antialiasing purposes - but only if it hasn't been
366
+ // done already
367
+ //
368
+ // MUST be the first thing done!
369
+ //
370
+ if (!this.canvas.__rgraph_aa_translated__) {
371
+ this.context.translate(0.5,0.5);
372
+
373
+ this.canvas.__rgraph_aa_translated__ = true;
374
+ }
375
+
376
+ //
377
+ // Make the margins easy ro access
378
+ //
379
+ this.marginLeft = properties.marginLeft;
380
+ this.marginRight = properties.marginRight;
381
+ this.marginTop = properties.marginTop;
382
+ this.marginBottom = properties.marginBottom;
383
+
384
+ //
385
+ // Stop this growing uncntrollably
386
+ //
387
+ this.coordsText = [];
388
+
389
+
390
+ //
391
+ // Parse the colors. This allows for simple gradient syntax
392
+ //
393
+ if (!this.colorsParsed) {
394
+
395
+ this.parseColors();
396
+
397
+ // Don't want to do this again
398
+ this.colorsParsed = true;
399
+ }
400
+
401
+ //
402
+ // Work out the graphArea
403
+ //
404
+ this.graphArea = this.canvas.width - this.marginLeft - this.marginRight;
405
+ this.graphHeight = this.canvas.height - this.marginTop - this.marginBottom;
406
+ this.numEvents = this.data.length
407
+ this.barHeight = this.graphHeight / this.numEvents;
408
+ this.halfBarHeight = this.barHeight / 2;
409
+
410
+ // Set the number of horizontal grid lines to the same as that of the
411
+ // data items that we have.
412
+ if (RGraph.isNull(properties.backgroundGridHlinesCount)) {
413
+ this.set('backgroundGridHlinesCount', this.data.length);
414
+ }
415
+
416
+
417
+ //
418
+ // Populate the yaxisLabels property from the data. But only do this once
419
+ //
420
+ properties.yaxisLabelsSpecific = [];
421
+ for (var i=0; i<this.data.length; ++i) {
422
+ if (typeof this.data[i] === 'object' && typeof this.data[i][0] === 'object') {
423
+ properties.yaxisLabelsSpecific.push(this.data[i][0].label);
424
+ } else {
425
+ properties.yaxisLabelsSpecific.push(this.data[i].label);
426
+ }
427
+ }
428
+ properties.yaxisLabels = properties.yaxisLabelsSpecific;
429
+
430
+
431
+
432
+ //
433
+ // Draw the background
434
+ //
435
+ RGraph.Background.draw(this);
436
+
437
+
438
+
439
+ //
440
+ // Draw the labels at the top
441
+ //
442
+ this.drawLabels();
443
+
444
+
445
+
446
+ //
447
+ // Draw the events
448
+ //
449
+ this.drawEvents();
450
+
451
+
452
+
453
+ //
454
+ // Setup the context menu if required
455
+ //
456
+ if (properties.contextmenu) {
457
+ RGraph.showContext(this);
458
+ }
459
+
460
+
461
+
462
+
463
+ //
464
+ // Add custom text thats specified
465
+ //
466
+ RGraph.addCustomText(this);
467
+
468
+
469
+
470
+
471
+
472
+
473
+
474
+
475
+ //
476
+ // This installs the event listeners
477
+ //
478
+ RGraph.installEventListeners(this);
479
+
480
+
481
+ //
482
+ // Fire the onfirstdraw event
483
+ //
484
+ if (this.firstDraw) {
485
+ this.firstDraw = false;
486
+ RGraph.fireCustomEvent(this, 'onfirstdraw');
487
+ this.firstDrawFunc();
488
+ }
489
+
490
+
491
+
492
+
493
+ //
494
+ // Fire the RGraph draw event
495
+ //
496
+ RGraph.fireCustomEvent(this, 'ondraw');
497
+
498
+
499
+
500
+
501
+
502
+
503
+
504
+
505
+
506
+
507
+ //
508
+ // Install any inline responsive configuration. This
509
+ // should be last in the draw function - even after
510
+ // the draw events.
511
+ //
512
+ RGraph.installInlineResponsive(this);
513
+
514
+
515
+
516
+
517
+
518
+
519
+
520
+
521
+
522
+
523
+
524
+ return this;
525
+ };
526
+
527
+
528
+
529
+
530
+
531
+
532
+
533
+
534
+ //
535
+ // Used in chaining. Runs a function there and then - not waiting for
536
+ // the events to fire (eg the onbeforedraw event)
537
+ //
538
+ // @param function func The function to execute
539
+ //
540
+ this.exec = function (func)
541
+ {
542
+ func(this);
543
+
544
+ return this;
545
+ };
546
+
547
+
548
+
549
+
550
+
551
+
552
+
553
+
554
+ //
555
+ // Draws the labels at the top and the left of the chart
556
+ //
557
+ this.drawLabels = function ()
558
+ {
559
+ // Use the RGraph.drawXAxis() function to draw the X axis labels
560
+ RGraph.drawXAxis(this);
561
+
562
+ // Use the RGraph.drawYAxis() function to draw the Y axis labels
563
+ RGraph.drawYAxis(this);
564
+ };
565
+
566
+
567
+
568
+
569
+
570
+
571
+
572
+
573
+ //
574
+ // Draws the events to the canvas
575
+ //
576
+ this.drawEvents = function ()
577
+ {
578
+ var events = this.data;
579
+
580
+ //
581
+ // Reset the coords array to prevent it growing
582
+ //
583
+ this.coords = [];
584
+
585
+
586
+
587
+
588
+ //
589
+ // First draw the vertical bars that have been added
590
+ //
591
+ if (properties.backgroundVbars) {
592
+
593
+ for (i=0,len=properties.backgroundVbars.length; i<len; ++i) {
594
+
595
+ // Boundary checking
596
+ if (properties.backgroundVbars[i][0] + properties.backgroundVbars[i][1] > properties.xaxisScaleMax) {
597
+ properties.backgroundVbars[i][1] = 364 - properties.backgroundVbars[i][0];
598
+ }
599
+
600
+ var barX = this.marginLeft + (( (properties.backgroundVbars[i][0] - properties.xaxisScaleMin) / (properties.xaxisScaleMax - properties.xaxisScaleMin) ) * this.graphArea),
601
+ barY = this.marginTop,
602
+ width = (this.graphArea / (properties.xaxisScaleMax - properties.xaxisScaleMin) ) * properties.backgroundVbars[i][1],
603
+ height = this.canvas.height - this.marginTop - this.marginBottom;
604
+
605
+ // Right hand bounds checking
606
+ if ( (barX + width) > (this.canvas.width - this.marginRight) ) {
607
+ width = this.canvas.width - this.marginRight - barX;
608
+ }
609
+
610
+ this.context.fillStyle = properties.backgroundVbars[i][2];
611
+ this.context.fillRect(barX, barY, width, height);
612
+ }
613
+ }
614
+
615
+
616
+
617
+ // Now draw the horizontal bars
618
+ if (properties.backgroundHbars) {
619
+
620
+ for (i=0,len=properties.backgroundHbars.length; i<len; ++i) {
621
+
622
+ if (properties.backgroundHbars[i]) {
623
+
624
+ var barX = this.marginLeft,
625
+ barY = ((this.canvas.height - this.marginTop - this.marginBottom) / this.data.length) * i + this.marginTop,
626
+ width = this.graphArea,
627
+ height = this.barHeight
628
+
629
+ this.context.fillStyle = properties.backgroundHbars[i];
630
+ this.context.fillRect(barX, barY, width, height);
631
+ }
632
+ }
633
+ }
634
+
635
+
636
+
637
+
638
+ // Draw the events
639
+ var sequentialIndex = 0;
640
+
641
+ for (i=0; i<events.length; ++i) {
642
+ if (typeof events[i].start === 'number') {
643
+
644
+ this.drawSingleEvent(
645
+ events[i],
646
+ i,
647
+ sequentialIndex++
648
+ );
649
+ } else {
650
+ for (var j=0; j<events[i].length; ++j) {
651
+
652
+ var index = j;
653
+
654
+ this.drawSingleEvent(
655
+ events[i][j],
656
+ i,
657
+ sequentialIndex++,
658
+ index
659
+ );
660
+
661
+ }
662
+ }
663
+
664
+ }
665
+ };
666
+
667
+
668
+
669
+
670
+
671
+
672
+
673
+
674
+ //
675
+ // Retrieves the bar (if any) that has been click on or is hovered over
676
+ //
677
+ // @param object e The event object
678
+ //
679
+ this.getShape = function (e)
680
+ {
681
+ var mouseXY = RGraph.getMouseXY(e),
682
+ mouseX = mouseXY[0],
683
+ mouseY = mouseXY[1];
684
+
685
+ //
686
+ // Loop through the bars determining if the mouse is over a bar
687
+ //
688
+ for (var i=0,len=this.coords.length; i<len; i++) {
689
+
690
+ if (RGraph.tooltipsHotspotIgnore(this, i)) {
691
+ continue;
692
+ }
693
+
694
+ var left = this.coords[i][0],
695
+ top = this.coords[i][1],
696
+ width = this.coords[i][2],
697
+ height = this.coords[i][3];
698
+
699
+ if ( mouseX >= left
700
+ && mouseX <= (left + width)
701
+ && mouseY >= top
702
+ && mouseY <= (top + height)
703
+ ) {
704
+
705
+ if (RGraph.parseTooltipText && properties.tooltips) {
706
+ var tooltip = RGraph.parseTooltipText(properties.tooltips, i);
707
+ }
708
+
709
+ var dataset = this.coords[i][4].dataset;
710
+ var index = (this.coords[i][4] && typeof this.coords[i][4].index === 'number' ? this.coords[i][4].index : 0);
711
+ var label = this.coords[i][4].label;
712
+
713
+ var ret = {
714
+ object: this,
715
+ x: left,
716
+ y: top,
717
+ width: width,
718
+ height: height,
719
+ dataset: dataset,
720
+ index: index,
721
+ sequentialIndex: this.coords[i][5],
722
+ label: label,
723
+ tooltip: typeof tooltip === 'string' ? tooltip : null
724
+ };
725
+
726
+ return ret;
727
+ }
728
+ }
729
+ };
730
+
731
+
732
+
733
+
734
+
735
+
736
+
737
+
738
+ // Draws a single event
739
+ this.drawSingleEvent = function (ev, dataset, sequentialIndex)
740
+ {
741
+ // Store the indexes on the original data
742
+ ev.dataset = dataset;
743
+ if (typeof arguments[3] === 'number') {
744
+ ev.index = arguments[3]
745
+ }
746
+
747
+ var min = properties.xaxisScaleMin;
748
+
749
+ this.context.beginPath();
750
+ this.context.strokeStyle = 'black';
751
+ this.context.fillStyle = ev.color ? ev.color : properties.colorsDefault;
752
+
753
+ var barStartX = this.marginLeft + (((ev.start - min) / (properties.xaxisScaleMax - min)) * this.graphArea),
754
+ barStartY = this.marginTop + (dataset * this.barHeight),
755
+ barWidth = (ev.duration / (properties.xaxisScaleMax - min) ) * this.graphArea;
756
+
757
+ // If the width is greater than the graph atrea, curtail it
758
+ if ( (barStartX + barWidth) > (this.canvas.width - this.marginRight) ) {
759
+ barWidth = this.canvas.width - this.marginRight - barStartX;
760
+ }
761
+
762
+ // Draw the bar storing the coordinates
763
+ this.coords.push([
764
+ barStartX,
765
+ barStartY + properties.marginInner,
766
+ barWidth,
767
+ this.barHeight - (2 * properties.marginInner),
768
+ ev,
769
+ sequentialIndex,
770
+ ]);
771
+
772
+
773
+
774
+
775
+
776
+ // draw the border around the bar
777
+ if (properties.borders || typeof ev.border === 'number') {
778
+
779
+ this.context.strokeStyle = typeof ev.border === 'string' ? ev.border : 'black';
780
+ this.context.lineWidth = (typeof ev.linewidth === 'number' ? ev.linewidth : 1);
781
+
782
+ if (ev.linewidth !== 0) {
783
+ this.context.strokeRect(
784
+ barStartX,
785
+ barStartY + properties.marginInner,
786
+ barWidth,
787
+ this.barHeight - (2 * properties.marginInner)
788
+ );
789
+ }
790
+ }
791
+
792
+ // Not entirely sure what this does...
793
+ if (RGraph.isNull(ev.complete)) {
794
+ this.context.fillStyle = ev.color ? ev.color : properties.colorsDefault;
795
+ } else {
796
+ this.context.fillStyle = ev.background ? ev.background : properties.colorsDefault;
797
+ }
798
+
799
+ this.context.fillRect(
800
+ barStartX,
801
+ barStartY + properties.marginInner,
802
+ barWidth,
803
+ this.barHeight - (2 * properties.marginInner)
804
+ );
805
+
806
+ // Work out the completeage indicator
807
+ var complete = (ev.complete / 100) * barWidth;
808
+
809
+ // Draw the % complete indicator. If it's greater than 0
810
+ if (typeof ev.complete === 'number') {
811
+
812
+ this.context.fillStyle = ev.color ? ev.color : '#0c0';
813
+
814
+ // Draw the percent complete bar if the complete option is given
815
+ this.context.fillRect(
816
+ barStartX,
817
+ barStartY + properties.marginInner,
818
+ (ev.complete / 100) * barWidth,
819
+ this.barHeight - (2 * properties.marginInner)
820
+ );
821
+
822
+ // Don't necessarily have to draw the label
823
+ if (properties.labelsComplete) {
824
+
825
+ this.context.beginPath();
826
+
827
+ // Get the text configuration
828
+ var textConf = RGraph.getTextConf({
829
+ object: this,
830
+ prefix: 'labelsComplete'
831
+ });
832
+
833
+ RGraph.text({
834
+
835
+ object: this,
836
+
837
+ font: textConf.font,
838
+ size: textConf.size,
839
+ color: textConf.color,
840
+ bold: textConf.bold,
841
+ italic: textConf.italic,
842
+
843
+ x: barStartX + barWidth + 5 + properties.labelsCompleteOffsetx,
844
+ y: barStartY + this.halfBarHeight + properties.labelsCompleteOffsety,
845
+
846
+ text: String(ev.complete) + '%',
847
+
848
+ valign: 'center',
849
+ tag: 'labels.complete'
850
+ });
851
+ }
852
+ }
853
+
854
+
855
+ //
856
+ // Draw the inbar label if it's defined
857
+ //
858
+ if (properties.labelsInbar && properties.labelsInbar[sequentialIndex]) {
859
+
860
+ var label = String(properties.labelsInbar[sequentialIndex]),
861
+ halign = properties.labelsInbarAlign == 'left' ? 'left' : 'center';
862
+
863
+ halign = properties.labelsInbarAlign == 'right' ? 'right' : halign;
864
+
865
+ // Work out the position of the text
866
+ if (halign == 'right') {
867
+ var x = (barStartX + barWidth) - 5;
868
+ } else if (halign == 'center') {
869
+ var x = barStartX + (barWidth / 2);
870
+ } else {
871
+ var x = barStartX + 5;
872
+ }
873
+
874
+
875
+ // Draw the labels "above" the bar
876
+ if (properties.labelsInbarAbove) {
877
+ x = barStartX + barWidth + 5;
878
+ halign = 'left';
879
+ }
880
+
881
+ // Get the text configuration
882
+ var textConf = RGraph.getTextConf({
883
+ object: this,
884
+ prefix: 'labelsInbar'
885
+ });
886
+
887
+ // Set the color
888
+ this.context.fillStyle = properties.labelsInbarColor;
889
+ RGraph.text({
890
+
891
+ object: this,
892
+
893
+ font: textConf.font,
894
+ size: textConf.size,
895
+ color: textConf.color,
896
+ bold: textConf.bold,
897
+ italic: textConf.italic,
898
+
899
+ x: x + properties.labelsInbarOffsetx,
900
+ y: barStartY + this.halfBarHeight + properties.labelsInbarOffsety,
901
+ text: label,
902
+ valign: 'center',
903
+ halign: halign,
904
+ bounding: typeof properties.labelsInbarBgcolor == 'string',
905
+ boundingFill: typeof properties.labelsInbarBgcolor === 'string' ? properties.labelsInbarBgcolor : null,
906
+ tag: 'labels.inbar'
907
+ });
908
+ }
909
+ };
910
+
911
+
912
+
913
+
914
+
915
+
916
+
917
+
918
+ //
919
+ // Each object type has its own Highlight() function which highlights the appropriate shape
920
+ //
921
+ // @param object shape The shape to highlight
922
+ //
923
+ this.highlight = function (shape)
924
+ {
925
+ // First check for inverted highlighting
926
+ if (typeof properties.highlightStyle === 'string' && properties.highlightStyle === 'invert') {
927
+ for (var i=0; i<this.coords.length; ++i) {
928
+ if (i !== shape.sequentialIndex) {
929
+ this.path(
930
+ 'b r % % % % s % f %',
931
+ this.coords[i][0] - 0.5,this.coords[i][1] - 0.5,this.coords[i][2] + 1, this.coords[i][3] + 1,
932
+ properties.highlightStroke,
933
+ properties.highlightFill
934
+ );
935
+ }
936
+ }
937
+
938
+ return;
939
+ }
940
+
941
+ if (typeof properties.highlightStyle === 'function') {
942
+ (properties.highlightStyle)(shape);
943
+ } else {
944
+ RGraph.Highlight.rect(this, shape);
945
+ }
946
+ };
947
+
948
+
949
+
950
+
951
+
952
+
953
+
954
+
955
+ //
956
+ // The getObjectByXY() worker method. Don't call this call:
957
+ //
958
+ // RGraph.ObjectRegistry.getObjectByXY(e)
959
+ //
960
+ // @param object e The event object
961
+ //
962
+ this.getObjectByXY = function (e)
963
+ {
964
+ var mouseXY = RGraph.getMouseXY(e);
965
+
966
+ if (
967
+ mouseXY[0] > this.marginLeft
968
+ && mouseXY[0] < (this.canvas.width - this.marginRight)
969
+ && mouseXY[1] > this.marginTop
970
+ && mouseXY[1] < (this.canvas.height - this.marginBottom)
971
+ ) {
972
+
973
+ return this;
974
+ }
975
+ };
976
+
977
+
978
+
979
+
980
+
981
+
982
+
983
+
984
+ //
985
+ // This method handles the adjusting calculation for when the mouse is moved
986
+ //
987
+ // @param object e The event object
988
+ //
989
+ this.adjusting_mousemove = function (e)
990
+ {
991
+ // Handle adjusting for the Bar
992
+ if (properties.adjustable && RGraph.Registry.get('adjusting') && RGraph.Registry.get('adjusting').uid == this.uid) {
993
+
994
+ var bar = RGraph.Registry.get('adjusting.gantt');
995
+
996
+ if (bar) {
997
+ var mouseXY = RGraph.getMouseXY(e),
998
+ obj = bar.object,
999
+ dataset = bar.dataset,
1000
+ index = bar.index,
1001
+ diff = ((mouseXY[0] - bar.mousex) / (obj.canvas.width - obj.marginLeft - obj.marginRight)) * properties.xaxisScaleMax,
1002
+ eventStart = bar.event_start || 0,
1003
+ duration = bar.event_duration,
1004
+ event = typeof obj.data[dataset][index] === 'object' ? obj.data[dataset][index] : obj.data[dataset]
1005
+
1006
+ if (bar['mode'] === 'move') {
1007
+
1008
+ diff = Math.round(diff);
1009
+
1010
+
1011
+ // Single event
1012
+ if (!RGraph.isArray(obj.data[dataset])) {
1013
+
1014
+ event.start = eventStart + diff;
1015
+
1016
+ if (eventStart + diff < 0) {
1017
+ obj.data[dataset].start = 0;
1018
+
1019
+ } else if ((eventStart + diff + obj.data[dataset].duration) > properties.xaxisScaleMax) {
1020
+ obj.data[dataset].start = properties.xaxisScaleMax - obj.data[dataset].duration;
1021
+ }
1022
+
1023
+
1024
+ // Multiple events
1025
+ } else {
1026
+
1027
+ var dataset = bar.dataset,
1028
+ index = typeof bar.index === 'number' ? bar.index : 0,
1029
+ event = obj.data[dataset][index];
1030
+
1031
+ event.start = eventStart + diff;
1032
+
1033
+ if ( (eventStart + diff) < 0) {
1034
+ event.start = 0;
1035
+ } else if ( (eventStart + diff + event.duration) > properties.xaxisScaleMax ) {
1036
+ event.start = properties.xaxisScaleMax - event.duration;
1037
+ }
1038
+ }
1039
+
1040
+
1041
+
1042
+
1043
+
1044
+
1045
+
1046
+
1047
+
1048
+
1049
+
1050
+
1051
+ } else if (bar.mode == 'resize') {
1052
+
1053
+ //
1054
+ // Account for the right hand gutter. Appears to be a FF bug
1055
+ //
1056
+ if (mouseXY[0] > (obj.canvas.width - obj.marginRight)) {
1057
+ mouseXY[0] = obj.canvas.width - obj.marginRight;
1058
+ }
1059
+
1060
+ var diff = ((mouseXY[0] - RGraph.Registry.get('adjusting.gantt')['mousex']) / (obj.canvas.width - obj.marginLeft - obj.marginRight)) * properties.xaxisScaleMax;
1061
+ diff = Math.round(diff);
1062
+
1063
+
1064
+
1065
+
1066
+
1067
+
1068
+ // Single event
1069
+ if (!RGraph.isArray(obj.data[dataset])) {
1070
+ obj.data[dataset].duration = duration + diff;
1071
+
1072
+ if (obj.data[dataset].duration < 0) {
1073
+ obj.data[dataset].duration = 1;
1074
+ }
1075
+
1076
+ // Multiple events
1077
+ } else {
1078
+
1079
+ obj.data[dataset][index].duration = duration + diff;
1080
+
1081
+ if (obj.data[dataset][index].duration <= 0) {
1082
+ obj.data[dataset][index].duration = 1;
1083
+ }
1084
+
1085
+ }
1086
+ }
1087
+
1088
+ RGraph.resetColorsToOriginalValues(obj);
1089
+
1090
+ //RGraph.clear(obj.canvas);
1091
+ RGraph.redrawCanvas(obj.canvas);
1092
+
1093
+ RGraph.fireCustomEvent(obj, 'onadjust');
1094
+ }
1095
+ }
1096
+ };
1097
+
1098
+
1099
+
1100
+
1101
+
1102
+
1103
+
1104
+
1105
+ //
1106
+ // Returns the X coordinate for the given value
1107
+ //
1108
+ // @param number value The desired value (eg minute/hour/day etc)
1109
+ //
1110
+ this.getXCoord = function (value)
1111
+ {
1112
+ var min = properties.xaxisScaleMin,
1113
+ max = properties.xaxisScaleMax,
1114
+ graphArea = this.canvas.width - this.marginLeft - this.marginRight;
1115
+
1116
+ if (value > max || value < min) {
1117
+ return null;
1118
+ }
1119
+
1120
+ var x = (((value - min) / (max - min)) * graphArea) + this.marginLeft;
1121
+
1122
+ return x;
1123
+ };
1124
+
1125
+
1126
+
1127
+
1128
+
1129
+
1130
+
1131
+
1132
+ //
1133
+ // Returns the value given EITHER the event object OR a two element array containing the X/Y coords
1134
+ //
1135
+ this.getValue = function (arg)
1136
+ {
1137
+ if (arg.length == 2) {
1138
+ var mouseXY = arg; // Two coords given
1139
+ } else {
1140
+ var mouseXY = RGraph.getMouseXY(arg); // event given
1141
+ }
1142
+
1143
+ var mouseX = mouseXY[0],
1144
+ mouseY = mouseXY[1];
1145
+
1146
+ var value = (mouseX - this.marginLeft) / (this.canvas.width - this.marginLeft - this.marginRight);
1147
+ value *= (properties.xaxisScaleMax - properties.xaxisScaleMin);
1148
+
1149
+ // Bounds checking
1150
+ if (value < properties.xaxisScaleMin || value > properties.xaxisScaleMax) {
1151
+ value = null;
1152
+ }
1153
+
1154
+ return value;
1155
+ };
1156
+
1157
+
1158
+
1159
+
1160
+
1161
+
1162
+
1163
+
1164
+ //
1165
+ // This allows for easy specification of gradients. Could optimise this not to repeatedly call parseSingleColors()
1166
+ //
1167
+ this.parseColors = function ()
1168
+ {
1169
+ // Save the original colors so that they can be restored when the canvas is reset
1170
+ if (this.original_colors.length === 0) {
1171
+
1172
+ this.original_colors.data = RGraph.arrayClone(this.data);
1173
+ this.original_colors.backgroundBarsColor1 = RGraph.arrayClone(properties.backgroundBarsColor1);
1174
+ this.original_colors.backgroundBarsColor2 = RGraph.arrayClone(properties.backgroundBarsColor2);
1175
+ this.original_colors.backgroundGridColor = RGraph.arrayClone(properties.backgroundGridColor);
1176
+ this.original_colors.colorsDefault = RGraph.arrayClone(properties.colorsDefault);
1177
+ this.original_colors.highlightStroke = RGraph.arrayClone(properties.highlightStroke);
1178
+ this.original_colors.highlightFill = RGraph.arrayClone(properties.highlightFill);
1179
+ }
1180
+
1181
+
1182
+
1183
+
1184
+ //
1185
+ // this.coords can be used here as gradients are only parsed on the SECOND draw - not the first.
1186
+ // A .redraw() is downe at the end of the first draw.
1187
+ //
1188
+ for (var i=0,sequentialIndex=0; i<this.data.length; ++i) {
1189
+
1190
+ // Multiple events
1191
+ if ( RGraph.isArray(this.data[i])
1192
+ && typeof this.data[i][0] === 'object'
1193
+ && typeof this.data[i][0].start === 'number'
1194
+ ) {
1195
+
1196
+ for (var j=0,len=this.data[i].length; j<len; j+=1,sequentialIndex+=1) {
1197
+ this.data[i][j].background = this.parseSingleColorForGradient(
1198
+ this.data[i][j].background,
1199
+ {start: this.data[i][j].start, duration: this.data[i][j].duration}
1200
+ );
1201
+
1202
+ this.data[i][j].color = this.parseSingleColorForGradient(
1203
+ this.data[i][j].color,
1204
+ {start: this.data[i][j].start, duration: this.data[i][j].duration}
1205
+ );
1206
+ }
1207
+
1208
+ // Single event
1209
+ } else {
1210
+
1211
+ if (typeof this.data[i].background === 'string') {
1212
+ this.data[i].background = this.parseSingleColorForGradient(
1213
+ this.data[i].background,
1214
+ {start: this.data[i].start, duration: this.data[i].duration}
1215
+ );
1216
+ }
1217
+
1218
+ if (typeof this.data[i].color === 'string') {
1219
+ this.data[i].color = this.parseSingleColorForGradient(
1220
+ this.data[i].color,
1221
+ {start: this.data[i].start, duration: this.data[i].duration}
1222
+ );
1223
+ }
1224
+
1225
+ ++sequentialIndex;
1226
+ }
1227
+ }
1228
+
1229
+ properties.backgroundBarsColor1 = this.parseSingleColorForGradient(properties.backgroundBarsColor1);
1230
+ properties.backgroundBarsColor2 = this.parseSingleColorForGradient(properties.backgroundBarsColor2);
1231
+ properties.backgroundGridColor = this.parseSingleColorForGradient(properties.backgroundGridColor);
1232
+ properties.backgroundColor = this.parseSingleColorForGradient(properties.backgroundColor);
1233
+ properties.colorsDefault = this.parseSingleColorForGradient(properties.colorsDefault);
1234
+ properties.highlightStroke = this.parseSingleColorForGradient(properties.highlightStroke);
1235
+ properties.highlightFill = this.parseSingleColorForGradient(properties.highlightFill);
1236
+ };
1237
+
1238
+
1239
+
1240
+
1241
+
1242
+
1243
+
1244
+
1245
+ //
1246
+ // Use this function to reset the object to the post-constructor state. Eg reset colors if
1247
+ // need be etc
1248
+ //
1249
+ this.reset = function ()
1250
+ {
1251
+ };
1252
+
1253
+
1254
+
1255
+
1256
+
1257
+
1258
+
1259
+
1260
+ //
1261
+ // This parses a single color value
1262
+ //
1263
+ // @param string color The color to parse
1264
+ //
1265
+ this.parseSingleColorForGradient = function (color)
1266
+ {
1267
+ var opts = arguments[1] || {};
1268
+
1269
+ if (!color || typeof color != 'string') {
1270
+ return color;
1271
+ }
1272
+
1273
+
1274
+ if (color.match(/^gradient\((.*)\)$/i)) {
1275
+
1276
+ // Allow for JSON gradients
1277
+ if (color.match(/^gradient\(({.*})\)$/i)) {
1278
+ return RGraph.parseJSONGradient({object: this, def: RegExp.$1});
1279
+ }
1280
+
1281
+ var parts = RegExp.$1.split(':'),
1282
+ value = (opts.start + opts.duration) > properties.xaxisScaleMax ? properties.xaxisScaleMax : (opts.start + opts.duration);
1283
+
1284
+ // Create the gradient
1285
+ var grad = this.context.createLinearGradient(
1286
+ typeof opts.start === 'number' ? this.getXCoord(opts.start) : this.marginLeft,
1287
+ 0,
1288
+ typeof opts.start === 'number' ? this.getXCoord(value) : this.canvas.width - this.marginRight,
1289
+ 0
1290
+ );
1291
+
1292
+ var diff = 1 / (parts.length - 1);
1293
+
1294
+ grad.addColorStop(0, RGraph.trim(parts[0]));
1295
+ for (var j=1; j<parts.length; ++j) {
1296
+ grad.addColorStop(j * diff, RGraph.trim(parts[j]));
1297
+ }
1298
+ }
1299
+
1300
+ return grad ? grad : color;
1301
+ };
1302
+
1303
+
1304
+
1305
+
1306
+
1307
+
1308
+
1309
+
1310
+ //
1311
+ // Using a function to add events makes it easier to facilitate method chaining
1312
+ //
1313
+ // @param string type The type of even to add
1314
+ // @param function func
1315
+ //
1316
+ this.on = function (type, func)
1317
+ {
1318
+ if (type.substr(0,2) !== 'on') {
1319
+ type = 'on' + type;
1320
+ }
1321
+
1322
+ if (typeof this[type] !== 'function') {
1323
+ this[type] = func;
1324
+ } else {
1325
+ RGraph.addCustomEventListener(this, type, func);
1326
+ }
1327
+
1328
+ return this;
1329
+ };
1330
+
1331
+
1332
+
1333
+
1334
+
1335
+
1336
+
1337
+
1338
+ //
1339
+ // This function runs once only
1340
+ // (put at the end of the file (before any effects))
1341
+ //
1342
+ this.firstDrawFunc = function ()
1343
+ {
1344
+ };
1345
+
1346
+
1347
+
1348
+
1349
+
1350
+
1351
+
1352
+
1353
+ //
1354
+ // Gantt chart Grow effect
1355
+ //
1356
+ // @param object obj Options for the grow effect
1357
+ // @param function Optional callback (a function)
1358
+ //
1359
+ this.grow = function ()
1360
+ {
1361
+ // Cancel any stop request if one is pending
1362
+ this.cancelStopAnimation();
1363
+
1364
+ // Reset the data to the original
1365
+ this.data = RGraph.arrayClone(this.original_data);
1366
+
1367
+ var obj = this,
1368
+ opt = arguments[0] || {},
1369
+ callback = arguments[1] ? arguments[1] : function () {},
1370
+ canvas = obj.canvas,
1371
+ context = obj.context,
1372
+ numFrames = opt.frames || 30,
1373
+ frame = 0;
1374
+ original_events = RGraph.arrayClone(obj.data);
1375
+
1376
+ function iterator ()
1377
+ {
1378
+ if (obj.stopAnimationRequested) {
1379
+
1380
+ // Reset the flag
1381
+ obj.stopAnimationRequested = false;
1382
+
1383
+ return;
1384
+ }
1385
+
1386
+ RGraph.clear(obj.canvas);
1387
+ RGraph.redrawCanvas(obj.canvas);
1388
+
1389
+
1390
+ if (frame <= numFrames) {
1391
+ // Update the events
1392
+ for (var i=0,len=obj.data.length; i<len; ++i) {
1393
+ if (typeof obj.data[i] === 'object' && obj.data[i][0] && typeof obj.data[i][0] === 'object') {
1394
+ for (var j=0; j<obj.data[i].length; ++j) {
1395
+ obj.data[i][j].duration = (frame / numFrames) * original_events[i][j].duration;
1396
+ }
1397
+ } else {
1398
+ obj.data[i].duration = (frame / numFrames) * original_events[i].duration;
1399
+ }
1400
+ }
1401
+
1402
+ obj.reset();
1403
+
1404
+
1405
+
1406
+ frame++;
1407
+
1408
+ RGraph.Effects.updateCanvas(iterator);
1409
+
1410
+ } else {
1411
+ callback(obj);
1412
+ }
1413
+ }
1414
+
1415
+ iterator();
1416
+
1417
+ return this;
1418
+ };
1419
+
1420
+
1421
+
1422
+
1423
+
1424
+
1425
+
1426
+
1427
+ //
1428
+ // Couple of functions that allow you to control the
1429
+ // animation effect
1430
+ //
1431
+ this.stopAnimation = function ()
1432
+ {
1433
+ this.stopAnimationRequested = true;
1434
+ };
1435
+
1436
+ this.cancelStopAnimation = function ()
1437
+ {
1438
+ this.stopAnimationRequested = false;
1439
+ };
1440
+
1441
+
1442
+
1443
+
1444
+
1445
+
1446
+
1447
+
1448
+ //
1449
+ // This helps the Gantt reset colors when the reset function is called.
1450
+ // It handles going through the data and resetting the colors.
1451
+ //
1452
+ this.resetColorsToOriginalValues = function ()
1453
+ {
1454
+ //
1455
+ // Copy the original colors over for single-event-per-line data
1456
+ //
1457
+ for (var i=0; i<this.original_colors.data.length; ++i) {
1458
+ if (this.original_colors.data[i].background) {
1459
+ this.data[i].background = RGraph.arrayClone(this.original_colors.data[i].background);
1460
+ }
1461
+
1462
+ if (this.original_colors.data[i].color) {
1463
+ this.data[i].color = RGraph.arrayClone(this.original_colors.data[i].color);
1464
+ }
1465
+
1466
+ if (typeof this.original_colors.data[i][0] === 'object' && typeof this.original_colors.data[i][0].start === 'number') {
1467
+ for (var j=0,len2=this.original_colors.data[i].length; j<len2; ++j) {
1468
+ this.data[i][j].background = RGraph.arrayClone(this.original_colors.data[i][j].background);
1469
+ this.data[i][j].color = RGraph.arrayClone(this.original_colors.data[i][j].color);
1470
+ }
1471
+ }
1472
+ }
1473
+ };
1474
+
1475
+
1476
+
1477
+
1478
+
1479
+
1480
+
1481
+
1482
+ //
1483
+ // This function resets the object - clearing it of any previously gathered info
1484
+ //
1485
+ this.reset = function ()
1486
+ {
1487
+ this.resetColorsToOriginalValues();
1488
+
1489
+ this.colorsParsed = false;
1490
+ this.coordsText = [];
1491
+ this.original_colors = [];
1492
+ this.firstDraw = true;
1493
+ this.coords = [];
1494
+ };
1495
+
1496
+
1497
+
1498
+
1499
+
1500
+
1501
+
1502
+
1503
+ // An unused function
1504
+ this.sequentialIndex2Grouped=function(){alert('[RGRAPH] Something went badly wrong - contact support');};
1505
+
1506
+
1507
+
1508
+
1509
+
1510
+
1511
+
1512
+
1513
+ // Determines whether the Gant is adjustable or not
1514
+ this.isAdjustable = function (shape)
1515
+ {
1516
+ if (RGraph.isNull(properties.adjustableOnly)) {
1517
+ return true;
1518
+
1519
+ } else if (RGraph.isArray(properties.adjustableOnly) && shape && properties.adjustableOnly[shape.sequentialIndex]) {
1520
+ return true;
1521
+ }
1522
+
1523
+ return false;
1524
+ };
1525
+
1526
+
1527
+
1528
+
1529
+
1530
+
1531
+
1532
+
1533
+ //
1534
+ // A worker function that handles Bar chart specific tooltip substitutions
1535
+ //
1536
+ this.tooltipSubstitutions = function (opt)
1537
+ {
1538
+ var event = this['$' + opt.index];
1539
+
1540
+ var value = {
1541
+ start: event.start,
1542
+ duration: event.duration,
1543
+ complete: event.complete
1544
+ };
1545
+
1546
+
1547
+ //
1548
+ // Return the values to the user
1549
+ //
1550
+ return {
1551
+ index: event.index,
1552
+ dataset: event.dataset,
1553
+ sequentialIndex: opt.index,
1554
+ value: value
1555
+ };
1556
+ };
1557
+
1558
+
1559
+
1560
+
1561
+
1562
+
1563
+
1564
+
1565
+ //
1566
+ // A worker function that returns the correct color/label/value
1567
+ //
1568
+ // @param object specific The indexes that are applicable
1569
+ // @param number index The appropriate index
1570
+ //
1571
+ this.tooltipsFormattedCustom = function (specific, index)
1572
+ {
1573
+ return {
1574
+ //label:,
1575
+ //color:,
1576
+ //value:
1577
+ };
1578
+ };
1579
+
1580
+
1581
+
1582
+
1583
+
1584
+
1585
+
1586
+
1587
+ //
1588
+ // This allows for static tooltip positioning
1589
+ //
1590
+ this.positionTooltipStatic = function (args)
1591
+ {
1592
+ var obj = args.object,
1593
+ e = args.event,
1594
+ tooltip = args.tooltip,
1595
+ index = args.index,
1596
+ canvasXY = RGraph.getCanvasXY(obj.canvas)
1597
+ coords = this.coords[args.index];
1598
+
1599
+ // Position the tooltip in the X direction
1600
+ args.tooltip.style.left = (
1601
+ canvasXY[0] // The X coordinate of the canvas
1602
+ + coords[0] // The X coordinate of the point on the chart
1603
+ + (coords[2] / 2) // Add half of the width of the bar
1604
+ - (tooltip.offsetWidth / 2) // Subtract half of the tooltip width
1605
+ + obj.properties.tooltipsOffsetx // Add any user defined offset
1606
+ ) + 'px';
1607
+
1608
+ args.tooltip.style.top = (
1609
+ canvasXY[1] // The Y coordinate of the canvas
1610
+ + coords[1] // The Y coordinate of the bar on the chart
1611
+ - tooltip.offsetHeight // The height of the tooltip
1612
+ - 10 // An arbitrary amount
1613
+ + obj.properties.tooltipsOffsety // Add any user defined offset
1614
+ ) + 'px';
1615
+
1616
+ // If the top of the tooltip is off the top of the page
1617
+ // then move the tooltip down
1618
+ if(parseFloat(args.tooltip.style.top) < 0) {
1619
+ args.tooltip.style.top = parseFloat(args.tooltip.style.top) + (coords[3] / 2) + 5 + 'px';
1620
+ }
1621
+ };
1622
+
1623
+
1624
+
1625
+
1626
+
1627
+
1628
+
1629
+
1630
+ //
1631
+ // Register the object
1632
+ //
1633
+ RGraph.register(this);
1634
+
1635
+
1636
+
1637
+
1638
+
1639
+
1640
+
1641
+
1642
+ //
1643
+ // This is the 'end' of the constructor so if the first argument
1644
+ // contains configuration data - handle that.
1645
+ //
1646
+ RGraph.parseObjectStyleConfig(this, conf.options);
1647
+ };