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,54 +1,1004 @@
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.HTML=RGraph.HTML||{};(function(win,doc,undefined)
3
- {var RG=RGraph,ua=navigator.userAgent,ma=Math;RG.drawKey=RG.DrawKey=function(obj,key,colors)
4
- {if(!key){return;}
5
- var ca=obj.canvas,co=obj.context,prop=obj.properties,keypos=prop['chart.key.position'],textsize=prop['chart.text.size'],key_non_null=[],colors_non_null=[];co.lineWidth=1;co.beginPath();if(typeof(prop['chart.key.vpos'])=='number'){obj.set('chart.key.position.y',prop['chart.key.vpos']*obj.get('chart.margin.top'));}
6
- for(var i=0;i<key.length;++i){if(key[i]!=null){colors_non_null.push(colors[i]);key_non_null.push(key[i]);}}
7
- key=key_non_null;colors=colors_non_null;var textAccessible=false;if(typeof prop['chart.key.text.accessible']==='boolean'){textAccessible=prop['chart.key.text.accessible'];}
8
- function DrawKey_graph(obj,key,colors)
9
- {var marginLeft=obj.marginLeft,marginRight=obj.marginRight,marginTop=obj.marginTop,marginBottom=obj.marginBottom,hpos=prop['chart.yaxis.position']=='right'?marginLeft+10:ca.width-marginRight-10,vpos=marginTop+10,title=prop['chart.title'],hmargin=8,vmargin=4,fillstyle=prop['chart.key.background'],strokestyle='#333',height=0,width=0;var textConf=RG.getTextConf({object:obj,prefix:'chart.key.labels'});blob_size=textConf.size;text_size=textConf.size;if(!obj.coords)obj.coords={};obj.coords.key=[];co.font=text_size+'pt '+prop['chart.text.font'];for(i=0;i<key.length;++i){width=Math.max(width,co.measureText(key[i]).width);}
10
- width+=5;width+=blob_size;width+=5;width+=5;width+=5;if(prop['chart.yaxispos']=='left'||(obj.type==='pie'&&!prop['chart.yaxis.position'])||(obj.type==='hbar'&&!prop['chart.yaxis.position'])||(obj.type==='hbar'&&prop['chart.yaxis.position']==='center')||(obj.type==='hbar'&&prop['chart.yaxis.position']==='right')||(obj.type==='rscatter'&&!prop['chart.yaxis.position'])||(obj.type==='radar'&&!prop['chart.yaxis.position'])||(obj.type==='rose'&&!prop['chart.yaxis.position'])||(obj.type==='funnel'&&!prop['chart.yaxis.position'])||(obj.type==='vprogress'&&!prop['chart.yaxis.position'])||(obj.type==='hprogress'&&!prop['chart.yaxis.position'])){hpos-=width;}
11
- if(typeof(prop['chart.key.halign'])=='string'){if(prop['chart.key.halign']=='left'){hpos=marginLeft+10;}else if(prop['chart.key.halign']=='right'){hpos=ca.width-marginRight-width;}}
12
- if(typeof(prop['chart.key.position.x'])=='number'){hpos=prop['chart.key.position.x'];}
13
- if(typeof(prop['chart.key.position.y'])=='number'){vpos=prop['chart.key.position.y'];}
14
- if(prop['chart.key.shadow']){co.shadowColor=prop['chart.key.shadow.color'];co.shadowBlur=prop['chart.key.shadow.blur'];co.shadowOffsetX=prop['chart.key.shadow.offsetx'];co.shadowOffsetY=prop['chart.key.shadow.offsety'];}
15
- co.beginPath();co.fillStyle=prop['chart.key.background'];co.strokeStyle='black';if(typeof(prop['chart.key.position.graph.boxed'])=='undefined'||(typeof(prop['chart.key.position.graph.boxed'])=='boolean'&&prop['chart.key.position.graph.boxed'])){if(arguments[3]!=false){co.lineWidth=typeof(prop['chart.key.linewidth'])=='number'?prop['chart.key.linewidth']:1;if(prop['chart.key.rounded']==true){co.beginPath();co.strokeStyle=strokestyle;RG.strokedCurvyRect(co,Math.round(hpos),Math.round(vpos),width-5,5+((text_size+5)*RG.getKeyLength(key)),4);co.stroke();co.fill();RG.NoShadow(obj);}else{co.strokeRect(Math.round(hpos),Math.round(vpos),width-5,5+((text_size+5)*RG.getKeyLength(key)));co.fillRect(Math.round(hpos),Math.round(vpos),width-5,5+((text_size+5)*RG.getKeyLength(key)));}}}
16
- RG.NoShadow(obj);co.beginPath();if(prop['chart.key.colors']){colors=prop['chart.key.colors'];}
17
- for(var i=key.length-1;i>=0;i--){var j=Number(i)+1;if(typeof prop['chart.key.color.shape']==='object'&&typeof prop['chart.key.color.shape'][i]==='string'){var blob_shape=prop['chart.key.color.shape'][i];}else if(typeof prop['chart.key.color.shape']==='object'&&typeof prop['chart.key.color.shape'][i]==='function'){var blob_shape=prop['chart.key.color.shape'][i];}else if(typeof prop['chart.key.color.shape']==='string'){var blob_shape=prop['chart.key.color.shape'];}else if(typeof prop['chart.key.color.shape']==='function'){var blob_shape=prop['chart.key.color.shape'];}else{var blob_shape='rect';}
18
- if(blob_shape=='circle'){co.beginPath();co.fillStyle=colors[i];co.arc(hpos+5+(blob_size/2),vpos+(5*j)+(text_size*j)-text_size+(blob_size/2),blob_size/2,0,6.26,0);co.fill();}else if(blob_shape=='line'){co.beginPath();co.strokeStyle=colors[i];co.moveTo(hpos+5,vpos+(5*j)+(text_size*j)-text_size+(blob_size/2));co.lineTo(hpos+blob_size+5,vpos+(5*j)+(text_size*j)-text_size+(blob_size/2));co.stroke();}else if(blob_shape=='triangle'){co.beginPath();co.strokeStyle=colors[i];co.moveTo(hpos+5,vpos+(5*j)+(text_size*j)-text_size+blob_size);co.lineTo(hpos+(blob_size/2)+5,vpos+(5*j)+(text_size*j)-text_size);co.lineTo(hpos+blob_size+5,vpos+(5*j)+(text_size*j)-text_size+blob_size);co.closePath();co.fillStyle=colors[i];co.fill();}else if(typeof blob_shape==='function'){blob_shape({object:obj,color:colors[i],x:hpos+5,y:vpos+(5*j)+(text_size*j)-text_size,width:text_size,height:text_size+1});}else{co.fillStyle=colors[i];co.fillRect(hpos+5,vpos+(5*j)+(text_size*j)-text_size,text_size,text_size+1);}
19
- co.beginPath();ret=RG.text2(obj,{font:textConf.font,size:textConf.size,bold:textConf.bold,italic:textConf.italic,color:typeof textConf.color=='object'?textConf.color[i]:textConf.color,x:hpos+blob_size+5+5+(prop['chart.key.labels.offsetx']||0),y:vpos+(5*j)+(text_size*j)+3+(prop['chart.key.labels.offsety']||0),text:key[i],accessible:textAccessible});obj.coords.key[i]=[ret.x,ret.y,ret.width,ret.height,key[i],colors[i],obj];}
20
- co.fill();}
21
- function DrawKey_margin(obj,key,colors)
22
- {var text_size=typeof(prop['chart.key.labels.size'])=='number'?prop['chart.key.labels.size']:prop['chart.text.size'],text_bold=prop['chart.key.labels.bold'],text_italic=prop['chart.key.labels.italic'],text_font=prop['chart.key.labels.font']||prop['chart.key.font']||prop['chart.text.font'],text_color=prop['chart.key.labels.color']||'black',marginLeft=obj.marginLeft,marginRight=obj.marginRight,marginTop=obj.marginTop,marginBottom=obj.marginBottom,hpos=((ca.width-marginLeft-marginRight)/2)+obj.marginLeft,vpos=marginTop-text_size-5,title=prop['chart.title'],blob_size=text_size,hmargin=8,vmargin=4,fillstyle=prop['chart.key.background'],strokestyle='#999',length=0;if(!obj.coords)obj.coords={};obj.coords.key=[];co.font=(obj.properties['chart.key.labels.italic']?'italic ':'')+(obj.properties['chart.key.labels.bold']?'bold ':'')+text_size+'pt '+text_font;for(i=0;i<key.length;++i){length+=hmargin;length+=blob_size;length+=hmargin;length+=co.measureText(key[i]).width;}
23
- length+=hmargin;if(obj.type=='pie'){if(prop['chart.align']=='left'){var hpos=obj.radius+marginLeft;}else if(prop['chart.align']=='right'){var hpos=ca.width-obj.radius-marginRight;}else{hpos=ca.width/2;}}
24
- hpos-=(length/2);if(typeof(prop['chart.key.position.x'])=='number'){hpos=prop['chart.key.position.x'];}
25
- if(typeof(prop['chart.key.position.y'])=='number'){vpos=prop['chart.key.position.y'];}
26
- if(obj.get('chart.key.position.gutter.boxed')||obj.get('chart.key.position.margin.boxed')){if(prop['chart.key.shadow']){co.shadowColor=prop['chart.key.shadow.color'];co.shadowBlur=prop['chart.key.shadow.blur'];co.shadowOffsetX=prop['chart.key.shadow.offsetx'];co.shadowOffsetY=prop['chart.key.shadow.offsety'];}
27
- co.beginPath();co.fillStyle=fillstyle;co.strokeStyle=strokestyle;if(prop['chart.key.rounded']){RG.strokedCurvyRect(co,hpos,vpos-vmargin,length,text_size+vmargin+vmargin)}else{co.rect(hpos,vpos-vmargin,length,text_size+vmargin+vmargin);}
28
- co.stroke();co.fill();RG.NoShadow(obj);}
29
- if(prop['chart.key.colors']){colors=prop['chart.key.colors'];}
30
- for(var i=0,pos=hpos;i<key.length;++i){pos+=hmargin;if(typeof prop['chart.key.color.shape']==='object'&&typeof prop['chart.key.color.shape'][i]==='string'){var blob_shape=prop['chart.key.color.shape'][i];}else if(typeof prop['chart.key.color.shape']==='object'&&typeof prop['chart.key.color.shape'][i]==='function'){var blob_shape=prop['chart.key.color.shape'][i];}else if(typeof prop['chart.key.color.shape']==='function'){var blob_shape=prop['chart.key.color.shape'];}else if(typeof(prop['chart.key.color.shape'])=='string'){var blob_shape=prop['chart.key.color.shape'];}else{var blob_shape='square';}
31
- if(blob_shape=='line'){co.beginPath();co.strokeStyle=colors[i];co.moveTo(pos,vpos+(blob_size/2));co.lineTo(pos+blob_size,vpos+(blob_size/2));co.stroke();}else if(blob_shape=='circle'){co.beginPath();co.fillStyle=colors[i];co.moveTo(pos,vpos+(blob_size/2));co.arc(pos+(blob_size/2),vpos+(blob_size/2),(blob_size/2),0,6.28,0);co.fill();}else if(blob_shape=='triangle'){co.fillStyle=colors[i];co.beginPath();co.strokeStyle=colors[i];co.moveTo(pos,vpos+blob_size);co.lineTo(pos+(blob_size/2),vpos);co.lineTo(pos+blob_size,vpos+blob_size);co.closePath();co.fill();}else if(typeof blob_shape==='function'){blob_shape({object:obj,color:colors[i],x:pos,y:vpos,width:blob_size,height:blob_size});}else{co.beginPath();co.fillStyle=colors[i];co.rect(pos,vpos,blob_size,blob_size);co.fill();}
32
- pos+=blob_size;pos+=hmargin;co.beginPath();co.fillStyle=(typeof text_color==='object')?text_color[i]:text_color;var ret=RG.Text2(obj,{font:text_font,bold:text_bold,size:text_size,italic:text_italic,x:pos+ +(prop['chart.key.labels.offsetx']||0),y:vpos+text_size+1+ +(prop['chart.key.labels.offsety']||0),text:key[i],accessible:textAccessible});co.fill();pos+=co.measureText(key[i]).width;obj.coords.key[i]=[ret.x,ret.y,ret.width,ret.height,key[i],colors[i],obj];}}
33
- if(keypos&&(keypos==='gutter'||keypos==='margin')){DrawKey_margin(obj,key,colors);}else if(keypos&&(keypos==='graph'||keypos==='chart')){DrawKey_graph(obj,key,colors);}else{alert('[COMMON] ('+obj.id+') Unknown key position: '+keypos);}
34
- if(prop['chart.key.interactive']){if(!RGraph.Drawing||!RGraph.Drawing.Rect){alert('[INTERACTIVE KEY] The drawing API Rect library does not appear to have been included (which the interactive key uses)');}
35
- if(!RGraph.InstallWindowMousedownListener){alert('[INTERACTIVE KEY] The dynamic library does not appear to have been included');}
36
- for(var i=0,len=obj.coords.key.length,maxlen=0;i<len;i+=1){maxlen=Math.max(maxlen,obj.coords.key[i][2]);}
37
- for(var i=0,len=obj.coords.key.length;i<len;i+=1){(function(idx)
38
- {var arr=obj.coords.key;var value=obj.coords.key[idx];var index=idx;var rect=new RGraph.Drawing.Rect(obj.id,value[0],value[1],(prop['chart.key.position']==='gutter'||prop['chart.key.position']==='margin')?value[2]:maxlen,value[3]).set('colorsFill','rgba(0,0,0,0)').draw();rect.onclick=function(e,shape)
39
- {var co=rect.context;co.fillStyle=prop['chart.key.interactive.highlight.label'];co.fillRect(shape.x,shape.y,shape.width,shape.height);if(typeof obj.interactiveKeyHighlight=='function'){obj.Set('chart.key.interactive.index',idx);RG.FireCustomEvent(obj,'onbeforeinteractivekey');obj.interactiveKeyHighlight(index);RG.FireCustomEvent(obj,'onafterinteractivekey');}}
40
- rect.onmousemove=function(e,shape)
41
- {return true;}})(i);}}};RG.getKeyLength=function(key)
42
- {var length=0;for(var i=0,len=key.length;i<len;i+=1){if(key[i]!=null){++length;}}
43
- return length;};RGraph.HTML.key=RGraph.HTML.Key=function(id,prop)
44
- {var div=doc.getElementById(id);var uid=RG.createUID();var str='<table border="0" cellspacing="0" cellpadding="0" id="rgraph_key_'+uid+'" style="display: inline;'+(function()
45
- {var style=''
46
- for(i in prop.tableCss){if(typeof i==='string'){style=style+i+': '+prop.tableCss[i]+';';}}
47
- return style;})()+'" '+(prop.tableClass?'class="'+prop.tableClass+'"':'')+'>';for(var i=0;i<prop.labels.length;i+=1){str+='<tr><td><div style="'+(function()
48
- {var style='';for(var j in prop.blobCss){if(typeof j==='string'){style=style+j+': '+prop.blobCss[j]+';';}}
49
- return style;})()+'display: inline-block; margin-right: 5px; margin-top: 4px; width: 15px; height: 15px; background-color: '+prop.colors[i]+'"'+(prop.blobClass?'class="'+prop.blobClass+'"':'')+'>&nbsp;</div><td>'+(prop.links&&prop.links[i]?'<a href="'+prop.links[i]+'">':'')+'<span '+(prop.labelClass?'class="'+prop.labelClass+'"':'')+'" style="'+(function()
50
- {var style='';for(var j in prop.labelCss){if(typeof j==='string'){style=style+j+': '+prop.labelCss[j]+';';}}
51
- return style;})()+' '+(function()
52
- {var style='';if(prop['labelCss_'+i]){for(var j in prop['labelCss_'+i]){style=style+j+': '+prop['labelCss_'+i][j]+';';}}
53
- return style?style+'"':'"';})()+'>'+prop.labels[i]+'</span>'+(prop.links&&prop.links[i]?'</a>':'')+'</td></tr>';}
54
- div.innerHTML+=(str+'</table>');return doc.getElementById('rgraph_key_'+uid);};})(window,document);
12
+ RGraph = window.RGraph || {isrgraph:true,isRGraph: true,rgraph:true};
13
+ RGraph.HTML = RGraph.HTML || {};
14
+
15
+ // Module pattern
16
+ (function (win, doc, undefined)
17
+ {
18
+ //
19
+ // Draws the graph key (used by various graphs)
20
+ //
21
+ RGraph.drawKey = function ()
22
+ {
23
+ var args = RGraph.getArgs(arguments, 'object,key,colors');
24
+
25
+ if (!args.key) {
26
+ return;
27
+ }
28
+
29
+ var prop = args.object.properties,
30
+ properties = args.object.properties,
31
+
32
+ // Key positioned in the margin
33
+ keypos = properties.keyPosition,
34
+ textsize = properties.textSize,
35
+ key_non_null = [],
36
+ colors_non_null = [];
37
+
38
+ args.object.context.lineWidth = 1;
39
+ args.object.context.beginPath();
40
+
41
+ //
42
+ // Change the older keyVpos to keyPositionY
43
+ //
44
+ if (typeof properties.keyVpos == 'number') {
45
+ args.object.set('keyPositionY', properties.keyVpos * args.object.get('marginTop'));
46
+ }
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+ // Account for the key now (March 2023) being able to be
59
+ // a string
60
+ if (RGraph.isString(args.key)) {
61
+
62
+ var len = 0;
63
+
64
+ if (RGraph.isNumber(args.object.properties.keyFormattedItemsCount)) {
65
+ len = args.object.properties.keyFormattedItemsCount;
66
+ } else {
67
+ len = args.object.getKeyNumDatapoints();
68
+ }
69
+
70
+ args.key = (new Array(len)).fill(args.key);
71
+ }
72
+
73
+
74
+
75
+
76
+
77
+
78
+
79
+
80
+
81
+
82
+
83
+
84
+
85
+
86
+ //
87
+ // Account for null values in the key
88
+ //
89
+ for (var i=0; i<args.key.length; ++i) {
90
+ if (args.key[i] !== null) {
91
+ colors_non_null.push(args.colors[i]);
92
+ key_non_null.push(args.key[i]);
93
+ }
94
+ }
95
+
96
+ key = key_non_null;
97
+ colors = colors_non_null;
98
+
99
+ // The key does not use accessible text by default
100
+ var textAccessible = false;
101
+
102
+ if (typeof properties.keyTextAccessible === 'boolean') {
103
+ textAccessible = properties.keyTextAccessible;
104
+ }
105
+
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+
124
+
125
+
126
+
127
+
128
+
129
+
130
+
131
+
132
+
133
+
134
+ //
135
+ // This does the actual drawing of the key when it's in the graph
136
+ //
137
+ // @param object obj The graph object
138
+ // @param array key The key items to draw
139
+ // @param array colors An aray of colors that the key will use
140
+ //
141
+ function drawKey_graph ()
142
+ {
143
+ var marginLeft = args.object.marginLeft,
144
+ marginRight = args.object.marginRight,
145
+ marginTop = args.object.marginTop,
146
+ marginBottom = args.object.marginBottom,
147
+ hpos = properties.yaxisPosition == 'right' ? marginLeft + 10 : args.object.canvas.width - marginRight - 10,
148
+ vpos = marginTop + 10,
149
+ title = properties.title,
150
+ hmargin = 8, // This is the size of the gaps between the blob of color and the text
151
+ vmargin = 4, // This is the vertical margin of the key
152
+ fillstyle = properties.keyBackground,
153
+ strokestyle = '#333',
154
+ height = 0,
155
+ width = 0;
156
+
157
+ // Get the text configuration
158
+ var textConf = RGraph.getTextConf({
159
+ object: args.object,
160
+ prefix: 'keyLabels'
161
+ });
162
+
163
+ blob_size = textConf.size; // The blob of color
164
+ text_size = textConf.size;
165
+
166
+ if (!args.object.coords) {
167
+ args.object.coords = {};
168
+ }
169
+
170
+ args.object.coords.key = [];
171
+
172
+ // Need to set this so that measuring the text works out OK
173
+ args.object.context.font = (textConf.italic ? 'italic ' : '') +
174
+ (textConf.bold ? 'bold ' : '') +
175
+ textConf.size + 'pt ' +
176
+ textConf.font;
177
+
178
+ // Work out the longest bit of text
179
+ for (i=0; i<key.length; ++i) {
180
+
181
+ ////////////////////////////////////
182
+ // Label substitution for the key //
183
+ ////////////////////////////////////
184
+ key[i] = RGraph.labelSubstitution({
185
+ object: args.object,
186
+ text: key[i],
187
+ index: i,
188
+ value: args.object.getKeyValue(i),
189
+ unitsPre: args.object.properties.keyFormattedUnitsPre,
190
+ unitsPost: args.object.properties.keyFormattedUnitsPost,
191
+ thousand: args.object.properties.keyFormattedThousand,
192
+ point: args.object.properties.keyFormattedPoint,
193
+ decimals: args.object.properties.keyFormattedDecimals
194
+ });
195
+ //////////// Label substitution for the key ////////////
196
+
197
+ width = Math.max(
198
+ width,
199
+ args.object.context.measureText(key[i]).width);
200
+ }
201
+
202
+ width += 5;
203
+ width += blob_size;
204
+ width += 5;
205
+ width += 5;
206
+ width += 5;
207
+
208
+ //
209
+ // Now we know the width, we can move the key left more accurately
210
+ //
211
+ if ( properties.yaxisPosition == 'left'
212
+ || (args.object.type === 'pie' && !properties.yaxisPosition)
213
+ || (args.object.type === 'pie' && !properties.yaxisPosition)
214
+ || (args.object.type === 'hbar' && !properties.yaxisPosition)
215
+ || (args.object.type === 'hbar' && properties.yaxisPosition === 'center')
216
+ || (args.object.type === 'hbar' && properties.yaxisPosition === 'right')
217
+ || (args.object.type === 'rscatter' && !properties.yaxisPosition)
218
+ || (args.object.type === 'radar' && !properties.yaxisPosition)
219
+ || (args.object.type === 'rose' && !properties.yaxisPosition)
220
+ || (args.object.type === 'funnel' && !properties.yaxisPosition)
221
+ || (args.object.type === 'vprogress' && !properties.yaxisPosition)
222
+ || (args.object.type === 'hprogress' && !properties.yaxisPosition)
223
+ ) {
224
+
225
+ hpos -= width;
226
+ }
227
+
228
+ //
229
+ // Horizontal alignment
230
+ //
231
+ if (typeof properties.keyHalign == 'string') {
232
+ if (properties.keyHalign === 'left') {
233
+ hpos = marginLeft + 10;
234
+ } else if (properties.keyHalign == 'right') {
235
+ hpos = args.object.canvas.width - marginRight - width;
236
+ }
237
+ }
238
+
239
+ //
240
+ // Specific location coordinates
241
+ //
242
+ if (typeof properties.keyPositionX === 'number') {hpos = properties.keyPositionX;}
243
+ if (typeof properties.keyPositionY === 'number') {vpos = properties.keyPositionY;}
244
+
245
+ // Now allow for offsetting the key
246
+ if (typeof properties.keyPositionOffsetx === 'number') {hpos += properties.keyPositionOffsetx;}
247
+ if (typeof properties.keyPositionOffsety === 'number') {vpos += properties.keyPositionOffsety;}
248
+
249
+
250
+ // Stipulate the shadow for the key box
251
+ if (properties.keyShadow) {
252
+ args.object.context.shadowColor = properties.keyShadowColor;
253
+ args.object.context.shadowBlur = properties.keyShadowBlur;
254
+ args.object.context.shadowOffsetX = properties.keyShadowOffsetx;
255
+ args.object.context.shadowOffsetY = properties.keyShadowOffsety;
256
+ }
257
+
258
+
259
+
260
+
261
+ // Draw the box that the key resides in
262
+ args.object.context.beginPath();
263
+ args.object.context.fillStyle = properties.keyBackground;
264
+ args.object.context.strokeStyle = 'black';
265
+
266
+ if (typeof properties.keyPositionGraphBoxed == 'undefined' || (typeof properties.keyPositionGraphBoxed == 'boolean' && properties.keyPositionGraphBoxed) ) {
267
+ if (arguments[3] != false) {
268
+
269
+ args.object.context.lineWidth = typeof properties.keyLinewidth == 'number' ? properties.keyLinewidth : 1;
270
+
271
+ // The older square rectangled key
272
+ if (properties.keyRounded == true) {
273
+
274
+ args.object.context.beginPath();
275
+ args.object.context.strokeStyle = strokestyle;
276
+
277
+ RGraph.roundedRect({
278
+ context: args.object.context,
279
+ x: Math.round(hpos),
280
+ y: Math.round(vpos),
281
+ width: width - 5,
282
+ height: 5 + ( (text_size + 5) * RGraph.getKeyLength(key)),
283
+ radius: 4
284
+ });
285
+ args.object.context.stroke();
286
+ args.object.context.fill();
287
+
288
+ RGraph.noShadow(args.object);
289
+
290
+ } else {
291
+ args.object.context.strokeRect(Math.round(hpos), Math.round(vpos), width - 5, 5 + ( (text_size + 5) * RGraph.getKeyLength(key)));
292
+ args.object.context.fillRect(Math.round(hpos), Math.round(vpos), width - 5, 5 + ( (text_size + 5) * RGraph.getKeyLength(key)));
293
+ }
294
+ }
295
+ }
296
+
297
+ RGraph.noShadow(args.object);
298
+
299
+ args.object.context.beginPath();
300
+
301
+ //
302
+ // Custom colors for the key
303
+ //
304
+ if (properties.keyColors) {
305
+ colors = properties.keyColors;
306
+ }
307
+
308
+
309
+
310
+ ////////////////////////////////////////////////////////////////////////////////////////////
311
+
312
+
313
+
314
+ // Draw the labels given
315
+ for (var i=key.length - 1; i>=0; i--) {
316
+
317
+ var j = Number(i) + 1;
318
+
319
+ //
320
+ // Draw the blob of color
321
+ //
322
+ // An array element, string
323
+ if (typeof properties.keyColorShape === 'object' && typeof properties.keyColorShape[i] === 'string') {
324
+ var blob_shape = properties.keyColorShape[i];
325
+
326
+ // An array element, function
327
+ } else if (typeof properties.keyColorShape === 'object' && typeof properties.keyColorShape[i] === 'function') {
328
+ var blob_shape = properties.keyColorShape[i];
329
+
330
+ // No array - just a string
331
+ } else if (typeof properties.keyColorShape === 'string') {
332
+ var blob_shape = properties.keyColorShape;
333
+
334
+ // No array - just a function
335
+ } else if (typeof properties.keyColorShape === 'function') {
336
+ var blob_shape = properties.keyColorShape;
337
+
338
+ // Unknown
339
+ } else {
340
+ var blob_shape = 'rect';
341
+ }
342
+
343
+ if (blob_shape == 'circle') {
344
+ args.object.context.beginPath();
345
+ args.object.context.fillStyle = colors[i];
346
+ args.object.context.arc(hpos + 5 + (blob_size / 2), vpos + (5 * j) + (text_size * j) - text_size + (blob_size / 2), blob_size / 2, 0, 6.26, 0);
347
+ args.object.context.fill();
348
+
349
+ } else if (blob_shape == 'line') {
350
+ args.object.context.beginPath();
351
+ args.object.context.strokeStyle = colors[i];
352
+ args.object.context.moveTo(hpos + 5, vpos + (5 * j) + (text_size * j) - text_size + (blob_size / 2));
353
+ args.object.context.lineTo(hpos + blob_size + 5, vpos + (5 * j) + (text_size * j) - text_size + (blob_size / 2));
354
+ args.object.context.stroke();
355
+
356
+ } else if (blob_shape == 'triangle') {
357
+ args.object.context.beginPath();
358
+ args.object.context.strokeStyle = colors[i];
359
+ args.object.context.moveTo(hpos + 5, vpos + (5 * j) + (text_size * j) - text_size + blob_size);
360
+ args.object.context.lineTo(hpos + (blob_size / 2) + 5, vpos + (5 * j) + (text_size * j) - text_size );
361
+ args.object.context.lineTo(hpos + blob_size + 5, vpos + (5 * j) + (text_size * j) - text_size + blob_size);
362
+ args.object.context.closePath();
363
+ args.object.context.fillStyle = colors[i];
364
+ args.object.context.fill();
365
+
366
+ } else if (typeof blob_shape === 'function') {
367
+
368
+ blob_shape({
369
+ object: args.object,
370
+ color: colors[i],
371
+ x: hpos + 5,
372
+ y: vpos + (5 * j) + (text_size * j) - text_size,
373
+ width: text_size,
374
+ height: text_size + 1
375
+ });
376
+ } else {
377
+ args.object.context.fillStyle = colors[i];
378
+ args.object.context.fillRect(
379
+ hpos + 5,
380
+ vpos + (5 * j) + (text_size * j) - text_size,
381
+ text_size,
382
+ text_size + 1
383
+ );
384
+ }
385
+
386
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////
387
+
388
+
389
+
390
+ args.object.context.beginPath();
391
+ //args.object.context.fillStyle = typeof text_color == 'object' ? text_color[i] : text_color;
392
+
393
+
394
+
395
+ ret = RGraph.text({
396
+
397
+ object: args.object,
398
+
399
+ font: textConf.font,
400
+ size: textConf.size,
401
+ bold: textConf.bold,
402
+ italic: textConf.italic,
403
+ color: typeof textConf.color == 'object' ? textConf.color[i] : textConf.color,
404
+
405
+ x: hpos + blob_size + 5 + 5 + (properties.keyLabelsOffsetx || 0),
406
+ y: vpos + (5 * j) + (text_size * j) + 3 + (properties.keyLabelsOffsety || 0),
407
+ text: key[i],
408
+ accessible: textAccessible
409
+ });
410
+
411
+ args.object.coords.key[i] = [
412
+ ret.x,
413
+ ret.y,
414
+ ret.width,
415
+ ret.height,
416
+ key[i],
417
+ colors[i],
418
+ args.object
419
+ ];
420
+ }
421
+ args.object.context.fill();
422
+ }
423
+
424
+
425
+
426
+
427
+
428
+
429
+
430
+
431
+
432
+
433
+
434
+
435
+
436
+
437
+
438
+
439
+
440
+
441
+
442
+
443
+
444
+
445
+
446
+
447
+
448
+
449
+
450
+
451
+
452
+
453
+
454
+
455
+
456
+
457
+
458
+
459
+
460
+
461
+ //
462
+ // This does the actual drawing of the key when it's in the margin
463
+ //
464
+ var drawKey_margin = function ()
465
+ {
466
+ var text_size = typeof properties.keyLabelsSize == 'number' ? properties.keyLabelsSize : properties.textSize,
467
+ text_bold = properties.keyLabelsBold,
468
+ text_italic = properties.keyLabelsItalic,
469
+ text_font = properties.keyLabelsFont || properties.keyFont || properties.textFont,
470
+ text_color = properties.keyLabelsColor || properties.textColor,
471
+ marginLeft = args.object.marginLeft,
472
+ marginRight = args.object.marginRight,
473
+ marginTop = args.object.marginTop,
474
+ marginBottom = args.object.marginBottom,
475
+ hpos = ((args.object.canvas.width - marginLeft - marginRight) / 2) + args.object.marginLeft,
476
+ vpos = marginTop - text_size - 5,
477
+ title = properties.title,
478
+ blob_size = text_size, // The blob of color
479
+ hmargin = 8, // This is the size of the gaps between the blob of color and the text
480
+ vmargin = 4, // This is the vertical margin of the key
481
+ fillstyle = properties.keyBackground,
482
+ strokestyle = '#999',
483
+ length = 0;
484
+
485
+ if (!args.object.coords) {
486
+ args.object.coords = {};
487
+ }
488
+ args.object.coords.key = [];
489
+
490
+
491
+
492
+ // Need to work out the length of the key first
493
+ args.object.context.font = (args.object.properties.keyLabelsItalic ? 'italic ' : '') + (args.object.properties.keyLabelsBold ? 'bold ' : '') + text_size + 'pt ' + text_font;
494
+
495
+ for (i=0; i<key.length; ++i) {
496
+
497
+ ////////////////////////////////////
498
+ // Label substitution for the key //
499
+ ////////////////////////////////////
500
+ key[i] = RGraph.labelSubstitution({
501
+ object: args.object,
502
+ text: key[i],
503
+ index: i,
504
+ value: args.object.getKeyValue(i),
505
+ unitsPre: args.object.properties.keyFormattedUnitsPre,
506
+ unitsPost: args.object.properties.keyFormattedUnitsPost,
507
+ thousand: args.object.properties.keyFormattedThousand,
508
+ point: args.object.properties.keyFormattedPoint,
509
+ decimals: args.object.properties.keyFormattedDecimals
510
+ });
511
+ //////////// Label substitution for the key ////////////
512
+
513
+
514
+
515
+
516
+ length += hmargin;
517
+ length += blob_size;
518
+ length += hmargin;
519
+ length += args.object.context.measureText(key[i]).width;
520
+ length += (properties.keyPositionMarginHSpace ? properties.keyPositionMarginHSpace : 0);
521
+ }
522
+ length += hmargin;
523
+
524
+ // Don't why we need this but here it is...
525
+ length += (properties.keyPositionMarginHSpace ? properties.keyPositionMarginHSpace : 0);
526
+
527
+
528
+
529
+
530
+ //
531
+ // Work out hpos since in the Pie it isn't necessarily dead center
532
+ //
533
+ if (args.object.type == 'pie') {
534
+ if (properties.align == 'left') {
535
+ var hpos = args.object.radius + marginLeft;
536
+
537
+ } else if (properties.align == 'right') {
538
+ var hpos = args.object.canvas.width - args.object.radius - marginRight;
539
+
540
+ } else {
541
+ hpos = args.object.canvas.width / 2;
542
+ }
543
+ }
544
+
545
+
546
+
547
+
548
+
549
+ //
550
+ // This makes the key centered
551
+ //
552
+ hpos -= (length / 2);
553
+
554
+
555
+ //
556
+ // Override the horizontal/vertical positioning
557
+ //
558
+ if (typeof properties.keyPositionX === 'number') {hpos = properties.keyPositionX;}
559
+ if (typeof properties.keyPositionY === 'number') {vpos = properties.keyPositionY;}
560
+
561
+ // Now allow for offsetting the key
562
+ if (typeof properties.keyPositionOffsetx === 'number') {hpos += properties.keyPositionOffsetx;}
563
+ if (typeof properties.keyPositionOffsety === 'number') {vpos += properties.keyPositionOffsety;}
564
+
565
+
566
+
567
+ //
568
+ // Draw the box that the key sits in
569
+ //
570
+ if ( args.object.get('keyPositionGutterBoxed')
571
+ || args.object.get('keyPositionMarginBoxed')
572
+ ) {
573
+
574
+ if (properties.keyShadow) {
575
+ args.object.context.shadowColor = properties.keyShadowColor;
576
+ args.object.context.shadowBlur = properties.keyShadowBlur;
577
+ args.object.context.shadowOffsetX = properties.keyShadowOffsetx;
578
+ args.object.context.shadowOffsetY = properties.keyShadowOffsety;
579
+ }
580
+
581
+
582
+ args.object.context.beginPath();
583
+ args.object.context.fillStyle = fillstyle;
584
+ args.object.context.strokeStyle = strokestyle;
585
+
586
+ if (properties.keyRounded) {
587
+ RGraph.roundedRect({
588
+ context: args.object.context,
589
+ x: hpos,
590
+ y: vpos - vmargin,
591
+ width: length,
592
+ height: text_size + vmargin + vmargin
593
+ });
594
+ } else {
595
+ args.object.context.rect(hpos, vpos - vmargin, length, text_size + vmargin + vmargin);
596
+ }
597
+
598
+ args.object.context.stroke();
599
+ args.object.context.fill();
600
+
601
+
602
+ RGraph.noShadow(args.object);
603
+ }
604
+
605
+
606
+ //
607
+ // Draw the blobs of color and the text
608
+ //
609
+
610
+ // Custom colors for the key
611
+ if (properties.keyColors) {
612
+ colors = properties.keyColors;
613
+ }
614
+
615
+ for (var i=0, pos=hpos; i<key.length; ++i) {
616
+
617
+ pos += hmargin;
618
+
619
+
620
+
621
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
622
+
623
+
624
+
625
+ // Draw the blob of color
626
+ if (typeof properties.keyColorShape === 'object' && typeof properties.keyColorShape[i] === 'string') {
627
+ var blob_shape = properties.keyColorShape[i];
628
+
629
+ } else if (typeof properties.keyColorShape === 'object' && typeof properties.keyColorShape[i] === 'function') {
630
+ var blob_shape = properties.keyColorShape[i];
631
+
632
+ // No array - just a function
633
+ } else if (typeof properties.keyColorShape === 'function') {
634
+ var blob_shape = properties.keyColorShape;
635
+
636
+ } else if (typeof properties.keyColorShape == 'string') {
637
+ var blob_shape = properties.keyColorShape;
638
+
639
+ } else {
640
+ var blob_shape = 'square';
641
+ }
642
+
643
+ // Allow for the keyPositionMarginHSpace property
644
+ pos += (properties.keyPositionMarginHSpace ? properties.keyPositionMarginHSpace : 0);
645
+
646
+ //
647
+ // Draw the blob of color - line
648
+ //
649
+ if (blob_shape =='line') {
650
+
651
+ args.object.context.beginPath();
652
+ args.object.context.strokeStyle = colors[i];
653
+ args.object.context.moveTo(pos, vpos + (blob_size / 2));
654
+ args.object.context.lineTo(pos + blob_size, vpos + (blob_size / 2));
655
+ args.object.context.stroke();
656
+
657
+ // Circle
658
+ } else if (blob_shape == 'circle') {
659
+
660
+ args.object.context.beginPath();
661
+ args.object.context.fillStyle = colors[i];
662
+ args.object.context.moveTo(pos, vpos + (blob_size / 2));
663
+ args.object.context.arc(pos + (blob_size / 2), vpos + (blob_size / 2), (blob_size / 2), 0, 6.28, 0);
664
+ args.object.context.fill();
665
+
666
+ } else if (blob_shape == 'triangle') {
667
+
668
+ args.object.context.fillStyle = colors[i];
669
+ args.object.context.beginPath();
670
+ args.object.context.strokeStyle = colors[i];
671
+ args.object.context.moveTo(pos, vpos + blob_size);
672
+ args.object.context.lineTo(pos + (blob_size / 2), vpos);
673
+ args.object.context.lineTo(pos + blob_size, vpos + blob_size);
674
+ args.object.context.closePath();
675
+ args.object.context.fill();
676
+
677
+ } else if (typeof blob_shape === 'function') {
678
+
679
+ blob_shape({
680
+ object: args.object,
681
+ color: colors[i],
682
+ x: pos,
683
+ y: vpos,
684
+ width: blob_size,
685
+ height: blob_size
686
+ });
687
+
688
+ } else {
689
+
690
+ args.object.context.beginPath();
691
+ args.object.context.fillStyle = colors[i];
692
+ args.object.context.rect(pos, vpos, blob_size, blob_size);
693
+ args.object.context.fill();
694
+ }
695
+
696
+
697
+
698
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
699
+
700
+
701
+
702
+
703
+ pos += blob_size;
704
+
705
+ pos += hmargin;
706
+
707
+ args.object.context.beginPath();
708
+ args.object.context.fillStyle = (typeof text_color === 'object') ? text_color[i] : text_color;
709
+
710
+ var ret = RGraph.text({
711
+ object: args.object,
712
+ font: text_font,
713
+ bold: text_bold,
714
+ size: text_size,
715
+ italic: text_italic,
716
+ x: pos + + (properties.keyLabelsOffsetx || 0),
717
+ y: vpos + text_size + 1 + + (properties.keyLabelsOffsety || 0),
718
+ text: key[i],
719
+ accessible: textAccessible
720
+ });
721
+ args.object.context.fill();
722
+ pos += args.object.context.measureText(key[i]).width;
723
+
724
+ args.object.coords.key[i] = [
725
+ ret.x,
726
+ ret.y,
727
+ ret.width,
728
+ ret.height,
729
+ key[i],
730
+ colors[i],
731
+ args.object
732
+ ];
733
+ }
734
+ };
735
+
736
+
737
+
738
+
739
+
740
+
741
+
742
+
743
+
744
+
745
+
746
+
747
+
748
+
749
+
750
+
751
+
752
+
753
+ if (keypos && (keypos === 'gutter' || keypos === 'margin')) {
754
+ drawKey_margin();
755
+ } else if (keypos && (keypos === 'graph' || keypos === 'chart') ) {
756
+ drawKey_graph();
757
+ } else {
758
+ alert('[KEY] (' + args.object.id + ') Unknown key position: ' + keypos);
759
+ }
760
+
761
+
762
+
763
+
764
+
765
+
766
+ if (properties.keyInteractive) {
767
+
768
+ if (!RGraph.Drawing || !RGraph.Drawing.Rect) {
769
+ alert('[INTERACTIVE KEY] The drawing API Rect library does not appear to have been included (which the interactive key uses)');
770
+ }
771
+
772
+
773
+
774
+ //
775
+ // Check that the RGraph.common.dynamic.js file has been included
776
+ //
777
+ if (!RGraph.installWindowMousedownListener) {
778
+ alert('[INTERACTIVE KEY] The dynamic library does not appear to have been included');
779
+ }
780
+
781
+
782
+
783
+ // Determine the maximum width of the labels
784
+ for (var i=0,len=args.object.coords.key.length,maxlen=0; i<len; i+=1) {
785
+ maxlen = Math.max(maxlen, args.object.coords.key[i][2]);
786
+ }
787
+
788
+
789
+ //args.object.coords.key.forEach(function (value, index, arr)
790
+ //{
791
+ for (var i=0,len=args.object.coords.key.length; i<len; i+=1) {
792
+
793
+ // Because the loop would have finished when the i variable is needed - put
794
+ // the onclick function inside a new context so that the value of the i
795
+ // variable is what we expect when the key has been clicked
796
+ (function (idx)
797
+ {
798
+ var arr = args.object.coords.key;
799
+ var value = args.object.coords.key[idx];
800
+ var index = idx;
801
+
802
+
803
+ var rect = new RGraph.Drawing.Rect({
804
+ id: args.object.id,
805
+ x: value[0],
806
+ y: value[1],
807
+ width: (properties.keyPosition === 'gutter' || properties.keyPosition === 'margin') ? value[2] : maxlen,
808
+ height: value[3],
809
+ options: {
810
+ colorsFill: 'rgba(0,0,0,0)'
811
+ }
812
+ }).draw();
813
+
814
+ rect.onclick = function (e, shape)
815
+ {
816
+ rect.context.fillStyle = properties.keyInteractiveHighlightLabel;
817
+ rect.context.fillRect(shape.x, shape.y, shape.width, shape.height);
818
+
819
+ if (typeof args.object.interactiveKeyHighlight == 'function') {
820
+
821
+ args.object.set('keyInteractiveIndex', idx);
822
+
823
+ RGraph.fireCustomEvent(args.object, 'onbeforeinteractivekey');
824
+ args.object.interactiveKeyHighlight(index);
825
+ RGraph.fireCustomEvent(args.object, 'onafterinteractivekey');
826
+ }
827
+ }
828
+
829
+ rect.onmousemove = function (e, shape)
830
+ {
831
+ return true;
832
+ }
833
+ })(i);
834
+ }
835
+ }
836
+ };
837
+
838
+
839
+
840
+
841
+
842
+
843
+
844
+
845
+ //
846
+ // Returns the key length, but accounts for null values
847
+ //
848
+ // @param array key The key elements
849
+ //
850
+ RGraph.getKeyLength = function (key)
851
+ {
852
+ var length = 0;
853
+
854
+ for (var i=0,len=key.length; i<len; i+=1) {
855
+ if (key[i] != null) {
856
+ ++length;
857
+ }
858
+ }
859
+
860
+ return length;
861
+ };
862
+
863
+
864
+
865
+
866
+
867
+
868
+
869
+
870
+ //
871
+ // Create a TABLE based HTML key. There's lots of options so it's
872
+ // suggested that you consult the documentation page
873
+ //
874
+ // @param mixed id This should be a string consisting of the ID of the container
875
+ // @param object prop An object map of the various properties that you can use to
876
+ // configure the key. See the documentation page for a list.
877
+ //
878
+ RGraph.HTML.key =
879
+ RGraph.HTML.Key = function (id, properties)
880
+ {
881
+ var div = doc.getElementById(id);
882
+ var uid = RGraph.createUID();
883
+
884
+
885
+ //
886
+ // Create the table that becomes the key. CSS Styles for
887
+ // the table, the color blobs and the labels are set below
888
+ // using the RGraph.setCSS() function.
889
+ //
890
+ var str = '<table border="0" cellspacing="0" cellpadding="0" id="rgraph_key_' + uid + '" ' + (properties.tableClass ? 'class="' + properties.tableClass + '"' : '') + '>';
891
+ //
892
+
893
+
894
+ //
895
+ // Add the individual key elements
896
+ //
897
+ for (var i=0; i<properties.labels.length; i+=1) {
898
+ str += '<tr><td valign="top"><div id="rgraph_html_key_blob_' + i + '" ' + (properties.blobClass ? 'class="rgraph_html_key_blob ' + properties.blobClass + '"' : 'rgraph_html_key_blob') + '>&nbsp;</div><td>' + (properties.links && properties.links[i] ? '<a href="' + properties.links[i] + '">' : '') + '<span ' + (properties.labelClass ? 'class="' + properties.labelClass + '"' : '') + '" id="rgraph_html_key_label_' + i + '">' + properties.labels[i] + '</span>' + (properties.links && properties.links[i] ? '</a>' : '') + '</td></tr>';
899
+ }
900
+
901
+ div.innerHTML += (str + '</table>');
902
+
903
+ for (var i=0; i<properties.labels.length; i+=1) {
904
+ var n = document.getElementById('rgraph_html_key_blob_' + i);
905
+ n.style.width = '20px';
906
+ n.style.height = '20px';
907
+ }
908
+
909
+
910
+
911
+
912
+
913
+
914
+
915
+
916
+
917
+
918
+
919
+
920
+
921
+ // Set CSS for the whole table that has been specified
922
+ RGraph.setCSS(doc.getElementById('rgraph_key_' + uid),
923
+ {
924
+ display: 'inline',
925
+ ...properties.tableCss
926
+ });
927
+
928
+
929
+
930
+
931
+
932
+
933
+
934
+
935
+
936
+
937
+
938
+
939
+ // Set the CSS for each entry in the key
940
+ for (var i=0; i<properties.labels.length; i+=1) {
941
+ // Set Styles on each color blob
942
+ RGraph.setCSS(doc.getElementById('rgraph_html_key_blob_' + i),
943
+ {
944
+ display: 'inline-block',
945
+ marginRight: '5px',
946
+ marginTop: '4px',
947
+ width: '15px',
948
+ height: '15px',
949
+ backgroundColor: properties.colors[i],
950
+ ...properties.blobCss
951
+ });
952
+
953
+
954
+
955
+
956
+
957
+
958
+
959
+
960
+ // Set the CSS that comes from the labelCss property
961
+ RGraph.setCSS(
962
+ doc.getElementById('rgraph_html_key_label_' + i),
963
+ properties.labelCss
964
+ );
965
+
966
+
967
+
968
+
969
+
970
+
971
+
972
+
973
+ // If there are styles set for a particular label,
974
+ // apply those too
975
+ if (properties['labelCss_' + i]) {
976
+ RGraph.setCSS(
977
+ doc.getElementById('rgraph_html_key_label_' + i),
978
+ properties['labelCss_' + i]
979
+ );
980
+ }
981
+ }
982
+
983
+
984
+
985
+
986
+
987
+
988
+
989
+
990
+
991
+
992
+
993
+
994
+
995
+
996
+ // Return the TABLE object that is the HTML key
997
+ return doc.getElementById('rgraph_key_' + uid);
998
+ };
999
+
1000
+
1001
+
1002
+
1003
+ // End module pattern
1004
+ })(window, document);