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,81 +1,1921 @@
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.RScatter=RGraph.Rscatter=function(conf)
3
- {if(typeof conf==='object'&&typeof conf.data==='object'&&typeof conf.id==='string'){var parseConfObjectForOptions=true;this.data=new Array(conf.data.length);this.data=RGraph.arrayClone(conf.data);if(typeof conf.data==='object'&&typeof conf.data[0]==='object'&&typeof conf.data[0][0]==='number'){var tmp=RGraph.arrayClone(conf.data);conf.data=new Array();conf.data[0]=RGraph.arrayClone(tmp);this.data=RGraph.arrayClone(conf.data);}}else{var conf={id:conf};conf.data=arguments[1];this.data=[];if(arguments[1][0]&&arguments[1][0][0]&&typeof arguments[1][0][0]=='object'){for(var i=0;i<arguments[1].length;++i){this.data[i]=arguments[1][i];}}else{for(var i=1;i<arguments.length;++i){this.data[i-1]=RGraph.arrayClone(arguments[i]);}}}
4
- this.id=conf.id
5
- this.canvas=document.getElementById(this.id)
6
- this.context=this.canvas.getContext?this.canvas.getContext("2d"):null;this.canvas.__object__=this;this.type='rscatter';this.hasTooltips=false;this.isRGraph=true;this.uid=RGraph.CreateUID();this.canvas.uid=this.canvas.uid?this.canvas.uid:RGraph.CreateUID();this.colorsParsed=false;this.coordsText=[];this.original_colors=[];this.firstDraw=true;this.propertyNameAliases={};this.centerx=0;this.centery=0;this.radius=0;this.max=0;for(var i=0;i<this.data.length;++i){for(var j=0;j<this.data[i].length;++j){if(typeof this.data[i][j][0]==='string'){this.data[i][j][0]=parseFloat(this.data[i][j][0]);}
7
- if(typeof this.data[i][j][1]==='string'){this.data[i][j][1]=parseFloat(this.data[i][j][1]);}}}
8
- this.properties={'chart.background.color':'transparent','chart.background.grid':true,'chart.background.grid.radials':true,'chart.background.grid.radials.count':null,'chart.background.grid.circles':true,'chart.background.grid.circles.count':null,'chart.background.grid.linewidth':1,'chart.background.grid.color':'#ccc','chart.centerx':null,'chart.centery':null,'chart.radius':null,'chart.colors':[],'chart.colors.default':'black','chart.margin.left':25,'chart.margin.right':25,'chart.margin.top':25,'chart.margin.bottom':25,'chart.title':'','chart.title.background':null,'chart.title.hpos':null,'chart.title.vpos':null,'chart.title.bold':true,'chart.title.font':null,'chart.title.size':null,'chart.title.italic':null,'chart.title.color':null,'chart.title.x':null,'chart.title.y':null,'chart.title.halign':null,'chart.title.valign':null,'chart.labels':null,'chart.labels.color':null,'chart.labels.font':null,'chart.labels.size':null,'chart.labels.italic':null,'chart.labels.bold':null,'chart.labels.axes':'n','chart.labels.axes.background':'rgba(255,255,255,0.7)','chart.labels.axes.count':5,'chart.labels.axes.font':null,'chart.labels.axes.size':null,'chart.labels.axes.color':null,'chart.labels.axes.bold':null,'chart.labels.axes.italic':null,'chart.text.color':'black','chart.text.font':'Arial, Verdana, sans-serif','chart.text.size':12,'chart.text.bold':false,'chart.text.italic':false,'chart.text.accessible':true,'chart.text.accessible.overflow':'visible','chart.text.accessible.pointerevents':false,'chart.key':null,'chart.key.background':'white','chart.key.position':'graph','chart.key.halign':'right','chart.key.shadow':false,'chart.key.shadow.color':'#666','chart.key.shadow.blur':3,'chart.key.shadow.offsetx':2,'chart.key.shadow.offsety':2,'chart.key.position.gutter.boxed':false,'chart.key.position.x':null,'chart.key.position.y':null,'chart.key.color.shape':'square','chart.key.rounded':true,'chart.key.linewidth':1,'chart.key.colors':null,'chart.key.interactive':false,'chart.key.interactive.highlight.chart.fill':'rgba(255,0,0,0.9)','chart.key.interactive.highlight.label':'rgba(255,0,0,0.2)','chart.key.labels.color':null,'chart.key.labels.font':null,'chart.key.labels.size':null,'chart.key.labels.bold':null,'chart.key.labels.italic':null,'chart.key.labels.offsetx':0,'chart.key.labels.offsety':0,'chart.contextmenu':null,'chart.tooltips':null,'chart.tooltips.event':'onmousemove','chart.tooltips.effect':'fade','chart.tooltips.css.class':'RGraph_tooltip','chart.tooltips.highlight':true,'chart.tooltips.hotspot':3,'chart.tooltips.coords.page':false,'chart.annotatable':false,'chart.annotatable.color':'black','chart.annotatable.linewidth':1,'chart.resizable':false,'chart.resizable.handle.background':null,'chart.scale.max':null,'chart.scale.min':0,'chart.scale.decimals':null,'chart.scale.point':'.','chart.scale.thousand':',','chart.scale.round':false,'chart.scale.zerostart':true,'chart.scale.units.pre':'','chart.scale.units.post':'','chart.tickmarks':'cross','chart.tickmarks.size':3,'chart.axes.color':'transparent','chart.events.mousemove':null,'chart.events.click':null,'chart.highlight.stroke':'transparent','chart.highlight.fill':'rgba(255,255,255,0.7)','chart.highlight.point.radius':3,'chart.segment.highlight':false,'chart.segment.highlight.count':null,'chart.segment.highlight.fill':'rgba(0,255,0,0.5)','chart.segment.highlight.stroke':'rgba(0,0,0,0)','chart.line':false,'chart.line.close':false,'chart.line.linewidth':1,'chart.line.colors':['black'],'chart.line.shadow':false,'chart.line.shadow.color':'black','chart.line.shadow.blur':2,'chart.line.shadow.offsetx':3,'chart.line.shadow.offsety':3,'chart.clearto':'rgba(0,0,0,0)'}
9
- for(var i=0,idx=0;i<this.data.length;++i){for(var j=0,len=this.data[i].length;j<len;j+=1,idx+=1){this['$'+idx]={}}}
10
- if(!this.canvas.__rgraph_aa_translated__){this.context.translate(0.5,0.5);this.canvas.__rgraph_aa_translated__=true;}
11
- var RG=RGraph,ca=this.canvas,co=ca.getContext('2d'),prop=this.properties,pa2=RG.path2,win=window,doc=document,ma=Math
12
- if(RG.Effects&&typeof RG.Effects.decorate==='function'){RG.Effects.decorate(this);}
13
- this.set=this.Set=function(name,value)
14
- {var value=typeof arguments[1]==='undefined'?null:arguments[1];if(arguments.length===1&&typeof name==='object'){RG.parseObjectStyleConfig(this,name);return this;}
15
- if(name.substr(0,6)!='chart.'){name='chart.'+name;}
16
- while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
17
- prop[name.toLowerCase()]=value;return this;};this.get=this.Get=function(name)
18
- {if(name.substr(0,6)!='chart.'){name='chart.'+name;}
19
- while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
20
- return prop[name.toLowerCase()];};this.draw=this.Draw=function()
21
- {RG.FireCustomEvent(this,'onbeforedraw');this.marginLeft=prop['chart.margin.left'];this.marginRight=prop['chart.margin.right'];this.marginTop=prop['chart.margin.top'];this.marginBottom=prop['chart.margin.bottom'];this.radius=(Math.min(ca.width-this.marginLeft-this.marginRight,ca.height-this.marginTop-this.marginBottom)/2);this.centerx=((ca.width-this.marginLeft-this.marginRight)/2)+this.marginLeft;this.centery=((ca.height-this.marginTop-this.marginBottom)/2)+this.marginTop;this.coords=[];this.coords2=[];this.coordsText=[];if(typeof(prop['chart.centerx'])=='number')this.centerx=prop['chart.centerx'];if(typeof(prop['chart.centery'])=='number')this.centery=prop['chart.centery'];if(typeof(prop['chart.radius'])=='number')this.radius=prop['chart.radius'];if(!this.colorsParsed){this.parseColors();this.colorsParsed=true;}
22
- var max=prop['chart.scale.max'];var min=prop['chart.scalemin'];if(typeof(max)=='number'){this.max=max;this.scale2=RG.getScale2(this,{'scale.max':max,'scale.min':min,'scale.strict':true,'scale.decimals':Number(prop['chart.scale.decimals']),'scale.point':prop['chart.scale.point'],'scale.thousand':prop['chart.scale.thousand'],'scale.round':prop['chart.scale.round'],'scale.units.pre':prop['chart.scale.units.pre'],'scale.units.post':prop['chart.scale.units.post'],'scale.labels.count':prop['chart.labels.axes.count']});}else{for(var i=0;i<this.data.length;i+=1){for(var j=0,len=this.data[i].length;j<len;j+=1){this.max=Math.max(this.max,this.data[i][j][1]);}}
23
- this.min=prop['chart.ymin'];this.scale2=RG.getScale2(this,{'scale.max':this.max,'scale.min':min,'scale.decimals':Number(prop['chart.scale.decimals']),'scale.point':prop['chart.scale.point'],'scale.thousand':prop['chart.scale.thousand'],'scale.round':prop['chart.scale.round'],'scale.units.pre':prop['chart.scale.units.pre'],'scale.units.post':prop['chart.scale.units.post'],'scale.labels.count':prop['chart.labels.axes.count']});this.max=this.scale2.max;}
24
- if(prop['chart.key']&&prop['chart.key'].length>0&&prop['chart.key'].length>=3){this.centerx=this.centerx-prop['chart.margin.right']+5;}
25
- if(typeof prop['chart.key']==='object'&&RG.isArray(prop['chart.key'])&&prop['chart.key'][0]){prop['chart.colors']=[];for(var i=0;i<this.data.length;i+=1){for(var j=0,len=this.data[i].length;j<len;j+=1){if(typeof this.data[i][j][2]=='string'){prop['chart.colors'].push(this.data[i][j][2]);}}}}
26
- this.set('chart.tooltips',[]);for(var i=0;i<this.data.length;i+=1){for(var j=0,len=this.data[i].length;j<len;j+=1){prop['chart.tooltips'].push(this.data[i][j][3]);}}
27
- co.beginPath();this.DrawBackground();this.DrawRscatter();this.DrawLabels();var key=prop['chart.key'];if(key&&key.length){RG.drawKey(this,prop['chart.key'],prop['chart.colors']);}
28
- if(prop['chart.contextmenu']){RG.showContext(this);}
29
- if(prop['chart.title']){RG.DrawTitle(this,prop['chart.title'],this.centery-this.radius-10,this.centerx,prop['chart.title.size']?prop['chart.title.size']:prop['chart.text.size']+2);}
30
- if(prop['chart.resizable']){RG.AllowResizing(this);}
31
- RG.InstallEventListeners(this);if(prop['chart.segment.highlight']){RG.allowSegmentHighlight({object:this,count:typeof prop['chart.segment.highlight.count']==='number'?prop['chart.segment.highlight.count']:((prop['chart.background.grid.diagonals.count']?prop['chart.background.grid.diagonals.count']:(prop['chart.labels']?prop['chart.labels'].length:8))),fill:prop['chart.segment.highlight.fill'],stroke:prop['chart.segment.highlight.stroke']});}
32
- if(this.firstDraw){this.firstDraw=false;RG.fireCustomEvent(this,'onfirstdraw');this.firstDrawFunc();}
33
- RG.FireCustomEvent(this,'ondraw');return this;};this.drawBackground=this.DrawBackground=function()
34
- {if(prop['chart.background.color']!='transparent'){pa2(co,['b','a',this.centerx,this.centery,this.radius,0,2*ma.PI,-1,'f',prop['chart.background.color']]);}
35
- var gridEnabled=prop['chart.background.grid'];if(gridEnabled){co.lineWidth=prop['chart.background.grid.linewidth'];if(prop['chart.background.grid.circles']){co.strokeStyle=prop['chart.background.grid.color'];co.beginPath();if(RG.isNull(prop['chart.background.grid.circles.count'])){prop['chart.background.grid.circles.count']=prop['chart.labels.axes.count'];}
36
- var r=this.radius/prop['chart.background.grid.circles.count'];for(var i=0,len=this.radius;i<=len;i+=r){co.moveTo(this.centerx+i,this.centery);co.arc(this.centerx,this.centery,i,0,RG.TWOPI,0);}
37
- co.stroke();}
38
- if(prop['chart.background.grid.radials']){co.strokeStyle=prop['chart.background.grid.color'];co.beginPath();if(typeof prop['chart.background.grid.radials.count']==='number'){var inc=360/prop['chart.background.grid.radials.count'];}else if(prop['chart.labels']&&prop['chart.labels'].length){var inc=360/prop['chart.labels'].length;}else{var inc=45;}
39
- for(var i=0;i<360;i+=inc){co.arc(this.centerx,this.centery,this.radius,(i/(180/RG.PI))-RG.HALFPI,((i+0.01)/(180/RG.PI))-RG.HALFPI,0);co.lineTo(this.centerx,this.centery);}
40
- co.stroke();}}
41
- co.lineWidth=1;co.beginPath();co.strokeStyle=prop['chart.axes.color'];co.moveTo(this.centerx-this.radius,Math.round(this.centery));co.lineTo(this.centerx+this.radius,Math.round(this.centery));co.moveTo(ma.round(this.centerx-this.radius),this.centery-5);co.lineTo(ma.round(this.centerx-this.radius),this.centery+5);co.moveTo(ma.round(this.centerx+this.radius),this.centery-5);co.lineTo(ma.round(this.centerx+this.radius),this.centery+5);var numticks=prop['chart.labels.axes.count'];if(numticks){for(var i=(this.centerx-this.radius);i<(this.centerx+this.radius);i+=(this.radius/numticks)){co.moveTo(ma.round(i),this.centery-3);co.lineTo(ma.round(i),this.centery+3);}
42
- for(var i=(this.centery-this.radius);i<(this.centery+this.radius);i+=(this.radius/numticks)){co.moveTo(this.centerx-3,ma.round(i));co.lineTo(this.centerx+3,ma.round(i));}}
43
- co.moveTo(ma.round(this.centerx),this.centery-this.radius);co.lineTo(ma.round(this.centerx),this.centery+this.radius);if(prop['chart.axes.caps']){co.moveTo(this.centerx-5,ma.round(this.centery-this.radius));co.lineTo(this.centerx+5,ma.round(this.centery-this.radius));co.moveTo(this.centerx-5,ma.round(this.centery+this.radius));co.lineTo(this.centerx+5,ma.round(this.centery+this.radius));}
44
- co.closePath();co.stroke();};this.drawRscatter=this.DrawRscatter=function()
45
- {for(var dataset=0;dataset<this.data.length;dataset+=1){var data=this.data[dataset];this.coords2[dataset]=[];var drawPoints=function(obj)
46
- {for(var i=0;i<data.length;++i){var d1=data[i][0],d2=data[i][1],a=d1/(180/RG.PI),r=((d2-prop['chart.scale.min'])/(obj.scale2.max-obj.scale2.min))*obj.radius,x=ma.sin(a)*r,y=ma.cos(a)*r,color=data[i][2]?data[i][2]:prop['chart.colors.default'],tooltip=data[i][3]?data[i][3]:null
47
- if(tooltip&&String(tooltip).length){obj.hasTooltips=true;}
48
- x=x+obj.centerx;y=obj.centery-y;obj.drawTick(x,y,color);obj.coords.push([x,y,color,tooltip]);obj.coords2[dataset].push([x,y,color,tooltip]);}}
49
- drawPoints(this);if(prop['chart.line']){this.drawLine(dataset);}}};this.drawLine=function(idx)
50
- {var opt={dataset:idx,coords:this.coords2[idx],color:prop['chart.line.colors'][idx],shadow:prop['chart.line.shadow'],shadowColor:prop['chart.line.shadow.color'],shadowOffsetX:prop['chart.line.shadow.offsetx'],shadowOffsetY:prop['chart.line.shadow.offsety'],shadowBlur:prop['chart.line.shadow.blur'],linewidth:prop['chart.line.linewidth']};co.beginPath();co.strokeStyle=this.parseSingleColorForGradient(opt.color);co.lineWidth=typeof prop['chart.line.linewidth']==='object'?prop['chart.line.linewidth'][idx]:prop['chart.line.linewidth'];co.lineCap='round';if(opt.shadow){RG.setShadow(this,opt.shadowColor,opt.shadowOffsetX,opt.shadowOffsetY,opt.shadowBlur);}
51
- for(var i=0;i<this.coords2[idx].length;++i){if(i===0){co.moveTo(this.coords2[idx][i][0],this.coords2[idx][i][1]);var startCoords=RG.arrayClone(this.coords2[idx]);}else{co.lineTo(this.coords2[idx][i][0],this.coords2[idx][i][1]);}}
52
- if((typeof prop['chart.line.close']==='boolean'&&prop['chart.line.close'])||(typeof prop['chart.line.close']==='object'&&prop['chart.line.close'][idx])){co.lineTo(this.coords2[idx][0][0],this.coords2[idx][0][1]);}
53
- co.stroke();RG.noShadow(this);};this.drawLabels=this.DrawLabels=function()
54
- {co.lineWidth=1;co.fillStyle='black';co.strokeStyle='black';var key=prop['chart.key'];var r=this.radius;var axesColor=prop['chart.axes.color'];var italic=prop['chart.text.italic'];var bold=prop['chart.text.bold'];var color=prop['chart.text.color'];var font=prop['chart.text.font'];var size=prop['chart.text.size'];var axes=prop['chart.labels.axes'].toLowerCase();var units_pre=prop['chart.scale.units.pre'];var units_post=prop['chart.scale.units.post'];var decimals=prop['chart.scale.decimals'];var centerx=this.centerx;var centery=this.centery;co.fillStyle=prop['chart.text.color'];if(typeof prop['chart.labels']=='object'&&prop['chart.labels']){this.DrawCircularLabels(co,prop['chart.labels'],font,size,r);}
55
- var offset=10;var centered=false;if(axesColor==='rgba(0,0,0,0)'||axesColor==='rgb(0,0,0)'||axesColor==='transparent'){offset=0;centered=true;}
56
- var textConf=RG.getTextConf({object:this,prefix:'chart.labels.axes'});for(var i=0,len=this.scale2.labels.length;i<len;++i){if(axes.indexOf('n')>-1)RG.text2(this,{'tag':'scale',font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,'x':centerx-offset,'y':centery-(r*((i+1)/len)),'text':this.scale2.labels[i],'valign':'center','halign':centered?'center':'right',bounding:true,boundingFill:prop['chart.labels.axes.background'],boundingStroke:'rgba(0,0,0,0)'});if(axes.indexOf('s')>-1)RG.text2(this,{'tag':'scale',font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,'x':centerx-offset,'y':centery+(r*((i+1)/len)),'text':this.scale2.labels[i],'valign':'center','halign':centered?'center':'right',bounding:true,boundingFill:prop['chart.labels.axes.background'],boundingStroke:'rgba(0,0,0,0)'});if(axes.indexOf('e')>-1)RG.text2(this,{'tag':'scale',font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,'x':centerx+(r*((i+1)/len)),'y':centery+offset,'text':this.scale2.labels[i],'valign':centered?'center':'top','halign':'center',bounding:true,boundingFill:prop['chart.labels.axes.background'],boundingStroke:'rgba(0,0,0,0)'});if(axes.indexOf('w')>-1)RG.text2(this,{'tag':'scale',font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,'x':centerx-(r*((i+1)/len)),'y':centery+offset,'text':this.scale2.labels[i],'valign':centered?'center':'top','halign':'center',bounding:true,boundingFill:prop['chart.labels.axes.background'],boundingStroke:'rgba(0,0,0,0)'});}
57
- if(prop['chart.labels.axes'].length>0&&prop['chart.scale.zerostart']){RG.text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,'x':centerx,'y':centery,'text':RG.numberFormat({object:this,number:Number(this.scale2.min).toFixed(this.scale2.decimals),unitspre:this.scale2.units_pre,unitspost:this.scale2.units_post}),'valign':'center','halign':'center','bounding':true,'boundingFill':prop['chart.labels.axes.background'],'boundingStroke':'rgba(0,0,0,0)','tag':'scale'});}};this.drawCircularLabels=this.DrawCircularLabels=function(context,labels,font_face,font_size,r)
58
- {var r=r+10,color=prop['chart.labels.color'];for(var i=0;i<labels.length;++i){var a=(360/labels.length)*(i+1)-(360/(labels.length*2));var a=a-90+(prop['chart.labels.position']=='edge'?((360/labels.length)/2):0);var x=ma.cos(a/(180/RG.PI))*r;var y=ma.sin(a/(180/RG.PI))*r;var textConf=RG.getTextConf({object:this,prefix:'chart.labels'});RG.Text2(this,{font:textConf.font,size:textConf.size,color:textConf.color,bold:textConf.bold,italic:textConf.italic,'x':this.centerx+x,'y':this.centery+y,'text':String(labels[i]),'valign':'center','halign':((this.centerx+x)>this.centerx)?'left':'right','tag':'labels'});}};this.drawTick=this.DrawTick=function(x,y,color)
59
- {var tickmarks=prop['chart.tickmarks'];var ticksize=prop['chart.tickmarks.size'];co.strokeStyle=color;co.fillStyle=color;var prevLinewidth=co.lineWidth;co.lineWidth=1;if(tickmarks=='cross'){co.beginPath();co.moveTo(x+ticksize,y+ticksize);co.lineTo(x-ticksize,y-ticksize);co.stroke();co.beginPath();co.moveTo(x-ticksize,y+ticksize);co.lineTo(x+ticksize,y-ticksize);co.stroke();}else if(tickmarks=='circle'){co.beginPath();co.arc(x,y,ticksize,0,6.2830,false);co.fill();}else if(tickmarks=='square'){co.beginPath();co.fillRect(x-ticksize,y-ticksize,2*ticksize,2*ticksize);co.fill();}else if(tickmarks=='diamond'){co.beginPath();co.moveTo(x,y-ticksize);co.lineTo(x+ticksize,y);co.lineTo(x,y+ticksize);co.lineTo(x-ticksize,y);co.closePath();co.fill();}else if(tickmarks=='plus'){co.lineWidth=1;co.beginPath();co.moveTo(x,y-ticksize);co.lineTo(x,y+ticksize);co.moveTo(x-ticksize,y);co.lineTo(x+ticksize,y);co.stroke();}
60
- co.lineWidth=prevLinewidth;};this.getShape=this.getPoint=function(e)
61
- {var mouseXY=RG.getMouseXY(e);var mouseX=mouseXY[0];var mouseY=mouseXY[1];var overHotspot=false;var offset=prop['chart.tooltips.hotspot'];for(var i=0,len=this.coords.length;i<len;++i){var x=this.coords[i][0];var y=this.coords[i][1];var tooltip=this.coords[i][3];if(mouseX<(x+offset)&&mouseX>(x-offset)&&mouseY<(y+offset)&&mouseY>(y-offset)){var tooltip=RG.parseTooltipText(prop['chart.tooltips'],i);return{0:this,1:x,2:y,3:i,'object':this,'x':x,'y':y,'index':i,'tooltip':tooltip};}}};this.allowTooltips=this.AllowTooltips=function()
62
- {RG.PreLoadTooltipImages(this);RG.InstallWindowMousedownTooltipListener(this);RG.InstallCanvasMousemoveTooltipListener(this);RG.InstallCanvasMouseupTooltipListener(this);};this.highlight=this.Highlight=function(shape)
63
- {if(typeof prop['chart.highlight.style']==='function'){(prop['chart.highlight.style'])(shape);}else{RG.Highlight.Point(this,shape);}};this.getObjectByXY=function(e)
64
- {var mouseXY=RG.getMouseXY(e);var mouseX=mouseXY[0];var mouseY=mouseXY[1];var centerx=this.centerx;var centery=this.centery;var radius=this.radius;if(mouseX>(centerx-radius)&&mouseX<(centerx+radius)&&mouseY>(centery-radius)&&mouseY<(centery+radius)){return this;}};this.getRadius=function(value)
65
- {var max=this.max;if(value<0||value>max){return null;}
66
- var r=(value/max)*this.radius;return r;};this.parseColors=function()
67
- {if(this.original_colors.length===0){this.original_colors['data']=RG.array_clone(this.data);this.original_colors['chart.highlight.stroke']=RG.arrayClone(prop['chart.highlight.stroke']);this.original_colors['chart.highlight.fill']=RG.arrayClone(prop['chart.highlight.fill']);this.original_colors['chart.colors.default']=RG.arrayClone(prop['chart.colors.default']);this.original_colors['chart.background.grid.color']=RG.arrayClone(prop['chart.background.grid.color']);this.original_colors['chart.background.color']=RG.arrayClone(prop['chart.background.color']);this.original_colors['chart.segment.highlight.stroke']=RG.arrayClone(prop['chart.segment.highlight.stroke']);this.original_colors['chart.segment.highlight.fill']=RG.arrayClone(prop['chart.segment.highlight.fill']);}
68
- for(var i=0;i<this.data.length;i+=1){for(var j=0,len=this.data[i].length;j<len;j+=1){this.data[i][j][2]=this.parseSingleColorForGradient(this.data[i][j][2]);}}
69
- prop['chart.highlight.stroke']=this.parseSingleColorForGradient(prop['chart.highlight.stroke']);prop['chart.highlight.fill']=this.parseSingleColorForGradient(prop['chart.highlight.fill']);prop['chart.colors.default']=this.parseSingleColorForGradient(prop['chart.colors.default']);prop['chart.background.grid.color']=this.parseSingleColorForGradient(prop['chart.background.grid.color']);prop['chart.background.color']=this.parseSingleColorForGradient(prop['chart.background.color']);prop['chart.segment.highlight.stroke']=this.parseSingleColorForGradient(prop['chart.segment.highlight.stroke']);prop['chart.segment.highlight.fill']=this.parseSingleColorForGradient(prop['chart.segment.highlight.fill']);};this.reset=function()
70
- {};this.parseSingleColorForGradient=function(color)
71
- {if(!color||typeof color!='string'){return color;}
72
- if(color.match(/^gradient\((.*)\)$/i)){if(color.match(/^gradient\(({.*})\)$/i)){return RGraph.parseJSONGradient({object:this,def:RegExp.$1});}
73
- var parts=RegExp.$1.split(':');var grad=co.createRadialGradient(this.centerx,this.centery,0,this.centerx,this.centery,this.radius);var diff=1/(parts.length-1);grad.addColorStop(0,RG.trim(parts[0]));for(var j=1;j<parts.length;++j){grad.addColorStop(j*diff,RG.trim(parts[j]));}}
74
- return grad?grad:color;};this.interactiveKeyHighlight=function(index)
75
- {if(this.coords2&&this.coords2[index]&&this.coords2[index].length){this.coords2[index].forEach(function(value,idx,arr)
76
- {co.beginPath();co.fillStyle=prop['chart.key.interactive.highlight.chart.fill'];co.arc(value[0],value[1],prop['chart.tickmarks.size']+2,0,RG.TWOPI,false);co.fill();});}};this.on=function(type,func)
77
- {if(type.substr(0,2)!=='on'){type='on'+type;}
78
- if(typeof this[type]!=='function'){this[type]=func;}else{RG.addCustomEventListener(this,type,func);}
79
- return this;};this.resetColorsToOriginalValues=function()
80
- {for(var i=0,len=this.original_colors['data'].length;i<len;++i){for(var j=0,len2=this.original_colors['data'][i].length;j<len2;++j){this.data[i][j][2]=RG.array_clone(this.original_colors['data'][i][j][2]);}}};this.firstDrawFunc=function()
81
- {};RG.register(this);if(parseConfObjectForOptions){RG.parseObjectStyleConfig(this,conf.options);}};
12
+ RGraph = window.RGraph || {isrgraph:true,isRGraph:true,rgraph:true};
13
+
14
+ //
15
+ // The chart constuctor
16
+ //
17
+ RGraph.RScatter = function (conf)
18
+ {
19
+ // Store the data set(s)
20
+ this.data = RGraph.arrayClone(conf.data);
21
+
22
+
23
+ // Account for just one dataset being given
24
+ if (typeof conf.data === 'object' && typeof conf.data[0] === 'object' && (typeof conf.data[0][0] === 'number' || typeof conf.data[0][0] === 'string') ) {
25
+
26
+ var tmp = RGraph.arrayClone(conf.data);
27
+
28
+ conf.data = new Array();
29
+ conf.data[0] = RGraph.arrayClone(tmp);
30
+
31
+ this.data = RGraph.arrayClone(conf.data);
32
+ }
33
+
34
+
35
+
36
+
37
+
38
+
39
+ this.id = conf.id
40
+ this.canvas = document.getElementById(this.id)
41
+ this.context = this.canvas.getContext ? this.canvas.getContext("2d") : null;
42
+ this.canvas.__object__ = this;
43
+ this.type = 'rscatter';
44
+ this.hasTooltips = false;
45
+ this.isRGraph = true;
46
+ this.isrgraph = true;
47
+ this.rgraph = true;
48
+ this.uid = RGraph.createUID();
49
+ this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.createUID();
50
+ this.colorsParsed = false;
51
+ this.coordsText = [];
52
+ this.original_colors = [];
53
+ this.firstDraw = true; // After the first draw this will be false
54
+
55
+
56
+
57
+
58
+
59
+
60
+ this.centerx = 0;
61
+ this.centery = 0;
62
+ this.radius = 0;
63
+ this.max = 0;
64
+
65
+ // Convert all of the data pieces to numbers as necessary
66
+ for (var i=0; i<this.data.length; ++i) { // For each dataset
67
+ for (var j=0; j<this.data[i].length; ++j) { // Gor each datapiece
68
+ if (typeof this.data[i][j][0] === 'string') { // Check the first value (the X value)
69
+ this.data[i][j][0] = parseFloat(this.data[i][j][0]);
70
+ }
71
+
72
+ if (typeof this.data[i][j][1] === 'string') { // Check the second value (the Y value)
73
+ this.data[i][j][1] = parseFloat(this.data[i][j][1]);
74
+ }
75
+ }
76
+ }
77
+
78
+
79
+
80
+
81
+
82
+
83
+
84
+
85
+
86
+
87
+
88
+ this.properties =
89
+ {
90
+ backgroundColor: 'transparent',
91
+ backgroundGrid: true,
92
+ backgroundGridRadials: true,
93
+ backgroundGridRadialsCount: null,
94
+ backgroundGridCircles: true,
95
+ backgroundGridCirclesCount: null,
96
+ backgroundGridLinewidth: 1,
97
+ backgroundGridColor: '#ccc',
98
+
99
+ centerx: null,
100
+ centery: null,
101
+ radius: null,
102
+
103
+ colors: [], // This is used internally for the key
104
+ colorsDefault: 'black',
105
+
106
+ marginLeft: 35,
107
+ marginRight: 35,
108
+ marginTop: 35,
109
+ marginBottom: 35,
110
+
111
+ title: '',
112
+ titleBold: null,
113
+ titleFont: null,
114
+ titleSize: null,
115
+ titleItalic: null,
116
+ titleColor: null,
117
+ titleX: null,
118
+ titleY: null,
119
+ titleHalign: null,
120
+ titleValign: null,
121
+ titleOffsetx: 0,
122
+ titleOffsety: 0,
123
+ titleSubtitle: '',
124
+ titleSubtitleSize: null,
125
+ titleSubtitleColor: '#aaa',
126
+ titleSubtitleFont: null,
127
+ titleSubtitleBold: null,
128
+ titleSubtitleItalic: null,
129
+ titleSubtitleOffsetx: 0,
130
+ titleSubtitleOffsety: 0,
131
+
132
+ labels: null,
133
+ labelsOffsetRadius: 0,
134
+ labelsFormattedDecimals: 0,
135
+ labelsFormattedPoint: '.',
136
+ labelsFormattedThousand: ',',
137
+ labelsFormattedUnitsPre: '',
138
+ labelsFormattedUnitsPost: '',
139
+ labelsColor: null,
140
+ labelsFont: null,
141
+ labelsSize: null,
142
+ labelsItalic: null,
143
+ labelsBold: null,
144
+ labelsAxes: 'n',
145
+ labelsAxesBackground: 'rgba(255,255,255,0.7)',
146
+ labelsAxesCount: 5,
147
+ labelsAxesFont: null,
148
+ labelsAxesSize: null,
149
+ labelsAxesColor: null,
150
+ labelsAxesBold: null,
151
+ labelsAxesItalic: null,
152
+ labelsAxesOffsetx: 0,
153
+ labelsAxesOffsety: 0,
154
+
155
+ textColor: 'black',
156
+ textFont: 'Arial, Verdana, sans-serif',
157
+ textSize: 12,
158
+ textBold: false,
159
+ textItalic: false,
160
+ textAccessible: false,
161
+ textAccessibleOverflow: 'visible',
162
+ textAccessiblePointerevents: false,
163
+ text: null,
164
+
165
+ key: null,
166
+ keyBackground: 'white',
167
+ keyPosition: 'graph',
168
+ keyHalign: 'right',
169
+ keyShadow: false,
170
+ keyShadowColor: '#666',
171
+ keyShadowBlur: 3,
172
+ keyShadowOffsetx: 2,
173
+ keyShadowOffsety: 2,
174
+ keyPositionGutterBoxed: false,
175
+ keyPositionX: null,
176
+ keyPositionY: null,
177
+ keyColorShape: 'square',
178
+ keyRounded: true,
179
+ keyLinewidth: 1,
180
+ keyColors: null,
181
+ keyInteractive: false,
182
+ keyInteractiveHighlightChartFill: 'rgba(255,0,0,0.9)',
183
+ keyInteractiveHighlightLabel: 'rgba(255,0,0,0.2)',
184
+ keyLabelsColor: null,
185
+ keyLabelsFont: null,
186
+ keyLabelsSize: null,
187
+ keyLabelsBold: null,
188
+ keyLabelsItalic: null,
189
+ keyLabelsOffsetx: 0,
190
+ keyLabelsOffsety: 0,
191
+ keyFormattedDecimals: 0,
192
+ keyFormattedPoint: '.',
193
+ keyFormattedThousand: ',',
194
+ keyFormattedUnitsPre: '',
195
+ keyFormattedUnitsPost: '',
196
+ keyFormattedValueSpecific: null,
197
+ keyFormattedItemsCount: null,
198
+
199
+ contextmenu: null,
200
+
201
+ tooltips: null,
202
+ tooltipsEvent: 'onmousemove',
203
+ tooltipsEffect: 'slide',
204
+ tooltipsCssClass: 'RGraph_tooltip',
205
+ tooltipsCss: null,
206
+ tooltipsHighlight: true,
207
+ tooltipsHotspot: 3,
208
+ tooltipsHotspotIgnore: null,
209
+ tooltipsCoordsPage: false,
210
+ tooltipsFormattedThousand: ',',
211
+ tooltipsFormattedPoint: '.',
212
+ tooltipsFormattedDecimals: 0,
213
+ tooltipsFormattedUnitsPre: '',
214
+ tooltipsFormattedUnitsPost: '',
215
+ tooltipsFormattedKeyColors: null,
216
+ tooltipsFormattedKeyColorsShape: 'square',
217
+ tooltipsFormattedKeyLabels: [],
218
+ tooltipsFormattedListType: 'ul',
219
+ tooltipsFormattedListItems: null,
220
+ tooltipsFormattedTableHeaders: null,
221
+ tooltipsFormattedTableData: null,
222
+ tooltipsPointer: true,
223
+ tooltipsPointerOffsetx: 0,
224
+ tooltipsPointerOffsety: 0,
225
+ tooltipsPositionStatic: true,
226
+
227
+ annotatable: false,
228
+ annotatableColor: 'black',
229
+ annotatableLinewidth: 1,
230
+
231
+ resizable: false,
232
+ resizableHandleBackground: null,
233
+
234
+ scaleMax: null,
235
+ scaleMin: 0, // TODO Not fully implemented
236
+ scaleDecimals: null,
237
+ scalePoint: '.',
238
+ scaleThousand: ',',
239
+ scaleRound: false,
240
+ scaleZerostart: true,
241
+ scaleUnitsPre: '',
242
+ scaleUnitsPost: '',
243
+
244
+ tickmarks : 'cross', // This is done like this for BC
245
+ tickmarksStyle: null, // This is done like this for BC ** Use this one **
246
+ tickmarksSize: 3,
247
+
248
+ axesColor: 'transparent',
249
+
250
+ highlightStroke: 'transparent',
251
+ highlightFill: 'rgba(255,255,255,0.7)',
252
+ highlightSize: null,
253
+ highlightStyle: null,
254
+
255
+ segmentHighlight: false,
256
+ segmentHighlightCount: null,
257
+ segmentHighlightFill: 'rgba(0,255,0,0.5)',
258
+ segmentHighlightStroke: 'rgba(0,0,0,0)',
259
+
260
+ line: false,
261
+ lineClose: false,
262
+ lineLinewidth: 1,
263
+ lineColors: ['black'],
264
+ lineShadow: false,
265
+ lineShadowColor: 'black',
266
+ lineShadowBlur: 2,
267
+ lineShadowOffsetx: 3,
268
+ lineShadowOffsety: 3,
269
+
270
+ clearto: 'rgba(0,0,0,0)'
271
+ }
272
+
273
+
274
+
275
+
276
+ //
277
+ // Create the $ objects so that functions can be added to them
278
+ //
279
+ for (var i=0,idx=0; i<this.data.length; ++i) {
280
+ for (var j=0,len=this.data[i].length; j<len; j+=1,idx+=1) {
281
+ this['$' + idx] = {}
282
+ }
283
+ }
284
+
285
+
286
+
287
+ // Easy access to properties and the path function
288
+ var properties = this.properties;
289
+ this.path = RGraph.pathObjectFunction;
290
+
291
+
292
+
293
+ //
294
+ // "Decorate" the object with the generic effects if the effects library has been included
295
+ //
296
+ if (RGraph.Effects && typeof RGraph.Effects.decorate === 'function') {
297
+ RGraph.Effects.decorate(this);
298
+ }
299
+
300
+
301
+
302
+ // Add the responsive method. This method resides in the common file.
303
+ this.responsive = RGraph.responsive;
304
+
305
+
306
+
307
+
308
+
309
+
310
+
311
+
312
+ //
313
+ // A simple setter
314
+ //
315
+ // @param string name The name of the property to set
316
+ // @param string value The value of the property
317
+ //
318
+ this.set = function (name)
319
+ {
320
+ var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
321
+
322
+ // the number of arguments is only one and it's an
323
+ // object - parse it for configuration data and return.
324
+ if (arguments.length === 1 && typeof arguments[0] === 'object') {
325
+ for (i in arguments[0]) {
326
+ if (typeof i === 'string') {
327
+ this.set(i, arguments[0][i]);
328
+ }
329
+ }
330
+
331
+ return this;
332
+ }
333
+
334
+ properties[name] = value;
335
+
336
+ // If a single tooltip has been given add it to each datapiece
337
+ if (name === 'tooltips' && typeof value === 'string') {
338
+ this.populateTooltips();
339
+ }
340
+
341
+ return this;
342
+ };
343
+
344
+
345
+
346
+
347
+
348
+
349
+
350
+
351
+ //
352
+ // A simple getter
353
+ //
354
+ // @param string name The name of the property to get
355
+ //
356
+ this.get = function (name)
357
+ {
358
+ return properties[name];
359
+ };
360
+
361
+
362
+
363
+
364
+
365
+
366
+
367
+
368
+ //
369
+ // This method draws the rose chart
370
+ //
371
+ this.draw = function ()
372
+ {
373
+ //
374
+ // Fire the onbeforedraw event
375
+ //
376
+ RGraph.fireCustomEvent(this, 'onbeforedraw');
377
+
378
+
379
+
380
+ // Translate half a pixel for antialiasing purposes - but only if it hasn't been
381
+ // done already
382
+ //
383
+ // MUST be the first thing done!
384
+ //
385
+ if (!this.canvas.__rgraph_aa_translated__) {
386
+ this.context.translate(0.5,0.5);
387
+
388
+ this.canvas.__rgraph_aa_translated__ = true;
389
+ }
390
+
391
+
392
+
393
+
394
+
395
+
396
+ //
397
+ // Populate the labels string/array if its a string
398
+ //
399
+ if (properties.labels && properties.labels.length) {
400
+ //
401
+ // If the labels option is a string then turn it
402
+ // into an array.
403
+ //
404
+
405
+ if (typeof properties.labels === 'string') {
406
+ properties.labels = RGraph.arrayPad({
407
+ array: [],
408
+ length: properties.labelsCount,
409
+ value: properties.labels
410
+ });
411
+ }
412
+
413
+ for (var i=0; i<properties.labels.length; ++i) {
414
+
415
+ properties.labels[i] = RGraph.labelSubstitution({
416
+ object: this,
417
+ text: properties.labels[i],
418
+ index: i,
419
+ value: this.data[0][i],
420
+ decimals: properties.labelsFormattedDecimals || 0,
421
+ unitsPre: properties.labelsFormattedUnitsPre || '',
422
+ unitsPost: properties.labelsFormattedUnitsPost || '',
423
+ thousand: properties.labelsFormattedThousand || ',',
424
+ point: properties.labelsFormattedPoint || '.'
425
+ });
426
+ }
427
+ }
428
+
429
+
430
+
431
+
432
+
433
+ //
434
+ // Make the margins easy ro access
435
+ //
436
+ this.marginLeft = properties.marginLeft;
437
+ this.marginRight = properties.marginRight;
438
+ this.marginTop = properties.marginTop;
439
+ this.marginBottom = properties.marginBottom;
440
+
441
+ // Calculate the radius
442
+ this.radius = (Math.min(this.canvas.width - this.marginLeft - this.marginRight, this.canvas.height - this.marginTop - this.marginBottom) / 2);
443
+ this.centerx = ((this.canvas.width - this.marginLeft - this.marginRight) / 2) + this.marginLeft;
444
+ this.centery = ((this.canvas.height - this.marginTop - this.marginBottom) / 2) + this.marginTop;
445
+ this.coords = [];
446
+ this.coords2 = [];
447
+
448
+
449
+
450
+ //
451
+ // Stop this growing uncontrollably
452
+ //
453
+ this.coordsText = [];
454
+
455
+
456
+
457
+
458
+ //
459
+ // If there's a user specified radius/centerx/centery, use them
460
+ //
461
+ if (typeof properties.centerx == 'number') this.centerx = properties.centerx;
462
+ if (typeof properties.centery == 'number') this.centery = properties.centery;
463
+ if (typeof properties.radius == 'number') this.radius = properties.radius;
464
+
465
+
466
+
467
+ //
468
+ // Parse the colors for gradients. Its down here so that the center X/Y can be used
469
+ //
470
+ if (!this.colorsParsed) {
471
+
472
+ this.parseColors();
473
+
474
+ // Don't want to do this again
475
+ this.colorsParsed = true;
476
+ }
477
+
478
+
479
+ //
480
+ // Work out the scale
481
+ //
482
+ var max = properties.scaleMax;
483
+ var min = properties.scaleMin;
484
+
485
+ if (typeof max == 'number') {
486
+ this.max = max;
487
+ this.scale2 = RGraph.getScale({object: this, options: {
488
+ 'scale.max': max,
489
+ 'scale.min': min,
490
+ 'scale.strict': true,
491
+ 'scale.decimals': Number(properties.scaleDecimals),
492
+ 'scale.point': properties.scalePoint,
493
+ 'scale.thousand': properties.scaleThousand,
494
+ 'scale.round': properties.scaleRound,
495
+ 'scale.units.pre': properties.scaleUnitsPre,
496
+ 'scale.units.post': properties.scaleUnitsPost,
497
+ 'scale.labels.count': properties.labelsAxesCount
498
+ }});
499
+ } else {
500
+
501
+ for (var i=0; i<this.data.length; i+=1) {
502
+ for (var j=0,len=this.data[i].length; j<len; j+=1) {
503
+ this.max = Math.max(this.max, this.data[i][j][1]);
504
+ }
505
+ }
506
+
507
+ this.min = 0;
508
+
509
+ this.scale2 = RGraph.getScale({object: this, options: {
510
+ 'scale.max': this.max,
511
+ 'scale.min': 0,
512
+ 'scale.decimals': Number(properties.scaleDecimals),
513
+ 'scale.point': properties.scalePoint,
514
+ 'scale.thousand': properties.scaleThousand,
515
+ 'scale.round': properties.scaleRound,
516
+ 'scale.units.pre': properties.scaleUnitsPre,
517
+ 'scale.units.post': properties.scaleUnitsPost,
518
+ 'scale.labels.count': properties.labelsAxesCount
519
+ }});
520
+ this.max = this.scale2.max;
521
+ }
522
+
523
+ //
524
+ // Change the centerx marginally if the key is defined
525
+ //
526
+ if (properties.key && properties.key.length > 0 && properties.key.length >= 3) {
527
+ this.centerx = this.centerx - properties.marginRight + 5;
528
+ }
529
+
530
+ //
531
+ // Populate the colors array for the purposes of generating the key
532
+ //
533
+ if (typeof properties.key === 'object' && RGraph.isArray(properties.key) && properties.key[0]) {
534
+
535
+ // Reset the colors array
536
+ properties.colors = [];
537
+
538
+ for (var i=0; i<this.data.length; i+=1) {
539
+ for (var j=0,len=this.data[i].length; j<len; j+=1) {
540
+ if (typeof this.data[i][j][2] == 'string') {
541
+ properties.colors.push(this.data[i][j][2]);
542
+ }
543
+ }
544
+ }
545
+ }
546
+
547
+
548
+
549
+
550
+ //
551
+ // Populate the tooltips array
552
+ //
553
+ this.set('tooltips', []);
554
+
555
+ for (var i=0; i<this.data.length; i+=1) {
556
+ for (var j=0,len=this.data[i].length; j<len; j+=1) {
557
+ properties.tooltips.push(this.data[i][j][3]);
558
+ }
559
+ }
560
+
561
+
562
+
563
+ // This resets the chart drawing state
564
+ this.context.beginPath();
565
+
566
+ this.drawBackground();
567
+ this.drawRscatter();
568
+ this.drawLabels();
569
+
570
+
571
+ //
572
+ // Draw the key
573
+ //
574
+ var key = properties.key;
575
+
576
+ if (key && key.length) {
577
+ RGraph.drawKey(this, properties.key, properties.colors);
578
+ }
579
+
580
+
581
+
582
+
583
+ //
584
+ // Setup the context menu if required
585
+ //
586
+ if (properties.contextmenu) {
587
+ RGraph.showContext(this);
588
+ }
589
+
590
+
591
+
592
+ // Draw the title if any has been set
593
+ if (properties.title) {
594
+ RGraph.drawTitle(this);
595
+ }
596
+
597
+
598
+
599
+
600
+ //
601
+ // Add custom text thats specified
602
+ //
603
+ RGraph.addCustomText(this);
604
+
605
+
606
+
607
+
608
+
609
+
610
+
611
+
612
+ //
613
+ // This installs the event listeners
614
+ //
615
+ RGraph.installEventListeners(this);
616
+
617
+
618
+
619
+
620
+
621
+
622
+ //
623
+ // Allow the segments to be highlighted
624
+ //
625
+ if (properties.segmentHighlight) {
626
+ RGraph.allowSegmentHighlight({
627
+ object: this,
628
+
629
+ // This is duplicated in the drawBackground function
630
+ count: typeof properties.segmentHighlightCount === 'number' ? properties.segmentHighlightCount : ((properties.backgroundGridDiagonalsCount ? properties.backgroundGridDiagonalsCount : (properties.labels ? properties.labels.length : 8))),
631
+
632
+ fill: properties.segmentHighlightFill,
633
+ stroke: properties.segmentHighlightStroke
634
+ });
635
+ }
636
+
637
+
638
+
639
+
640
+ //
641
+ // Fire the onfirstdraw event
642
+ //
643
+ if (this.firstDraw) {
644
+ this.firstDraw = false;
645
+ RGraph.fireCustomEvent(this, 'onfirstdraw');
646
+ this.firstDrawFunc();
647
+ }
648
+
649
+
650
+
651
+
652
+ //
653
+ // Fire the RGraph draw event
654
+ //
655
+ RGraph.fireCustomEvent(this, 'ondraw');
656
+
657
+
658
+
659
+
660
+
661
+
662
+
663
+
664
+
665
+ //
666
+ // Install any inline responsive configuration. This
667
+ // should be last in the draw function - even after
668
+ // the draw events.
669
+ //
670
+ RGraph.installInlineResponsive(this);
671
+
672
+
673
+
674
+
675
+
676
+
677
+
678
+
679
+
680
+
681
+
682
+
683
+
684
+
685
+ return this;
686
+ };
687
+
688
+
689
+
690
+
691
+
692
+
693
+
694
+
695
+ //
696
+ // Used in chaining. Runs a function there and then - not waiting for
697
+ // the events to fire (eg the onbeforedraw event)
698
+ //
699
+ // @param function func The function to execute
700
+ //
701
+ this.exec = function (func)
702
+ {
703
+ func(this);
704
+
705
+ return this;
706
+ };
707
+
708
+
709
+
710
+
711
+
712
+
713
+
714
+
715
+ //
716
+ // This method draws the rscatter charts background
717
+ //
718
+ this.drawBackground = function ()
719
+ {
720
+ // Draw the background color first
721
+ if (properties.backgroundColor != 'transparent') {
722
+ this.path(
723
+ 'b a % % % % % false f %',
724
+ this.centerx, this.centery, this.radius, 0, 2 * Math.PI,
725
+ properties.backgroundColor
726
+ );
727
+ }
728
+
729
+
730
+ var gridEnabled = properties.backgroundGrid;
731
+
732
+
733
+ if (gridEnabled) {
734
+
735
+ this.context.lineWidth = properties.backgroundGridLinewidth;
736
+
737
+
738
+ // Draw the background grey circles
739
+ if (properties.backgroundGridCircles) {
740
+
741
+ this.context.strokeStyle = properties.backgroundGridColor;
742
+ this.context.beginPath();
743
+
744
+ if (RGraph.isNull(properties.backgroundGridCirclesCount)) {
745
+ properties.backgroundGridCirclesCount = properties.labelsAxesCount;
746
+ }
747
+
748
+ // Radius must be greater than 0 for Opera to work
749
+
750
+ var r = this.radius / properties.backgroundGridCirclesCount;
751
+
752
+ for (var i=0,len=this.radius; i<=len; i+=r) {
753
+
754
+ // Radius must be greater than 0 for Opera to work
755
+ this.context.moveTo(this.centerx + i, this.centery);
756
+ this.context.arc(
757
+ this.centerx,
758
+ this.centery,
759
+ i,
760
+ 0,
761
+ RGraph.TWOPI,
762
+ 0
763
+ );
764
+ }
765
+ this.context.stroke();
766
+ }
767
+
768
+
769
+
770
+
771
+
772
+
773
+
774
+ // Draw the background lines that go from the center outwards
775
+ if (properties.backgroundGridRadials) {
776
+
777
+ this.context.strokeStyle = properties.backgroundGridColor;
778
+
779
+ this.context.beginPath();
780
+
781
+ // This is duplicated in the allowSegmentHighlight call
782
+ if (typeof properties.backgroundGridRadialsCount === 'number') {
783
+ var inc = 360 / properties.backgroundGridRadialsCount;
784
+ } else if (properties.labels && properties.labels.length) {
785
+ var inc = 360 / properties.labels.length;
786
+ } else {
787
+ var inc = 45; //360 / 8
788
+ }
789
+
790
+
791
+ for (var i=0; i<360; i+=inc) {
792
+
793
+ // Radius must be greater than 0 for Opera to work
794
+ this.context.arc(
795
+ this.centerx,
796
+ this.centery,
797
+ this.radius,
798
+ (i / (180 / RGraph.PI)) - RGraph.HALFPI,
799
+ ((i + 0.01) / (180 / RGraph.PI)) - RGraph.HALFPI,
800
+ 0
801
+ );
802
+
803
+ this.context.lineTo(this.centerx, this.centery);
804
+ }
805
+ this.context.stroke();
806
+ }
807
+ }
808
+
809
+ // Reset the linewidth
810
+ this.context.lineWidth = 1;
811
+
812
+
813
+
814
+
815
+
816
+
817
+
818
+
819
+
820
+
821
+
822
+
823
+
824
+ this.context.beginPath();
825
+ this.context.strokeStyle = properties.axesColor;
826
+
827
+ // Draw the X axis
828
+ this.context.moveTo(this.centerx - this.radius, Math.round(this.centery));
829
+ this.context.lineTo(this.centerx + this.radius, Math.round(this.centery));
830
+
831
+ // Draw the X ends
832
+ this.context.moveTo(Math.round(this.centerx - this.radius), this.centery - 5);
833
+ this.context.lineTo(Math.round(this.centerx - this.radius), this.centery + 5);
834
+ this.context.moveTo(Math.round(this.centerx + this.radius), this.centery - 5);
835
+ this.context.lineTo(Math.round(this.centerx + this.radius), this.centery + 5);
836
+
837
+
838
+ var numticks = properties.labelsAxesCount;
839
+
840
+ if (numticks) {
841
+ // Draw the X check marks
842
+ for (var i=(this.centerx - this.radius); i<(this.centerx + this.radius); i+=(this.radius / numticks)) {
843
+ this.context.moveTo(Math.round(i), this.centery - 3);
844
+ this.context.lineTo(Math.round(i), this.centery + 3);
845
+ }
846
+
847
+ // Draw the Y check marks
848
+ for (var i=(this.centery - this.radius); i<(this.centery + this.radius); i+=(this.radius / numticks)) {
849
+ this.context.moveTo(this.centerx - 3, Math.round(i));
850
+ this.context.lineTo(this.centerx + 3, Math.round(i));
851
+ }
852
+ }
853
+
854
+ // Draw the Y axis
855
+ this.context.moveTo(Math.round(this.centerx), this.centery - this.radius);
856
+ this.context.lineTo(Math.round(this.centerx), this.centery + this.radius);
857
+
858
+ // Draw the Y ends
859
+ if (properties.axesCaps) {
860
+ this.context.moveTo(this.centerx - 5, Math.round(this.centery - this.radius));
861
+ this.context.lineTo(this.centerx + 5, Math.round(this.centery - this.radius));
862
+
863
+ this.context.moveTo(this.centerx - 5, Math.round(this.centery + this.radius));
864
+ this.context.lineTo(this.centerx + 5, Math.round(this.centery + this.radius));
865
+ }
866
+
867
+ // Stroke it
868
+ this.context.closePath();
869
+ this.context.stroke();
870
+ };
871
+
872
+
873
+
874
+
875
+
876
+
877
+
878
+
879
+ //
880
+ // This method draws a set of data on the graph
881
+ //
882
+ this.drawRscatter = function ()
883
+ {
884
+ for (var dataset=0; dataset<this.data.length; dataset+=1) {
885
+
886
+ var data = this.data[dataset];
887
+
888
+ // Don't do this
889
+ // this.coords = [];
890
+
891
+ this.coords2[dataset] = [];
892
+
893
+ var drawPoints = function (obj)
894
+ {
895
+ for (var i=0; i<data.length; ++i) {
896
+
897
+ var d1 = data[i][0],
898
+ d2 = data[i][1],
899
+ a = d1 / (180 / RGraph.PI), // RADIANS
900
+ r = ( (d2 - properties.scaleMin) / (obj.scale2.max - obj.scale2.min) ) * obj.radius,
901
+ x = Math.sin(a) * r,
902
+ y = Math.cos(a) * r,
903
+ color = data[i][2] ? data[i][2] : properties.colorsDefault,
904
+ tooltip = data[i][3] ? data[i][3] : null
905
+
906
+ if (tooltip && String(tooltip).length) {
907
+ obj.hasTooltips = true;
908
+ }
909
+
910
+ //
911
+ // Account for the correct quadrant
912
+ //
913
+ x = x + obj.centerx;
914
+ y = obj.centery - y;
915
+
916
+
917
+ obj.drawTick(x, y, color);
918
+
919
+ // Populate the coords array with the coordinates and the tooltip
920
+
921
+ obj.coords.push([x, y, color, tooltip]);
922
+ obj.coords2[dataset].push([x, y, color, tooltip]);
923
+ }
924
+ }
925
+
926
+ drawPoints(this);
927
+
928
+ if (properties.line) {
929
+ this.drawLine(dataset);
930
+ }
931
+ }
932
+ };
933
+
934
+
935
+
936
+
937
+
938
+
939
+
940
+
941
+ //
942
+ // Draws a connecting line through the points if requested
943
+ //
944
+ // @param object opt The options to the line
945
+ //
946
+ this.drawLine = function (idx)
947
+ {
948
+ var opt = {
949
+ dataset: idx,
950
+ coords: this.coords2[idx],
951
+ color: properties.lineColors[idx],
952
+ shadow: properties.lineShadow,
953
+ shadowColor: properties.lineShadowColor,
954
+ shadowOffsetX: properties.lineShadowOffsetx,
955
+ shadowOffsetY: properties.lineShadowOffsety,
956
+ shadowBlur: properties.lineShadowBlur,
957
+ linewidth: properties.lineLinewidth
958
+ };
959
+
960
+ this.context.beginPath();
961
+
962
+ this.context.strokeStyle = this.parseSingleColorForGradient(opt.color);
963
+ this.context.lineWidth = typeof properties.lineLinewidth === 'object' ? properties.lineLinewidth[idx] : properties.lineLinewidth;
964
+ this.context.lineCap = 'round';
965
+
966
+ if (opt.shadow) {
967
+ RGraph.setShadow(
968
+ this,
969
+ opt.shadowColor,
970
+ opt.shadowOffsetX,
971
+ opt.shadowOffsetY,
972
+ opt.shadowBlur
973
+ );
974
+ }
975
+
976
+ for (var i=0; i<this.coords2[idx].length; ++i) {
977
+ if (i === 0) {
978
+ this.context.moveTo(this.coords2[idx][i][0], this.coords2[idx][i][1]);
979
+
980
+ var startCoords = RGraph.arrayClone(this.coords2[idx]);
981
+
982
+ } else {
983
+ this.context.lineTo(this.coords2[idx][i][0], this.coords2[idx][i][1]);
984
+ }
985
+ }
986
+
987
+ // Draw the line back to the start?
988
+ if (
989
+ (typeof properties.lineClose === 'boolean' && properties.lineClose)
990
+ || (typeof properties.lineClose === 'object' && properties.lineClose[idx])
991
+ ) {
992
+ this.context.lineTo(this.coords2[idx][0][0], this.coords2[idx][0][1]);
993
+ }
994
+
995
+ this.context.stroke();
996
+
997
+ RGraph.noShadow(this);
998
+ };
999
+
1000
+
1001
+
1002
+
1003
+
1004
+
1005
+
1006
+
1007
+ //
1008
+ // Unsuprisingly, draws the labels
1009
+ //
1010
+ this.drawLabels = function ()
1011
+ {
1012
+ this.context.lineWidth = 1;
1013
+
1014
+ // Default the color to black
1015
+ this.context.fillStyle = 'black';
1016
+ this.context.strokeStyle = 'black';
1017
+
1018
+ var key = properties.key;
1019
+ var r = this.radius;
1020
+ var axesColor = properties.axesColor;
1021
+ var italic = properties.textItalic;
1022
+ var bold = properties.textBold;
1023
+ var color = properties.textColor;
1024
+ var font = properties.textFont;
1025
+ var size = properties.textSize;
1026
+ var axes = properties.labelsAxes.toLowerCase();
1027
+ var units_pre = properties.scaleUnitsPre;
1028
+ var units_post = properties.scaleUnitsPost;
1029
+ var decimals = properties.scaleDecimals;
1030
+ var centerx = this.centerx;
1031
+ var centery = this.centery;
1032
+
1033
+ this.context.fillStyle = properties.textColor;
1034
+
1035
+ // Draw any labels
1036
+ if (typeof properties.labels == 'object' && properties.labels) {
1037
+ this.drawCircularLabels(this.context, properties.labels, font , size, r);
1038
+ }
1039
+
1040
+
1041
+ //
1042
+ // If the axes are transparent - then the labels should have no offset,
1043
+ // otherwise it defaults to true. Similarly the labels can or can't be
1044
+ // centered if there's no axes
1045
+ //
1046
+ var offset = 10;
1047
+ var centered = false;
1048
+
1049
+ if ( axesColor === 'rgba(0,0,0,0)'
1050
+ || axesColor === 'rgb(0,0,0)'
1051
+ || axesColor === 'transparent') {
1052
+
1053
+ offset = 0;
1054
+ centered = true;
1055
+ }
1056
+
1057
+
1058
+ var textConf = RGraph.getTextConf({
1059
+ object: this,
1060
+ prefix: 'labelsAxes'
1061
+ });
1062
+
1063
+
1064
+ // Draw the axis labels
1065
+ for (var i=0,len=this.scale2.labels.length; i<len; ++i) {
1066
+ if (axes.indexOf('n') > -1) RGraph.text({object: this,tag: 'scale',font: textConf.font,size: textConf.size,color: textConf.color,bold: textConf.bold,italic: textConf.italic,x:centerx - offset + properties.labelsAxesOffsetx,y:centery - (r * ((i+1) / len)) + properties.labelsAxesOffsety,text:this.scale2.labels[i],valign:'center',halign:centered ? 'center' : 'right',bounding: true, boundingFill: properties.labelsAxesBackground, boundingStroke: 'rgba(0,0,0,0)'});
1067
+ if (axes.indexOf('s') > -1) RGraph.text({object: this,tag: 'scale',font: textConf.font,size: textConf.size,color: textConf.color,bold: textConf.bold,italic: textConf.italic,x:centerx - offset + properties.labelsAxesOffsetx,y:centery + (r * ((i+1) / len)) + properties.labelsAxesOffsety,text:this.scale2.labels[i],valign:'center',halign:centered ? 'center' : 'right',bounding: true, boundingFill: properties.labelsAxesBackground, boundingStroke: 'rgba(0,0,0,0)'});
1068
+ if (axes.indexOf('e') > -1) RGraph.text({object: this,tag: 'scale',font: textConf.font,size: textConf.size,color: textConf.color,bold: textConf.bold,italic: textConf.italic,x:centerx + (r * ((i+1) / len)) + properties.labelsAxesOffsetx,y:centery + offset + properties.labelsAxesOffsety,text:this.scale2.labels[i],valign:centered ? 'center' : 'top',halign:'center',bounding: true, boundingFill: properties.labelsAxesBackground, boundingStroke: 'rgba(0,0,0,0)'});
1069
+ if (axes.indexOf('w') > -1) RGraph.text({object: this,tag: 'scale',font: textConf.font,size: textConf.size,color: textConf.color,bold: textConf.bold,italic: textConf.italic,x:centerx - (r * ((i+1) / len)) + properties.labelsAxesOffsetx,y:centery + offset + properties.labelsAxesOffsety,text:this.scale2.labels[i],valign:centered ? 'center' : 'top',halign:'center',bounding: true, boundingFill: properties.labelsAxesBackground, boundingStroke: 'rgba(0,0,0,0)'});
1070
+ }
1071
+
1072
+ // Draw the center minimum value (but only if there's at least one axes labels stipulated)
1073
+ if (properties.labelsAxes.length > 0 && properties.scaleZerostart) {
1074
+ RGraph.text({
1075
+
1076
+ object: this,
1077
+
1078
+ font: textConf.font,
1079
+ size: textConf.size,
1080
+ color: textConf.color,
1081
+ bold: textConf.bold,
1082
+ italic: textConf.italic,
1083
+
1084
+ x: centerx + properties.labelsAxesOffsetx,
1085
+ y: centery + properties.labelsAxesOffsety,
1086
+
1087
+ text: RGraph.numberFormat({
1088
+ object: this,
1089
+ number: Number(this.scale2.min).toFixed(this.scale2.decimals),
1090
+ unitspre: this.scale2.units_pre,
1091
+ unitspost: this.scale2.units_post
1092
+ }),
1093
+ valign: 'center',
1094
+ halign: 'center',
1095
+ bounding: true,
1096
+ boundingFill: properties.labelsAxesBackground,
1097
+ boundingStroke: 'rgba(0,0,0,0)',
1098
+ tag: 'scale'
1099
+ });
1100
+ }
1101
+ };
1102
+
1103
+
1104
+
1105
+
1106
+
1107
+
1108
+
1109
+
1110
+ //
1111
+ // Draws the circular labels that go around the charts
1112
+ //
1113
+ // @param labels array The labels that go around the chart
1114
+ //
1115
+ this.drawCircularLabels = function (context, labels, font_face, font_size, r)
1116
+ {
1117
+ var r = r + properties.labelsOffsetRadius + 25,
1118
+ color = properties.labelsColor;
1119
+
1120
+ for (var i=0; i<labels.length; ++i) {
1121
+
1122
+ var a = (360 / labels.length) * (i + 1) - (360 / (labels.length * 2));
1123
+ var a = a - 90 + (properties.labelsPosition == 'edge' ? ((360 / labels.length) / 2) : 0);
1124
+
1125
+ var x = Math.cos(a / (180/RGraph.PI) ) * r;
1126
+ var y = Math.sin(a / (180/RGraph.PI)) * r;
1127
+
1128
+ var textConf = RGraph.getTextConf({
1129
+ object: this,
1130
+ prefix: 'labels'
1131
+ });
1132
+
1133
+
1134
+ RGraph.text({
1135
+
1136
+ object: this,
1137
+
1138
+ font: textConf.font,
1139
+ size: textConf.size,
1140
+ color: textConf.color,
1141
+ bold: textConf.bold,
1142
+ italic: textConf.italic,
1143
+
1144
+ x: this.centerx + x,
1145
+ y: this.centery + y,
1146
+
1147
+ text: String(labels[i]),
1148
+
1149
+ valign: 'center',
1150
+ halign: ((this.centerx + x) > this.centerx) ? 'left' : 'right',
1151
+ tag: 'labels',
1152
+ cssClass: RGraph.getLabelsCSSClassName({
1153
+ object: this,
1154
+ name: 'labelsClass',
1155
+ index: i
1156
+ })
1157
+ });
1158
+ }
1159
+ };
1160
+
1161
+
1162
+
1163
+
1164
+
1165
+
1166
+
1167
+
1168
+ //
1169
+ // Draws a single tickmark
1170
+ //
1171
+ this.drawTick = function (x, y, color)
1172
+ {
1173
+ var tickmarks = properties.tickmarksStyle || properties.tickmarks;
1174
+ var ticksize = properties.tickmarksSize;
1175
+
1176
+ this.context.strokeStyle = color;
1177
+ this.context.fillStyle = color;
1178
+
1179
+ // Set the linewidth for the tickmark to 1
1180
+ var prevLinewidth = this.context.lineWidth;
1181
+ this.context.lineWidth = 1;
1182
+
1183
+ // Cross
1184
+ if (tickmarks == 'cross') {
1185
+
1186
+ this.context.beginPath();
1187
+ this.context.moveTo(x + ticksize, y + ticksize);
1188
+ this.context.lineTo(x - ticksize, y - ticksize);
1189
+ this.context.stroke();
1190
+
1191
+ this.context.beginPath();
1192
+ this.context.moveTo(x - ticksize, y + ticksize);
1193
+ this.context.lineTo(x + ticksize, y - ticksize);
1194
+ this.context.stroke();
1195
+
1196
+ // Circle
1197
+ } else if (tickmarks == 'circle') {
1198
+
1199
+ this.context.beginPath();
1200
+ this.context.arc(x, y, ticksize, 0, 6.2830, false);
1201
+ this.context.fill();
1202
+
1203
+ // Square
1204
+ } else if (tickmarks == 'square') {
1205
+
1206
+ this.context.beginPath();
1207
+ this.context.fillRect(x - ticksize, y - ticksize, 2 * ticksize, 2 * ticksize);
1208
+ this.context.fill();
1209
+
1210
+ // Diamond shape tickmarks
1211
+ } else if (tickmarks == 'diamond') {
1212
+
1213
+ this.context.beginPath();
1214
+ this.context.moveTo(x, y - ticksize);
1215
+ this.context.lineTo(x + ticksize, y);
1216
+ this.context.lineTo(x, y + ticksize);
1217
+ this.context.lineTo(x - ticksize, y);
1218
+ this.context.closePath();
1219
+ this.context.fill();
1220
+
1221
+ // Plus style tickmarks
1222
+ } else if (tickmarks == 'plus') {
1223
+
1224
+ this.context.lineWidth = 1;
1225
+
1226
+ this.context.beginPath();
1227
+ this.context.moveTo(x, y - ticksize);
1228
+ this.context.lineTo(x, y + ticksize);
1229
+ this.context.moveTo(x - ticksize, y);
1230
+ this.context.lineTo(x + ticksize, y);
1231
+ this.context.stroke();
1232
+ }
1233
+
1234
+
1235
+ this.context.lineWidth = prevLinewidth;
1236
+ };
1237
+
1238
+
1239
+
1240
+
1241
+
1242
+
1243
+
1244
+
1245
+ //
1246
+ // This function makes it much easier to get the (if any) point that is currently being hovered over.
1247
+ //
1248
+ // @param object e The event object
1249
+ //
1250
+ this.getShape = function (e)
1251
+ {
1252
+ var mouseXY = RGraph.getMouseXY(e);
1253
+ var mouseX = mouseXY[0];
1254
+ var mouseY = mouseXY[1];
1255
+ var overHotspot = false;
1256
+ var offset = properties.tooltipsHotspot; // This is how far the hotspot extends
1257
+
1258
+ for (var i=0,len=this.coords.length; i<len; ++i) {
1259
+
1260
+ if (RGraph.tooltipsHotspotIgnore(this, i)) {
1261
+ continue;
1262
+ }
1263
+
1264
+ var x = this.coords[i][0],
1265
+ y = this.coords[i][1],
1266
+ tooltip = this.coords[i][3];
1267
+
1268
+ if (
1269
+ mouseX < (x + offset) &&
1270
+ mouseX > (x - offset) &&
1271
+ mouseY < (y + offset) &&
1272
+ mouseY > (y - offset)
1273
+ ) {
1274
+
1275
+ if (RGraph.parseTooltipText) {
1276
+ var tooltip = RGraph.parseTooltipText(properties.tooltips, i);
1277
+ }
1278
+
1279
+ var indexes = RGraph.sequentialIndexToGrouped(i, this.data);
1280
+
1281
+ return {
1282
+ object: this,
1283
+ x: x,
1284
+ y: y,
1285
+ dataset: indexes[0],
1286
+ index: indexes[1],
1287
+ sequentialIndex: i,
1288
+ tooltip: typeof tooltip === 'string' ? tooltip : null
1289
+ };
1290
+ }
1291
+ }
1292
+ };
1293
+
1294
+
1295
+
1296
+
1297
+
1298
+
1299
+
1300
+
1301
+ //
1302
+ // This function facilitates the installation of tooltip event listeners if
1303
+ // tooltips are defined.
1304
+ //
1305
+ this.allowTooltips = function ()
1306
+ {
1307
+ // Preload any tooltip images that are used in the tooltips
1308
+ RGraph.preLoadTooltipImages(this);
1309
+
1310
+
1311
+ //
1312
+ // This installs the window mousedown event listener that lears any
1313
+ // highlight that may be visible.
1314
+ //
1315
+ RGraph.installWindowMousedownTooltipListener(this);
1316
+
1317
+
1318
+ //
1319
+ // This installs the canvas mousemove event listener. This function
1320
+ // controls the pointer shape.
1321
+ //
1322
+ RGraph.installCanvasMousemoveTooltipListener(this);
1323
+
1324
+
1325
+ //
1326
+ // This installs the canvas mouseup event listener. This is the
1327
+ // function that actually shows the appropriate tooltip (if any).
1328
+ //
1329
+ RGraph.installCanvasMouseupTooltipListener(this);
1330
+ };
1331
+
1332
+
1333
+
1334
+
1335
+
1336
+
1337
+
1338
+
1339
+ //
1340
+ // Each object type has its own Highlight() function which highlights the appropriate shape
1341
+ //
1342
+ // @param object shape The shape to highlight
1343
+ //
1344
+ this.highlight = function (shape)
1345
+ {
1346
+ if (typeof properties.highlightStyle === 'function') {
1347
+ (properties.highlightStyle)(shape);
1348
+
1349
+
1350
+
1351
+
1352
+
1353
+ } else if (properties.highlightStyle === 'invert') {
1354
+
1355
+ var radius = RGraph.isNumber(properties.highlightSize) ? properties.highlightSize : 25;
1356
+
1357
+ this.path(
1358
+ 'b a % % % -1 6.29 false',
1359
+ this.centerx, this.centery, this.radius
1360
+ );
1361
+
1362
+ this.path(
1363
+ 'a % % % 0 6.29 true c s rgba(0,0,0,0) f %',
1364
+ shape.x, shape.y, radius,
1365
+ properties.highlightFill
1366
+ );
1367
+
1368
+ // Draw a border around the circular cutout
1369
+ this.path(
1370
+ 'b a % % % 0 6.29 false s %',
1371
+ shape.x, shape.y, radius,
1372
+ properties.highlightStroke
1373
+ );
1374
+
1375
+
1376
+
1377
+
1378
+ } else {
1379
+
1380
+
1381
+
1382
+
1383
+ //
1384
+ // Draw an arc on the canvas to highlight the appropriate area
1385
+ //
1386
+ this.context.beginPath();
1387
+ this.context.strokeStyle = properties.highlightStroke;
1388
+ this.context.fillStyle = properties.highlightFill;
1389
+
1390
+ this.context.arc(
1391
+ shape.x, shape.y, RGraph.isNumber(properties.highlightSize) ? properties.highlightSize : properties.tickmarksSize,
1392
+ 0, RGraph.TWOPI, false
1393
+ );
1394
+ this.context.stroke();
1395
+ this.context.fill();
1396
+
1397
+
1398
+
1399
+
1400
+
1401
+
1402
+
1403
+
1404
+
1405
+
1406
+ }
1407
+ };
1408
+
1409
+
1410
+
1411
+
1412
+
1413
+
1414
+
1415
+
1416
+ //
1417
+ // The getObjectByXY() worker method. Don't call this call:
1418
+ //
1419
+ // RGraph.ObjectRegistry.getObjectByXY(e)
1420
+ //
1421
+ // @param object e The event object
1422
+ //
1423
+ this.getObjectByXY = function (e)
1424
+ {
1425
+ var mouseXY = RGraph.getMouseXY(e);
1426
+ var mouseX = mouseXY[0];
1427
+ var mouseY = mouseXY[1];
1428
+ var centerx = this.centerx;
1429
+ var centery = this.centery;
1430
+ var radius = this.radius;
1431
+
1432
+ if (
1433
+ mouseX > (centerx - radius)
1434
+ && mouseX < (centerx + radius)
1435
+ && mouseY > (centery - radius)
1436
+ && mouseY < (centery + radius)
1437
+ ) {
1438
+
1439
+ return this;
1440
+ }
1441
+ };
1442
+
1443
+
1444
+
1445
+
1446
+
1447
+
1448
+
1449
+
1450
+ //
1451
+ // This function returns the radius (ie the distance from the center) for a particular
1452
+ // value.
1453
+ //
1454
+ // @param number value The value you want the radius for
1455
+ //
1456
+ this.getRadius = function (value)
1457
+ {
1458
+ var max = this.max;
1459
+
1460
+ if (value < 0 || value > max) {
1461
+ return null;
1462
+ }
1463
+
1464
+ var r = (value / max) * this.radius;
1465
+
1466
+ return r;
1467
+ };
1468
+
1469
+
1470
+
1471
+
1472
+
1473
+
1474
+
1475
+
1476
+ //
1477
+ // This allows for easy specification of gradients
1478
+ //
1479
+ this.parseColors = function ()
1480
+ {
1481
+ // Save the original colors so that they can be restored when the canvas is reset
1482
+ if (this.original_colors.length === 0) {
1483
+ this.original_colors.data = RGraph.arrayClone(this.data);
1484
+ this.original_colors.highlightStroke = RGraph.arrayClone(properties.highlightStroke);
1485
+ this.original_colors.highlightFill = RGraph.arrayClone(properties.highlightFill);
1486
+ this.original_colors.colorsDefault = RGraph.arrayClone(properties.colorsDefault);
1487
+ this.original_colors.backgroundGridColor = RGraph.arrayClone(properties.backgroundGridColor);
1488
+ this.original_colors.backgroundColor = RGraph.arrayClone(properties.backgroundColor);
1489
+ this.original_colors.segmentHighlightStroke = RGraph.arrayClone(properties.segmentHighlightStroke);
1490
+ this.original_colors.segmentHighlightFill = RGraph.arrayClone(properties.segmentHighlightFill);
1491
+ }
1492
+
1493
+
1494
+
1495
+
1496
+
1497
+
1498
+ // Go through the data
1499
+ for (var i=0; i<this.data.length; i+=1) {
1500
+ for (var j=0,len=this.data[i].length; j<len; j+=1) {
1501
+ this.data[i][j][2] = this.parseSingleColorForGradient(this.data[i][j][2]);
1502
+ }
1503
+ }
1504
+
1505
+ properties.highlightStroke = this.parseSingleColorForGradient(properties.highlightStroke);
1506
+ properties.highlightFill = this.parseSingleColorForGradient(properties.highlightFill);
1507
+ properties.colorsDefault = this.parseSingleColorForGradient(properties.colorsDefault);
1508
+ properties.backgroundGridColor = this.parseSingleColorForGradient(properties.backgroundGridColor);
1509
+ properties.backgroundColor = this.parseSingleColorForGradient(properties.backgroundColor);
1510
+ properties.segmentHighlightStroke = this.parseSingleColorForGradient(properties.segmentHighlightStroke);
1511
+ properties.segmentHighlightFill = this.parseSingleColorForGradient(properties.segmentHighlightFill);
1512
+ };
1513
+
1514
+
1515
+
1516
+
1517
+
1518
+
1519
+
1520
+
1521
+ //
1522
+ // Use this function to reset the object to the post-constructor state. Eg reset colors if
1523
+ // need be etc
1524
+ //
1525
+ this.reset = function ()
1526
+ {
1527
+ };
1528
+
1529
+
1530
+
1531
+
1532
+
1533
+
1534
+
1535
+
1536
+ //
1537
+ // This parses a single color value
1538
+ //
1539
+ this.parseSingleColorForGradient = function (color)
1540
+ {
1541
+ if (!color || typeof color != 'string') {
1542
+ return color;
1543
+ }
1544
+
1545
+ if (color.match(/^gradient\((.*)\)$/i)) {
1546
+
1547
+ // Allow for JSON gradients
1548
+ if (color.match(/^gradient\(({.*})\)$/i)) {
1549
+ return RGraph.parseJSONGradient({object: this, def: RegExp.$1});
1550
+ }
1551
+
1552
+ var parts = RegExp.$1.split(':');
1553
+
1554
+ // Create the gradient
1555
+ var grad = this.context.createRadialGradient(this.centerx, this.centery, 0, this.centerx, this.centery, this.radius);
1556
+
1557
+ var diff = 1 / (parts.length - 1);
1558
+
1559
+ grad.addColorStop(0, RGraph.trim(parts[0]));
1560
+
1561
+ for (var j=1; j<parts.length; ++j) {
1562
+ grad.addColorStop(j * diff, RGraph.trim(parts[j]));
1563
+ }
1564
+ }
1565
+
1566
+ return grad ? grad : color;
1567
+ };
1568
+
1569
+
1570
+
1571
+
1572
+
1573
+
1574
+
1575
+
1576
+ //
1577
+ // This function handles highlighting an entire data-series for the interactive
1578
+ // key
1579
+ //
1580
+ // @param int index The index of the data series to be highlighted
1581
+ //
1582
+ this.interactiveKeyHighlight = function (index)
1583
+ {
1584
+ var obj = this;
1585
+
1586
+ if (this.coords2 && this.coords2[index] && this.coords2[index].length) {
1587
+ this.coords2[index].forEach(function (value, idx, arr)
1588
+ {
1589
+ obj.context.beginPath();
1590
+ obj.context.fillStyle = properties.keyInteractiveHighlightChartFill;
1591
+ obj.context.arc(value[0], value[1], properties.tickmarksSize + 2, 0, RGraph.TWOPI, false);
1592
+ obj.context.fill();
1593
+ });
1594
+ }
1595
+ };
1596
+
1597
+
1598
+
1599
+
1600
+
1601
+
1602
+
1603
+
1604
+ //
1605
+ // Using a function to add events makes it easier to facilitate method chaining
1606
+ //
1607
+ // @param string type The type of even to add
1608
+ // @param function func
1609
+ //
1610
+ this.on = function (type, func)
1611
+ {
1612
+ if (type.substr(0,2) !== 'on') {
1613
+ type = 'on' + type;
1614
+ }
1615
+
1616
+ if (typeof this[type] !== 'function') {
1617
+ this[type] = func;
1618
+ } else {
1619
+ RGraph.addCustomEventListener(this, type, func);
1620
+ }
1621
+
1622
+ return this;
1623
+ };
1624
+
1625
+
1626
+
1627
+
1628
+
1629
+
1630
+
1631
+
1632
+ //
1633
+ // This helps the Gantt reset colors when the reset function is called.
1634
+ // It handles going through the data and resetting the colors.
1635
+ //
1636
+ this.resetColorsToOriginalValues = function ()
1637
+ {
1638
+ //
1639
+ // Copy the original colors over for single-event-per-line data
1640
+ //
1641
+ for (var i=0,len=this.original_colors.data.length; i<len; ++i) {
1642
+ for (var j=0,len2=this.original_colors.data[i].length; j<len2;++j) {
1643
+ this.data[i][j][2] = RGraph.arrayClone(this.original_colors.data[i][j][2]);
1644
+ }
1645
+ }
1646
+ };
1647
+
1648
+
1649
+
1650
+
1651
+
1652
+
1653
+
1654
+
1655
+ //
1656
+ // This function runs once only
1657
+ // (put at the end of the file (before any effects))
1658
+ //
1659
+ this.firstDrawFunc = function ()
1660
+ {
1661
+ };
1662
+
1663
+
1664
+
1665
+
1666
+
1667
+
1668
+
1669
+
1670
+ //
1671
+ // The explode effect.
1672
+ //
1673
+ // @param object Options for the effect.
1674
+ // @param int A function that is called when the ffect is complete
1675
+ //
1676
+ this.explode = function ()
1677
+ {
1678
+ var obj = this,
1679
+ callback = arguments[2],
1680
+ opt = arguments[0] || {},
1681
+ frames = opt.frames || 15,
1682
+ frame = 0,
1683
+ callback = arguments[1] || function () {},
1684
+ step = 1 / frames,
1685
+ original = RGraph.clone(this.data);
1686
+
1687
+ // First draw the chart, set the yaxisScaleMax to the maximum value that's calculated
1688
+ // and then animate
1689
+ this.draw();
1690
+ this.set('scaleMax', this.scale2.max);
1691
+
1692
+
1693
+ function iterator ()
1694
+ {
1695
+ RGraph.clear(obj.canvas);
1696
+
1697
+ for (var i=0; i<obj.data.length; ++i) { // Loop through each dataset
1698
+ for (var j=0; j<obj.data[i].length; ++j) { // Loop through each point
1699
+ obj.data[i][j][1] = original[i][j][1] * step * frame;
1700
+ }
1701
+ }
1702
+
1703
+ RGraph.redrawCanvas(obj.canvas);
1704
+
1705
+ if (frame++ < frames) {
1706
+ RGraph.Effects.updateCanvas(iterator);
1707
+ } else {
1708
+ RGraph.redrawCanvas(obj.canvas);
1709
+ callback(obj);
1710
+ }
1711
+ }
1712
+
1713
+ iterator();
1714
+
1715
+ return this;
1716
+ };
1717
+
1718
+
1719
+
1720
+
1721
+
1722
+
1723
+
1724
+
1725
+ // If only one tooltip has been given populate each data-piece with it
1726
+ this.populateTooltips = function ()
1727
+ {
1728
+ for (var i=0; i<this.data.length; ++i) { // for each dataset...
1729
+ for (var j=0; j<this.data[i].length; ++j) { // For each point in the dataset
1730
+ this.data[i][j][3] = properties.tooltips;
1731
+ }
1732
+ }
1733
+ };
1734
+
1735
+
1736
+
1737
+
1738
+
1739
+
1740
+
1741
+
1742
+ //
1743
+ // A worker function that handles Bar chart specific tooltip substitutions
1744
+ //
1745
+ this.tooltipSubstitutions = function (opt)
1746
+ {
1747
+ var indexes = RGraph.sequentialIndexToGrouped(opt.index, this.data);
1748
+
1749
+ return {
1750
+ index: indexes[1],
1751
+ dataset: indexes[0],
1752
+ sequentialIndex: opt.index,
1753
+ value: this.data[indexes[0]][indexes[1]][1],
1754
+ values: [this.data[indexes[0]][indexes[1]][1]]
1755
+ };
1756
+ };
1757
+
1758
+
1759
+
1760
+
1761
+
1762
+
1763
+
1764
+
1765
+ //
1766
+ // A worker function that returns the correct color/label/value
1767
+ //
1768
+ // @param object specific The indexes that are applicable
1769
+ // @param number index The appropriate index
1770
+ //
1771
+ this.tooltipsFormattedCustom = function (specific, index)
1772
+ {
1773
+ var color = this.data[specific.dataset][specific.index][2] ? this.data[specific.dataset][specific.index][2] : properties.colorsDefault;
1774
+
1775
+ // The tooltipsFormattedKeyColors property has been specified so use that if
1776
+ // there's a relevant color
1777
+ if (!RGraph.isNull(properties.tooltipsFormattedKeyColors) && typeof properties.tooltipsFormattedKeyColors === 'object' && typeof properties.tooltipsFormattedKeyColors[specific.dataset] === 'string') {
1778
+ color = properties.tooltipsFormattedKeyColors[specific.dataset];
1779
+ }
1780
+
1781
+ // Figure out the correct label to use if one has indeed been specified
1782
+ label = (!RGraph.isNull(properties.tooltipsFormattedKeyLabels) && typeof properties.tooltipsFormattedKeyLabels === 'object' && typeof properties.tooltipsFormattedKeyLabels[specific.dataset] === 'string')
1783
+ ? properties.tooltipsFormattedKeyLabels[specific.dataset]
1784
+ : '';
1785
+
1786
+ return {
1787
+ label: label,
1788
+ color: color
1789
+ };
1790
+ };
1791
+
1792
+
1793
+
1794
+
1795
+
1796
+
1797
+
1798
+
1799
+ //
1800
+ // This allows for static tooltip positioning
1801
+ //
1802
+ this.positionTooltipStatic = function (args)
1803
+ {
1804
+ var obj = args.object,
1805
+ e = args.event,
1806
+ tooltip = args.tooltip,
1807
+ index = args.index,
1808
+ canvasXY = RGraph.getCanvasXY(obj.canvas)
1809
+ coords = this.coords[args.index];
1810
+
1811
+ // Position the tooltip in the X direction
1812
+ args.tooltip.style.left = (
1813
+ canvasXY[0] // The X coordinate of the canvas
1814
+ + coords[0] // The X coordinate of the point on the chart
1815
+ - (tooltip.offsetWidth / 2) // Subtract half of the tooltip width
1816
+ + obj.properties.tooltipsOffsetx // Add any user defined offset
1817
+ ) + 'px';
1818
+
1819
+ args.tooltip.style.top = (
1820
+ canvasXY[1] // The Y coordinate of the canvas
1821
+ + coords[1] // The Y coordinate of the bar on the chart
1822
+ - tooltip.offsetHeight // The height of the tooltip
1823
+ - 15 // An arbitrary amount
1824
+ + obj.properties.tooltipsOffsety // Add any user defined offset
1825
+ ) + 'px';
1826
+ };
1827
+
1828
+
1829
+
1830
+
1831
+
1832
+
1833
+
1834
+
1835
+ //
1836
+ // This returns the relevant value for the formatted key
1837
+ // macro %{value}. THIS VALUE SHOULD NOT BE FORMATTED.
1838
+ //
1839
+ // @param number index The index in the dataset to get
1840
+ // the value for
1841
+ //
1842
+ this.getKeyValue = function (index)
1843
+ {
1844
+ if ( RGraph.isArray(this.properties.keyFormattedValueSpecific)
1845
+ && RGraph.isNumber(this.properties.keyFormattedValueSpecific[index])) {
1846
+
1847
+ return this.properties.keyFormattedValueSpecific[index];
1848
+
1849
+
1850
+
1851
+
1852
+ } else {
1853
+ var totalA = 0;
1854
+ var totalM = 0;
1855
+
1856
+ for (let i=0; i<this.data[index].length; ++i) {
1857
+ totalA += this.data[index][i][0];
1858
+ totalM += this.data[index][i][1];
1859
+ }
1860
+
1861
+ return [totalA, totalM];
1862
+ }
1863
+ };
1864
+
1865
+
1866
+
1867
+
1868
+
1869
+
1870
+
1871
+
1872
+ //
1873
+ // Returns how many data-points there should be when a string
1874
+ // based key property has been specified. For example, this:
1875
+ //
1876
+ // key: '%{property:_labels[%{index}]} %{value_formatted}'
1877
+ //
1878
+ // ...depending on how many bits of data ther is might get
1879
+ // turned into this:
1880
+ //
1881
+ // key: [
1882
+ // '%{property:_labels[%{index}]} %{value_formatted}',
1883
+ // '%{property:_labels[%{index}]} %{value_formatted}',
1884
+ // '%{property:_labels[%{index}]} %{value_formatted}',
1885
+ // '%{property:_labels[%{index}]} %{value_formatted}',
1886
+ // '%{property:_labels[%{index}]} %{value_formatted}',
1887
+ // ]
1888
+ //
1889
+ // ... ie in that case there would be 4 data-points so the
1890
+ // template is repeated 4 times.
1891
+ //
1892
+ this.getKeyNumDatapoints = function ()
1893
+ {
1894
+ return this.data[0].length;
1895
+ };
1896
+
1897
+
1898
+
1899
+
1900
+
1901
+
1902
+
1903
+
1904
+ //
1905
+ // Register the object
1906
+ //
1907
+ RGraph.register(this);
1908
+
1909
+
1910
+
1911
+
1912
+
1913
+
1914
+
1915
+
1916
+ //
1917
+ // This is the 'end' of the constructor so if the first argument
1918
+ // contains configuration data - handle that.
1919
+ //
1920
+ RGraph.parseObjectStyleConfig(this, conf.options);
1921
+ };