rgraph-rails 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +4 -0
  5. data/CODE_OF_CONDUCT.md +13 -0
  6. data/Gemfile +4 -0
  7. data/README.md +73 -0
  8. data/Rakefile +6 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +7 -0
  11. data/lib/rgraph-rails/version.rb +3 -0
  12. data/lib/rgraph-rails.rb +8 -0
  13. data/license.txt +19 -0
  14. data/rgraph-rails.gemspec +26 -0
  15. data/vendor/assets/images/bg.png +0 -0
  16. data/vendor/assets/images/bullet.png +0 -0
  17. data/vendor/assets/images/facebook-large.png +0 -0
  18. data/vendor/assets/images/google-plus-large.png +0 -0
  19. data/vendor/assets/images/logo.png +0 -0
  20. data/vendor/assets/images/meter-image-sd-needle.png +0 -0
  21. data/vendor/assets/images/meter-image-sd.png +0 -0
  22. data/vendor/assets/images/meter-sketch-needle.png +0 -0
  23. data/vendor/assets/images/meter-sketch.png +0 -0
  24. data/vendor/assets/images/odometer-background.png +0 -0
  25. data/vendor/assets/images/rgraph.jpg +0 -0
  26. data/vendor/assets/images/title.png +0 -0
  27. data/vendor/assets/images/twitter-large.png +0 -0
  28. data/vendor/assets/javascripts/RGraph.bar.js +3246 -0
  29. data/vendor/assets/javascripts/RGraph.bipolar.js +2003 -0
  30. data/vendor/assets/javascripts/RGraph.common.annotate.js +399 -0
  31. data/vendor/assets/javascripts/RGraph.common.context.js +600 -0
  32. data/vendor/assets/javascripts/RGraph.common.core.js +4751 -0
  33. data/vendor/assets/javascripts/RGraph.common.csv.js +275 -0
  34. data/vendor/assets/javascripts/RGraph.common.deprecated.js +454 -0
  35. data/vendor/assets/javascripts/RGraph.common.dynamic.js +1194 -0
  36. data/vendor/assets/javascripts/RGraph.common.effects.js +1524 -0
  37. data/vendor/assets/javascripts/RGraph.common.key.js +735 -0
  38. data/vendor/assets/javascripts/RGraph.common.resizing.js +550 -0
  39. data/vendor/assets/javascripts/RGraph.common.tooltips.js +605 -0
  40. data/vendor/assets/javascripts/RGraph.common.zoom.js +223 -0
  41. data/vendor/assets/javascripts/RGraph.drawing.background.js +636 -0
  42. data/vendor/assets/javascripts/RGraph.drawing.circle.js +579 -0
  43. data/vendor/assets/javascripts/RGraph.drawing.image.js +810 -0
  44. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +710 -0
  45. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +672 -0
  46. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +568 -0
  47. data/vendor/assets/javascripts/RGraph.drawing.poly.js +623 -0
  48. data/vendor/assets/javascripts/RGraph.drawing.rect.js +603 -0
  49. data/vendor/assets/javascripts/RGraph.drawing.text.js +648 -0
  50. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +815 -0
  51. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +860 -0
  52. data/vendor/assets/javascripts/RGraph.fuel.js +965 -0
  53. data/vendor/assets/javascripts/RGraph.funnel.js +988 -0
  54. data/vendor/assets/javascripts/RGraph.gantt.js +1242 -0
  55. data/vendor/assets/javascripts/RGraph.gauge.js +1391 -0
  56. data/vendor/assets/javascripts/RGraph.hbar.js +1794 -0
  57. data/vendor/assets/javascripts/RGraph.hprogress.js +1307 -0
  58. data/vendor/assets/javascripts/RGraph.line.js +3940 -0
  59. data/vendor/assets/javascripts/RGraph.meter.js +1242 -0
  60. data/vendor/assets/javascripts/RGraph.modaldialog.js +292 -0
  61. data/vendor/assets/javascripts/RGraph.odo.js +1265 -0
  62. data/vendor/assets/javascripts/RGraph.pie.js +1979 -0
  63. data/vendor/assets/javascripts/RGraph.radar.js +1840 -0
  64. data/vendor/assets/javascripts/RGraph.rose.js +1860 -0
  65. data/vendor/assets/javascripts/RGraph.rscatter.js +1332 -0
  66. data/vendor/assets/javascripts/RGraph.scatter.js +3029 -0
  67. data/vendor/assets/javascripts/RGraph.thermometer.js +1131 -0
  68. data/vendor/assets/javascripts/RGraph.vprogress.js +1326 -0
  69. data/vendor/assets/javascripts/RGraph.waterfall.js +1252 -0
  70. data/vendor/assets/javascripts/financial-data.js +1067 -0
  71. data/vendor/assets/stylesheets/ModalDialog.css +90 -0
  72. data/vendor/assets/stylesheets/animations.css +3347 -0
  73. data/vendor/assets/stylesheets/website.css +402 -0
  74. metadata +175 -0
