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,107 +1,3534 @@
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.SVG=RGraph.SVG||{};(function(win,doc,undefined)
3
- {var RG=RGraph,ua=navigator.userAgent,ma=Math,win=window,doc=document;RG.SVG.Bipolar=function(conf)
4
- {this.set=function(name,value)
5
- {if(arguments.length===1&&typeof name==='object'){for(i in arguments[0]){if(typeof i==='string'){name=ret.name;value=ret.value;this.set(name,value);}}}else{var ret=RG.SVG.commonSetter({object:this,name:name,value:value});name=ret.name;value=ret.value;this.properties[name]=value;if(name==='colors'){this.originalColors=RG.SVG.arrayClone(value);this.colorsParsed=false;}}
6
- return this;};this.get=function(name)
7
- {return this.properties[name];};this.id=conf.id;this.uid=RG.SVG.createUID();this.container=document.getElementById(this.id);this.layers={};this.svg=RG.SVG.createSVG({object:this,container:this.container});this.isRGraph=true;this.data=[conf.left,conf.right];this.left=conf.left;this.right=conf.right;this.type='bipolar';this.coords=[];this.coordsLeft=[];this.coordsRight=[];this.coords2=[];this.coords2Left=[];this.coords2Right=[];this.stackedBackfacesLeft=[];this.stackedBackfacesRight=[];this.originalColors={};this.gradientCounter=1;this.sequentialIndex=0;this.propertyNameAliases={};RG.SVG.OR.add(this);this.container.style.display='inline-block';this.properties={marginLeft:35,marginRight:35,marginTop:35,marginBottom:35,marginCenter:null,backgroundColor:null,backgroundGrid:true,backgroundGridColor:'#ddd',backgroundGridLinewidth:1,backgroundGridHlines:true,backgroundGridHlinesCount:null,backgroundGridVlines:true,backgroundGridVlinesCount:null,backgroundGridBorder:true,backgroundGridDashed:false,backgroundGridDotted:false,backgroundGridDashArray:null,xaxis:true,xaxisLinewidth:1,xaxisTickmarks:true,xaxisTickmarksLength:5,xaxisLabelsCount:5,xaxisLabelsPositionEdgeTickmarksCount:5,xaxisColor:'black',xaxisLabelsOffsetx:0,xaxisLabelsOffsety:0,xaxisLabelsFont:null,xaxisLabelsSize:null,xaxisLabelsBold:null,xaxisLabelsItalic:null,xaxisLabelsColor:null,xaxisScaleUnitsPre:'',xaxisScaleUnitsPost:'',xaxisScaleStrict:false,xaxisScaleDecimals:0,xaxisScalePoint:'.',xaxisScaleThousand:',',xaxisScaleRound:false,xaxisScaleMax:null,xaxisScaleMin:0,xaxisScaleFormatter:null,yaxis:true,yaxisTickmarks:true,yaxisTickmarksLength:5,yaxisColor:'black',yaxisScale:false,yaxisLabels:null,yaxisLabelsOffsetx:0,yaxisLabelsOffsety:0,yaxisLabelsFont:null,yaxisLabelsSize:null,yaxisLabelsBold:null,yaxisLabelsItalic:null,yaxisLabelsColor:null,colors:['red','#0f0','#00f','#ff0','#0ff','#0f0','pink','orange','gray','black','red','#0f0','#00f','#ff0','#0ff','#0f0','pink','orange','gray','black'],colorsSequential:false,colorsStroke:'rgba(0,0,0,0)',vmargin:3,vmarginGrouped:2,labelsAbove:false,labelsAboveFont:null,labelsAboveSize:null,labelsAboveBold:null,labelsAboveItalic:null,labelsAboveColor:null,labelsAboveBackground:null,labelsAboveBackgroundPadding:0,labelsAboveUnitsPre:null,labelsAboveUnitsPost:null,labelsAbovePoint:null,labelsAboveThousand:null,labelsAboveFormatter:null,labelsAboveDecimals:null,labelsAboveOffsetx:0,labelsAboveOffsety:0,labelsAboveSpecific:null,textColor:'black',textFont:'Arial, Verdana, sans-serif',textSize:12,textBold:false,textItalic:false,linewidth:1,grouping:'grouped',tooltips:null,tooltipsOverride:null,tooltipsEffect:'fade',tooltipsCssClass:'RGraph_tooltip',tooltipsEvent:'click',highlightStroke:'rgba(0,0,0,0)',highlightFill:'rgba(255,255,255,0.7)',highlightLinewidth:1,title:'',titleX:null,titleY:null,titleHalign:'center',titleValign:null,titleSize:null,titleColor:null,titleFont:null,titleBold:null,titleItalic:null,titleSubtitle:null,titleSubtitleX:null,titleSubtitleY:null,titleSubtitleHalign:'center',titleSubtitleValign:null,titleSubtitleColor:'#aaa',titleSubtitleSize:null,titleSubtitleFont:null,titleSubtitleBold:null,titleSubtitleItalic:null,shadow:false,shadowOffsetx:2,shadowOffsety:2,shadowBlur:2,shadowOpacity:0.25,key:null,keyColors:null,keyOffsetx:0,keyOffsety:0,keyLabelsOffsetx:0,keyLabelsOffsety:-1,keyLabelsSize:null,keyLabelsBold:null,keyLabelsItalic:null,keyLabelsFont:null,keyLabelsColor:null};RG.SVG.getGlobals(this);if(RG.SVG.FX&&typeof RG.SVG.FX.decorate==='function'){RG.SVG.FX.decorate(this);}
8
- var prop=this.properties;this.draw=function()
9
- {RG.SVG.fireCustomEvent(this,'onbeforedraw');this.width=Number(this.svg.getAttribute('width'));this.height=Number(this.svg.getAttribute('height'));RG.SVG.createDefs(this);if(typeof prop.marginCenter!=='number'){prop.marginCenter=this.getMarginCenter();}
10
- this.coords=[];this.coordsLeft=[];this.coordsRight=[];this.coords2=[];this.coords2Left=[];this.coords2Right=[];this.graphWidth=(this.width-prop.marginLeft-prop.marginRight-prop.marginCenter)/2;this.graphHeight=this.height-prop.marginTop-prop.marginBottom;RG.SVG.resetColorsToOriginalValues({object:this});this.parseColors();var values=[];for(var i=0;i<2;++i){for(var j=0,max=0;j<this.data[i].length;++j){if(typeof this.data[i][j]==='number'){values.push(this.data[i][j]);}else if(RG.SVG.isArray(this.data[i][j])&&prop.grouping==='grouped'){values.push(RG.SVG.arrayMax(this.data[i][j]));}else if(RG.SVG.isArray(this.data[i][j])&&prop.grouping==='stacked'){values.push(RG.SVG.arraySum(this.data[i][j]));}}}
11
- var max=RG.SVG.arrayMax(values);if(typeof prop.xaxisScaleMax==='number'){max=prop.xaxisScaleMax;}
12
- this.scale=RG.SVG.getScale({object:this,numlabels:prop.xaxisLabelsCount,unitsPre:prop.xaxisScaleUnitsPre,unitsPost:prop.xaxisScaleUnitsPost,max:max,min:prop.xaxisScaleMin,point:prop.xaxisScalePoint,round:prop.xaxisScaleRound,thousand:prop.xaxisScaleThousand,decimals:prop.xaxisScaleDecimals,strict:typeof prop.xaxisScaleMax==='number',formatter:prop.xaxisScaleFormatter});this.max=this.scale.max;this.min=this.scale.min;prop.yaxisScaleMax=this.scale.max;prop.yaxisScaleMin=this.scale.min;this.drawBackground(this);this.drawTitle();this.drawBars();this.drawAxes();this.drawLabels()
13
- this.drawLabelsAbove();if(typeof prop.key!==null&&RG.SVG.drawKey){RG.SVG.drawKey(this);}else if(!RG.SVG.isNull(prop.key)){alert('The drawKey() function does not exist - have you forgotten to include the key library?');}
14
- RG.SVG.fireCustomEvent(this,'ondraw');return this;};this.drawBackground=function()
15
- {var originalMarginRight=prop.marginRight,originalMarginLeft=prop.marginLeft;prop.marginRight=this.width-(prop.marginLeft+this.graphWidth);if(RG.SVG.isNull(prop.backgroundGridHlinesCount)){var resetToNull=true;prop.backgroundGridHlinesCount=this.left.length;}
16
- var properties=['','Aspect','Opacity','Stretch','X','Y','W','H',];for(i in properties){if(typeof properties[i]==='string'){prop['backgroundImage'+String(properties[i])]=prop['backgroundImageLeft'+properties[i]];}}
17
- RG.SVG.drawBackground(this);if(resetToNull){prop.backgroundGridHlinesCount=null;}
18
- prop.marginRight=originalMarginRight;prop.marginLeft=this.width-(prop.marginRight+this.graphWidth);if(RG.SVG.isNull(prop.backgroundGridHlinesCount)){prop.backgroundGridHlinesCount=this.right.length;}
19
- var properties=['','Aspect','Opacity','Stretch','X','Y','W','H',];for(i in properties){if(typeof properties[i]==='string'){prop['backgroundImage'+properties[i]]=prop['backgroundImageRight'+properties[i]];}}
20
- RG.SVG.drawBackground(this);prop.marginLeft=originalMarginLeft;prop.marginRight=originalMarginRight;};this.drawAxes=function()
21
- {if(prop.xaxis){RG.SVG.create({svg:this.svg,type:'path',parent:this.svg.all,attr:{d:'M {1} {2} L {3} {4}'.format(prop.marginLeft,this.height-prop.marginBottom,prop.marginLeft+this.graphWidth,this.height-prop.marginBottom),'stroke-width':prop.xaxisLinewidth,stroke:prop.xaxisColor,fill:'rgba(0,0,0,0)','shape-rendering':'crispEdges'}});RG.SVG.create({svg:this.svg,type:'path',parent:this.svg.all,attr:{d:'M {1} {2} L {3} {4}'.format(this.width-prop.marginRight,this.height-prop.marginBottom,this.width-prop.marginRight-this.graphWidth,this.height-prop.marginBottom),'stroke-width':prop.xaxisLinewidth,stroke:prop.xaxisColor,fill:'rgba(0,0,0,0)','shape-rendering':'crispEdges'}});if(prop.xaxisTickmarks){var startY=this.height-prop.marginBottom,endY=this.height-prop.marginBottom+prop.xaxisTickmarksLength;for(var i=0;i<prop.xaxisLabelsPositionEdgeTickmarksCount;++i){var x=prop.marginLeft+(i*(this.graphWidth/prop.xaxisLabelsPositionEdgeTickmarksCount));RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(x+0.001,startY,x,endY),stroke:prop.xaxisColor,'stroke-width':prop.xaxisLinewidth,'shape-rendering':"crispEdges"}});}
22
- if(!prop.yaxis){var x=prop.marginLeft+this.graphWidth;RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(x+0.001,startY,x,endY),stroke:prop.xaxisColor,'stroke-width':prop.xaxisLinewidth,'shape-rendering':"crispEdges"}});}
23
- for(var i=0;i<prop.xaxisLabelsPositionEdgeTickmarksCount;++i){var x=prop.marginLeft+prop.marginCenter+this.graphWidth+((i+1)*(this.graphWidth/prop.xaxisLabelsPositionEdgeTickmarksCount));RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(x+0.001,startY,x,endY),stroke:prop.xaxisColor,'stroke-width':prop.xaxisLinewidth,'shape-rendering':"crispEdges"}});}
24
- if(!prop.yaxis){var x=prop.marginLeft+this.graphWidth+prop.marginCenter;RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(x+0.001,startY,x,endY),stroke:prop.xaxisColor,'stroke-width':prop.xaxisLinewidth,'shape-rendering':"crispEdges"}});}}}
25
- if(prop.yaxis){RG.SVG.create({svg:this.svg,type:'path',parent:this.svg.all,attr:{d:'M {1} {2} L {3} {4}'.format(prop.marginLeft+this.graphWidth,this.height-prop.marginBottom,prop.marginLeft+this.graphWidth,prop.marginTop),'stroke-width':prop.yaxisLinewidth,stroke:prop.yaxisColor,fill:'rgba(0,0,0,0)','shape-rendering':'crispEdges','stroke-linecap':'square'}});RG.SVG.create({svg:this.svg,type:'path',parent:this.svg.all,attr:{d:'M {1} {2} L {3} {4}'.format(prop.marginLeft+this.graphWidth+prop.marginCenter,this.height-prop.marginBottom,prop.marginLeft+this.graphWidth+prop.marginCenter,prop.marginTop),'stroke-width':prop.yaxisLinewidth,stroke:prop.yaxisColor,fill:'rgba(0,0,0,0)','shape-rendering':'crispEdges','stroke-linecap':'square'}});if(prop.yaxisTickmarks){var startX=prop.marginLeft+this.graphWidth,endX=prop.marginLeft+this.graphWidth+prop.yaxisTickmarksLength,numticks=this.left.length;for(var i=0;i<numticks;++i){var y=prop.marginTop+(i*(this.graphHeight/numticks));RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(startX+0.001,y,endX,y),stroke:prop.yaxisColor,'stroke-width':prop.yaxisLinewidth,'shape-rendering':"crispEdges"}});}
26
- if(!prop.xaxis){var y=prop.marginTop+this.graphHeight;RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(startX+0.001,y,endX,y),stroke:prop.yaxisColor,'stroke-width':prop.yaxisLinewidth,'shape-rendering':"crispEdges"}});}
27
- var startX=prop.marginLeft+this.graphWidth+prop.marginCenter,endX=prop.marginLeft+this.graphWidth+prop.marginCenter-prop.yaxisTickmarksLength,numticks=this.right.length;for(var i=0;i<numticks;++i){var y=prop.marginTop+(i*(this.graphHeight/numticks));RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(startX+0.001,y,endX,y),stroke:prop.yaxisColor,'stroke-width':prop.yaxisLinewidth,'shape-rendering':"crispEdges"}});}
28
- if(!prop.xaxis){var y=prop.marginTop+this.graphHeight;RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'path',attr:{d:'M{1} {2} L{3} {4}'.format(startX+0.001,y,endX,y),stroke:prop.yaxisColor,'stroke-width':prop.yaxisLinewidth,'shape-rendering':"crispEdges"}});}}}};this.drawLabels=function()
29
- {var numlabels=prop.yaxisLabels?prop.yaxisLabels.length:5
30
- for(var i=0;i<numlabels;++i){var segment=this.graphHeight/numlabels,y=prop.marginTop+(segment*i)+(segment/2)+prop.yaxisLabelsOffsety,x=prop.marginLeft+this.graphWidth+(prop.marginCenter/2)+prop.yaxisLabelsOffsetx;var text=RG.SVG.text({object:this,parent:this.svg.all,text:prop.yaxisLabels&&prop.yaxisLabels[i]?prop.yaxisLabels[i]:'',x:x,y:y,halign:'center',valign:'center',tag:'labels.yaxis',font:prop.yaxisLabelsFont||prop.textFont,size:typeof prop.yaxisLabelsSize==='number'?prop.yaxisLabelsSize:prop.textSize,bold:typeof prop.yaxisLabelsBold==='boolean'?prop.yaxisLabelsBold:prop.textBold,italic:typeof prop.yaxisLabelsItalic==='boolean'?prop.yaxisLabelsItalic:prop.textItalic,color:prop.yaxisLabelsColor||prop.textColor});}
31
- var segment=this.graphWidth/prop.xaxisLabelsCount;for(var i=0;i<this.scale.labels.length;++i){RG.SVG.text({object:this,parent:this.svg.all,text:this.scale.labels[i],x:prop.marginLeft+this.graphWidth-(segment*(i+1))+prop.xaxisLabelsOffsetx,y:this.height-prop.marginBottom+10+prop.xaxisLabelsOffsety,halign:'center',valign:'top',tag:'labels.xaxis',font:prop.xaxisLabelsFont||prop.textFont,size:typeof prop.xaxisLabelsSize==='number'?prop.xaxisLabelsSize:prop.textSize,bold:typeof prop.xaxisLabelsBold==='boolean'?prop.xaxisLabelsBold:prop.textBold,italic:typeof prop.xaxisLabelsItalic==='boolean'?prop.xaxisLabelsItalic:prop.textItalic,color:prop.xaxisLabelsColor||prop.textColor});}
32
- var y=this.height-prop.marginBottom+10,str=(prop.xaxisScaleUnitsPre+prop.xaxisScaleMin.toFixed(prop.xaxisScaleDecimals).replace(/\./,prop.xaxisScalePoint)+prop.xaxisScaleUnitsPost);var text=RG.SVG.text({object:this,parent:this.svg.all,text:str,x:prop.marginLeft+this.graphWidth+prop.xaxisLabelsOffsetx,y:y+prop.xaxisLabelsOffsety,halign:'center',valign:'top',tag:'labels.xaxis',font:prop.xaxisLabelsFont||prop.textFont,size:typeof prop.xaxisLabelsSize==='number'?prop.xaxisLabelsSize:prop.textSize,bold:typeof prop.xaxisLabelsBold==='boolean'?prop.xaxisLabelsBold:prop.textBold,italic:typeof prop.xaxisLabelsItalic==='boolean'?prop.xaxisLabelsItalic:prop.textItalic,color:prop.xaxisLabelsColor||prop.textColor});for(var i=0;i<this.scale.labels.length;++i){RG.SVG.text({object:this,parent:this.svg.all,text:this.scale.labels[i],x:prop.marginLeft+this.graphWidth+prop.marginCenter+(segment*(i+1))+prop.xaxisLabelsOffsetx,y:this.height-prop.marginBottom+10+prop.xaxisLabelsOffsety,halign:'center',valign:'top',tag:'labels.xaxis',font:prop.xaxisLabelsFont||prop.textFont,size:typeof prop.xaxisLabelsSize==='number'?prop.xaxisLabelsSize:prop.textSize,bold:typeof prop.xaxisLabelsBold==='boolean'?prop.xaxisLabelsBold:prop.textBold,italic:typeof prop.xaxisLabelsItalic==='boolean'?prop.xaxisLabelsItalic:prop.textItalic,color:prop.xaxisLabelsColor||prop.textColor});}
33
- var text=RG.SVG.text({object:this,parent:this.svg.all,text:prop.xaxisScaleUnitsPre+prop.xaxisScaleMin.toFixed(prop.xaxisScaleDecimals).replace(/\./,prop.xaxisScalePoint)+prop.xaxisScaleUnitsPost,x:prop.marginLeft+this.graphWidth+prop.marginCenter+prop.xaxisLabelsOffsetx,y:this.height-prop.marginBottom+10+prop.xaxisLabelsOffsety,halign:'center',valign:'top',tag:'labels.xaxis',font:prop.xaxisLabelsFont||prop.textFont,size:typeof prop.xaxisLabelsSize==='number'?prop.xaxisLabelsSize:prop.textSize,bold:typeof prop.xaxisLabelsBold==='boolean'?prop.xaxisLabelsBold:prop.textBold,italic:typeof prop.xaxisLabelsItalic==='boolean'?prop.xaxisLabelsItalic:prop.textItalic,color:prop.xaxisLabelsColor||prop.textColor});};this.drawBars=function()
34
- {if(prop.shadow){RG.SVG.setShadow({object:this,offsetx:prop.shadowOffsetx,offsety:prop.shadowOffsety,blur:prop.shadowBlur,opacity:prop.shadowOpacity,id:'dropShadow'});}
35
- for(var i=0;i<this.left.length;++i){if(typeof this.left[i]==='number'){var color=prop.colors[this.sequentialIndex],tooltip=RG.SVG.isNull(prop.tooltips)?null:prop.tooltips[this.sequentialIndex],y=prop.marginTop+((this.graphHeight/this.left.length)*i)+prop.vmargin,width=this.getWidth(this.left[i]),x=prop.marginLeft+this.graphWidth-width,height=(this.graphHeight/this.left.length)-prop.vmargin-prop.vmargin;var rect=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'rect',attr:{x:x,y:y,width:width,height:height,fill:prop.colorsSequential?prop.colors[this.sequentialIndex]:prop.colors[0],stroke:prop.colorsStroke,'stroke-width':prop.linewidth,'shape-rendering':'crispEdges','data-original-x':x,'data-original-y':y,'data-original-width':width,'data-original-height':height,'data-tooltop':(tooltip||''),'data-index':i,'data-sequential-index':this.sequentialIndex,'data-value':this.left[i],filter:prop.shadow?'url(#dropShadow)':''}});this.coords.push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});this.coordsLeft.push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});this.installTooltipsEventListeners({rect:rect,index:i,sequentialIndex:this.sequentialIndex});this.sequentialIndex++;}else if(RG.SVG.isArray(this.left[i])&&prop.grouping==='stacked'){var accWidth=0;for(var j=0;j<this.left[i].length;++j){var color=prop.colors[this.sequentialIndex],tooltip=RG.SVG.isNull(prop.tooltips)?null:prop.tooltips[this.sequentialIndex],y=prop.marginTop+((this.graphHeight/this.left.length)*i)+prop.vmargin,width=this.getWidth(this.left[i][j]),accWidth=accWidth+width,x=prop.marginLeft+this.graphWidth-accWidth,height=(this.graphHeight/this.left.length)-prop.vmargin-prop.vmargin;if(j===0&&prop.shadow){var shadowBackfaceX=prop.marginLeft+this.graphWidth-this.getWidth(RG.SVG.arraySum(this.left[i])),shadowBackfaceWidth=this.getWidth(RG.SVG.arraySum(this.left[i]));var rect=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'rect',attr:{fill:'#eee',x:shadowBackfaceX,y:y,width:shadowBackfaceWidth,height:height,'stroke-width':0,'data-index':i,filter:'url(#dropShadow)'}});this.stackedBackfacesLeft[i]=rect;}
36
- var rect=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'rect',attr:{x:x,y:y,width:width,height:height,fill:prop.colorsSequential?prop.colors[this.sequentialIndex]:prop.colors[j],stroke:prop.colorsStroke,'stroke-width':prop.linewidth,'shape-rendering':'crispEdges','data-original-x':x,'data-original-y':y,'data-original-width':width,'data-original-height':height,'data-tooltop':(tooltip||''),'data-index':i,'data-subindex':j,'data-sequential-index':this.sequentialIndex,'data-value':this.left[i][j]}});this.coords.push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});this.coordsLeft.push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});if(!this.coords2[i]){this.coords2[i]=[];}
37
- if(!this.coords2Left[i]){this.coords2Left[i]=[];}
38
- this.coords2[i].push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});this.coords2Left[i].push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});this.installTooltipsEventListeners({rect:rect,index:i,sequentialIndex:this.sequentialIndex});this.sequentialIndex++;}}else if(RG.SVG.isArray(this.left[i])&&prop.grouping==='grouped'){for(var j=0;j<this.left[i].length;++j){var color=prop.colors[this.sequentialIndex],tooltip=RG.SVG.isNull(prop.tooltips)?null:prop.tooltips[this.sequentialIndex],height=((this.graphHeight/this.left.length)-prop.vmargin-prop.vmargin-(prop.vmarginGrouped*(this.left[i].length-1)))/this.left[i].length,y=prop.marginTop+((this.graphHeight/this.left.length)*i)+prop.vmargin+(height*j)+(j*prop.vmarginGrouped),width=this.getWidth(this.left[i][j]),x=prop.marginLeft+this.graphWidth-width;var rect=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'rect',attr:{x:x,y:y,width:width,height:height,fill:prop.colorsSequential?prop.colors[this.sequentialIndex]:prop.colors[j],stroke:prop.colorsStroke,'stroke-width':prop.linewidth,'shape-rendering':'crispEdges','data-original-x':x,'data-original-y':y,'data-original-width':width,'data-original-height':height,'data-tooltop':(tooltip||''),'data-index':i,'data-subindex':j,'data-sequential-index':this.sequentialIndex,'data-value':this.left[i][j],filter:prop.shadow?'url(#dropShadow)':''}});this.coords.push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});this.coordsLeft.push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});if(!this.coords2[i]){this.coords2[i]=[];}
39
- if(!this.coords2Left[i]){this.coords2Left[i]=[];}
40
- this.coords2[i].push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});this.coords2Left[i].push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});this.installTooltipsEventListeners({rect:rect,index:i,sequentialIndex:this.sequentialIndex});this.sequentialIndex++;}}}
41
- for(var i=0;i<this.right.length;++i){if(typeof this.right[i]==='number'){var color=prop.colors[this.sequentialIndex],tooltip=RG.SVG.isNull(prop.tooltips)?null:prop.tooltips[this.sequentialIndex],y=prop.marginTop+((this.graphHeight/this.right.length)*i)+prop.vmargin,width=this.getWidth(this.right[i]),x=prop.marginLeft+this.graphWidth+prop.marginCenter,height=(this.graphHeight/this.right.length)-prop.vmargin-prop.vmargin;var rect=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'rect',attr:{x:x,y:y,width:width,height:height,fill:prop.colorsSequential?prop.colors[this.sequentialIndex]:prop.colors[0],stroke:prop.colorsStroke,'stroke-width':prop.linewidth,'shape-rendering':'crispEdges','data-original-x':x,'data-original-y':y,'data-original-width':width,'data-original-height':height,'data-tooltop':(tooltip||''),'data-index':i,'data-sequential-index':this.sequentialIndex,'data-value':this.right[i],filter:prop.shadow?'url(#dropShadow)':''}});this.coords.push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});this.coordsRight.push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});this.installTooltipsEventListeners({rect:rect,index:i,sequentialIndex:this.sequentialIndex});this.sequentialIndex++;}else if(RG.SVG.isArray(this.right[i])&&prop.grouping==='stacked'){var accWidth=0;for(var j=0;j<this.right[i].length;++j){var color=prop.colors[this.sequentialIndex],tooltip=RG.SVG.isNull(prop.tooltips)?null:prop.tooltips[this.sequentialIndex],y=prop.marginTop+((this.graphHeight/this.right.length)*i)+prop.vmargin,width=this.getWidth(this.right[i][j]),x=prop.marginLeft+this.graphWidth+prop.marginCenter+accWidth,accWidth=accWidth+width,height=(this.graphHeight/this.left.length)-prop.vmargin-prop.vmargin;if(j===0&&prop.shadow){var shadowBackfaceX=prop.marginLeft+this.graphWidth+prop.marginCenter,shadowBackfaceWidth=this.getWidth(RG.SVG.arraySum(this.right[i]));var rect=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'rect',attr:{fill:'#eee',x:shadowBackfaceX,y:y,width:shadowBackfaceWidth,height:height,'stroke-width':0,'data-index':i,filter:'url(#dropShadow)'}});this.stackedBackfacesRight[i]=rect;}
42
- var rect=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'rect',attr:{x:x,y:y,width:width,height:height,fill:prop.colorsSequential?prop.colors[this.sequentialIndex]:prop.colors[j],stroke:prop.colorsStroke,'stroke-width':prop.linewidth,'shape-rendering':'crispEdges','data-original-x':x,'data-original-y':y,'data-original-width':width,'data-original-height':height,'data-tooltop':(tooltip||''),'data-index':i,'data-subindex':j,'data-sequential-index':this.sequentialIndex,'data-value':this.right[i][j]}});this.coords.push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});this.coordsRight.push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});if(!this.coords2[i+this.left.length]){this.coords2[i+this.left.length]=[];}
43
- if(!this.coords2Right[i]){this.coords2Right[i]=[];}
44
- this.coords2[i+this.left.length].push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});this.coords2Right[i].push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});this.installTooltipsEventListeners({rect:rect,index:i,sequentialIndex:this.sequentialIndex});this.sequentialIndex++;}}else if(RG.SVG.isArray(this.right[i])&&prop.grouping==='grouped'){for(var j=0;j<this.right[i].length;++j){var color=prop.colors[this.sequentialIndex],tooltip=RG.SVG.isNull(prop.tooltips)?null:prop.tooltips[this.sequentialIndex],height=((this.graphHeight/this.right.length)-prop.vmargin-prop.vmargin-(prop.vmarginGrouped*(this.right[i].length-1)))/this.right[i].length,y=prop.marginTop+((this.graphHeight/this.right.length)*i)+prop.vmargin+(height*j)+(j*prop.vmarginGrouped),width=this.getWidth(this.right[i][j]),x=prop.marginLeft+this.graphWidth+prop.marginCenter;var rect=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'rect',attr:{x:x,y:y,width:width,height:height,fill:prop.colorsSequential?prop.colors[this.sequentialIndex]:prop.colors[j],stroke:prop.colorsStroke,'stroke-width':prop.linewidth,'shape-rendering':'crispEdges','data-original-x':x,'data-original-y':y,'data-original-width':width,'data-original-height':height,'data-tooltop':(tooltip||''),'data-index':i,'data-subindex':j,'data-sequential-index':this.sequentialIndex,'data-value':this.right[i][j],filter:prop.shadow?'url(#dropShadow)':''}});this.coords.push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});this.coordsRight.push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});if(!this.coords2[i+this.left.length]){this.coords2[i+this.left.length]=[];}
45
- if(!this.coords2Right[i]){this.coords2Right[i]=[];}
46
- this.coords2[i+this.left.length].push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});this.coords2Right[i].push({object:this,element:rect,x:parseFloat(rect.getAttribute('x')),y:parseFloat(rect.getAttribute('y')),width:parseFloat(rect.getAttribute('width')),height:parseFloat(rect.getAttribute('height'))});this.installTooltipsEventListeners({rect:rect,index:i,sequentialIndex:this.sequentialIndex});this.sequentialIndex++;}}}};this.installTooltipsEventListeners=function(opt)
47
- {var obj=this;if(!RG.SVG.isNull(prop.tooltips)&&prop.tooltips[this.sequentialIndex]){(function(idx,seq)
48
- {opt.rect.addEventListener(prop.tooltipsEvent.replace(/^on/,''),function(e)
49
- {obj.removeHighlight();RG.SVG.tooltip({object:obj,index:idx,group:null,sequentialIndex:seq,text:prop.tooltips[seq],event:e});obj.highlight(e.target);},false);opt.rect.addEventListener('mousemove',function(e)
50
- {e.target.style.cursor='pointer'},false);})(opt.index,opt.sequentialIndex);}};this.getWidth=function(value)
51
- {var x1=this.getLeftXCoord(0),x2=this.getLeftXCoord(value);if(RG.SVG.isNull(x1)||RG.SVG.isNull(x2)){return null;}
52
- return x1-x2;};this.getLeftXCoord=function(value)
53
- {var width;if(value>this.scale.max){return null;}
54
- if(value<this.scale.min){return null;}
55
- width=((value-this.scale.min)/(this.scale.max-this.scale.min));width*=this.graphWidth;var x=prop.marginLeft+this.graphWidth-width;return x;};this.getRightXCoord=function(value)
56
- {var width;if(value>this.scale.max){return null;}
57
- if(value<this.scale.min){return null;}
58
- width=((value-this.scale.min)/(this.scale.max-this.scale.min));width*=this.graphWidth;var x=prop.marginLeft+this.graphWidth+prop.marginCenter+width;return x;};this.highlight=function(rect)
59
- {var x=parseInt(rect.getAttribute('x')),y=parseInt(rect.getAttribute('y')),width=parseInt(rect.getAttribute('width')),height=parseInt(rect.getAttribute('height'));var highlight=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'rect',attr:{stroke:prop.highlightStroke,fill:prop.highlightFill,x:x-1,y:y-1,width:width+2,height:height+2},style:{pointerEvents:'none'}});RG.SVG.REG.set('highlight',highlight);};this.parseColors=function()
60
- {if(!Object.keys(this.originalColors).length){this.originalColors={colors:RG.SVG.arrayClone(prop.colors),backgroundGridColor:RG.SVG.arrayClone(prop.backgroundGridColor),highlightFill:RG.SVG.arrayClone(prop.highlightFill),backgroundColor:RG.SVG.arrayClone(prop.backgroundColor)}}
61
- var colors=prop.colors;if(colors){for(var i=0;i<colors.length;++i){colors[i]=RG.SVG.parseColorLinear({object:this,color:colors[i],direction:'horizontal'});}}
62
- prop.backgroundGridColor=RG.SVG.parseColorLinear({object:this,color:prop.backgroundGridColor,direction:'horizontal'});prop.highlightFill=RG.SVG.parseColorLinear({object:this,color:prop.highlightFill,direction:'horizontal'});prop.backgroundColor=RG.SVG.parseColorLinear({object:this,color:prop.backgroundColor,direction:'horizontal'});};this.drawLabelsAbove=function()
63
- {if(prop.labelsAbove){for(var dataset=0,seq=0;dataset<this.data.length;++dataset,++seq){for(var i=0;i<this.data[dataset].length;++i,++seq){var value=this.data[dataset][i],halign=dataset===0?'right':'left',valign='center',hoffset=dataset===0?-10:10;if(typeof value==='number'){if(this.coords[seq]){var x=parseInt(this.coords[seq].element.getAttribute('x'))+hoffset+prop.labelsAboveOffsetx;var height=parseInt(this.coords[seq].element.getAttribute('height'));var y=parseInt(this.coords[seq].element.getAttribute('y'))+(height/2)+prop.labelsAboveOffsety;var width=parseInt(this.coords[seq].element.getAttribute('width'));if(dataset===1){x+=width;}
64
- var str=RG.SVG.numberFormat({object:this,num:value.toFixed(prop.labelsAboveDecimals),prepend:typeof prop.labelsAboveUnitsPre==='string'?prop.labelsAboveUnitsPre:null,append:typeof prop.labelsAboveUnitsPost==='string'?prop.labelsAboveUnitsPost:null,point:typeof prop.labelsAbovePoint==='string'?prop.labelsAbovePoint:null,thousand:typeof prop.labelsAboveThousand==='string'?prop.labelsAboveThousand:null,formatter:typeof prop.labelsAboveFormatter==='function'?prop.labelsAboveFormatter:null});if(prop.labelsAboveSpecific&&prop.labelsAboveSpecific.length&&(typeof prop.labelsAboveSpecific[seq]==='string'||typeof prop.labelsAboveSpecific[seq]==='number')){str=String(prop.labelsAboveSpecific[seq]);}else if(prop.labelsAboveSpecific&&prop.labelsAboveSpecific.length&&typeof prop.labelsAboveSpecific[seq]!=='string'&&typeof prop.labelsAboveSpecific[seq]!=='number'){continue;}
65
- RG.SVG.text({object:this,parent:this.svg.all,text:str,x:x,y:y,halign:halign,valign:valign,tag:'labels.above',font:prop.labelsAboveFont||prop.textFont,size:typeof prop.labelsAboveSize==='number'?prop.labelsAboveSize:prop.textSize,bold:typeof prop.labelsAboveBold==='boolean'?prop.labelsAboveBold:prop.textBold,italic:typeof prop.labelsAboveItalic==='boolean'?prop.labelsAboveItalic:prop.textItalic,color:prop.labelsAboveColor||prop.textColor,background:prop.labelsAboveBackground,padding:prop.labelsAboveBackgroundPadding});}}else if(!RG.SVG.isNull(value)&&typeof value==='object'&&prop.grouping==='stacked'){for(var k=0,sum=0,width=0;k<this.coords2[seq].length;++k){sum+=parseFloat(this.coords2[seq][k].element.getAttribute('data-value'));}
66
- var len=this.coords2[seq].length;if(dataset===0){var x=parseFloat(this.coords2[seq][len-1].x)+hoffset,height=parseFloat(this.coords2[seq][len-1].height),y=parseFloat(this.coords2[seq][0].y)+(height/2);}else{var x=parseFloat(this.coords2[this.data[0].length+i][0].x)+hoffset+prop.labelsAboveOffsetx,height=parseFloat(this.coords2[seq][len-1].height),y=parseFloat(this.coords2[seq][0].y)+(height/2)+prop.labelsAboveOffsety;for(var j=0;j<this.coords2Right[i].length;++j){x+=this.coords2Right[i][j].width;}}
67
- var str=RG.SVG.numberFormat({object:this,num:sum.toFixed(prop.labelsAboveDecimals),prepend:typeof prop.labelsAboveUnitsPre==='string'?prop.labelsAboveUnitsPre:null,append:typeof prop.labelsAboveUnitsPost==='string'?prop.labelsAboveUnitsPost:null,point:typeof prop.labelsAbovePoint==='string'?prop.labelsAbovePoint:null,thousand:typeof prop.labelsAboveThousand==='string'?prop.labelsAboveThousand:null,formatter:typeof prop.labelsAboveFormatter==='function'?prop.labelsAboveFormatter:null});if(prop.labelsAboveSpecific&&prop.labelsAboveSpecific.length&&(typeof prop.labelsAboveSpecific[seq]==='string'||typeof prop.labelsAboveSpecific[seq]==='number')){str=String(prop.labelsAboveSpecific[seq]);}else if(prop.labelsAboveSpecific&&prop.labelsAboveSpecific.length&&typeof prop.labelsAboveSpecific[seq]!=='string'&&typeof prop.labelsAboveSpecific[seq]!=='number'){continue;}
68
- RG.SVG.text({object:this,parent:this.svg.all,text:str,x:x,y:y,halign:halign,valign:valign,tag:'labels.above',font:prop.labelsAboveFont||prop.textFont,size:typeof prop.labelsAboveSize==='number'?prop.labelsAboveSize:prop.textSize,bold:typeof prop.labelsAboveBold==='boolean'?prop.labelsAboveBold:prop.textBold,italic:typeof prop.labelsAboveItalic==='boolean'?prop.labelsAboveItalic:prop.textItalic,color:prop.labelsAboveColor||prop.textColor,background:prop.labelsAboveBackground,padding:prop.labelsAboveBackgroundPadding});}else if(!RG.SVG.isNull(value)&&typeof value==='object'&&prop.grouping==='grouped'){for(var k=0;k<value.length;++k){val=value[k];if(typeof val!=='number'){val='';}
69
- var x=parseInt(this.coords[seq].element.getAttribute('x'))+hoffset+prop.labelsAboveOffsetx,height=parseInt(this.coords[seq].element.getAttribute('height')),y=parseInt(this.coords[seq].element.getAttribute('y'))+(height/2)+prop.labelsAboveOffsety,width=parseInt(this.coords[seq].element.getAttribute('width'));if(dataset===1){x+=width;}
70
- var str=RG.SVG.numberFormat({object:this,num:parseFloat(val).toFixed(prop.labelsAboveDecimals),prepend:typeof prop.labelsAboveUnitsPre==='string'?prop.labelsAboveUnitsPre:null,append:typeof prop.labelsAboveUnitsPost==='string'?prop.labelsAboveUnitsPost:null,point:typeof prop.labelsAbovePoint==='string'?prop.labelsAbovePoint:null,thousand:typeof prop.labelsAboveThousand==='string'?prop.labelsAboveThousand:null,formatter:typeof prop.labelsAboveFormatter==='function'?prop.labelsAboveFormatter:null});if(val===0||RG.SVG.isNull(val)||val===''){str='';}
71
- if(prop.labelsAboveSpecific&&prop.labelsAboveSpecific.length&&(typeof prop.labelsAboveSpecific[seq]==='string'||typeof prop.labelsAboveSpecific[seq]==='number')){str=String(prop.labelsAboveSpecific[seq]);}else if(prop.labelsAboveSpecific&&prop.labelsAboveSpecific.length&&typeof prop.labelsAboveSpecific[seq]!=='string'&&typeof prop.labelsAboveSpecific[seq]!=='number'){continue;}
72
- RG.SVG.text({object:this,parent:this.svg.all,text:str,x:x,y:y,halign:halign,valign:valign,tag:'labels.above',font:prop.labelsAboveFont||prop.textFont,size:typeof prop.labelsAboveSize==='number'?prop.labelsAboveSize:prop.textSize,bold:typeof prop.labelsAboveBold==='boolean'?prop.labelsAboveBold:prop.textBold,italic:typeof prop.labelsAboveItalic==='boolean'?prop.labelsAboveItalic:prop.textItalic,color:prop.labelsAboveColor||prop.textColor,background:prop.labelsAboveBackground,padding:prop.labelsAboveBackgroundPadding});seq++;}
73
- seq--;}else if(RG.SVG.isNull(value)){--seq;}}
74
- --seq;}}};this.on=function(type,func)
75
- {if(type.substr(0,2)!=='on'){type='on'+type;}
76
- RG.SVG.addCustomEventListener(this,type,func);return this;};this.exec=function(func)
77
- {func(this);return this;};this.removeHighlight=function()
78
- {var highlight=RG.SVG.REG.get('highlight');if(highlight&&highlight.parentNode){highlight.parentNode.removeChild(highlight);}
79
- RG.SVG.REG.set('highlight',null);};this.getMarginCenter=this.getGutterCenter=function()
80
- {var bold=typeof prop.yaxisLabelsBold==='boolean'?prop.yaxisLabelsBold:prop.textBold,font=typeof prop.yaxisLabelsFont==='string'?prop.yaxisLabelsFont:prop.textFont,size=typeof prop.yaxisLabelsSize==='number'?prop.yaxisLabelsSize:prop.textSize,width=0;if(prop.yaxisLabels){for(var i=0,len=prop.yaxisLabels.length;i<len;++i){width=ma.max(width,RG.SVG.measureText({text:prop.yaxisLabels[i],bold:bold,font:font,size:size})[0]);}}else{var width=50;}
81
- return width+15;};this.drawTitle=function()
82
- {if(RG.SVG.isNull(prop.titleX)){prop.titleX=((this.width-prop.marginLeft-prop.marginRight)/2)+prop.marginLeft;}
83
- RG.SVG.drawTitle(this);};this.grow=function()
84
- {var opt=arguments[0]||{},frames=opt.frames||30,frame=0,obj=this,left=RG.SVG.arrayClone(this.left),right=RG.SVG.arrayClone(this.right),seq=0;this.draw();var iterate=function()
85
- {for(var i=0,seq=0,len=obj.coordsLeft.length;i<len;++i,++seq){var multiplier=(frame/frames)*RG.SVG.FX.getEasingMultiplier(frames,frame)*RG.SVG.FX.getEasingMultiplier(frames,frame);if(typeof left[i]==='number'){width=ma.abs(obj.getLeftXCoord(left[i])-obj.getLeftXCoord(0));left[i]=obj.left[i]*multiplier;obj.coordsLeft[i].element.setAttribute('width',width);obj.coords[seq].element.setAttribute('x',obj.getLeftXCoord(0)-width);}else if(typeof left[i]==='object'&&prop.grouping==='stacked'){var accumulativeWidth=0;for(var j=0,len2=left[i].length;j<len2;++j,++seq){width=ma.abs(obj.getLeftXCoord(left[i][j])-obj.getLeftXCoord(0));left[i][j]=obj.left[i][j]*multiplier;obj.coords[seq].element.setAttribute('width',width);obj.coords[seq].element.setAttribute('x',obj.getLeftXCoord(0)-width-accumulativeWidth);accumulativeWidth+=(prop.grouping==='stacked'?width:0);}
86
- if(obj.stackedBackfacesLeft[i]){obj.stackedBackfacesLeft[i].setAttribute('width',accumulativeWidth);obj.stackedBackfacesLeft[i].setAttribute('x',obj.getLeftXCoord(0)-accumulativeWidth);}
87
- --seq;}else if(typeof left[i]==='object'&&prop.grouping==='grouped'){for(var j=0,len2=left[i].length;j<len2;++j,++seq){width=ma.abs(obj.getLeftXCoord(left[i][j])-obj.getLeftXCoord(0));left[i][j]=obj.left[i][j]*multiplier;obj.coords[seq].element.setAttribute('width',width);obj.coords[seq].element.setAttribute('x',obj.getLeftXCoord(0)-width);}
88
- --seq;}}
89
- for(var i=0,seq=0,len=obj.coordsRight.length;i<len;++i,++seq){var multiplier=(frame/frames)*RG.SVG.FX.getEasingMultiplier(frames,frame)*RG.SVG.FX.getEasingMultiplier(frames,frame);if(typeof right[i]==='number'){width=ma.abs(obj.getRightXCoord(right[i])-obj.getRightXCoord(0));right[i]=obj.right[i]*multiplier;obj.coordsRight[i].element.setAttribute('width',width);obj.coordsRight[seq].element.setAttribute('x',obj.getRightXCoord(0));}else if(typeof right[i]==='object'&&prop.grouping==='stacked'){var accumulativeWidth=0;for(var j=0,len2=right[i].length;j<len2;++j,++seq){width=ma.abs(obj.getRightXCoord(right[i][j])-obj.getRightXCoord(0));right[i][j]=obj.right[i][j]*multiplier;obj.coordsRight[seq].element.setAttribute('width',width);obj.coordsRight[seq].element.setAttribute('x',obj.getRightXCoord(0)+accumulativeWidth);accumulativeWidth+=width;}
90
- if(obj.stackedBackfacesRight[i]){obj.stackedBackfacesRight[i].setAttribute('width',accumulativeWidth);obj.stackedBackfacesRight[i].setAttribute('x',obj.getRightXCoord(0));}
91
- --seq;}else if(typeof right[i]==='object'&&prop.grouping==='grouped'){for(var j=0,len2=right[i].length;j<len2;++j,++seq){width=ma.abs(obj.getRightXCoord(right[i][j])-obj.getRightXCoord(0));right[i][j]=obj.right[i][j]*multiplier;obj.coordsRight[seq].element.setAttribute('width',width);obj.coordsRight[seq].element.setAttribute('x',obj.getRightXCoord(0));}
92
- --seq;}}
93
- if(frame++<=frames){RG.SVG.FX.update(iterate);}else if(opt.callback){(opt.callback)(obj);}};iterate();return this;};this.wave=function()
94
- {var obj=this,opt=arguments[0]||{},frames=opt.frames||120,startFrames_left=[],startFrames_right=[],counters_left=[],counters_right=[];var framesperbar=frames/3,frame_left=-1,frame_right=-1,callback=arguments[1]||function(){},original_left=RG.SVG.arrayClone(this.left),original_right=RG.SVG.arrayClone(this.right);for(var i=0,len=this.left.length,seq=0;i<len;i+=1,++seq){startFrames_left[seq]=((frames/3)/(RG.SVG.arrayLinearize(this.left).length-1))*i;startFrames_right[seq]=((frames/3)/(RG.SVG.arrayLinearize(this.right).length-1))*i;counters_left[seq]=0;counters_right[seq]=0;if(RG.SVG.isArray(this.left[i])){for(var j=0;j<this.left[i].length;++j,seq++){startFrames_left[seq]=((frames/3)/(RG.SVG.arrayLinearize(this.left).length-1))*seq;startFrames_right[seq]=((frames/3)/(RG.SVG.arrayLinearize(this.right).length-1))*seq;counters_left[seq]=0;counters_right[seq]=0;}
95
- --seq;}}
96
- this.draw();for(var i=0,len=this.left.length;i<len;i+=1){if(typeof this.left[i]==='number'){this.left[i]=0;this.right[i]=0;if(this.coordsLeft[i]&&this.coordsLeft[i].element)this.coordsLeft[i].element.setAttribute('width',0);if(this.coordsRight[i]&&this.coordsRight[i].element)this.coordsRight[i].element.setAttribute('width',0);}else if(typeof this.left[i]==='object'&&!RG.SVG.isNull(this.left[i])){for(var j=0;j<this.left[i].length;++j){this.left[i][j]=0;this.right[i][j]=0;this.coords2Left[i][j].element.setAttribute('width',0);this.coords2Right[i][j].element.setAttribute('width',0);}}}
97
- function iteratorLeft()
98
- {++frame_left;for(var i=0,len=obj.left.length,seq=0;i<len;i+=1,seq+=1){if(frame_left>=startFrames_left[seq]){var isNull=RG.SVG.isNull(obj.left[i]);if(typeof obj.left[i]==='number'){obj.left[i]=ma.min(ma.abs(original_left[i]),ma.abs(original_left[i]*((counters_left[i]++)/framesperbar)));var rect_left=obj.coords[i].element;rect_left.setAttribute('width',parseFloat(rect_left.getAttribute('data-original-width'))*(obj.left[i]/rect_left.getAttribute('data-value')));rect_left.setAttribute('x',obj.properties.marginLeft+obj.graphWidth-(parseFloat(rect_left.getAttribute('data-original-width'))*(obj.left[i]/rect_left.getAttribute('data-value'))));}else if(RG.SVG.isArray(obj.left[i])){for(var j=0,accWidth=0;j<obj.left[i].length;++j,++seq){obj.left[i][j]=ma.min(ma.abs(original_left[i][j]),ma.abs(original_left[i][j]*((counters_left[seq]++)/framesperbar)));var rect_left=obj.coords[seq].element;rect_left.setAttribute('width',parseFloat(rect_left.getAttribute('data-original-width'))*(obj.left[i][j]/rect_left.getAttribute('data-value')));rect_left.setAttribute('x',obj.properties.marginLeft+obj.graphWidth-(parseFloat(rect_left.getAttribute('data-original-width'))*(obj.left[i][j]/rect_left.getAttribute('data-value')))-accWidth);if(obj.properties.grouping==='stacked'){accWidth+=parseFloat(rect_left.getAttribute('width'));}}
99
- seq--;}
100
- if(isNull){obj.left[i]=null;}}else{obj.left[i]=typeof obj.left[i]==='object'&&obj.left[i]?RG.SVG.arrayPad([],obj.left[i].length,0):(RG.SVG.isNull(obj.left[i])?null:0);}}
101
- if(frame_left<=frames){RG.SVG.FX.update(iteratorLeft);}}
102
- function iteratorRight()
103
- {++frame_right;for(var i=0,len=obj.right.length,seq=0;i<len;i+=1,seq+=1){if(frame_right>=startFrames_right[seq]){var isNull=RG.SVG.isNull(obj.right[i]);if(typeof obj.right[i]==='number'){obj.right[i]=ma.min(ma.abs(original_right[i]),ma.abs(original_right[i]*((counters_right[i]++)/framesperbar)));var rect_right=obj.coords[i+obj.left.length].element;rect_right.setAttribute('width',parseFloat(rect_right.getAttribute('data-original-width'))*(obj.right[i]/rect_right.getAttribute('data-value')));rect_right.setAttribute('x',obj.properties.marginLeft+obj.graphWidth+prop.marginCenter);}else if(RG.SVG.isArray(obj.right[i])){for(var j=0,accWidth=0;j<obj.right[i].length;++j,++seq){obj.right[i][j]=ma.min(ma.abs(original_right[i][j]),ma.abs(original_right[i][j]*((counters_right[seq]++)/framesperbar)));var rect_right=obj.coordsRight[seq].element;rect_right.setAttribute('width',parseFloat(rect_right.getAttribute('data-original-width'))*(obj.right[i][j]/rect_right.getAttribute('data-value')));rect_right.setAttribute('x',obj.properties.marginLeft+obj.graphWidth+prop.marginCenter+accWidth);if(obj.properties.grouping==='stacked'){accWidth+=parseFloat(rect_right.getAttribute('width'));}}
104
- seq--;}
105
- if(isNull){obj.right[i]=null;}}else{obj.right[i]=typeof obj.right[i]==='object'&&obj.right[i]?RG.SVG.arrayPad([],obj.right[i].length,0):(RG.SVG.isNull(obj.right[i])?null:0);}}
106
- if(frame_right<=frames){RG.SVG.FX.update(iteratorRight);}else{}}
107
- iteratorLeft();iteratorRight();return this;};for(i in conf.options){if(typeof i==='string'){this.set(i,conf.options[i]);}}};return this;})(window,document);
12
+ RGraph = window.RGraph || {isrgraph:true,isRGraph:true,rgraph:true};
13
+ RGraph.SVG = RGraph.SVG || {};
14
+
15
+ // Module pattern
16
+ (function (win, doc, undefined)
17
+ {
18
+ RGraph.SVG.Bipolar = function (conf)
19
+ {
20
+ //
21
+ // A setter that the constructor uses (at the end)
22
+ // to set all of the properties
23
+ //
24
+ // @param string name The name of the property to set
25
+ // @param string value The value to set the property to
26
+ //
27
+ this.set = function (name, value)
28
+ {
29
+ if (arguments.length === 1 && typeof name === 'object') {
30
+ for (i in arguments[0]) {
31
+ if (typeof i === 'string') {
32
+
33
+ name = ret.name;
34
+ value = ret.value;
35
+
36
+ this.set(name, value);
37
+ }
38
+ }
39
+ } else {
40
+
41
+ var ret = RGraph.SVG.commonSetter({
42
+ object: this,
43
+ name: name,
44
+ value: value
45
+ });
46
+
47
+ name = ret.name;
48
+ value = ret.value;
49
+
50
+ this.properties[name] = value;
51
+
52
+ // If setting the colors, update the originalColors
53
+ // property too
54
+ if (name === 'colors') {
55
+ this.originalColors = RGraph.SVG.arrayClone(value);
56
+ this.colorsParsed = false;
57
+ }
58
+ }
59
+
60
+ return this;
61
+ };
62
+
63
+
64
+
65
+
66
+
67
+
68
+
69
+
70
+ //
71
+ // A getter.
72
+ //
73
+ // @param name string The name of the property to get
74
+ //
75
+ this.get = function (name)
76
+ {
77
+ return this.properties[name];
78
+ };
79
+
80
+
81
+
82
+
83
+
84
+
85
+
86
+
87
+ this.id = conf.id;
88
+ this.uid = RGraph.SVG.createUID();
89
+ this.container = document.getElementById(this.id);
90
+ this.layers = {}; // MUST be before the SVG tag is created!
91
+ this.svg = RGraph.SVG.createSVG({object: this,container: this.container});
92
+ this.isRGraph = true;
93
+ this.isrgraph = true;
94
+ this.rgraph = true;
95
+ this.data = [conf.left, conf.right];
96
+ this.left = conf.left;
97
+ this.right = conf.right;
98
+ this.type = 'bipolar';
99
+ this.coords = [];
100
+ this.coordsLeft = [];
101
+ this.coordsRight = [];
102
+ this.coords2 = [];
103
+ this.coords2Left = [];
104
+ this.coords2Right = [];
105
+ this.stackedBackfacesLeft = [];
106
+ this.stackedBackfacesRight = [];
107
+ this.originalColors = {};
108
+ this.gradientCounter = 1;
109
+ this.sequentialIndex = 0; // Used for tooltips
110
+ this.firstDraw = true; // After the first draw this will be false
111
+
112
+
113
+
114
+
115
+
116
+ //
117
+ // Convert strings to numbers
118
+ //
119
+ this.data[0] = RGraph.SVG.stringsToNumbers(this.data[0]);
120
+ this.data[1] = RGraph.SVG.stringsToNumbers(this.data[1]);
121
+ this.left = RGraph.SVG.stringsToNumbers(this.left);
122
+ this.right = RGraph.SVG.stringsToNumbers(this.right);
123
+
124
+
125
+
126
+
127
+
128
+
129
+
130
+
131
+ //
132
+ // Make the .data_arr variable (All data in a linear array)
133
+ //
134
+ this.data_arr = [];
135
+ for (var i=0; i<this.left.length; ++i) this.data_arr.push(this.left[i]);
136
+ for (var i=0; i<this.right.length; ++i) this.data_arr.push(this.right[i]);
137
+
138
+
139
+
140
+ // Add this object to the ObjectRegistry
141
+ RGraph.SVG.OR.add(this);
142
+
143
+ this.container.style.display = 'inline-block';
144
+
145
+ this.properties =
146
+ {
147
+ marginLeft: 35,
148
+ marginRight: 35,
149
+ marginTop: 35,
150
+ marginBottom: 35,
151
+ marginCenter: null,
152
+ marginInner: 3,
153
+ marginInnerGrouped: 2,
154
+
155
+ backgroundColor: null,
156
+ backgroundGrid: true,
157
+ backgroundGridColor: '#ddd',
158
+ backgroundGridLinewidth: 1,
159
+ backgroundGridHlines: true,
160
+ backgroundGridHlinesCount: null,
161
+ backgroundGridVlines: true,
162
+ backgroundGridVlinesCount: null,
163
+ backgroundGridBorder: true,
164
+ backgroundGridDashed: false,
165
+ backgroundGridDotted: false,
166
+ backgroundGridDashArray: null,
167
+
168
+ xaxis: true,
169
+ xaxisLinewidth: 1,
170
+ xaxisTickmarks: true,
171
+ xaxisTickmarksLength: 5,
172
+ xaxisLabelsCount: 5,
173
+ xaxisLabelsPositionEdgeTickmarksCount: 5,
174
+ xaxisColor: 'black',
175
+ xaxisLabelsOffsetx: 0,
176
+ xaxisLabelsOffsety: 0,
177
+ xaxisLabelsFont: null,
178
+ xaxisLabelsSize: null,
179
+ xaxisLabelsBold: null,
180
+ xaxisLabelsItalic: null,
181
+ xaxisLabelsColor: null,
182
+ xaxisScaleUnitsPre: '',
183
+ xaxisScaleUnitsPost: '',
184
+ xaxisScaleStrict: false,
185
+ xaxisScaleDecimals: 0,
186
+ xaxisScalePoint: '.',
187
+ xaxisScaleThousand: ',',
188
+ xaxisScaleRound: false,
189
+ xaxisScaleMax: null,
190
+ xaxisScaleMin: 0,
191
+ xaxisScaleFormatter: null,
192
+
193
+ yaxis: true,
194
+ yaxisTickmarks: true,
195
+ yaxisTickmarksLength: 5,
196
+ yaxisColor: 'black',
197
+ yaxisScale: false,
198
+ yaxisLabels: null,
199
+ yaxisLabelsOffsetx: 0,
200
+ yaxisLabelsOffsety: 0,
201
+ yaxisLabelsFont: null,
202
+ yaxisLabelsSize: null,
203
+ yaxisLabelsBold: null,
204
+ yaxisLabelsItalic: null,
205
+ yaxisLabelsColor: null,
206
+ yaxisLabelsFormattedDecimals: 0,
207
+ yaxisLabelsFormattedPoint: '.',
208
+ yaxisLabelsFormattedThousand: ',',
209
+ yaxisLabelsFormattedUnitsPre: '',
210
+ yaxisLabelsFormattedUnitsPost: '',
211
+
212
+ // 20 colors. If you need more you need to set the colors property
213
+ colors: [
214
+ 'red', '#0f0', '#00f', '#ff0', '#0ff', '#0f0','pink','orange','gray','black',
215
+ 'red', '#0f0', '#00f', '#ff0', '#0ff', '#0f0','pink','orange','gray','black'
216
+ ],
217
+ colorsSequential: false,
218
+ colorsStroke: 'rgba(0,0,0,0)',
219
+ colorsLeft: null,
220
+ colorsRight: null,
221
+
222
+ labelsAbove: false,
223
+ labelsAboveFont: null,
224
+ labelsAboveSize: null,
225
+ labelsAboveBold: null,
226
+ labelsAboveItalic: null,
227
+ labelsAboveColor: null,
228
+ labelsAboveBackground: null,
229
+ labelsAboveBackgroundPadding: 0,
230
+ labelsAboveUnitsPre: null,
231
+ labelsAboveUnitsPost: null,
232
+ labelsAbovePoint: null,
233
+ labelsAboveThousand: null,
234
+ labelsAboveFormatter: null,
235
+ labelsAboveDecimals: null,
236
+ labelsAboveOffsetx: 0,
237
+ labelsAboveOffsety: 0,
238
+ labelsAboveSpecific: null,
239
+
240
+ textColor: 'black',
241
+ textFont: 'Arial, Verdana, sans-serif',
242
+ textSize: 12,
243
+ textBold: false,
244
+ textItalic: false,
245
+ text: null,
246
+
247
+ linewidth: 1,
248
+ grouping: 'grouped',
249
+
250
+ tooltips: null,
251
+ tooltipsOverride: null,
252
+ tooltipsEffect: 'fade',
253
+ tooltipsCssClass: 'RGraph_tooltip',
254
+ tooltipsCss: null,
255
+ tooltipsEvent: 'click',
256
+ tooltipsFormattedThousand: ',',
257
+ tooltipsFormattedPoint: '.',
258
+ tooltipsFormattedDecimals: 0,
259
+ tooltipsFormattedUnitsPre: '',
260
+ tooltipsFormattedUnitsPost: '',
261
+ tooltipsFormattedKeyColors: null,
262
+ tooltipsFormattedKeyColorsShape: 'square',
263
+ tooltipsFormattedKeyLabels: [],
264
+ tooltipsFormattedTableHeaders: null,
265
+ tooltipsFormattedTableData: null,
266
+ tooltipsPointer: true,
267
+ tooltipsPointerOffsetx: 0,
268
+ tooltipsPointerOffsety: 0,
269
+ tooltipsPositionStatic: true,
270
+
271
+ highlightStroke: 'rgba(0,0,0,0)',
272
+ highlightFill: 'rgba(255,255,255,0.7)',
273
+ highlightLinewidth: 1,
274
+
275
+ title: '',
276
+ titleX: null,
277
+ titleY: null,
278
+ titleHalign: 'center',
279
+ titleValign: null,
280
+ titleSize: null,
281
+ titleColor: null,
282
+ titleFont: null,
283
+ titleBold: null,
284
+ titleItalic: null,
285
+
286
+ titleSubtitle: null,
287
+ titleSubtitleColor: '#aaa',
288
+ titleSubtitleSize: null,
289
+ titleSubtitleFont: null,
290
+ titleSubtitleBold: null,
291
+ titleSubtitleItalic: null,
292
+
293
+ shadow: false,
294
+ shadowOffsetx: 2,
295
+ shadowOffsety: 2,
296
+ shadowBlur: 2,
297
+ shadowColor: 'rgb(0,0,0,0.25)',
298
+
299
+ key: null,
300
+ keyColors: null,
301
+ keyOffsetx: 0,
302
+ keyOffsety: 0,
303
+ keyLabelsOffsetx: 0,
304
+ keyLabelsOffsety: -1,
305
+ keyLabelsSize: null,
306
+ keyLabelsBold: null,
307
+ keyLabelsItalic: null,
308
+ keyLabelsFont: null,
309
+ keyLabelsColor: null
310
+ };
311
+
312
+
313
+
314
+
315
+ //
316
+ // Copy the global object properties to this instance
317
+ //
318
+ RGraph.SVG.getGlobals(this);
319
+
320
+
321
+
322
+
323
+
324
+ //
325
+ // "Decorate" the object with the generic effects if the effects library has been included
326
+ //
327
+ if (RGraph.SVG.FX && typeof RGraph.SVG.FX.decorate === 'function') {
328
+ RGraph.SVG.FX.decorate(this);
329
+ }
330
+
331
+
332
+
333
+
334
+
335
+ // Add the responsive function to the object
336
+ this.responsive = RGraph.SVG.responsive;
337
+
338
+
339
+
340
+
341
+
342
+ var properties = this.properties;
343
+
344
+
345
+
346
+
347
+
348
+
349
+
350
+
351
+ //
352
+ // The draw method draws the Bar chart
353
+ //
354
+ this.draw = function ()
355
+ {
356
+ // Fire the beforedraw event
357
+ RGraph.SVG.fireCustomEvent(this, 'onbeforedraw');
358
+
359
+
360
+
361
+
362
+
363
+
364
+
365
+ if (properties.yaxisLabels && properties.yaxisLabels.length) {
366
+ //
367
+ // If the xaxisLabels option is a string then turn it
368
+ // into an array.
369
+ //
370
+ if (typeof properties.yaxisLabels === 'string') {
371
+ properties.yaxisLabels = RGraph.SVG.arrayPad({
372
+ array: [],
373
+ length: this.left.length,
374
+ value: properties.yaxisLabels
375
+ });
376
+ }
377
+
378
+ //
379
+ // Label substitution
380
+ //
381
+ for (var i=0; i<properties.yaxisLabels.length; ++i) {
382
+ properties.yaxisLabels[i] = RGraph.SVG.labelSubstitution({
383
+ object: this,
384
+ text: properties.yaxisLabels[i],
385
+ index: i,
386
+ value: this.left[i],
387
+ decimals: properties.yaxisLabelsFormattedDecimals || 0,
388
+ unitsPre: properties.yaxisLabelsFormattedUnitsPre || '',
389
+ unitsPost: properties.yaxisLabelsFormattedUnitsPost || '',
390
+ thousand: properties.yaxisLabelsFormattedThousand || ',',
391
+ point: properties.yaxisLabelsFormattedPoint || '.'
392
+ });
393
+ }
394
+ }
395
+
396
+
397
+
398
+
399
+ // Should the first thing that's done inthe.draw() function
400
+ // except for the onbeforedraw event
401
+ this.width = Number(this.svg.getAttribute('width'));
402
+ this.height = Number(this.svg.getAttribute('height'));
403
+
404
+
405
+
406
+
407
+
408
+
409
+
410
+
411
+
412
+
413
+ // Create the defs tag if necessary
414
+ RGraph.SVG.createDefs(this);
415
+
416
+
417
+
418
+
419
+
420
+
421
+ //
422
+ // Autosize the center gutter to allow for big labels
423
+
424
+ // 16th September 2019 - took out the IF() condition so that the centermargin i
425
+ // ALWAYS calculated
426
+
427
+ properties.marginCenter = this.getMarginCenter();
428
+ //}
429
+
430
+
431
+ // Reset the coords arrays
432
+ this.coords = [];
433
+ this.coordsLeft = [];
434
+ this.coordsRight = [];
435
+ this.coords2 = [];
436
+ this.coords2Left = [];
437
+ this.coords2Right = [];
438
+
439
+
440
+ // (Re)set this to zero
441
+ this.sequentialIndex = 0;
442
+
443
+
444
+ this.graphWidth = (this.width - properties.marginLeft - properties.marginRight - properties.marginCenter) / 2;
445
+ this.graphHeight = this.height - properties.marginTop - properties.marginBottom;
446
+
447
+
448
+
449
+ //
450
+ // Parse the colors. This allows for simple gradient syntax
451
+ //
452
+
453
+ // Parse the colors for gradients
454
+ RGraph.SVG.resetColorsToOriginalValues({object:this});
455
+ this.parseColors();
456
+
457
+
458
+
459
+ // Go through the data and work out the maximum value
460
+ var values = [];
461
+
462
+ for (var i=0; i<2; ++i) {
463
+ for (var j=0,max=0; j<this.data[i].length; ++j) {
464
+ if (typeof this.data[i][j] === 'number') {
465
+ values.push(this.data[i][j]);
466
+
467
+ } else if (RGraph.SVG.isArray(this.data[i][j]) && properties.grouping === 'grouped') {
468
+ values.push(RGraph.SVG.arrayMax(this.data[i][j]));
469
+
470
+ } else if (RGraph.SVG.isArray(this.data[i][j]) && properties.grouping === 'stacked') {
471
+ values.push(RGraph.SVG.arraySum(this.data[i][j]));
472
+ }
473
+ }
474
+ }
475
+
476
+ var max = RGraph.SVG.arrayMax(values);
477
+
478
+ // A custom, user-specified maximum value
479
+ if (typeof properties.xaxisScaleMax === 'number') {
480
+ max = properties.xaxisScaleMax;
481
+ }
482
+
483
+
484
+
485
+
486
+
487
+
488
+
489
+ //
490
+ // Generate an appropiate scale
491
+ //
492
+ this.scale = RGraph.SVG.getScale({
493
+ object: this,
494
+ numlabels: properties.xaxisLabelsCount,
495
+ unitsPre: properties.xaxisScaleUnitsPre,
496
+ unitsPost: properties.xaxisScaleUnitsPost,
497
+ max: max,
498
+ min: properties.xaxisScaleMin,
499
+ point: properties.xaxisScalePoint,
500
+ round: properties.xaxisScaleRound,
501
+ thousand: properties.xaxisScaleThousand,
502
+ decimals: properties.xaxisScaleDecimals,
503
+ strict: typeof properties.xaxisScaleMax === 'number',
504
+ formatter: properties.xaxisScaleFormatter
505
+ });
506
+
507
+
508
+
509
+
510
+
511
+ // Now the scale has been generated adopt its max value
512
+ this.max = this.scale.max;
513
+ this.min = this.scale.min;
514
+ properties.yaxisScaleMax = this.scale.max;
515
+ properties.yaxisScaleMin = this.scale.min;
516
+
517
+
518
+
519
+ // Draw the background first
520
+ this.drawBackground(this);
521
+
522
+ // Draw the title
523
+ this.drawTitle();
524
+
525
+
526
+
527
+ // Draw the bars
528
+ this.drawBars();
529
+
530
+
531
+ // Draw the axes over the bars
532
+ this.drawAxes();
533
+
534
+
535
+ // Draw the labels for both of the axes
536
+ this.drawLabels()
537
+
538
+
539
+ // Draw the labelsAbove labels
540
+ this.drawLabelsAbove();
541
+
542
+
543
+
544
+
545
+
546
+ // Draw the key
547
+ if (typeof properties.key !== null && RGraph.SVG.drawKey) {
548
+ RGraph.SVG.drawKey(this);
549
+ } else if (!RGraph.SVG.isNull(properties.key)) {
550
+ alert('The drawKey() function does not exist - have you forgotten to include the key library?');
551
+ }
552
+
553
+
554
+
555
+
556
+
557
+
558
+
559
+
560
+ //
561
+ // Allow the addition of custom text via the
562
+ // text: property.
563
+ //
564
+ RGraph.SVG.addCustomText(this);
565
+
566
+
567
+
568
+
569
+
570
+
571
+
572
+
573
+
574
+
575
+
576
+
577
+ //
578
+ // Fire the onfirstdraw event
579
+ //
580
+ if (this.firstDraw) {
581
+ this.firstDraw = false;
582
+ RGraph.SVG.fireCustomEvent(this, 'onfirstdraw');
583
+ }
584
+
585
+
586
+ // Fire the draw event
587
+ RGraph.SVG.fireCustomEvent(this, 'ondraw');
588
+
589
+
590
+
591
+
592
+
593
+
594
+
595
+ //
596
+ // Install any inline responsive configuration. This
597
+ // should be last in the draw function - even after
598
+ // the draw events.
599
+ //
600
+ RGraph.SVG.installInlineResponsive(this);
601
+
602
+
603
+
604
+
605
+
606
+
607
+
608
+
609
+
610
+ return this;
611
+ };
612
+
613
+
614
+
615
+
616
+
617
+
618
+
619
+
620
+ //
621
+ // New create() shortcut function
622
+ // For example:
623
+ // this.create('rect,x:0,y:0,width:100,height:100'[,parent]);
624
+ //
625
+ // @param str string The tag definition to parse and create
626
+ // @param object The (optional) parent element
627
+ // @return object The new tag
628
+ //
629
+ this.create = function (str)
630
+ {
631
+ var def = RGraph.SVG.create.parseStr(this, str);
632
+ def.svg = this.svg;
633
+
634
+ // By default the parent is the SVG tag - but if
635
+ // requested then change it to the tag that has
636
+ // been given
637
+ if (arguments[1]) {
638
+ def.parent = arguments[1];
639
+ }
640
+
641
+ return RGraph.SVG.create(def);
642
+ };
643
+
644
+
645
+
646
+
647
+
648
+
649
+
650
+
651
+ //
652
+ // Draws the background
653
+ //
654
+ this.drawBackground = function ()
655
+ {
656
+ // For some reason this appears to be necessary
657
+ var properties = this.properties;
658
+
659
+ // Save the original margin properties
660
+ var originalMarginRight = properties.marginRight,
661
+ originalMarginLeft = properties.marginLeft;
662
+
663
+ // Draw the LEFT background
664
+ properties.marginRight = this.width - (properties.marginLeft + this.graphWidth);
665
+ if (RGraph.SVG.isNull(properties.backgroundGridHlinesCount)) {
666
+ var resetToNull = true;
667
+ properties.backgroundGridHlinesCount = this.left.length;
668
+ }
669
+
670
+
671
+
672
+
673
+
674
+ // Set the LEFT background image properties
675
+ var props = ['','Aspect','Opacity','Stretch','X','Y','W','H',];
676
+
677
+ for (i in props) {
678
+ if (typeof props[i] === 'string') {
679
+ properties['backgroundImage' + String(props[i])] = properties['backgroundImageLeft' + props[i]];
680
+ }
681
+ }
682
+
683
+
684
+
685
+
686
+ RGraph.SVG.drawBackground(this);
687
+
688
+ if (resetToNull) {
689
+ properties.backgroundGridHlinesCount = null;
690
+ }
691
+
692
+
693
+
694
+
695
+
696
+
697
+
698
+
699
+
700
+
701
+
702
+
703
+
704
+
705
+
706
+
707
+ // Draw the RIGHT background
708
+ properties.marginRight = originalMarginRight;
709
+ properties.marginLeft = this.width - (properties.marginRight + this.graphWidth);
710
+
711
+ if (RGraph.SVG.isNull(properties.backgroundGridHlinesCount)) {
712
+ properties.backgroundGridHlinesCount = this.right.length;
713
+ }
714
+
715
+
716
+
717
+
718
+
719
+
720
+
721
+
722
+
723
+
724
+
725
+
726
+
727
+
728
+ // Set the RIGHT background image properties
729
+ var props = ['','Aspect','Opacity','Stretch','X','Y','W','H',];
730
+
731
+ for (i in props) {
732
+ if (typeof props[i] === 'string') {
733
+ properties['backgroundImage' + props[i]] = properties['backgroundImageRight' + props[i]];
734
+ }
735
+ }
736
+
737
+
738
+
739
+
740
+
741
+ // Draw the background
742
+ RGraph.SVG.drawBackground(this);
743
+
744
+
745
+
746
+
747
+
748
+
749
+ // Reset the margin properties to the original values
750
+ properties.marginLeft = originalMarginLeft;
751
+ properties.marginRight = originalMarginRight;
752
+ };
753
+
754
+
755
+
756
+
757
+
758
+
759
+
760
+
761
+
762
+
763
+
764
+
765
+
766
+
767
+
768
+
769
+
770
+
771
+
772
+
773
+
774
+
775
+
776
+
777
+
778
+
779
+
780
+ //
781
+ // Draws the axes
782
+ //
783
+ this.drawAxes = function ()
784
+ {
785
+ // Draw the LEFT X axes
786
+ if (properties.xaxis) {
787
+ RGraph.SVG.create({
788
+ svg: this.svg,
789
+ type: 'path',
790
+ parent: this.svg.all,
791
+ attr: {
792
+ d: 'M {1} {2} L {3} {4}'.format(
793
+ properties.marginLeft,
794
+ this.height - properties.marginBottom,
795
+ properties.marginLeft + this.graphWidth,
796
+ this.height - properties.marginBottom
797
+ ),
798
+ 'stroke-width': properties.xaxisLinewidth,
799
+ stroke: properties.xaxisColor,
800
+ fill: 'rgba(0,0,0,0)',
801
+ 'shape-rendering': 'crispEdges'
802
+ }
803
+ });
804
+
805
+
806
+
807
+
808
+ // Draw the right X axis
809
+ var foo2 = RGraph.SVG.create({
810
+ svg: this.svg,
811
+ type: 'path',
812
+ parent: this.svg.all,
813
+ attr: {
814
+ d: 'M {1} {2} L {3} {4}'.format(
815
+ this.width - properties.marginRight,
816
+ this.height - properties.marginBottom,
817
+ this.width - properties.marginRight - this.graphWidth,
818
+ this.height - properties.marginBottom
819
+ ),
820
+ 'stroke-width': properties.xaxisLinewidth,
821
+ stroke: properties.xaxisColor,
822
+ fill: 'rgba(0,0,0,0)',
823
+ 'shape-rendering': 'crispEdges'
824
+ }
825
+ });
826
+
827
+ //
828
+ // Draw tickmarks if necessary
829
+ //
830
+ if (properties.xaxisTickmarks) {
831
+
832
+ var startY = this.height - properties.marginBottom,
833
+ endY = this.height - properties.marginBottom + properties.xaxisTickmarksLength;
834
+
835
+ // Draw the LEFT sides tickmarks
836
+ for (var i=0; i<properties.xaxisLabelsPositionEdgeTickmarksCount; ++i) {
837
+
838
+ var x = properties.marginLeft + (i * (this.graphWidth / properties.xaxisLabelsPositionEdgeTickmarksCount));
839
+
840
+ RGraph.SVG.create({
841
+ svg: this.svg,
842
+ parent: this.svg.all,
843
+ type: 'path',
844
+ attr: {
845
+ d: 'M{1} {2} L{3} {4}'.format(
846
+ x + 0.001,
847
+ startY,
848
+ x,
849
+ endY
850
+ ),
851
+ stroke: properties.xaxisColor,
852
+ 'stroke-width': properties.xaxisLinewidth,
853
+ 'shape-rendering': "crispEdges"
854
+ }
855
+ });
856
+ }
857
+
858
+ // Draw an extra LEFT tick if no Y axis is being shown
859
+ if (!properties.yaxis) {
860
+
861
+ var x = properties.marginLeft + this.graphWidth;
862
+
863
+ RGraph.SVG.create({
864
+ svg: this.svg,
865
+ parent: this.svg.all,
866
+ type: 'path',
867
+ attr: {
868
+ d: 'M{1} {2} L{3} {4}'.format(
869
+ x + 0.001,
870
+ startY,
871
+ x,
872
+ endY
873
+ ),
874
+ stroke: properties.xaxisColor,
875
+ 'stroke-width': properties.xaxisLinewidth,
876
+ 'shape-rendering': "crispEdges"
877
+ }
878
+ });
879
+ }
880
+
881
+
882
+
883
+
884
+
885
+
886
+
887
+
888
+
889
+ // Draw the RIGHT sides tickmarks
890
+ for (var i=0; i<properties.xaxisLabelsPositionEdgeTickmarksCount; ++i) {
891
+
892
+ var x = properties.marginLeft + properties.marginCenter + this.graphWidth + ((i+1) * (this.graphWidth / properties.xaxisLabelsPositionEdgeTickmarksCount));
893
+
894
+ RGraph.SVG.create({
895
+ svg: this.svg,
896
+ parent: this.svg.all,
897
+ type: 'path',
898
+ attr: {
899
+ d: 'M{1} {2} L{3} {4}'.format(
900
+ x + 0.001,
901
+ startY,
902
+ x,
903
+ endY
904
+ ),
905
+ stroke: properties.xaxisColor,
906
+ 'stroke-width': properties.xaxisLinewidth,
907
+ 'shape-rendering': "crispEdges"
908
+ }
909
+ });
910
+ }
911
+
912
+
913
+ // Draw an extra RIGHT tick if no Y axis is being shown
914
+ if (!properties.yaxis) {
915
+
916
+ var x = properties.marginLeft + this.graphWidth + properties.marginCenter;
917
+
918
+ RGraph.SVG.create({
919
+ svg: this.svg,
920
+ parent: this.svg.all,
921
+ type: 'path',
922
+ attr: {
923
+ d: 'M{1} {2} L{3} {4}'.format(
924
+ x + 0.001,
925
+ startY,
926
+ x,
927
+ endY
928
+ ),
929
+ stroke: properties.xaxisColor,
930
+ 'stroke-width': properties.xaxisLinewidth,
931
+ 'shape-rendering': "crispEdges"
932
+ }
933
+ });
934
+ }
935
+ }
936
+ }
937
+
938
+
939
+
940
+
941
+
942
+
943
+
944
+
945
+
946
+
947
+
948
+
949
+
950
+
951
+ // Draw the LEFT vertical axes
952
+ if (properties.yaxis) {
953
+ RGraph.SVG.create({
954
+ svg: this.svg,
955
+ type: 'path',
956
+ parent: this.svg.all,
957
+ attr: {
958
+ d: 'M {1} {2} L {3} {4}'.format(
959
+ properties.marginLeft + this.graphWidth,
960
+ this.height - properties.marginBottom,
961
+ properties.marginLeft + this.graphWidth,
962
+ properties.marginTop
963
+ ),
964
+ 'stroke-width': properties.yaxisLinewidth,
965
+ stroke: properties.yaxisColor,
966
+ fill: 'rgba(0,0,0,0)',
967
+ 'shape-rendering': 'crispEdges',
968
+ 'stroke-linecap': 'square'
969
+ }
970
+ });
971
+
972
+
973
+
974
+
975
+ // Draw the RIGHT vertical axis
976
+ RGraph.SVG.create({
977
+ svg: this.svg,
978
+ type: 'path',
979
+ parent: this.svg.all,
980
+ attr: {
981
+ d: 'M {1} {2} L {3} {4}'.format(
982
+ properties.marginLeft + this.graphWidth + properties.marginCenter,
983
+ this.height - properties.marginBottom,
984
+ properties.marginLeft + this.graphWidth + properties.marginCenter,
985
+ properties.marginTop
986
+ ),
987
+ 'stroke-width': properties.yaxisLinewidth,
988
+ stroke: properties.yaxisColor,
989
+ fill: 'rgba(0,0,0,0)',
990
+ 'shape-rendering': 'crispEdges',
991
+ 'stroke-linecap': 'square'
992
+ }
993
+ });
994
+
995
+
996
+
997
+
998
+ //
999
+ // Draw Y axis tickmarks if necessary
1000
+ //
1001
+ if (properties.yaxisTickmarks) {
1002
+
1003
+ var startX = properties.marginLeft + this.graphWidth,
1004
+ endX = properties.marginLeft + this.graphWidth + properties.yaxisTickmarksLength,
1005
+ numticks = this.left.length;
1006
+
1007
+ // Draw the left sides tickmarks
1008
+ for (var i=0; i<numticks; ++i) {
1009
+
1010
+ var y = properties.marginTop + (i * (this.graphHeight / numticks));
1011
+
1012
+ RGraph.SVG.create({
1013
+ svg: this.svg,
1014
+ parent: this.svg.all,
1015
+ type: 'path',
1016
+ attr: {
1017
+ d: 'M{1} {2} L{3} {4}'.format(
1018
+ startX + 0.001,
1019
+ y,
1020
+ endX,
1021
+ y
1022
+ ),
1023
+ stroke: properties.yaxisColor,
1024
+ 'stroke-width': properties.yaxisLinewidth,
1025
+ 'shape-rendering': "crispEdges"
1026
+ }
1027
+ });
1028
+ }
1029
+
1030
+ // Draw an extra LEFT tickmark if the X axis is not being shown
1031
+ if (!properties.xaxis) {
1032
+
1033
+ var y = properties.marginTop + this.graphHeight;
1034
+
1035
+ RGraph.SVG.create({
1036
+ svg: this.svg,
1037
+ parent: this.svg.all,
1038
+ type: 'path',
1039
+ attr: {
1040
+ d: 'M{1} {2} L{3} {4}'.format(
1041
+ startX + 0.001,
1042
+ y,
1043
+ endX,
1044
+ y
1045
+ ),
1046
+ stroke: properties.yaxisColor,
1047
+ 'stroke-width': properties.yaxisLinewidth,
1048
+ 'shape-rendering': "crispEdges"
1049
+ }
1050
+ });
1051
+ }
1052
+
1053
+
1054
+
1055
+
1056
+
1057
+
1058
+
1059
+
1060
+
1061
+
1062
+
1063
+
1064
+ var startX = properties.marginLeft + this.graphWidth + properties.marginCenter,
1065
+ endX = properties.marginLeft + this.graphWidth + properties.marginCenter - properties.yaxisTickmarksLength,
1066
+ numticks = this.right.length;
1067
+
1068
+
1069
+
1070
+ for (var i=0; i<numticks; ++i) {
1071
+
1072
+ var y = properties.marginTop + (i * (this.graphHeight / numticks));
1073
+
1074
+ RGraph.SVG.create({
1075
+ svg: this.svg,
1076
+ parent: this.svg.all,
1077
+ type: 'path',
1078
+ attr: {
1079
+ d: 'M{1} {2} L{3} {4}'.format(
1080
+ startX + 0.001,
1081
+ y,
1082
+ endX,
1083
+ y
1084
+ ),
1085
+ stroke: properties.yaxisColor,
1086
+ 'stroke-width': properties.yaxisLinewidth,
1087
+ 'shape-rendering': "crispEdges"
1088
+ }
1089
+ });
1090
+ }
1091
+
1092
+ // Draw an extra RIGHT tickmark if the X axis is not being shown
1093
+ if (!properties.xaxis) {
1094
+
1095
+ var y = properties.marginTop + this.graphHeight;
1096
+
1097
+ RGraph.SVG.create({
1098
+ svg: this.svg,
1099
+ parent: this.svg.all,
1100
+ type: 'path',
1101
+ attr: {
1102
+ d: 'M{1} {2} L{3} {4}'.format(
1103
+ startX + 0.001,
1104
+ y,
1105
+ endX,
1106
+ y
1107
+ ),
1108
+ stroke: properties.yaxisColor,
1109
+ 'stroke-width': properties.yaxisLinewidth,
1110
+ 'shape-rendering': "crispEdges"
1111
+ }
1112
+ });
1113
+ }
1114
+ }
1115
+ }
1116
+ };
1117
+
1118
+
1119
+
1120
+
1121
+
1122
+
1123
+
1124
+
1125
+ //
1126
+ // Draws the labels
1127
+ //
1128
+ this.drawLabels = function ()
1129
+ {
1130
+ //
1131
+ // Draw the Y axis labels
1132
+ //
1133
+ var numlabels = properties.yaxisLabels ? properties.yaxisLabels.length : 5
1134
+
1135
+ // Get the Y axis labels configuration
1136
+ var textConf = RGraph.SVG.getTextConf({
1137
+ object: this,
1138
+ prefix: 'yaxisLabels'
1139
+ });
1140
+
1141
+ for (var i=0; i<numlabels; ++i) {
1142
+
1143
+ var segment = this.graphHeight / numlabels,
1144
+ y = properties.marginTop + (segment * i) + (segment / 2) + properties.yaxisLabelsOffsety,
1145
+ x = properties.marginLeft + this.graphWidth + (properties.marginCenter / 2) + properties.yaxisLabelsOffsetx;
1146
+
1147
+ var text = RGraph.SVG.text({
1148
+
1149
+ object: this,
1150
+ parent: this.svg.all,
1151
+ tag: 'labels.yaxis',
1152
+
1153
+ text: properties.yaxisLabels && properties.yaxisLabels[i] ? properties.yaxisLabels[i] : '',
1154
+
1155
+ x: x,
1156
+ y: y,
1157
+
1158
+ halign: 'center',
1159
+ valign: 'center',
1160
+
1161
+ font: textConf.font,
1162
+ size: textConf.size,
1163
+ bold: textConf.bold,
1164
+ italic: textConf.italic,
1165
+ color: textConf.color
1166
+ });
1167
+ }
1168
+
1169
+
1170
+
1171
+
1172
+
1173
+ //
1174
+ // Add the minimum label for the LEFT side
1175
+ //
1176
+ var y = this.height - properties.marginBottom + 10,
1177
+ str = (typeof properties.xaxisScaleFormatter === 'function') ?
1178
+ properties.xaxisScaleFormatter(this, properties.xaxisScaleMin)
1179
+ :
1180
+ (properties.xaxisScaleUnitsPre + properties.xaxisScaleMin.toFixed(properties.xaxisScaleDecimals).replace(/\./, properties.xaxisScalePoint) + properties.xaxisScaleUnitsPost);
1181
+
1182
+ // Get the Y axis labels configuration
1183
+ var textConf = RGraph.SVG.getTextConf({
1184
+ object: this,
1185
+ prefix: 'xaxisLabels'
1186
+ });
1187
+
1188
+ var text = RGraph.SVG.text({
1189
+
1190
+ object: this,
1191
+ parent: this.svg.all,
1192
+
1193
+ text: str,
1194
+
1195
+ x: properties.marginLeft + this.graphWidth + properties.xaxisLabelsOffsetx,
1196
+ y: y + properties.xaxisLabelsOffsety,
1197
+ halign: 'center',
1198
+ valign: 'top',
1199
+
1200
+ tag: 'labels.xaxis',
1201
+
1202
+ font: textConf.font,
1203
+ size: textConf.size,
1204
+ bold: textConf.bold,
1205
+ italic: textConf.italic,
1206
+ color: textConf.color
1207
+ });
1208
+
1209
+
1210
+ //
1211
+ // Draw the X axis scale for the LEFT side
1212
+ //
1213
+ var segment = this.graphWidth / properties.xaxisLabelsCount;
1214
+
1215
+ for (var i=0; i<this.scale.labels.length; ++i) {
1216
+
1217
+ RGraph.SVG.text({
1218
+
1219
+ object: this,
1220
+ parent: this.svg.all,
1221
+
1222
+ text: this.scale.labels[i],
1223
+
1224
+ x: properties.marginLeft + this.graphWidth - (segment * (i+1)) + properties.xaxisLabelsOffsetx,
1225
+ y: this.height - properties.marginBottom + 10 + properties.xaxisLabelsOffsety,
1226
+ halign: 'center',
1227
+ valign: 'top',
1228
+
1229
+ tag: 'labels.xaxis',
1230
+
1231
+ font: textConf.font,
1232
+ size: textConf.size,
1233
+ bold: textConf.bold,
1234
+ italic: textConf.italic,
1235
+ color: textConf.color
1236
+ });
1237
+ }
1238
+
1239
+
1240
+
1241
+
1242
+
1243
+
1244
+
1245
+
1246
+
1247
+
1248
+
1249
+ //
1250
+ // Add the minimum label for the RIGHT side
1251
+ //
1252
+ var text = RGraph.SVG.text({
1253
+
1254
+ object: this,
1255
+ parent: this.svg.all,
1256
+ tag: 'labels.xaxis',
1257
+
1258
+ text: (typeof properties.xaxisScaleFormatter == 'function') ?
1259
+ properties.xaxisScaleFormatter(this, properties.xaxisScaleMin)
1260
+ :
1261
+ properties.xaxisScaleUnitsPre + properties.xaxisScaleMin.toFixed(properties.xaxisScaleDecimals).replace(/\./, properties.xaxisScalePoint) + properties.xaxisScaleUnitsPost,
1262
+
1263
+ x: properties.marginLeft + this.graphWidth + properties.marginCenter + properties.xaxisLabelsOffsetx,
1264
+ y: this.height - properties.marginBottom + 10 + properties.xaxisLabelsOffsety,
1265
+
1266
+ halign: 'center',
1267
+ valign: 'top',
1268
+
1269
+ font: textConf.font,
1270
+ size: textConf.size,
1271
+ bold: textConf.bold,
1272
+ italic: textConf.italic,
1273
+ color: textConf.color
1274
+ });
1275
+
1276
+ //
1277
+ // Draw the X axis scale for the RIGHT side
1278
+ //
1279
+ for (var i=0; i<this.scale.labels.length; ++i) {
1280
+
1281
+ RGraph.SVG.text({
1282
+
1283
+ object: this,
1284
+ parent: this.svg.all,
1285
+ tag: 'labels.xaxis',
1286
+
1287
+ text: this.scale.labels[i],
1288
+
1289
+ x: properties.marginLeft + this.graphWidth + properties.marginCenter + (segment * (i + 1)) + properties.xaxisLabelsOffsetx,
1290
+ y: this.height - properties.marginBottom + 10 + properties.xaxisLabelsOffsety,
1291
+
1292
+ halign: 'center',
1293
+ valign: 'top',
1294
+
1295
+ font: textConf.font,
1296
+ size: textConf.size,
1297
+ bold: textConf.bold,
1298
+ italic: textConf.italic,
1299
+ color: textConf.color
1300
+ });
1301
+ }
1302
+
1303
+
1304
+
1305
+
1306
+
1307
+ };
1308
+
1309
+
1310
+
1311
+
1312
+
1313
+
1314
+
1315
+
1316
+ //
1317
+ // Draws the bars
1318
+ //
1319
+ this.drawBars = function ()
1320
+ {
1321
+ if (properties.shadow) {
1322
+ RGraph.SVG.setShadow({
1323
+ object: this,
1324
+ offsetx: properties.shadowOffsetx,
1325
+ offsety: properties.shadowOffsety,
1326
+ blur: properties.shadowBlur,
1327
+ color: properties.shadowColor,
1328
+ id: 'dropShadow'
1329
+ });
1330
+ }
1331
+
1332
+
1333
+
1334
+
1335
+
1336
+
1337
+
1338
+ // Go thru the LEFT data and draw the bars
1339
+ for (var i=0; i<this.left.length; ++i) {
1340
+
1341
+ // LEFT REGULAR NUMBER
1342
+ if (typeof this.left[i] === 'number') {
1343
+
1344
+ var color = properties.colors[this.sequentialIndex],
1345
+ tooltip = RGraph.SVG.isNull(properties.tooltips) ? null : properties.tooltips[this.sequentialIndex],
1346
+ y = properties.marginTop + ((this.graphHeight / this.left.length) * i) + properties.marginInner,
1347
+ width = this.getWidth(this.left[i]),
1348
+ x = properties.marginLeft + this.graphWidth - width,
1349
+ height = (this.graphHeight / this.left.length) - properties.marginInner - properties.marginInner;
1350
+
1351
+ //
1352
+ // If the colorsLeft option is set then change
1353
+ // the colors option to that.
1354
+ //
1355
+ if (!RGraph.SVG.isNull(properties.colorsLeft)) {
1356
+
1357
+ // Save the initial colors value
1358
+ properties.colorsInitial = properties.colors;
1359
+
1360
+ // Set the new value
1361
+ properties.colors = properties.colorsLeft;
1362
+ }
1363
+
1364
+
1365
+
1366
+ var rect = RGraph.SVG.create({
1367
+ svg: this.svg,
1368
+ parent: this.svg.all,
1369
+ type: 'rect',
1370
+ attr: {
1371
+ x: x,
1372
+ y: y,
1373
+ width: width,
1374
+ height: height,
1375
+ fill: properties.colorsSequential ? properties.colors[this.sequentialIndex] : properties.colors[0],
1376
+ stroke: properties.colorsStroke,
1377
+ 'stroke-width': properties.linewidth,
1378
+ 'shape-rendering': 'crispEdges',
1379
+ 'data-original-x': x,
1380
+ 'data-original-y': y,
1381
+ 'data-original-width': width,
1382
+ 'data-original-height': height,
1383
+ 'data-tooltop': (tooltip || ''),
1384
+ 'data-index': i,
1385
+ 'data-sequential-index': this.sequentialIndex,
1386
+ 'data-value': this.left[i],
1387
+ filter: properties.shadow ? 'url(#dropShadow)' : ''
1388
+ }
1389
+ });
1390
+
1391
+
1392
+
1393
+
1394
+
1395
+
1396
+
1397
+
1398
+
1399
+
1400
+
1401
+ this.coords.push({
1402
+ object: this,
1403
+ element: rect,
1404
+ x: parseFloat(rect.getAttribute('x')),
1405
+ y: parseFloat(rect.getAttribute('y')),
1406
+ width: parseFloat(rect.getAttribute('width')),
1407
+ height: parseFloat(rect.getAttribute('height'))
1408
+ });
1409
+
1410
+ this.coordsLeft.push({
1411
+ object: this,
1412
+ element: rect,
1413
+ x: parseFloat(rect.getAttribute('x')),
1414
+ y: parseFloat(rect.getAttribute('y')),
1415
+ width: parseFloat(rect.getAttribute('width')),
1416
+ height: parseFloat(rect.getAttribute('height'))
1417
+ });
1418
+
1419
+
1420
+
1421
+
1422
+ this.installTooltipsEventListeners({
1423
+ rect: rect,
1424
+ index: i,
1425
+ sequentialIndex: this.sequentialIndex
1426
+ });
1427
+
1428
+ this.sequentialIndex++;
1429
+
1430
+
1431
+ //
1432
+ // If the colorsLeft option is set then change
1433
+ // the colors option back to what it was.
1434
+ //
1435
+ if (!RGraph.SVG.isNull(properties.colorsLeft)) {
1436
+ properties.colors = properties.colorsInitial;
1437
+ }
1438
+
1439
+
1440
+
1441
+
1442
+ // LEFT STACKED
1443
+ } else if (RGraph.SVG.isArray(this.left[i]) && properties.grouping === 'stacked') {
1444
+
1445
+ var accWidth = 0;
1446
+
1447
+ for (var j=0; j<this.left[i].length; ++j) {
1448
+
1449
+ var color = properties.colors[this.sequentialIndex],
1450
+ tooltip = RGraph.SVG.isNull(properties.tooltips) ? null : properties.tooltips[this.sequentialIndex],
1451
+ y = properties.marginTop + ((this.graphHeight / this.left.length) * i) + properties.marginInner,
1452
+ width = this.getWidth(this.left[i][j]),
1453
+ accWidth = accWidth + width,
1454
+ x = properties.marginLeft + this.graphWidth - accWidth,
1455
+ height = (this.graphHeight / this.left.length) - properties.marginInner - properties.marginInner;
1456
+
1457
+
1458
+
1459
+ //
1460
+ // If the colorsLeft option is set then change
1461
+ // the colors option to that.
1462
+ //
1463
+ if (!RGraph.SVG.isNull(properties.colorsLeft)) {
1464
+
1465
+ // Save the initial colors value
1466
+ properties.colorsInitial = properties.colors;
1467
+
1468
+ // Set the new value
1469
+ properties.colors = properties.colorsLeft;
1470
+ }
1471
+
1472
+
1473
+
1474
+
1475
+
1476
+
1477
+ // If this is the first iteration of the loop and a shadow
1478
+ // is requested draw a rect here to create it.
1479
+ if (j === 0 && properties.shadow) {
1480
+
1481
+ var shadowBackfaceX = properties.marginLeft + this.graphWidth - (this.getWidth(RGraph.SVG.arraySum(this.left[i]))),
1482
+ shadowBackfaceWidth = this.getWidth(RGraph.SVG.arraySum(this.left[i]));
1483
+
1484
+
1485
+ var rect = RGraph.SVG.create({
1486
+ svg: this.svg,
1487
+ parent: this.svg.all,
1488
+ type: 'rect',
1489
+ attr: {
1490
+ fill: '#eee',
1491
+ x: shadowBackfaceX,
1492
+ y: y,
1493
+ width: shadowBackfaceWidth,
1494
+ height: height,
1495
+ 'stroke-width': 0,
1496
+ 'data-index': i,
1497
+ filter: 'url(#dropShadow)'
1498
+ }
1499
+ });
1500
+
1501
+ this.stackedBackfacesLeft[i] = rect;
1502
+ }
1503
+
1504
+
1505
+
1506
+
1507
+
1508
+
1509
+ var rect = RGraph.SVG.create({
1510
+ svg: this.svg,
1511
+ parent: this.svg.all,
1512
+ type: 'rect',
1513
+ attr: {
1514
+ x: x,
1515
+ y: y,
1516
+ width: width,
1517
+ height: height,
1518
+ fill: properties.colorsSequential ? properties.colors[this.sequentialIndex] : properties.colors[j],
1519
+ stroke: properties.colorsStroke,
1520
+ 'stroke-width': properties.linewidth,
1521
+ 'shape-rendering': 'crispEdges',
1522
+ 'data-original-x': x,
1523
+ 'data-original-y': y,
1524
+ 'data-original-width': width,
1525
+ 'data-original-height': height,
1526
+ 'data-tooltop': (tooltip || ''),
1527
+ 'data-index': i,
1528
+ 'data-subindex': j,
1529
+ 'data-sequential-index': this.sequentialIndex,
1530
+ 'data-value': this.left[i][j]
1531
+ }
1532
+ });
1533
+
1534
+
1535
+
1536
+
1537
+
1538
+
1539
+ this.coords.push({
1540
+ object: this,
1541
+ element: rect,
1542
+ x: parseFloat(rect.getAttribute('x')),
1543
+ y: parseFloat(rect.getAttribute('y')),
1544
+ width: parseFloat(rect.getAttribute('width')),
1545
+ height: parseFloat(rect.getAttribute('height'))
1546
+ });
1547
+
1548
+ this.coordsLeft.push({
1549
+ object: this,
1550
+ element: rect,
1551
+ x: parseFloat(rect.getAttribute('x')),
1552
+ y: parseFloat(rect.getAttribute('y')),
1553
+ width: parseFloat(rect.getAttribute('width')),
1554
+ height: parseFloat(rect.getAttribute('height'))
1555
+ });
1556
+
1557
+ if (!this.coords2[i]) {
1558
+ this.coords2[i] = [];
1559
+ }
1560
+
1561
+ if (!this.coords2Left[i]) {
1562
+ this.coords2Left[i] = [];
1563
+ }
1564
+
1565
+ this.coords2[i].push({
1566
+ object: this,
1567
+ element: rect,
1568
+ x: parseFloat(rect.getAttribute('x')),
1569
+ y: parseFloat(rect.getAttribute('y')),
1570
+ width: parseFloat(rect.getAttribute('width')),
1571
+ height: parseFloat(rect.getAttribute('height'))
1572
+ });
1573
+
1574
+ this.coords2Left[i].push({
1575
+ object: this,
1576
+ element: rect,
1577
+ x: parseFloat(rect.getAttribute('x')),
1578
+ y: parseFloat(rect.getAttribute('y')),
1579
+ width: parseFloat(rect.getAttribute('width')),
1580
+ height: parseFloat(rect.getAttribute('height'))
1581
+ });
1582
+
1583
+
1584
+
1585
+
1586
+
1587
+
1588
+
1589
+
1590
+
1591
+
1592
+ this.installTooltipsEventListeners({
1593
+ rect: rect,
1594
+ index: i,
1595
+ sequentialIndex: this.sequentialIndex
1596
+ });
1597
+
1598
+
1599
+ //
1600
+ // If the colorsLeft option is set then change
1601
+ // the colors option back to what it was.
1602
+ //
1603
+ if (!RGraph.SVG.isNull(properties.colorsLeft)) {
1604
+ properties.colors = properties.colorsInitial;
1605
+ }
1606
+
1607
+ this.sequentialIndex++;
1608
+ }
1609
+
1610
+
1611
+
1612
+
1613
+
1614
+
1615
+
1616
+
1617
+
1618
+ // LEFT GROUPED
1619
+ } else if (RGraph.SVG.isArray(this.left[i]) && properties.grouping === 'grouped') {
1620
+
1621
+ for (var j=0; j<this.left[i].length; ++j) {
1622
+
1623
+ var color = properties.colors[this.sequentialIndex],
1624
+ tooltip = RGraph.SVG.isNull(properties.tooltips) ? null : properties.tooltips[this.sequentialIndex],
1625
+ height = ((this.graphHeight / this.left.length) - properties.marginInner - properties.marginInner - (properties.marginInnerGrouped * (this.left[i].length - 1))) / this.left[i].length,
1626
+ y = properties.marginTop + ((this.graphHeight / this.left.length) * i) + properties.marginInner + (height * j) + (j * properties.marginInnerGrouped),
1627
+ width = this.getWidth(this.left[i][j]),
1628
+ x = properties.marginLeft + this.graphWidth - width;
1629
+
1630
+
1631
+ //
1632
+ // If the colorsLeft option is set then change
1633
+ // the colors option to that.
1634
+ //
1635
+ if (!RGraph.SVG.isNull(properties.colorsLeft)) {
1636
+
1637
+ // Save the initial colors value
1638
+ properties.colorsInitial = properties.colors;
1639
+
1640
+ // Set the new value
1641
+ properties.colors = properties.colorsLeft;
1642
+ }
1643
+
1644
+
1645
+ var rect = RGraph.SVG.create({
1646
+ svg: this.svg,
1647
+ parent: this.svg.all,
1648
+ type: 'rect',
1649
+ attr: {
1650
+ x: x,
1651
+ y: y,
1652
+ width: width,
1653
+ height: height,
1654
+ fill: properties.colorsSequential ? properties.colors[this.sequentialIndex] : properties.colors[j],
1655
+ stroke: properties.colorsStroke,
1656
+ 'stroke-width': properties.linewidth,
1657
+ 'shape-rendering': 'crispEdges',
1658
+ 'data-original-x': x,
1659
+ 'data-original-y': y,
1660
+ 'data-original-width': width,
1661
+ 'data-original-height': height,
1662
+ 'data-tooltop': (tooltip || ''),
1663
+ 'data-index': i,
1664
+ 'data-subindex': j,
1665
+ 'data-sequential-index': this.sequentialIndex,
1666
+ 'data-value': this.left[i][j],
1667
+ filter: properties.shadow ? 'url(#dropShadow)' : ''
1668
+ }
1669
+ });
1670
+
1671
+
1672
+
1673
+
1674
+
1675
+
1676
+ this.coords.push({
1677
+ object: this,
1678
+ element: rect,
1679
+ x: parseFloat(rect.getAttribute('x')),
1680
+ y: parseFloat(rect.getAttribute('y')),
1681
+ width: parseFloat(rect.getAttribute('width')),
1682
+ height: parseFloat(rect.getAttribute('height'))
1683
+ });
1684
+
1685
+ this.coordsLeft.push({
1686
+ object: this,
1687
+ element: rect,
1688
+ x: parseFloat(rect.getAttribute('x')),
1689
+ y: parseFloat(rect.getAttribute('y')),
1690
+ width: parseFloat(rect.getAttribute('width')),
1691
+ height: parseFloat(rect.getAttribute('height'))
1692
+ });
1693
+
1694
+
1695
+ if (!this.coords2[i]) {
1696
+ this.coords2[i] = [];
1697
+ }
1698
+
1699
+ if (!this.coords2Left[i]) {
1700
+ this.coords2Left[i] = [];
1701
+ }
1702
+
1703
+ this.coords2[i].push({
1704
+ object: this,
1705
+ element: rect,
1706
+ x: parseFloat(rect.getAttribute('x')),
1707
+ y: parseFloat(rect.getAttribute('y')),
1708
+ width: parseFloat(rect.getAttribute('width')),
1709
+ height: parseFloat(rect.getAttribute('height'))
1710
+ });
1711
+
1712
+ this.coords2Left[i].push({
1713
+ object: this,
1714
+ element: rect,
1715
+ x: parseFloat(rect.getAttribute('x')),
1716
+ y: parseFloat(rect.getAttribute('y')),
1717
+ width: parseFloat(rect.getAttribute('width')),
1718
+ height: parseFloat(rect.getAttribute('height'))
1719
+ });
1720
+
1721
+ this.installTooltipsEventListeners({
1722
+ rect: rect,
1723
+ index: i,
1724
+ sequentialIndex: this.sequentialIndex
1725
+ });
1726
+
1727
+ //
1728
+ // If the colorsLeft option is set then change
1729
+ // the colors option back to what it was.
1730
+ //
1731
+ if (!RGraph.SVG.isNull(properties.colorsLeft)) {
1732
+ properties.colors = properties.colorsInitial;
1733
+ }
1734
+
1735
+ this.sequentialIndex++;
1736
+ }
1737
+ }
1738
+ }
1739
+
1740
+
1741
+
1742
+
1743
+
1744
+
1745
+
1746
+
1747
+
1748
+
1749
+
1750
+
1751
+
1752
+
1753
+
1754
+
1755
+
1756
+
1757
+ // Go thru the RIGHT data and draw the bars
1758
+ for (var i=0; i<this.right.length; ++i) {
1759
+
1760
+ // RIGHT REGULAR
1761
+ if (typeof this.right[i] === 'number') {
1762
+
1763
+ var color = properties.colors[this.sequentialIndex],
1764
+ tooltip = RGraph.SVG.isNull(properties.tooltips) ? null : properties.tooltips[this.sequentialIndex],
1765
+ y = properties.marginTop + ((this.graphHeight / this.right.length) * i) + properties.marginInner,
1766
+ width = this.getWidth(this.right[i]),
1767
+ x = properties.marginLeft + this.graphWidth + properties.marginCenter,
1768
+ height = (this.graphHeight / this.right.length) - properties.marginInner - properties.marginInner;
1769
+
1770
+ //
1771
+ // If the colorsRight option is set then change
1772
+ // the colors option to that.
1773
+ //
1774
+ if (!RGraph.SVG.isNull(properties.colorsRight)) {
1775
+
1776
+ // Save the initial colors value
1777
+ properties.colorsInitial = properties.colors;
1778
+
1779
+ // Set the new value
1780
+ properties.colors = properties.colorsRight;
1781
+ }
1782
+
1783
+
1784
+ var rect = RGraph.SVG.create({
1785
+ svg: this.svg,
1786
+ parent: this.svg.all,
1787
+ type: 'rect',
1788
+ attr: {
1789
+ x: x,
1790
+ y: y,
1791
+ width: width,
1792
+ height: height,
1793
+ fill: properties.colorsSequential ? properties.colors[this.sequentialIndex] : properties.colors[0],
1794
+ stroke: properties.colorsStroke,
1795
+ 'stroke-width': properties.linewidth,
1796
+ 'shape-rendering': 'crispEdges',
1797
+ 'data-original-x': x,
1798
+ 'data-original-y': y,
1799
+ 'data-original-width': width,
1800
+ 'data-original-height': height,
1801
+ 'data-tooltop': (tooltip || ''),
1802
+ 'data-index': i,
1803
+ 'data-sequential-index': this.sequentialIndex,
1804
+ 'data-value': this.right[i],
1805
+ filter: properties.shadow ? 'url(#dropShadow)' : ''
1806
+ }
1807
+ });
1808
+
1809
+ this.coords.push({
1810
+ object: this,
1811
+ element: rect,
1812
+ x: parseFloat(rect.getAttribute('x')),
1813
+ y: parseFloat(rect.getAttribute('y')),
1814
+ width: parseFloat(rect.getAttribute('width')),
1815
+ height: parseFloat(rect.getAttribute('height'))
1816
+ });
1817
+
1818
+ this.coordsRight.push({
1819
+ object: this,
1820
+ element: rect,
1821
+ x: parseFloat(rect.getAttribute('x')),
1822
+ y: parseFloat(rect.getAttribute('y')),
1823
+ width: parseFloat(rect.getAttribute('width')),
1824
+ height: parseFloat(rect.getAttribute('height'))
1825
+ });
1826
+
1827
+ this.installTooltipsEventListeners({
1828
+ rect: rect,
1829
+ index: i,
1830
+ sequentialIndex: this.sequentialIndex
1831
+ });
1832
+
1833
+ //
1834
+ // If the colorsRight option is set then change
1835
+ // the colors option back to what it was.
1836
+ //
1837
+ if (!RGraph.SVG.isNull(properties.colorsRight)) {
1838
+ properties.colors = properties.colorsInitial;
1839
+ }
1840
+
1841
+ this.sequentialIndex++;
1842
+
1843
+
1844
+ // RIGHT STACKED
1845
+ } else if (RGraph.SVG.isArray(this.right[i]) && properties.grouping === 'stacked') {
1846
+
1847
+
1848
+ var accWidth = 0;
1849
+
1850
+ for (var j=0; j<this.right[i].length; ++j) {
1851
+
1852
+ var color = properties.colors[this.sequentialIndex],
1853
+ tooltip = RGraph.SVG.isNull(properties.tooltips) ? null : properties.tooltips[this.sequentialIndex],
1854
+ y = properties.marginTop + ((this.graphHeight / this.right.length) * i) + properties.marginInner,
1855
+ width = this.getWidth(this.right[i][j]),
1856
+ x = properties.marginLeft + this.graphWidth + properties.marginCenter + accWidth,
1857
+ accWidth = accWidth + width,
1858
+ height = (this.graphHeight / this.left.length) - properties.marginInner - properties.marginInner;
1859
+
1860
+
1861
+
1862
+
1863
+ //
1864
+ // If the colorsRight option is set then change
1865
+ // the colors option to that.
1866
+ //
1867
+ if (!RGraph.SVG.isNull(properties.colorsRight)) {
1868
+
1869
+ // Save the initial colors value
1870
+ properties.colorsInitial = properties.colors;
1871
+
1872
+ // Set the new value
1873
+ properties.colors = properties.colorsRight;
1874
+ }
1875
+
1876
+
1877
+
1878
+
1879
+ // If this is the first iteration of the loop and a shadow
1880
+ // is requested draw a rect here to create it.
1881
+ if (j === 0 && properties.shadow) {
1882
+
1883
+ var shadowBackfaceX = properties.marginLeft + this.graphWidth + properties.marginCenter,
1884
+ shadowBackfaceWidth = this.getWidth(RGraph.SVG.arraySum(this.right[i]));
1885
+
1886
+
1887
+ var rect = RGraph.SVG.create({
1888
+ svg: this.svg,
1889
+ parent: this.svg.all,
1890
+ type: 'rect',
1891
+ attr: {
1892
+ fill: '#eee',
1893
+ x: shadowBackfaceX,
1894
+ y: y,
1895
+ width: shadowBackfaceWidth,
1896
+ height: height,
1897
+ 'stroke-width': 0,
1898
+ 'data-index': i,
1899
+ filter: 'url(#dropShadow)'
1900
+ }
1901
+ });
1902
+
1903
+ this.stackedBackfacesRight[i] = rect;
1904
+ }
1905
+
1906
+
1907
+
1908
+
1909
+
1910
+
1911
+
1912
+
1913
+
1914
+
1915
+
1916
+
1917
+
1918
+
1919
+
1920
+
1921
+ var rect = RGraph.SVG.create({
1922
+ svg: this.svg,
1923
+ parent: this.svg.all,
1924
+ type: 'rect',
1925
+ attr: {
1926
+ x: x,
1927
+ y: y,
1928
+ width: width,
1929
+ height: height,
1930
+ fill: properties.colorsSequential ? properties.colors[this.sequentialIndex] : properties.colors[j],
1931
+ stroke: properties.colorsStroke,
1932
+ 'stroke-width': properties.linewidth,
1933
+ 'shape-rendering': 'crispEdges',
1934
+ 'data-original-x': x,
1935
+ 'data-original-y': y,
1936
+ 'data-original-width': width,
1937
+ 'data-original-height': height,
1938
+ 'data-tooltop': (tooltip || ''),
1939
+ 'data-index': i,
1940
+ 'data-subindex': j,
1941
+ 'data-sequential-index': this.sequentialIndex,
1942
+ 'data-value': this.right[i][j]
1943
+ }
1944
+ });
1945
+
1946
+
1947
+
1948
+
1949
+
1950
+
1951
+
1952
+
1953
+
1954
+ this.coords.push({
1955
+ object: this,
1956
+ element: rect,
1957
+ x: parseFloat(rect.getAttribute('x')),
1958
+ y: parseFloat(rect.getAttribute('y')),
1959
+ width: parseFloat(rect.getAttribute('width')),
1960
+ height: parseFloat(rect.getAttribute('height'))
1961
+ });
1962
+
1963
+ this.coordsRight.push({
1964
+ object: this,
1965
+ element: rect,
1966
+ x: parseFloat(rect.getAttribute('x')),
1967
+ y: parseFloat(rect.getAttribute('y')),
1968
+ width: parseFloat(rect.getAttribute('width')),
1969
+ height: parseFloat(rect.getAttribute('height'))
1970
+ });
1971
+
1972
+
1973
+
1974
+ if (!this.coords2[i + this.left.length]) {
1975
+ this.coords2[i + this.left.length] = [];
1976
+ }
1977
+
1978
+ if (!this.coords2Right[i]) {
1979
+ this.coords2Right[i] = [];
1980
+ }
1981
+
1982
+ this.coords2[i + this.left.length].push({
1983
+ object: this,
1984
+ element: rect,
1985
+ x: parseFloat(rect.getAttribute('x')),
1986
+ y: parseFloat(rect.getAttribute('y')),
1987
+ width: parseFloat(rect.getAttribute('width')),
1988
+ height: parseFloat(rect.getAttribute('height'))
1989
+ });
1990
+
1991
+ this.coords2Right[i].push({
1992
+ object: this,
1993
+ element: rect,
1994
+ x: parseFloat(rect.getAttribute('x')),
1995
+ y: parseFloat(rect.getAttribute('y')),
1996
+ width: parseFloat(rect.getAttribute('width')),
1997
+ height: parseFloat(rect.getAttribute('height'))
1998
+ });
1999
+
2000
+ this.installTooltipsEventListeners({
2001
+ rect: rect,
2002
+ index: i,
2003
+ sequentialIndex: this.sequentialIndex
2004
+ });
2005
+
2006
+ //
2007
+ // If the colorsRight option is set then change
2008
+ // the colors option back to what it was.
2009
+ //
2010
+ if (!RGraph.SVG.isNull(properties.colorsRight)) {
2011
+ properties.colors = properties.colorsInitial;
2012
+ }
2013
+
2014
+ this.sequentialIndex++;
2015
+ }
2016
+
2017
+
2018
+
2019
+
2020
+
2021
+
2022
+
2023
+
2024
+
2025
+
2026
+
2027
+
2028
+
2029
+ // RIGHT GROUPED
2030
+ } else if (RGraph.SVG.isArray(this.right[i]) && properties.grouping === 'grouped') {
2031
+
2032
+ for (var j=0; j<this.right[i].length; ++j) {
2033
+
2034
+ var color = properties.colors[this.sequentialIndex],
2035
+ tooltip = RGraph.SVG.isNull(properties.tooltips) ? null : properties.tooltips[this.sequentialIndex],
2036
+ height = ((this.graphHeight / this.right.length) - properties.marginInner - properties.marginInner - (properties.marginInnerGrouped * (this.right[i].length - 1))) / this.right[i].length,
2037
+ y = properties.marginTop + ((this.graphHeight / this.right.length) * i) + properties.marginInner + (height * j) + (j * properties.marginInnerGrouped),
2038
+ width = this.getWidth(this.right[i][j]),
2039
+ x = properties.marginLeft + this.graphWidth + properties.marginCenter;
2040
+
2041
+ //
2042
+ // If the colorsRight option is set then change
2043
+ // the colors option to that.
2044
+ //
2045
+ if (!RGraph.SVG.isNull(properties.colorsRight)) {
2046
+
2047
+ // Save the initial colors value
2048
+ properties.colorsInitial = properties.colors;
2049
+
2050
+ // Set the new value
2051
+ properties.colors = properties.colorsRight;
2052
+ }
2053
+
2054
+
2055
+
2056
+ var rect = RGraph.SVG.create({
2057
+ svg: this.svg,
2058
+ parent: this.svg.all,
2059
+ type: 'rect',
2060
+ attr: {
2061
+ x: x,
2062
+ y: y,
2063
+ width: width,
2064
+ height: height,
2065
+ fill: properties.colorsSequential ? properties.colors[this.sequentialIndex] : properties.colors[j],
2066
+ stroke: properties.colorsStroke,
2067
+ 'stroke-width': properties.linewidth,
2068
+ 'shape-rendering': 'crispEdges',
2069
+ 'data-original-x': x,
2070
+ 'data-original-y': y,
2071
+ 'data-original-width': width,
2072
+ 'data-original-height': height,
2073
+ 'data-tooltop': (tooltip || ''),
2074
+ 'data-index': i,
2075
+ 'data-subindex': j,
2076
+ 'data-sequential-index': this.sequentialIndex,
2077
+ 'data-value': this.right[i][j],
2078
+ filter: properties.shadow ? 'url(#dropShadow)' : ''
2079
+ }
2080
+ });
2081
+
2082
+
2083
+
2084
+
2085
+
2086
+
2087
+
2088
+
2089
+
2090
+ this.coords.push({
2091
+ object: this,
2092
+ element: rect,
2093
+ x: parseFloat(rect.getAttribute('x')),
2094
+ y: parseFloat(rect.getAttribute('y')),
2095
+ width: parseFloat(rect.getAttribute('width')),
2096
+ height: parseFloat(rect.getAttribute('height'))
2097
+ });
2098
+
2099
+ this.coordsRight.push({
2100
+ object: this,
2101
+ element: rect,
2102
+ x: parseFloat(rect.getAttribute('x')),
2103
+ y: parseFloat(rect.getAttribute('y')),
2104
+ width: parseFloat(rect.getAttribute('width')),
2105
+ height: parseFloat(rect.getAttribute('height'))
2106
+ });
2107
+
2108
+
2109
+
2110
+
2111
+
2112
+
2113
+
2114
+
2115
+
2116
+ if (!this.coords2[i + this.left.length]) {
2117
+ this.coords2[i + this.left.length] = [];
2118
+ }
2119
+
2120
+ if (!this.coords2Right[i]) {
2121
+ this.coords2Right[i] = [];
2122
+ }
2123
+
2124
+ this.coords2[i + this.left.length].push({
2125
+ object: this,
2126
+ element: rect,
2127
+ x: parseFloat(rect.getAttribute('x')),
2128
+ y: parseFloat(rect.getAttribute('y')),
2129
+ width: parseFloat(rect.getAttribute('width')),
2130
+ height: parseFloat(rect.getAttribute('height'))
2131
+ });
2132
+
2133
+ this.coords2Right[i].push({
2134
+ object: this,
2135
+ element: rect,
2136
+ x: parseFloat(rect.getAttribute('x')),
2137
+ y: parseFloat(rect.getAttribute('y')),
2138
+ width: parseFloat(rect.getAttribute('width')),
2139
+ height: parseFloat(rect.getAttribute('height'))
2140
+ });
2141
+
2142
+
2143
+
2144
+
2145
+
2146
+
2147
+
2148
+
2149
+
2150
+ this.installTooltipsEventListeners({
2151
+ rect: rect,
2152
+ index: i,
2153
+ sequentialIndex: this.sequentialIndex
2154
+ });
2155
+
2156
+ //
2157
+ // If the colorsRight option is set then change
2158
+ // the colors option back to what it was.
2159
+ //
2160
+ if (!RGraph.SVG.isNull(properties.colorsRight)) {
2161
+ properties.colors = properties.colorsInitial;
2162
+ }
2163
+
2164
+
2165
+
2166
+ this.sequentialIndex++;
2167
+ }
2168
+ }
2169
+ }
2170
+ };
2171
+
2172
+
2173
+
2174
+
2175
+
2176
+
2177
+
2178
+
2179
+ //
2180
+ // Installs the tooltips event lissteners. This is called from the
2181
+ // above function.
2182
+ //
2183
+ // @param object opt The various arguments to the function
2184
+ //
2185
+ this.installTooltipsEventListeners = function (opt)
2186
+ {
2187
+ var obj = this;
2188
+
2189
+ // Add the tooltip events
2190
+ if (!RGraph.SVG.isNull(properties.tooltips) && (properties.tooltips[this.sequentialIndex] || typeof properties.tooltips === 'string') ) {
2191
+ //
2192
+ // Add tooltip event listeners
2193
+ //
2194
+ (function (idx, seq)
2195
+ {
2196
+ opt.rect.addEventListener(properties.tooltipsEvent.replace(/^on/, ''), function (e)
2197
+ {
2198
+ obj.removeHighlight();
2199
+
2200
+ // Show the tooltip
2201
+ RGraph.SVG.tooltip({
2202
+ object: obj,
2203
+ index: idx,
2204
+ group: null,
2205
+ sequentialIndex: seq,
2206
+ text: typeof properties.tooltips === 'string' ? properties.tooltips : properties.tooltips[seq],
2207
+ event: e
2208
+ });
2209
+
2210
+ // Highlight the rect that has been clicked on
2211
+ obj.highlight(e.target);
2212
+ }, false);
2213
+
2214
+ opt.rect.addEventListener('mousemove', function (e)
2215
+ {
2216
+ e.target.style.cursor = 'pointer'
2217
+ }, false);
2218
+ })(opt.index, opt.sequentialIndex);
2219
+ }
2220
+ };
2221
+
2222
+
2223
+
2224
+
2225
+
2226
+
2227
+
2228
+
2229
+ //
2230
+ //
2231
+ //
2232
+ // @param int value The value to get the width for.
2233
+ //
2234
+ this.getWidth = function (value)
2235
+ {
2236
+ var x1 = this.getLeftXCoord(0),
2237
+ x2 = this.getLeftXCoord(value);
2238
+
2239
+ if (RGraph.SVG.isNull(x1) || RGraph.SVG.isNull(x2)) {
2240
+ return null;
2241
+ }
2242
+
2243
+ return x1 - x2;
2244
+ };
2245
+
2246
+
2247
+
2248
+
2249
+
2250
+
2251
+
2252
+
2253
+ //
2254
+ // This function is similar to the above but instead
2255
+ // of a width it gets a relevant coord for a value
2256
+ // on the LEFT side
2257
+ //
2258
+ // @param int value The value to get the coordinate for.
2259
+ //
2260
+ this.getLeftXCoord = function (value)
2261
+ {
2262
+ var width;
2263
+
2264
+ if (value > this.scale.max) {
2265
+ return null;
2266
+ }
2267
+
2268
+ if (value < this.scale.min) {
2269
+ return null;
2270
+ }
2271
+
2272
+ width = ((value - this.scale.min) / (this.scale.max - this.scale.min));
2273
+ width *= this.graphWidth;
2274
+
2275
+ // Calculate the X coord
2276
+ var x = properties.marginLeft + this.graphWidth - width;
2277
+
2278
+ return x;
2279
+ };
2280
+
2281
+
2282
+
2283
+
2284
+
2285
+
2286
+
2287
+
2288
+ //
2289
+ // This function gets an X coordinate for the RIGHT
2290
+ // side.
2291
+ //
2292
+ // @param int value The value to get the coordinate for.
2293
+ //
2294
+ this.getRightXCoord = function (value)
2295
+ {
2296
+ var width;
2297
+
2298
+ if (value > this.scale.max) {
2299
+ return null;
2300
+ }
2301
+
2302
+ if (value < this.scale.min) {
2303
+ return null;
2304
+ }
2305
+
2306
+ width = ((value - this.scale.min) / (this.scale.max - this.scale.min));
2307
+ width *= this.graphWidth;
2308
+
2309
+ // Calculate the X coord
2310
+ var x = properties.marginLeft + this.graphWidth + properties.marginCenter + width;
2311
+
2312
+ return x;
2313
+ };
2314
+
2315
+
2316
+
2317
+
2318
+
2319
+
2320
+
2321
+
2322
+ //
2323
+ // This function can be used to highlight a bar on the chart
2324
+ //
2325
+ // @param object rect The rectangle to highlight
2326
+ //
2327
+ this.highlight = function (rect)
2328
+ {
2329
+ var x = parseFloat(rect.getAttribute('x')) - 0.5,
2330
+ y = parseFloat(rect.getAttribute('y')) - 0.5,
2331
+ width = parseFloat(rect.getAttribute('width')) + 1,
2332
+ height = parseFloat(rect.getAttribute('height')) + 1;
2333
+
2334
+ var highlight = RGraph.SVG.create({
2335
+ svg: this.svg,
2336
+ parent: this.svg.all,
2337
+ type: 'rect',
2338
+ attr: {
2339
+ 'stroke-width': properties.highlightLinewidth,
2340
+ stroke: properties.highlightStroke,
2341
+ fill: properties.highlightFill,
2342
+ x: x,
2343
+ y: y,
2344
+ width: width,
2345
+ height: height
2346
+ },
2347
+ style: {
2348
+ pointerEvents: 'none'
2349
+ }
2350
+ });
2351
+
2352
+
2353
+ // Store the highlight rect in the rebistry so
2354
+ // it can be cleared later
2355
+ RGraph.SVG.REG.set('highlight', highlight);
2356
+ };
2357
+
2358
+
2359
+
2360
+
2361
+
2362
+
2363
+
2364
+
2365
+ //
2366
+ // This allows for easy specification of gradients
2367
+ //
2368
+ this.parseColors = function ()
2369
+ {
2370
+ // Save the original colors so that they can be restored when
2371
+ // the canvas is cleared
2372
+ if (!Object.keys(this.originalColors).length) {
2373
+ this.originalColors = {
2374
+ colors: RGraph.SVG.arrayClone(properties.colors),
2375
+ backgroundGridColor: RGraph.SVG.arrayClone(properties.backgroundGridColor),
2376
+ highlightFill: RGraph.SVG.arrayClone(properties.highlightFill),
2377
+ backgroundColor: RGraph.SVG.arrayClone(properties.backgroundColor)
2378
+ }
2379
+ }
2380
+
2381
+
2382
+ // colors
2383
+ var colors = properties.colors;
2384
+
2385
+ if (colors) {
2386
+ for (var i=0; i<colors.length; ++i) {
2387
+ colors[i] = RGraph.SVG.parseColorLinear({
2388
+ object: this,
2389
+ color: colors[i],
2390
+ direction: 'horizontal'
2391
+ });
2392
+ }
2393
+ }
2394
+
2395
+ properties.backgroundGridColor = RGraph.SVG.parseColorLinear({object: this, color: properties.backgroundGridColor,direction:'horizontal'});
2396
+ properties.highlightFill = RGraph.SVG.parseColorLinear({object: this, color: properties.highlightFill,direction:'horizontal'});
2397
+ properties.backgroundColor = RGraph.SVG.parseColorLinear({object: this, color: properties.backgroundColor,direction:'horizontal'});
2398
+ };
2399
+
2400
+
2401
+
2402
+
2403
+
2404
+
2405
+
2406
+
2407
+ //
2408
+ // Draws the labelsAbove
2409
+ //
2410
+ this.drawLabelsAbove = function ()
2411
+ {
2412
+ // Go through the above labels
2413
+ if (properties.labelsAbove) {
2414
+
2415
+ //var data_seq = RGraph.SVG.arrayLinearize(this.data),
2416
+ // seq = 0,
2417
+ // stacked_total = 0;
2418
+
2419
+ // Get the text configuration
2420
+ var textConf = RGraph.SVG.getTextConf({
2421
+ object: this,
2422
+ prefix: 'labelsAbove'
2423
+ });
2424
+
2425
+ for (var dataset=0,seq=0; dataset<this.data.length; ++dataset,++seq) {
2426
+ for (var i=0; i<this.data[dataset].length; ++i,++seq) {
2427
+
2428
+ var value = this.data[dataset][i],
2429
+ halign = dataset === 0 ? 'right' : 'left',
2430
+ valign = 'center',
2431
+ hoffset = dataset === 0 ? -10 : 10;
2432
+
2433
+ // REGULAR CHART
2434
+ if (typeof value === 'number') {
2435
+
2436
+ if (this.coords[seq]) {
2437
+
2438
+ var x = parseInt(this.coords[seq].element.getAttribute('x')) + hoffset + properties.labelsAboveOffsetx;
2439
+ var height = parseInt(this.coords[seq].element.getAttribute('height'));
2440
+ var y = parseInt(this.coords[seq].element.getAttribute('y')) + (height / 2) + properties.labelsAboveOffsety;
2441
+ var width = parseInt(this.coords[seq].element.getAttribute('width'));
2442
+
2443
+ // If the dataset is the RHS (which would equal )
2444
+ // then set the alignment appropriately
2445
+ if (dataset === 1) {
2446
+ x += width;
2447
+ }
2448
+
2449
+ var str = RGraph.SVG.numberFormat({
2450
+ object: this,
2451
+ num: value.toFixed(properties.labelsAboveDecimals),
2452
+ prepend: typeof properties.labelsAboveUnitsPre === 'string' ? properties.labelsAboveUnitsPre : null,
2453
+ append: typeof properties.labelsAboveUnitsPost === 'string' ? properties.labelsAboveUnitsPost : null,
2454
+ point: typeof properties.labelsAbovePoint === 'string' ? properties.labelsAbovePoint : null,
2455
+ thousand: typeof properties.labelsAboveThousand === 'string' ? properties.labelsAboveThousand : null,
2456
+ formatter: typeof properties.labelsAboveFormatter === 'function' ? properties.labelsAboveFormatter : null
2457
+ });
2458
+
2459
+
2460
+ // Facilitate labelsAboveSpecific
2461
+ if (properties.labelsAboveSpecific && properties.labelsAboveSpecific.length && (typeof properties.labelsAboveSpecific[seq] === 'string' || typeof properties.labelsAboveSpecific[seq] === 'number') ) {
2462
+ str = String(properties.labelsAboveSpecific[seq]);
2463
+ } else if ( properties.labelsAboveSpecific && properties.labelsAboveSpecific.length && typeof properties.labelsAboveSpecific[seq] !== 'string' && typeof properties.labelsAboveSpecific[seq] !== 'number') {
2464
+ continue;
2465
+ }
2466
+
2467
+ // Add the text to the SVG
2468
+ RGraph.SVG.text({
2469
+
2470
+ object: this,
2471
+ parent: this.svg.all,
2472
+ tag: 'labels.above',
2473
+
2474
+ text: str,
2475
+
2476
+ x: x,
2477
+ y: y,
2478
+
2479
+ halign: halign,
2480
+ valign: valign,
2481
+
2482
+ font: textConf.font,
2483
+ size: textConf.size,
2484
+ bold: textConf.bold,
2485
+ italic: textConf.italic,
2486
+ color: textConf.color,
2487
+
2488
+ background: properties.labelsAboveBackground,
2489
+ padding: properties.labelsAboveBackgroundPadding
2490
+ });
2491
+ }
2492
+
2493
+
2494
+
2495
+
2496
+
2497
+
2498
+
2499
+
2500
+
2501
+
2502
+
2503
+
2504
+
2505
+
2506
+ // STACKED CHART
2507
+ } else if (!RGraph.SVG.isNull(value) && typeof value === 'object' && properties.grouping === 'stacked') {
2508
+
2509
+ for (var k=0,sum=0,width=0; k<this.coords2[seq].length; ++k) {
2510
+ sum += parseFloat(this.coords2[seq][k].element.getAttribute('data-value'));
2511
+ }
2512
+
2513
+ var len =this.coords2[seq].length;
2514
+
2515
+ if (dataset === 0) {
2516
+ var x = parseFloat(this.coords2[seq][len - 1].x) + hoffset,
2517
+ height = parseFloat(this.coords2[seq][len - 1].height),
2518
+ y = parseFloat(this.coords2[seq][0].y) + (height / 2);
2519
+ } else {
2520
+ var x = parseFloat(this.coords2[this.data[0].length + i][0].x) + hoffset + properties.labelsAboveOffsetx,
2521
+ height = parseFloat(this.coords2[seq][len - 1].height),
2522
+ y = parseFloat(this.coords2[seq][0].y) + (height / 2) + properties.labelsAboveOffsety;
2523
+
2524
+ // Work out the total width by summing all the individual widths
2525
+
2526
+ for (var j=0; j<this.coords2Right[i].length; ++j) {
2527
+ x += this.coords2Right[i][j].width;
2528
+ }
2529
+ }
2530
+
2531
+ var str = RGraph.SVG.numberFormat({
2532
+ object: this,
2533
+ num: sum.toFixed(properties.labelsAboveDecimals),
2534
+ prepend: typeof properties.labelsAboveUnitsPre === 'string' ? properties.labelsAboveUnitsPre : null,
2535
+ append: typeof properties.labelsAboveUnitsPost === 'string' ? properties.labelsAboveUnitsPost : null,
2536
+ point: typeof properties.labelsAbovePoint === 'string' ? properties.labelsAbovePoint : null,
2537
+ thousand: typeof properties.labelsAboveThousand === 'string' ? properties.labelsAboveThousand : null,
2538
+ formatter: typeof properties.labelsAboveFormatter === 'function' ? properties.labelsAboveFormatter : null
2539
+ });
2540
+
2541
+ // Facilitate labelsAboveSpecific
2542
+ if (properties.labelsAboveSpecific && properties.labelsAboveSpecific.length && (typeof properties.labelsAboveSpecific[seq] === 'string' || typeof properties.labelsAboveSpecific[seq] === 'number') ) {
2543
+ str = String(properties.labelsAboveSpecific[seq]);
2544
+ } else if ( properties.labelsAboveSpecific && properties.labelsAboveSpecific.length && typeof properties.labelsAboveSpecific[seq] !== 'string' && typeof properties.labelsAboveSpecific[seq] !== 'number') {
2545
+ continue;
2546
+ }
2547
+
2548
+ // Add the text to the SVG
2549
+ RGraph.SVG.text({
2550
+
2551
+ object: this,
2552
+ parent: this.svg.all,
2553
+ tag: 'labels.above',
2554
+
2555
+ text: str,
2556
+
2557
+ x: x,
2558
+ y: y,
2559
+
2560
+ halign: halign,
2561
+ valign: valign,
2562
+
2563
+ font: textConf.font,
2564
+ size: textConf.size,
2565
+ bold: textConf.bold,
2566
+ italic: textConf.italic,
2567
+ color: textConf.color,
2568
+
2569
+ background: properties.labelsAboveBackground,
2570
+ padding: properties.labelsAboveBackgroundPadding
2571
+ });
2572
+
2573
+
2574
+
2575
+
2576
+
2577
+
2578
+
2579
+
2580
+
2581
+
2582
+
2583
+
2584
+
2585
+
2586
+
2587
+
2588
+
2589
+
2590
+ // GROUPED CHART
2591
+ } else if (!RGraph.SVG.isNull(value) && typeof value === 'object' && properties.grouping === 'grouped') {
2592
+
2593
+ for (var k=0; k<value.length; ++k) {
2594
+
2595
+ val = value[k];
2596
+
2597
+ if (typeof val !== 'number') {
2598
+ val = '';
2599
+ }
2600
+
2601
+
2602
+ var x = parseInt(this.coords[seq].element.getAttribute('x')) + hoffset + properties.labelsAboveOffsetx,
2603
+ height = parseInt(this.coords[seq].element.getAttribute('height')),
2604
+ y = parseInt(this.coords[seq].element.getAttribute('y')) + (height / 2) + properties.labelsAboveOffsety,
2605
+ width = parseInt(this.coords[seq].element.getAttribute('width'));
2606
+
2607
+ // If the dataset is the RHS (which would equal )
2608
+ // then set the alignment appropriately
2609
+ if (dataset === 1) {
2610
+ x += width;
2611
+ }
2612
+
2613
+ var str = RGraph.SVG.numberFormat({
2614
+ object: this,
2615
+ num: parseFloat(val).toFixed(properties.labelsAboveDecimals),
2616
+ prepend: typeof properties.labelsAboveUnitsPre === 'string' ? properties.labelsAboveUnitsPre : null,
2617
+ append: typeof properties.labelsAboveUnitsPost === 'string' ? properties.labelsAboveUnitsPost : null,
2618
+ point: typeof properties.labelsAbovePoint === 'string' ? properties.labelsAbovePoint : null,
2619
+ thousand: typeof properties.labelsAboveThousand === 'string' ? properties.labelsAboveThousand : null,
2620
+ formatter: typeof properties.labelsAboveFormatter === 'function' ? properties.labelsAboveFormatter : null
2621
+ });
2622
+
2623
+ if (val === 0 || RGraph.SVG.isNull(val) || val === '') {
2624
+ str = '';
2625
+ }
2626
+
2627
+ // Facilitate labelsAboveSpecific
2628
+ if (properties.labelsAboveSpecific && properties.labelsAboveSpecific.length && (typeof properties.labelsAboveSpecific[seq] === 'string' || typeof properties.labelsAboveSpecific[seq] === 'number') ) {
2629
+ str = String(properties.labelsAboveSpecific[seq]);
2630
+ } else if ( properties.labelsAboveSpecific && properties.labelsAboveSpecific.length && typeof properties.labelsAboveSpecific[seq] !== 'string' && typeof properties.labelsAboveSpecific[seq] !== 'number') {
2631
+ continue;
2632
+ }
2633
+
2634
+ // Add the text to the SVG
2635
+ RGraph.SVG.text({
2636
+
2637
+ object: this,
2638
+ parent: this.svg.all,
2639
+ tag: 'labels.above',
2640
+
2641
+ text: str,
2642
+
2643
+ x: x,
2644
+ y: y,
2645
+
2646
+ halign: halign,
2647
+ valign: valign,
2648
+
2649
+ font: textConf.font,
2650
+ size: textConf.size,
2651
+ bold: textConf.bold,
2652
+ italic: textConf.italic,
2653
+ color: textConf.color,
2654
+
2655
+ background: properties.labelsAboveBackground,
2656
+ padding: properties.labelsAboveBackgroundPadding
2657
+ });
2658
+
2659
+ seq++;
2660
+ }
2661
+
2662
+ seq--;
2663
+ } else if (RGraph.SVG.isNull(value)) {
2664
+ --seq;
2665
+ }
2666
+ }
2667
+
2668
+ --seq;
2669
+ }
2670
+ }
2671
+ };
2672
+
2673
+
2674
+
2675
+
2676
+
2677
+
2678
+
2679
+
2680
+ //
2681
+ // Using a function to add events makes it easier to facilitate method
2682
+ // chaining
2683
+ //
2684
+ // @param string type The type of even to add
2685
+ // @param function func
2686
+ //
2687
+ this.on = function (type, func)
2688
+ {
2689
+ if (type.substr(0,2) !== 'on') {
2690
+ type = 'on' + type;
2691
+ }
2692
+
2693
+ RGraph.SVG.addCustomEventListener(this, type, func);
2694
+
2695
+ return this;
2696
+ };
2697
+
2698
+
2699
+
2700
+
2701
+
2702
+
2703
+
2704
+
2705
+ //
2706
+ // Used in chaining. Runs a function there and then - not waiting for
2707
+ // the events to fire (eg the onbeforedraw event)
2708
+ //
2709
+ // @param function func The function to execute
2710
+ //
2711
+ this.exec = function (func)
2712
+ {
2713
+ func(this);
2714
+
2715
+ return this;
2716
+ };
2717
+
2718
+
2719
+
2720
+
2721
+
2722
+
2723
+
2724
+
2725
+ //
2726
+ // Remove highlight from the chart (tooltips)
2727
+ //
2728
+ this.removeHighlight = function ()
2729
+ {
2730
+ //var highlight = RGraph.SVG.REG.get('highlight');
2731
+ //if (highlight && highlight.parentNode) {
2732
+ // highlight.parentNode.removeChild(highlight);
2733
+ //}
2734
+
2735
+ //RGraph.SVG.REG.set('highlight', null);
2736
+
2737
+ RGraph.SVG.removeHighlight();
2738
+ };
2739
+
2740
+
2741
+
2742
+
2743
+
2744
+
2745
+
2746
+
2747
+ //
2748
+ // Calulate the center gutter size
2749
+ //
2750
+ this.getMarginCenter =
2751
+ this.getGutterCenter = function ()
2752
+ {
2753
+ var bold = typeof properties.yaxisLabelsBold === 'boolean' ? properties.yaxisLabelsBold : properties.textBold,
2754
+ font = typeof properties.yaxisLabelsFont === 'string' ? properties.yaxisLabelsFont : properties.textFont,
2755
+ size = typeof properties.yaxisLabelsSize === 'number' ? properties.yaxisLabelsSize : properties.textSize,
2756
+ width = 0;
2757
+
2758
+ // Loop through the labels measuring them
2759
+ if (properties.yaxisLabels) {
2760
+
2761
+ for (var i=0,len=properties.yaxisLabels.length; i<len; ++i) {
2762
+
2763
+ width = Math.max(width, RGraph.SVG.measureText({
2764
+ text: properties.yaxisLabels[i],
2765
+ bold: bold,
2766
+ font: font,
2767
+ size: size
2768
+ })[0]);
2769
+
2770
+ }
2771
+ } else {
2772
+ var width = 50;
2773
+ }
2774
+
2775
+ return width + 15;
2776
+ };
2777
+
2778
+
2779
+
2780
+
2781
+
2782
+
2783
+
2784
+
2785
+ //
2786
+ // Draw the title
2787
+ //
2788
+ this.drawTitle = function ()
2789
+ {
2790
+ // Taken out on 16th Sep 2019 to accommodate responsive()ness. Setting the titleX
2791
+ // property was causing the smaller charts to rtain the larger charts titleX
2792
+ //position
2793
+
2794
+ //if (RGraph.SVG.isNull(properties.titleX)) {
2795
+ // properties.titleX = ((this.width - properties.marginLeft - properties.marginRight) / 2) + properties.marginLeft;
2796
+ //}
2797
+
2798
+ RGraph.SVG.drawTitle(this);
2799
+ };
2800
+
2801
+
2802
+
2803
+
2804
+
2805
+
2806
+
2807
+ //
2808
+ // The Bar chart grow effect
2809
+ //
2810
+ this.grow = function ()
2811
+ {
2812
+ var opt = arguments[0] || {},
2813
+ frames = opt.frames || 30,
2814
+ frame = 0,
2815
+ obj = this,
2816
+ left = RGraph.SVG.arrayClone(this.left),
2817
+ right = RGraph.SVG.arrayClone(this.right),
2818
+ seq = 0;
2819
+
2820
+ this.draw();
2821
+
2822
+ var iterate = function ()
2823
+ {
2824
+ // LOOP THROUGH THE LEFT DATA
2825
+ for (var i=0,seq=0,len=obj.coordsLeft.length; i<len; ++i, ++seq) {
2826
+
2827
+ var multiplier = (frame / frames);
2828
+
2829
+ // The main loop through the data
2830
+
2831
+ // LEFT REGULAR
2832
+ if (typeof left[i] === 'number') {
2833
+
2834
+ var width = Math.abs(obj.getLeftXCoord(left[i]) - obj.getLeftXCoord(0));
2835
+ left[i] = obj.left[i] * multiplier;
2836
+
2837
+ // Set the new height on the rect
2838
+ obj.coords[seq].element.setAttribute(
2839
+ 'width',
2840
+ width
2841
+ );
2842
+
2843
+ // Set the correct Y coord on the object
2844
+ obj.coords[seq].element.setAttribute(
2845
+ 'x',
2846
+ obj.getLeftXCoord(0) - width
2847
+ );
2848
+
2849
+
2850
+
2851
+
2852
+
2853
+ // LEFT STACKED
2854
+ } else if (typeof left[i] === 'object' && properties.grouping === 'stacked') {
2855
+
2856
+ var accumulativeWidth = 0;
2857
+
2858
+ for (var j=0,len2=left[i].length; j<len2; ++j, ++seq) {
2859
+
2860
+ var width = Math.abs(obj.getLeftXCoord(left[i][j]) - obj.getLeftXCoord(0));
2861
+ left[i][j] = obj.left[i][j] * multiplier;
2862
+
2863
+ obj.coords[seq].element.setAttribute(
2864
+ 'width',
2865
+ width
2866
+ );
2867
+
2868
+ obj.coords[seq].element.setAttribute(
2869
+ 'x',
2870
+ obj.getLeftXCoord(0) - width - accumulativeWidth
2871
+ );
2872
+
2873
+ accumulativeWidth += (properties.grouping === 'stacked' ? width : 0);
2874
+ }
2875
+
2876
+
2877
+
2878
+ //
2879
+ // Set the width and X coord of the backfaces
2880
+ //
2881
+ if (obj.stackedBackfacesLeft[i]) {
2882
+ obj.stackedBackfacesLeft[i].setAttribute(
2883
+ 'width',
2884
+ accumulativeWidth
2885
+ );
2886
+
2887
+ obj.stackedBackfacesLeft[i].setAttribute(
2888
+ 'x',
2889
+ obj.getLeftXCoord(0) - accumulativeWidth
2890
+ );
2891
+ }
2892
+
2893
+ // Decrease seq by one so that it's not incremented twice
2894
+ --seq;
2895
+
2896
+ // LEFT GROUPED
2897
+ } else if (typeof left[i] === 'object' && properties.grouping === 'grouped') {
2898
+
2899
+ // Loop thru the group
2900
+ for (var j=0,len2=left[i].length; j<len2; ++j, ++seq) {
2901
+
2902
+ var width = obj.getLeftXCoord(0) - obj.getLeftXCoord(left[i][j]);
2903
+ left[i][j] = obj.left[i][j] * multiplier;
2904
+
2905
+ obj.coords[seq].element.setAttribute(
2906
+ 'width',
2907
+ width
2908
+ );
2909
+
2910
+ obj.coords[seq].element.setAttribute(
2911
+ 'x',
2912
+ obj.getLeftXCoord(0) - width
2913
+ );
2914
+ }
2915
+
2916
+ // Decrease seq by one so that it's not incremented twice
2917
+ --seq;
2918
+ }
2919
+ }
2920
+
2921
+
2922
+
2923
+
2924
+
2925
+
2926
+
2927
+
2928
+
2929
+ // LOOP THROUGH THE RIGHT DATA
2930
+ for (var i=0,seq=0,len=obj.coordsRight.length; i<len; ++i, ++seq) {
2931
+
2932
+ var multiplier = (frame / frames)
2933
+ // RGraph.SVG.FX.getEasingMultiplier(frames, frame)
2934
+ // RGraph.SVG.FX.getEasingMultiplier(frames, frame);
2935
+
2936
+
2937
+
2938
+
2939
+ // The main loop through the data
2940
+ // RIGHT REGULAR
2941
+ if (typeof right[i] === 'number') {
2942
+
2943
+ width = Math.abs(obj.getRightXCoord(right[i]) - obj.getRightXCoord(0));
2944
+ right[i] = obj.right[i] * multiplier;
2945
+
2946
+ // Set the new height on the rect
2947
+ obj.coordsRight[i].element.setAttribute(
2948
+ 'width',
2949
+ width
2950
+ );
2951
+
2952
+ // Set the correct Y coord on the object
2953
+ obj.coordsRight[seq].element.setAttribute(
2954
+ 'x',
2955
+ obj.getRightXCoord(0)
2956
+ );
2957
+
2958
+
2959
+
2960
+
2961
+
2962
+ // RIGHT STACKED
2963
+ } else if (typeof right[i] === 'object' && properties.grouping === 'stacked') {
2964
+
2965
+ var accumulativeWidth = 0;
2966
+
2967
+ for (var j=0,len2=right[i].length; j<len2; ++j, ++seq) {
2968
+
2969
+ width = Math.abs(obj.getRightXCoord(right[i][j]) - obj.getRightXCoord(0));
2970
+ right[i][j] = obj.right[i][j] * multiplier;
2971
+
2972
+ obj.coordsRight[seq].element.setAttribute(
2973
+ 'width',
2974
+ width
2975
+ );
2976
+
2977
+ obj.coordsRight[seq].element.setAttribute(
2978
+ 'x',
2979
+ obj.getRightXCoord(0) + accumulativeWidth
2980
+ );
2981
+
2982
+ accumulativeWidth += width;
2983
+ }
2984
+
2985
+
2986
+
2987
+ //
2988
+ // Set the width and X coord of the backfaces
2989
+ //
2990
+ if (obj.stackedBackfacesRight[i]) {
2991
+ obj.stackedBackfacesRight[i].setAttribute(
2992
+ 'width',
2993
+ accumulativeWidth
2994
+ );
2995
+
2996
+ obj.stackedBackfacesRight[i].setAttribute(
2997
+ 'x',
2998
+ obj.getRightXCoord(0)
2999
+ );
3000
+ }
3001
+
3002
+ // Decrease seq by one so that it's not incremented twice
3003
+ --seq;
3004
+
3005
+ // RIGHT GROUPED
3006
+ } else if (typeof right[i] === 'object' && properties.grouping === 'grouped') {
3007
+
3008
+ // Loop thru the group
3009
+ for (var j=0,len2=right[i].length; j<len2; ++j, ++seq) {
3010
+
3011
+ width = Math.abs(obj.getRightXCoord(right[i][j]) - obj.getRightXCoord(0));
3012
+ right[i][j] = obj.right[i][j] * multiplier;
3013
+
3014
+ obj.coordsRight[seq].element.setAttribute(
3015
+ 'width',
3016
+ width
3017
+ );
3018
+
3019
+ obj.coordsRight[seq].element.setAttribute(
3020
+ 'x',
3021
+ obj.getRightXCoord(0)
3022
+ );
3023
+ }
3024
+
3025
+ // Decrease seq by one so that it's not incremented twice
3026
+ --seq;
3027
+ }
3028
+ }
3029
+
3030
+
3031
+
3032
+
3033
+
3034
+
3035
+
3036
+ if (frame++ <= frames) {
3037
+ RGraph.SVG.FX.update(iterate);
3038
+ } else if (opt.callback) {
3039
+ (opt.callback)(obj);
3040
+ }
3041
+ };
3042
+
3043
+ iterate();
3044
+
3045
+ return this;
3046
+ };
3047
+
3048
+
3049
+
3050
+
3051
+
3052
+
3053
+
3054
+
3055
+ //
3056
+ // Bipolar chart Wave effect.
3057
+ //
3058
+ // @param object OPTIONAL An object map of options. You specify 'frames'
3059
+ // here to give the number of frames in the effect
3060
+ // and also callback to specify a callback function
3061
+ // thats called at the end of the effect
3062
+ //
3063
+ this.wave = function ()
3064
+ {
3065
+ var obj = this,
3066
+ opt = arguments[0] || {},
3067
+ frames = opt.frames || 120,
3068
+ startFrames_left = [],
3069
+ startFrames_right = [],
3070
+ counters_left = [],
3071
+ counters_right = [];
3072
+
3073
+ var framesperbar = frames / 3,
3074
+ frame_left = -1,
3075
+ frame_right = -1,
3076
+ callback = arguments[1] || function () {},
3077
+ original_left = RGraph.SVG.arrayClone(this.left),
3078
+ original_right = RGraph.SVG.arrayClone(this.right);
3079
+
3080
+
3081
+
3082
+
3083
+
3084
+
3085
+
3086
+
3087
+
3088
+
3089
+
3090
+
3091
+
3092
+
3093
+
3094
+
3095
+
3096
+
3097
+ for (var i=0,len=this.left.length,seq=0; i<len; i+=1,++seq) {
3098
+
3099
+ startFrames_left[seq] = ((frames / 3) / (RGraph.SVG.arrayLinearize(this.left).length - 1)) * i;
3100
+ counters_left[seq] = 0;
3101
+
3102
+ if (RGraph.SVG.isArray(this.left[i])) {
3103
+ for (var j=0; j<this.left[i].length; ++j,seq++) {
3104
+ startFrames_left[seq] = ((frames / 3) / (RGraph.SVG.arrayLinearize(this.left).length - 1)) * seq;
3105
+ counters_left[seq] = 0;
3106
+ }
3107
+
3108
+ --seq;
3109
+ }
3110
+ }
3111
+
3112
+
3113
+
3114
+
3115
+
3116
+ for (var i=0,len=this.right.length,seq=0; i<len; i+=1,++seq) {
3117
+
3118
+ startFrames_right[seq] = ((frames / 3) / (RGraph.SVG.arrayLinearize(this.right).length - 1)) * i;
3119
+ counters_right[seq] = 0;
3120
+
3121
+ if (RGraph.SVG.isArray(this.right[i])) {
3122
+ for (var j=0; j<this.right[i].length; ++j,seq++) {
3123
+ startFrames_right[seq] = ((frames / 3) / (RGraph.SVG.arrayLinearize(this.right).length - 1)) * seq;
3124
+ counters_right[seq] = 0;
3125
+ }
3126
+
3127
+ --seq;
3128
+ }
3129
+ }
3130
+
3131
+
3132
+
3133
+
3134
+
3135
+
3136
+
3137
+
3138
+
3139
+
3140
+
3141
+
3142
+
3143
+
3144
+
3145
+
3146
+
3147
+
3148
+
3149
+
3150
+ // This stops the chart from jumping
3151
+ this.draw();
3152
+
3153
+
3154
+
3155
+
3156
+
3157
+
3158
+
3159
+
3160
+
3161
+
3162
+
3163
+
3164
+
3165
+
3166
+
3167
+ // Zero all of the data for the left side
3168
+ for (var i=0,len=this.left.length; i<len; i+=1) {
3169
+ if (typeof this.left[i] === 'number') {
3170
+ this.left[i] = 0;
3171
+ } else if (typeof this.left[i] === 'object' && !RGraph.SVG.isNull(this.left[i])) {
3172
+ for (var j=0; j<this.left[i].length; ++j) {
3173
+ this.left[i][j] = 0;
3174
+ }
3175
+ }
3176
+ }
3177
+
3178
+ // Zero all of the bar-lengths for the left side
3179
+ for (var i=0; i<this.coordsLeft.length; i+=1) {
3180
+ this.coordsLeft[i].element.setAttribute('width', 0);
3181
+
3182
+ if (this.stackedBackfacesLeft[i]) {
3183
+ this.stackedBackfacesLeft[i].setAttribute('width', 0);
3184
+ }
3185
+ }
3186
+
3187
+
3188
+
3189
+
3190
+ // Zero all of the data for the right side
3191
+ for (var i=0; i<this.right.length; i+=1) {
3192
+ if (RGraph.SVG.isNumber(this.right[i])) {
3193
+ this.right[i] = 0;
3194
+ } else if (RGraph.SVG.isArray(this.right[i])) {
3195
+ for (var j=0; j<this.right[i].length; ++j) {
3196
+ this.right[i][j] = 0;
3197
+ }
3198
+ }
3199
+ }
3200
+
3201
+ // Zero all of the bar-lengths for the right side
3202
+ for (var i=0; i<this.coordsRight.length; i+=1) {
3203
+ this.coordsRight[i].element.setAttribute('width', 0);
3204
+
3205
+ if (this.stackedBackfacesRight[i]) {
3206
+ this.stackedBackfacesRight[i].setAttribute('width', 0);
3207
+ }
3208
+ }
3209
+
3210
+
3211
+
3212
+
3213
+
3214
+
3215
+
3216
+
3217
+
3218
+
3219
+
3220
+
3221
+
3222
+
3223
+
3224
+
3225
+
3226
+ //
3227
+ // Iterate over the left side
3228
+ //
3229
+ function iteratorLeft ()
3230
+ {
3231
+ ++frame_left;
3232
+
3233
+ for (var i=0,len=obj.left.length,seq=0; i<len; i+=1,seq+=1) {
3234
+
3235
+ if (frame_left >= startFrames_left[seq]) {
3236
+
3237
+ var isNull = RGraph.SVG.isNull(obj.left[i]);
3238
+
3239
+ // Regular bars
3240
+ if (typeof obj.left[i] === 'number') {
3241
+
3242
+ obj.left[i] = Math.min(
3243
+ Math.abs(original_left[i]),
3244
+ Math.abs(original_left[i] * ( (counters_left[i]++) / framesperbar))
3245
+ );
3246
+
3247
+ var rect_left = obj.coords[seq].element;
3248
+
3249
+ rect_left.setAttribute(
3250
+ 'width',
3251
+ parseFloat(rect_left.getAttribute('data-original-width')) * (obj.left[i] / rect_left.getAttribute('data-value'))
3252
+ );
3253
+
3254
+
3255
+ rect_left.setAttribute(
3256
+ 'x',
3257
+ obj.properties.marginLeft + obj.graphWidth - (parseFloat(rect_left.getAttribute('data-original-width')) * (obj.left[i] / rect_left.getAttribute('data-value')))
3258
+ );
3259
+
3260
+
3261
+ // Stacked or grouped bars
3262
+ } else if (RGraph.SVG.isArray(obj.left[i])) {
3263
+
3264
+ for (var j=0,accWidth=0; j<obj.left[i].length; ++j,++seq) {
3265
+
3266
+ obj.left[i][j] = Math.min(
3267
+ Math.abs(original_left[i][j]),
3268
+ Math.abs(original_left[i][j] * ( (counters_left[seq]++) / framesperbar))
3269
+ );
3270
+
3271
+ var rect_left = obj.coords[seq].element;
3272
+
3273
+ rect_left.setAttribute(
3274
+ 'width',
3275
+ parseFloat(rect_left.getAttribute('data-original-width')) * (obj.left[i][j] / rect_left.getAttribute('data-value'))
3276
+ );
3277
+
3278
+ rect_left.setAttribute(
3279
+ 'x',
3280
+ obj.properties.marginLeft + obj.graphWidth - (parseFloat(rect_left.getAttribute('data-original-width')) * (obj.left[i][j] / rect_left.getAttribute('data-value'))) - accWidth
3281
+ );
3282
+
3283
+ // Only update this for stacked charts
3284
+ if (obj.properties.grouping === 'stacked') {
3285
+ accWidth += parseFloat(rect_left.getAttribute('width'));
3286
+ obj.stackedBackfacesLeft[i].setAttribute('x', obj.properties.marginLeft + obj.graphWidth - accWidth);
3287
+ obj.stackedBackfacesLeft[i].setAttribute('width', accWidth);
3288
+ }
3289
+ }
3290
+
3291
+ seq--;
3292
+ }
3293
+
3294
+ if (isNull) {
3295
+ obj.left[i] = null;
3296
+ }
3297
+ } else {
3298
+ obj.left[i] = typeof obj.left[i] === 'object' && obj.left[i] ? RGraph.SVG.arrayPad({array: [], length: obj.left[i].length, value: 0}) : (RGraph.SVG.isNull(obj.left[i]) ? null : 0);
3299
+ }
3300
+ }
3301
+
3302
+
3303
+ // No callback here - only called by the right function
3304
+ if (frame_left <= frames) {
3305
+ RGraph.SVG.FX.update(iteratorLeft);
3306
+ }
3307
+ }
3308
+
3309
+
3310
+
3311
+
3312
+
3313
+
3314
+
3315
+
3316
+
3317
+
3318
+
3319
+
3320
+ //
3321
+ // Iterate over the right side
3322
+ //
3323
+ function iteratorRight ()
3324
+ {
3325
+ ++frame_right;
3326
+
3327
+ for (var i=0,len=obj.right.length,seq=0; i<len; i+=1,seq+=1) {
3328
+
3329
+ if (frame_right >= startFrames_right[seq]) {
3330
+
3331
+ var isNull = RGraph.SVG.isNull(obj.right[i]);
3332
+
3333
+ // Regular bars
3334
+ if (typeof obj.right[i] === 'number') {
3335
+
3336
+ obj.right[i] = Math.min(
3337
+ Math.abs(original_right[i]),
3338
+ Math.abs(original_right[i] * ( (counters_right[i]++) / framesperbar))
3339
+ );
3340
+
3341
+ var rect_right = obj.coordsRight[seq].element;
3342
+
3343
+ rect_right.setAttribute(
3344
+ 'width',
3345
+ parseFloat(rect_right.getAttribute('data-original-width')) * (obj.right[i] / rect_right.getAttribute('data-value'))
3346
+ );
3347
+
3348
+
3349
+ rect_right.setAttribute(
3350
+ 'x',
3351
+ properties.marginLeft + obj.graphWidth + properties.marginCenter
3352
+ );
3353
+
3354
+
3355
+ // Stacked or grouped bars
3356
+ } else if (RGraph.SVG.isArray(obj.right[i])) {
3357
+
3358
+ for (var j=0,accWidth=0; j<obj.right[i].length; ++j,++seq) {
3359
+
3360
+ obj.right[i][j] = Math.min(
3361
+ Math.abs(original_right[i][j]),
3362
+ Math.abs(original_right[i][j] * ( (counters_right[seq]++) / framesperbar))
3363
+ );
3364
+
3365
+ var rect_right = obj.coordsRight[seq].element;
3366
+
3367
+ rect_right.setAttribute(
3368
+ 'width',
3369
+ parseFloat(rect_right.getAttribute('data-original-width')) * (obj.right[i][j] / rect_right.getAttribute('data-value'))
3370
+ );
3371
+
3372
+ rect_right.setAttribute(
3373
+ 'x',
3374
+ obj.properties.marginLeft + obj.graphWidth + obj.properties.marginCenter + accWidth
3375
+ );
3376
+
3377
+ // Only update this for stacked charts
3378
+ if (obj.properties.grouping === 'stacked') {
3379
+ accWidth += parseFloat(rect_right.getAttribute('width'));
3380
+ obj.stackedBackfacesRight[i].setAttribute('x', obj.properties.marginLeft + obj.graphWidth + obj.properties.marginCenter);
3381
+ obj.stackedBackfacesRight[i].setAttribute('width', accWidth);
3382
+ }
3383
+ }
3384
+
3385
+ seq--;
3386
+ }
3387
+
3388
+ if (isNull) {
3389
+ obj.right[i] = null;
3390
+ }
3391
+ } else {
3392
+ obj.right[i] = typeof obj.right[i] === 'object' && obj.right[i] ? RGraph.SVG.arrayPad({array: [], length: obj.right[i].length, value: 0}) : (RGraph.SVG.isNull(obj.right[i]) ? null : 0);
3393
+ }
3394
+ }
3395
+
3396
+
3397
+ // No callback here - only called by the right function
3398
+ if (frame_right <= frames) {
3399
+ RGraph.SVG.FX.update(iteratorRight);
3400
+ }
3401
+ }
3402
+
3403
+
3404
+
3405
+ iteratorLeft();
3406
+ iteratorRight();
3407
+
3408
+ return this;
3409
+ };
3410
+
3411
+
3412
+
3413
+
3414
+
3415
+
3416
+
3417
+
3418
+
3419
+ //
3420
+ // A worker function that handles Bipolar chart specific tooltip substitutions
3421
+ //
3422
+ this.tooltipSubstitutions = function (opt)
3423
+ {
3424
+ var indexes = RGraph.SVG.sequentialIndexToGrouped(opt.index, this.data);
3425
+ var linear_indexes = RGraph.SVG.sequentialIndexToGrouped(opt.index, this.data_arr);
3426
+
3427
+ return {
3428
+ index: linear_indexes[1],
3429
+ dataset: linear_indexes[0],
3430
+ dataset2: linear_indexes[0] >= this.left.length ? linear_indexes[0] - this.left.length : linear_indexes[0],
3431
+ sequentialIndex: opt.index,
3432
+ value: typeof this.data_arr[linear_indexes[0]] === 'number'
3433
+ ? this.data_arr[linear_indexes[0]]
3434
+ : this.data_arr[linear_indexes[0]][linear_indexes[1]],
3435
+ values: typeof this.data_arr[linear_indexes[0]] === 'number'
3436
+ ? [this.data_arr[linear_indexes[0]]]
3437
+ : this.data_arr[linear_indexes[0]]
3438
+ };
3439
+ };
3440
+
3441
+
3442
+
3443
+
3444
+
3445
+
3446
+
3447
+
3448
+ //
3449
+ // A worker function that returns the correct color/label/value
3450
+ //
3451
+ // @param object specific The indexes that are applicable
3452
+ // @param number index The appropriate index
3453
+ //
3454
+ this.tooltipsFormattedCustom = function (specific, index)
3455
+ {
3456
+ var side = ((specific.dataset + 1) > this.left.length) ? 'right' : 'left';
3457
+
3458
+ var color = (!RGraph.SVG.isNull(properties.tooltipsFormattedKeyColors) && typeof properties.tooltipsFormattedKeyColors === 'object' && properties.tooltipsFormattedKeyColors[index])
3459
+ ? properties.tooltipsFormattedKeyColors[index]
3460
+ : properties.colors[index];
3461
+
3462
+ if (typeof this[side][specific.dataset2] === 'object') {
3463
+
3464
+ var label = (!RGraph.SVG.isNull(properties.tooltipsFormattedKeyLabels) && typeof properties.tooltipsFormattedKeyLabels === 'object' && properties.tooltipsFormattedKeyLabels[index])
3465
+ ? properties.tooltipsFormattedKeyLabels[index]
3466
+ : '';
3467
+ } else {
3468
+ var label = (!RGraph.SVG.isNull(properties.tooltipsFormattedKeyLabels) && typeof properties.tooltipsFormattedKeyLabels === 'object' && properties.tooltipsFormattedKeyLabels[specific.dataset2])
3469
+ ? properties.tooltipsFormattedKeyLabels[specific.dataset2]
3470
+ : '';
3471
+ }
3472
+
3473
+ return {
3474
+ label: label,
3475
+ color: color
3476
+ };
3477
+ };
3478
+
3479
+
3480
+
3481
+
3482
+
3483
+
3484
+
3485
+
3486
+ //
3487
+ // This allows for static tooltip positioning
3488
+ //
3489
+ this.positionTooltipStatic = function (args)
3490
+ {
3491
+ var obj = args.object,
3492
+ e = args.event,
3493
+ tooltip = args.tooltip,
3494
+ index = args.index,
3495
+ svgXY = RGraph.SVG.getSVGXY(obj.svg),
3496
+ coords = this.coords[args.index];
3497
+
3498
+ // Position the tooltip in the X direction
3499
+ args.tooltip.style.left = (
3500
+ svgXY[0] // The X coordinate of the canvas
3501
+ + coords.x // The X coordinate of the bar on the chart
3502
+ - (tooltip.offsetWidth / 2) // Subtract half of the tooltip width
3503
+ + (coords.width / 2) // Add half of the bar width
3504
+ ) + 'px';
3505
+
3506
+ args.tooltip.style.top = (
3507
+ svgXY[1] // The Y coordinate of the canvas
3508
+ + coords.y // The Y coordinate of the bar on the chart
3509
+ - tooltip.offsetHeight // The height of the tooltip
3510
+ - 10 // An arbitrary amount
3511
+ ) + 'px';
3512
+ };
3513
+
3514
+
3515
+
3516
+
3517
+
3518
+
3519
+
3520
+
3521
+ //
3522
+ // Set the options that the user has provided
3523
+ //
3524
+ for (i in conf.options) {
3525
+ if (typeof i === 'string') {
3526
+ this.set(i, conf.options[i]);
3527
+ }
3528
+ }
3529
+ };
3530
+
3531
+ return this;
3532
+
3533
+ // End module pattern
3534
+ })(window, document);