@@ -0,0 +1,735 @@
1
+ // version: 2015-11-02
2
+ /**
3
+ * o--------------------------------------------------------------------------------o
4
+ * | This file is part of the RGraph package - you can learn more at: |
5
+ * | |
6
+ * | http://www.rgraph.net |
7
+ * | |
8
+ * | RGraph is dual licensed under the Open Source GPL (General Public License) |
9
+ * | v2.0 license and a commercial license which means that you're not bound by |
10
+ * | the terms of the GPL. The commercial license is just �99 (GBP) and you can |
11
+ * | read about it here: |
12
+ * | http://www.rgraph.net/license |
13
+ * o--------------------------------------------------------------------------------o
14
+ */
15
+
16
+ RGraph = window.RGraph || {isRGraph: true};
17
+ RGraph.HTML = RGraph.HTML || {};
18
+
19
+ // Module pattern
20
+ (function (win, doc, undefined)
21
+ {
22
+ var RG = RGraph,
23
+ ua = navigator.userAgent,
24
+ ma = Math;
25
+
26
+
27
+
28
+
29
+ /**
30
+ * Draws the graph key (used by various graphs)
31
+ *
32
+ * @param object obj The graph object
33
+ * @param array key An array of the texts to be listed in the key
34
+ * @param colors An array of the colors to be used
35
+ */
36
+ RG.drawKey =
37
+ RG.DrawKey = function (obj, key, colors)
38
+ {
39
+ if (!key) {
40
+ return;
41
+ }
42
+
43
+ var ca = obj.canvas,
44
+ co = obj.context,
45
+ prop = obj.properties,
46
+
47
+ // Key positioned in the gutter
48
+ keypos = prop['chart.key.position'],
49
+ textsize = prop['chart.text.size'],
50
+ key_non_null = [],
51
+ colors_non_null = [];
52
+
53
+ co.lineWidth = 1;
54
+
55
+ co.beginPath();
56
+
57
+ /**
58
+ * Change the older chart.key.vpos to chart.key.position.y
59
+ */
60
+ if (typeof(prop['chart.key.vpos']) == 'number') {
61
+ obj.Set('chart.key.position.y', prop['chart.key.vpos'] * prop['chart.gutter.top']);
62
+ }
63
+
64
+ /**
65
+ * Account for null values in the key
66
+ */
67
+ for (var i=0; i<key.length; ++i) {
68
+ if (key[i] != null) {
69
+ colors_non_null.push(colors[i]);
70
+ key_non_null.push(key[i]);
71
+ }
72
+ }
73
+
74
+ key = key_non_null;
75
+ colors = colors_non_null;
76
+
77
+
78
+
79
+
80
+
81
+
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+
101
+
102
+
103
+ /**
104
+ * This does the actual drawing of the key when it's in the graph
105
+ *
106
+ * @param object obj The graph object
107
+ * @param array key The key items to draw
108
+ * @param array colors An aray of colors that the key will use
109
+ */
110
+ function DrawKey_graph (obj, key, colors)
111
+ {
112
+ var text_size = typeof(prop['chart.key.text.size']) == 'number' ? prop['chart.key.text.size'] : prop['chart.text.size'];
113
+ var text_italic = prop['chart.key.text.italic'] ? true : false
114
+ var text_bold = prop['chart.key.text.bold'] ? true : false
115
+ var text_font = prop['chart.key.text.font'] || prop['chart.key.font'] || prop['chart.text.font'];
116
+
117
+ var gutterLeft = obj.gutterLeft;
118
+ var gutterRight = obj.gutterRight;
119
+ var gutterTop = obj.gutterTop;
120
+ var gutterBottom = obj.gutterBottom;
121
+ var hpos = prop['chart.yaxispos'] == 'right' ? gutterLeft + 10 : ca.width - gutterRight - 10;
122
+ var vpos = gutterTop + 10;
123
+ var title = prop['chart.title'];
124
+ var blob_size = text_size; // The blob of color
125
+ var hmargin = 8; // This is the size of the gaps between the blob of color and the text
126
+ var vmargin = 4; // This is the vertical margin of the key
127
+ var fillstyle = prop['chart.key.background'];
128
+ var text_color = prop['chart.key.text.color'];
129
+ var strokestyle = '#333';
130
+ var height = 0;
131
+ var width = 0;
132
+
133
+ if (!obj.coords) obj.coords = {};
134
+ obj.coords.key = [];
135
+
136
+
137
+ // Need to set this so that measuring the text works out OK
138
+ co.font = text_size + 'pt ' + prop['chart.text.font'];
139
+
140
+ // Work out the longest bit of text
141
+ for (i=0; i<key.length; ++i) {
142
+ width = Math.max(width, co.measureText(key[i]).width);
143
+ }
144
+
145
+ width += 5;
146
+ width += blob_size;
147
+ width += 5;
148
+ width += 5;
149
+ width += 5;
150
+
151
+ /**
152
+ * Now we know the width, we can move the key left more accurately
153
+ */
154
+ if ( prop['chart.yaxispos'] == 'left'
155
+ || (obj.type === 'pie' && !prop['chart.yaxispos'])
156
+ || (obj.type === 'hbar' && !prop['chart.yaxispos'])
157
+ || (obj.type === 'hbar' && prop['chart.yaxispos'] === 'center')
158
+ || (obj.type === 'hbar' && prop['chart.yaxispos'] === 'right')
159
+ || (obj.type === 'rscatter' && !prop['chart.yaxispos'])
160
+ || (obj.type === 'radar' && !prop['chart.yaxispos'])
161
+ || (obj.type === 'rose' && !prop['chart.yaxispos'])
162
+ || (obj.type === 'funnel' && !prop['chart.yaxispos'])
163
+ || (obj.type === 'vprogress' && !prop['chart.yaxispos'])
164
+ || (obj.type === 'hprogress' && !prop['chart.yaxispos'])
165
+ ) {
166
+
167
+ hpos -= width;
168
+ }
169
+
170
+ /**
171
+ * Horizontal alignment
172
+ */
173
+ if (typeof(prop['chart.key.halign']) == 'string') {
174
+ if (prop['chart.key.halign'] == 'left') {
175
+ hpos = gutterLeft + 10;
176
+ } else if (prop['chart.key.halign'] == 'right') {
177
+ hpos = ca.width - gutterRight - width;
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Specific location coordinates
183
+ */
184
+ if (typeof(prop['chart.key.position.x']) == 'number') {
185
+ hpos = prop['chart.key.position.x'];
186
+ }
187
+
188
+ if (typeof(prop['chart.key.position.y']) == 'number') {
189
+ vpos = prop['chart.key.position.y'];
190
+ }
191
+
192
+
193
+ // Stipulate the shadow for the key box
194
+ if (prop['chart.key.shadow']) {
195
+ co.shadowColor = prop['chart.key.shadow.color'];
196
+ co.shadowBlur = prop['chart.key.shadow.blur'];
197
+ co.shadowOffsetX = prop['chart.key.shadow.offsetx'];
198
+ co.shadowOffsetY = prop['chart.key.shadow.offsety'];
199
+ }
200
+
201
+
202
+
203
+
204
+ // Draw the box that the key resides in
205
+ co.beginPath();
206
+ co.fillStyle = prop['chart.key.background'];
207
+ co.strokeStyle = 'black';
208
+
209
+ if (typeof(prop['chart.key.position.graph.boxed']) == 'undefined' || (typeof(prop['chart.key.position.graph.boxed']) == 'boolean' && prop['chart.key.position.graph.boxed']) ) {
210
+ if (arguments[3] != false) {
211
+
212
+ co.lineWidth = typeof(prop['chart.key.linewidth']) == 'number' ? prop['chart.key.linewidth'] : 1;
213
+
214
+ // The older square rectangled key
215
+ if (prop['chart.key.rounded'] == true) {
216
+ co.beginPath();
217
+ co.strokeStyle = strokestyle;
218
+ RG.strokedCurvyRect(co, Math.round(hpos), Math.round(vpos), width - 5, 5 + ( (text_size + 5) * RG.getKeyLength(key)),4);
219
+ co.stroke();
220
+ co.fill();
221
+
222
+ RG.NoShadow(obj);
223
+
224
+ } else {
225
+ co.strokeRect(Math.round(hpos), Math.round(vpos), width - 5, 5 + ( (text_size + 5) * RG.getKeyLength(key)));
226
+ co.fillRect(Math.round(hpos), Math.round(vpos), width - 5, 5 + ( (text_size + 5) * RG.getKeyLength(key)));
227
+ }
228
+ }
229
+ }
230
+
231
+ RG.NoShadow(obj);
232
+
233
+ co.beginPath();
234
+
235
+ /**
236
+ * Custom colors for the key
237
+ */
238
+ if (prop['chart.key.colors']) {
239
+ colors = prop['chart.key.colors'];
240
+ }
241
+
242
+
243
+
244
+ ////////////////////////////////////////////////////////////////////////////////////////////
245
+
246
+
247
+
248
+ // Draw the labels given
249
+ for (var i=key.length - 1; i>=0; i--) {
250
+
251
+ var j = Number(i) + 1;
252
+
253
+ /**
254
+ * Draw the blob of color
255
+ */
256
+ if (typeof(prop['chart.key.color.shape']) == 'object' && typeof(prop['chart.key.color.shape'][i]) == 'string') {
257
+ var blob_shape = prop['chart.key.color.shape'][i];
258
+
259
+ } else if (typeof(prop['chart.key.color.shape']) == 'string') {
260
+ var blob_shape = prop['chart.key.color.shape'];
261
+ } else {
262
+ var blob_shape = 'square';
263
+ }
264
+
265
+ if (blob_shape == 'circle') {
266
+ co.beginPath();
267
+ co.fillStyle = colors[i];
268
+ 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);
269
+ co.fill();
270
+
271
+ } else if (blob_shape == 'line') {
272
+ co.beginPath();
273
+ co.strokeStyle = colors[i];
274
+ co.moveTo(hpos + 5, vpos + (5 * j) + (text_size * j) - text_size + (blob_size / 2));
275
+ co.lineTo(hpos + blob_size + 5, vpos + (5 * j) + (text_size * j) - text_size + (blob_size / 2));
276
+ co.stroke();
277
+
278
+ } else if (blob_shape == 'triangle') {
279
+ co.beginPath();
280
+ co.strokeStyle = colors[i];
281
+ co.moveTo(hpos + 5, vpos + (5 * j) + (text_size * j) - text_size + blob_size);
282
+ co.lineTo(hpos + (blob_size / 2) + 5, vpos + (5 * j) + (text_size * j) - text_size );
283
+ co.lineTo(hpos + blob_size + 5, vpos + (5 * j) + (text_size * j) - text_size + blob_size);
284
+ co.closePath();
285
+ co.fillStyle = colors[i];
286
+ co.fill();
287
+
288
+ } else {
289
+ co.fillStyle = colors[i];
290
+ co.fillRect(hpos + 5, vpos + (5 * j) + (text_size * j) - text_size, text_size, text_size + 1);
291
+ }
292
+
293
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////
294
+
295
+
296
+
297
+ co.beginPath();
298
+ co.fillStyle = typeof text_color == 'object' ? text_color[i] : text_color;
299
+
300
+ ret = RG.Text2(obj, {'font': text_font,
301
+ 'size': text_size,
302
+ 'bold': text_bold,
303
+ 'italic': text_italic,
304
+ 'x': hpos + blob_size + 5 + 5,
305
+ 'y': vpos + (5 * j) + (text_size * j) + 3,
306
+ 'text': key[i]});
307
+
308
+ obj.coords.key[i] = [ret.x, ret.y, ret.width, ret.height, key[i], colors[i], obj];
309
+ }
310
+ co.fill();
311
+ }
312
+
313
+
314
+
315
+
316
+
317
+
318
+
319
+
320
+
321
+
322
+
323
+
324
+
325
+
326
+
327
+
328
+
329
+
330
+
331
+
332
+
333
+
334
+
335
+ /**
336
+ * This does the actual drawing of the key when it's in the gutter
337
+ *
338
+ * @param object obj The graph object
339
+ * @param array key The key items to draw
340
+ * @param array colors An aray of colors that the key will use
341
+ */
342
+ function DrawKey_gutter (obj, key, colors)
343
+ {
344
+ var text_size = typeof(prop['chart.key.text.size']) == 'number' ? prop['chart.key.text.size'] : prop['chart.text.size'],
345
+ text_bold = prop['chart.key.text.bold'],
346
+ text_italic = prop['chart.key.text.italic'],
347
+ text_font = prop['chart.key.text.font'] || prop['chart.key.font'] || prop['chart.text.font'],
348
+ text_color = prop['chart.key.text.color'],
349
+ gutterLeft = obj.gutterLeft,
350
+ gutterRight = obj.gutterRight,
351
+ gutterTop = obj.gutterTop,
352
+ gutterBottom = obj.gutterBottom,
353
+ hpos = ((ca.width - gutterLeft - gutterRight) / 2) + obj.gutterLeft,
354
+ vpos = gutterTop - text_size - 5,
355
+ title = prop['chart.title'],
356
+ blob_size = text_size, // The blob of color
357
+ hmargin = 8, // This is the size of the gaps between the blob of color and the text
358
+ vmargin = 4, // This is the vertical margin of the key
359
+ fillstyle = prop['chart.key.background'],
360
+ strokestyle = '#999',
361
+ length = 0;
362
+
363
+ if (!obj.coords) obj.coords = {};
364
+ obj.coords.key = [];
365
+
366
+
367
+
368
+ // Need to work out the length of the key first
369
+ co.font = text_size + 'pt ' + text_font;
370
+ for (i=0; i<key.length; ++i) {
371
+ length += hmargin;
372
+ length += blob_size;
373
+ length += hmargin;
374
+ length += co.measureText(key[i]).width;
375
+ }
376
+ length += hmargin;
377
+
378
+
379
+
380
+
381
+ /**
382
+ * Work out hpos since in the Pie it isn't necessarily dead center
383
+ */
384
+ if (obj.type == 'pie') {
385
+ if (prop['chart.align'] == 'left') {
386
+ var hpos = obj.radius + gutterLeft;
387
+
388
+ } else if (prop['chart.align'] == 'right') {
389
+ var hpos = ca.width - obj.radius - gutterRight;
390
+
391
+ } else {
392
+ hpos = ca.width / 2;
393
+ }
394
+ }
395
+
396
+
397
+
398
+
399
+
400
+ /**
401
+ * This makes the key centered
402
+ */
403
+ hpos -= (length / 2);
404
+
405
+
406
+ /**
407
+ * Override the horizontal/vertical positioning
408
+ */
409
+ if (typeof(prop['chart.key.position.x']) == 'number') {
410
+ hpos = prop['chart.key.position.x'];
411
+ }
412
+ if (typeof(prop['chart.key.position.y']) == 'number') {
413
+ vpos = prop['chart.key.position.y'];
414
+ }
415
+
416
+
417
+
418
+ /**
419
+ * Draw the box that the key sits in
420
+ */
421
+ if (obj.Get('chart.key.position.gutter.boxed')) {
422
+
423
+ if (prop['chart.key.shadow']) {
424
+ co.shadowColor = prop['chart.key.shadow.color'];
425
+ co.shadowBlur = prop['chart.key.shadow.blur'];
426
+ co.shadowOffsetX = prop['chart.key.shadow.offsetx'];
427
+ co.shadowOffsetY = prop['chart.key.shadow.offsety'];
428
+ }
429
+
430
+
431
+ co.beginPath();
432
+ co.fillStyle = fillstyle;
433
+ co.strokeStyle = strokestyle;
434
+
435
+ if (prop['chart.key.rounded']) {
436
+ RG.strokedCurvyRect(co, hpos, vpos - vmargin, length, text_size + vmargin + vmargin)
437
+ // Odd... RG.filledCurvyRect(co, hpos, vpos - vmargin, length, text_size + vmargin + vmargin);
438
+ } else {
439
+ co.rect(hpos, vpos - vmargin, length, text_size + vmargin + vmargin);
440
+ }
441
+
442
+ co.stroke();
443
+ co.fill();
444
+
445
+
446
+ RG.NoShadow(obj);
447
+ }
448
+
449
+
450
+ /**
451
+ * Draw the blobs of color and the text
452
+ */
453
+
454
+ // Custom colors for the key
455
+ if (prop['chart.key.colors']) {
456
+ colors = prop['chart.key.colors'];
457
+ }
458
+
459
+ for (var i=0, pos=hpos; i<key.length; ++i) {
460
+ pos += hmargin;
461
+
462
+
463
+
464
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
465
+
466
+
467
+
468
+ // Draw the blob of color
469
+ if (typeof(prop['chart.key.color.shape']) == 'object' && typeof(prop['chart.key.color.shape'][i]) == 'string') {
470
+ var blob_shape = prop['chart.key.color.shape'][i];
471
+
472
+ } else if (typeof(prop['chart.key.color.shape']) == 'string') {
473
+ var blob_shape = prop['chart.key.color.shape'];
474
+
475
+ } else {
476
+ var blob_shape = 'square';
477
+ }
478
+
479
+
480
+ /**
481
+ * Draw the blob of color - line
482
+ */
483
+ if (blob_shape =='line') {
484
+
485
+ co.beginPath();
486
+ co.strokeStyle = colors[i];
487
+ co.moveTo(pos, vpos + (blob_size / 2));
488
+ co.lineTo(pos + blob_size, vpos + (blob_size / 2));
489
+ co.stroke();
490
+
491
+ // Circle
492
+ } else if (blob_shape == 'circle') {
493
+
494
+ co.beginPath();
495
+ co.fillStyle = colors[i];
496
+ co.moveTo(pos, vpos + (blob_size / 2));
497
+ co.arc(pos + (blob_size / 2), vpos + (blob_size / 2), (blob_size / 2), 0, 6.28, 0);
498
+ co.fill();
499
+
500
+ } else if (blob_shape == 'triangle') {
501
+
502
+ co.fillStyle = colors[i];
503
+ co.beginPath();
504
+ co.strokeStyle = colors[i];
505
+ co.moveTo(pos, vpos + blob_size);
506
+ co.lineTo(pos + (blob_size / 2), vpos);
507
+ co.lineTo(pos + blob_size, vpos + blob_size);
508
+ co.closePath();
509
+ co.fill();
510
+
511
+ } else {
512
+
513
+ co.beginPath();
514
+ co.fillStyle = colors[i];
515
+ co.rect(pos, vpos, blob_size, blob_size);
516
+ co.fill();
517
+ }
518
+
519
+
520
+
521
+ //////////////////////////////////////////////////////////////////////////////////////////////////////
522
+
523
+
524
+
525
+
526
+ pos += blob_size;
527
+
528
+ pos += hmargin;
529
+
530
+ co.beginPath();
531
+ co.fillStyle = typeof text_color == 'object' ? text_color[i] : text_color;;
532
+ var ret = RG.Text2(obj, {
533
+ 'font':text_font,
534
+ 'bold':text_bold,
535
+ 'size':text_size,
536
+ 'italic': text_italic,
537
+ 'x':pos,
538
+ 'y':vpos + text_size + 3,
539
+ 'text': key[i]
540
+ });
541
+ co.fill();
542
+ pos += co.measureText(key[i]).width;
543
+
544
+ obj.coords.key[i] = [ret.x, ret.y, ret.width, ret.height, key[i], colors[i], obj];
545
+ }
546
+ }
547
+
548
+
549
+
550
+
551
+ if (keypos && keypos == 'gutter') {
552
+ DrawKey_gutter(obj, key, colors);
553
+ } else if (keypos && keypos == 'graph') {
554
+ DrawKey_graph(obj, key, colors);
555
+ } else {
556
+ alert('[COMMON] (' + obj.id + ') Unknown key position: ' + keypos);
557
+ }
558
+
559
+
560
+
561
+
562
+
563
+
564
+ if (prop['chart.key.interactive']) {
565
+
566
+ if (!RGraph.Drawing || !RGraph.Drawing.Rect) {
567
+ alert('[INTERACTIVE KEY] The drawing API Rect library does not appear to have been included (which the interactive key uses)');
568
+ }
569
+
570
+
571
+
572
+ /**
573
+ * Check that the RGraph.common.dynamic.js file has been included
574
+ */
575
+ if (!RGraph.InstallWindowMousedownListener) {
576
+ alert('[INTERACTIVE KEY] The dynamic library does not appear to have been included');
577
+ }
578
+
579
+
580
+
581
+ // Determine the maximum width of the labels
582
+ for (var i=0,len=obj.coords.key.length,maxlen=0; i<len; i+=1) {
583
+ maxlen = Math.max(maxlen, obj.coords.key[i][2]);
584
+ }
585
+
586
+
587
+ //obj.coords.key.forEach(function (value, index, arr)
588
+ //{
589
+ for (var i=0,len=obj.coords.key.length; i<len; i+=1) {
590
+
591
+ // Because the loop would have finished when the i variable is needed - put
592
+ // the onclick function inside a new context so that the value of the i
593
+ // variable is what we expect when the key has been clicked
594
+ (function (idx)
595
+ {
596
+ var arr = obj.coords.key;
597
+ var value = obj.coords.key[idx];
598
+ var index = idx;
599
+
600
+
601
+ var rect = new RGraph.Drawing.Rect(obj.id,value[0], value[1], prop['chart.key.position'] == 'gutter' ? value[2] : maxlen, value[3])
602
+ .Set('fillstyle', 'rgba(0,0,0,0)')
603
+ .Draw();
604
+
605
+ rect.onclick = function (e, shape)
606
+ {
607
+ var co = rect.context;
608
+
609
+ co.fillStyle = prop['chart.key.interactive.highlight.label'];
610
+ co.fillRect(shape.x, shape.y, shape.width, shape.height);
611
+
612
+ if (typeof obj.interactiveKeyHighlight == 'function') {
613
+
614
+ obj.Set('chart.key.interactive.index', idx);
615
+
616
+ RG.FireCustomEvent(obj, 'onbeforeinteractivekey');
617
+ obj.interactiveKeyHighlight(index);
618
+ RG.FireCustomEvent(obj, 'onafterinteractivekey');
619
+ }
620
+ }
621
+
622
+ rect.onmousemove = function (e, shape)
623
+ {
624
+ e.target.style.cursor = 'pointer';
625
+ }
626
+ })(i);
627
+ }
628
+ }
629
+ };
630
+
631
+
632
+
633
+
634
+ /**
635
+ * Returns the key length, but accounts for null values
636
+ *
637
+ * @param array key The key elements
638
+ */
639
+ RG.getKeyLength = function (key)
640
+ {
641
+ var length = 0;
642
+
643
+ for (var i=0,len=key.length; i<len; i+=1) {
644
+ if (key[i] != null) {
645
+ ++length;
646
+ }
647
+ }
648
+
649
+ return length;
650
+ };
651
+
652
+
653
+
654
+
655
+ /**
656
+ * Create a TABLE based HTML key. There's lots of options so it's
657
+ * suggested that you consult the documentation page
658
+ *
659
+ * @param mixed id This should be a string consisting of the ID of the container
660
+ * @param object prop An object map of the various properties that you can use to
661
+ * configure the key. See the documentation page for a list.
662
+ */
663
+ RGraph.HTML.key =
664
+ RGraph.HTML.Key = function (id, prop)
665
+ {
666
+ var div = doc.getElementById(id);
667
+
668
+
669
+ /**
670
+ * Create the table that becomes the key
671
+ */
672
+ var str = '<table border="0" cellspacing="0" cellpadding="0" id="rgraph_key" style="display: inline;' + (function ()
673
+ {
674
+ var style = ''
675
+ for (i in prop.tableCss) {
676
+ if (typeof i === 'string') {
677
+ style = style + i + ': ' + prop.tableCss[i] + ';';
678
+ }
679
+ }
680
+ return style;
681
+ })() + '" ' + (prop.tableClass ? 'class="' + prop.tableClass + '"' : '') + '>';
682
+
683
+
684
+
685
+ /**
686
+ * Add the individual key elements
687
+ */
688
+ for (var i=0; i<prop.labels.length; i+=1) {
689
+ str += '<tr><td><div style="' + (function ()
690
+ {
691
+ var style = '';
692
+
693
+ for (var j in prop.blobCss) {
694
+ if (typeof j === 'string') {
695
+ style = style + j + ': ' + prop.blobCss[j] + ';';
696
+ }
697
+ }
698
+
699
+ return style;
700
+ })() + '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 + '"' : '') + '" ' + (function ()
701
+ {
702
+ var style = '';
703
+
704
+ for (var j in prop.labelCss) {
705
+ if (typeof j === 'string') {
706
+ style = style + j + ': ' + prop.labelCss[j] + ';';
707
+ }
708
+ }
709
+
710
+ return style;
711
+ })() + (function ()
712
+ {
713
+ var style = '';
714
+
715
+ if (prop['labelCss_' + i]) {
716
+ for (var j in prop['labelCss_' + i]) {
717
+ style = style + j + ': ' + prop['labelCss_' + i][j] + ';';
718
+ }
719
+ }
720
+
721
+ return style ? 'style="' + style + '"' : '';
722
+ })() + '>' + prop.labels[i] + '</span>' + (prop.links && prop.links[i] ? '</a>' : '') + '</td></tr>';
723
+ }
724
+
725
+ div.innerHTML += (str + '</table>');
726
+
727
+ // Return the TABLE object that is the HTML key
728
+ return doc.getElementById('rgraph_key');
729
+ };
730
+
731
+
732
+
733
+
734
+ // End module pattern
735
+ })(window, document);