rgraph-rails 1.0.5 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +0 -1
  3. data/README.md +3 -3
  4. data/lib/rgraph-rails/version.rb +1 -1
  5. data/vendor/assets/javascripts/RGraph.bar.js +239 -3764
  6. data/vendor/assets/javascripts/RGraph.bipolar.js +115 -1986
  7. data/vendor/assets/javascripts/RGraph.common.annotate.js +35 -399
  8. data/vendor/assets/javascripts/RGraph.common.context.js +30 -600
  9. data/vendor/assets/javascripts/RGraph.common.core.js +403 -5187
  10. data/vendor/assets/javascripts/RGraph.common.csv.js +19 -275
  11. data/vendor/assets/javascripts/RGraph.common.deprecated.js +35 -454
  12. data/vendor/assets/javascripts/RGraph.common.dynamic.js +84 -1189
  13. data/vendor/assets/javascripts/RGraph.common.effects.js +90 -1548
  14. data/vendor/assets/javascripts/RGraph.common.key.js +54 -755
  15. data/vendor/assets/javascripts/RGraph.common.resizing.js +37 -567
  16. data/vendor/assets/javascripts/RGraph.common.sheets.js +29 -356
  17. data/vendor/assets/javascripts/RGraph.common.tooltips.js +32 -614
  18. data/vendor/assets/javascripts/RGraph.common.zoom.js +14 -223
  19. data/vendor/assets/javascripts/RGraph.cornergauge.js +71 -0
  20. data/vendor/assets/javascripts/RGraph.drawing.background.js +35 -620
  21. data/vendor/assets/javascripts/RGraph.drawing.circle.js +35 -576
  22. data/vendor/assets/javascripts/RGraph.drawing.image.js +52 -807
  23. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +41 -717
  24. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +37 -668
  25. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +36 -563
  26. data/vendor/assets/javascripts/RGraph.drawing.poly.js +40 -608
  27. data/vendor/assets/javascripts/RGraph.drawing.rect.js +35 -597
  28. data/vendor/assets/javascripts/RGraph.drawing.text.js +34 -642
  29. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +50 -809
  30. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +51 -856
  31. data/vendor/assets/javascripts/RGraph.fuel.js +58 -964
  32. data/vendor/assets/javascripts/RGraph.funnel.js +55 -984
  33. data/vendor/assets/javascripts/RGraph.gantt.js +75 -1241
  34. data/vendor/assets/javascripts/RGraph.gauge.js +87 -1397
  35. data/vendor/assets/javascripts/RGraph.hbar.js +143 -2376
  36. data/vendor/assets/javascripts/RGraph.hprogress.js +80 -1397
  37. data/vendor/assets/javascripts/RGraph.line.js +241 -4162
  38. data/vendor/assets/javascripts/RGraph.meter.js +74 -1278
  39. metadata +3 -30
  40. data/vendor/assets/images/bg.png +0 -0
  41. data/vendor/assets/images/bullet.png +0 -0
  42. data/vendor/assets/images/facebook-large.png +0 -0
  43. data/vendor/assets/images/google-plus-large.png +0 -0
  44. data/vendor/assets/images/logo.png +0 -0
  45. data/vendor/assets/images/meter-image-sd-needle.png +0 -0
  46. data/vendor/assets/images/meter-image-sd.png +0 -0
  47. data/vendor/assets/images/meter-sketch-needle.png +0 -0
  48. data/vendor/assets/images/meter-sketch.png +0 -0
  49. data/vendor/assets/images/odometer-background.png +0 -0
  50. data/vendor/assets/images/rgraph.jpg +0 -0
  51. data/vendor/assets/images/title.png +0 -0
  52. data/vendor/assets/images/twitter-large.png +0 -0
  53. data/vendor/assets/javascripts/RGraph.modaldialog.js +0 -301
  54. data/vendor/assets/javascripts/RGraph.odo.js +0 -1265
  55. data/vendor/assets/javascripts/RGraph.pie.js +0 -2272
  56. data/vendor/assets/javascripts/RGraph.radar.js +0 -1847
  57. data/vendor/assets/javascripts/RGraph.rose.js +0 -1877
  58. data/vendor/assets/javascripts/RGraph.rscatter.js +0 -1425
  59. data/vendor/assets/javascripts/RGraph.scatter.js +0 -2970
  60. data/vendor/assets/javascripts/RGraph.semicircularprogress.js +0 -1015
  61. data/vendor/assets/javascripts/RGraph.thermometer.js +0 -1129
  62. data/vendor/assets/javascripts/RGraph.vprogress.js +0 -1452
  63. data/vendor/assets/javascripts/RGraph.waterfall.js +0 -1252
  64. data/vendor/assets/javascripts/financial-data.js +0 -1067
  65. data/vendor/assets/stylesheets/ModalDialog.css +0 -90
  66. data/vendor/assets/stylesheets/animations.css +0 -3347
  67. data/vendor/assets/stylesheets/website.css +0 -446
@@ -1,985 +1,56 @@
1
- // version: 2016-06-04
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
1
 
16
- RGraph = window.RGraph || {isRGraph: true};
17
-
18
- /**
19
- * The bar chart constructor
20
- *
21
- * @param object canvas The canvas object
22
- * @param array data The chart data
23
- */
24
- RGraph.Funnel = function (conf)
25
- {
26
- /**
27
- * Allow for object config style
28
- */
29
- if ( typeof conf === 'object'
30
- && typeof conf.data === 'object'
31
- && typeof conf.id === 'string') {
32
-
33
- var id = conf.id
34
- var canvas = document.getElementById(id);
35
- var data = conf.data;
36
- var parseConfObjectForOptions = true; // Set this so the config is parsed (at the end of the constructor)
37
-
38
- } else {
39
-
40
- var id = conf;
41
- var canvas = document.getElementById(id);
42
- var data = arguments[1];
43
- }
44
-
45
-
46
- this.id = id;
47
- this.canvas = canvas;
48
- this.context = this.canvas.getContext ? this.canvas.getContext("2d", {alpha: (typeof id === 'object' && id.alpha === false) ? false : true}) : null;
49
- this.canvas.__object__ = this;
50
- this.type = 'funnel';
51
- this.coords = [];
52
- this.isRGraph = true;
53
- this.uid = RGraph.CreateUID();
54
- this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.CreateUID();
55
- this.coordsText = [];
56
- this.original_colors = [];
57
- this.firstDraw = true; // After the first draw this will be false
58
-
59
-
60
-
61
- // Check for support
62
- if (!this.canvas) {
63
- alert('[FUNNEL] No canvas support');
64
- return;
65
- }
66
-
67
- /**
68
- * The funnel charts properties
69
- */
70
- this.properties =
71
- {
72
- 'chart.strokestyle': 'rgba(0,0,0,0)',
73
- 'chart.gutter.left': 25,
74
- 'chart.gutter.right': 25,
75
- 'chart.gutter.top': 25,
76
- 'chart.gutter.bottom': 25,
77
- 'chart.labels': null,
78
- 'chart.labels.sticks': false,
79
- 'chart.labels.x': null,
80
- 'chart.title': '',
81
- 'chart.title.background': null,
82
- 'chart.title.hpos': null,
83
- 'chart.title.vpos': null,
84
- 'chart.title.bold': true,
85
- 'chart.title.font': null,
86
- 'chart.title.x': null,
87
- 'chart.title.y': null,
88
- 'chart.title.halign': null,
89
- 'chart.title.valign': null,
90
- 'chart.colors': [
91
- 'Gradient(white:red)',
92
- 'Gradient(white:green)',
93
- 'Gradient(white:gray)',
94
- 'Gradient(white:blue)',
95
- 'Gradient(white:black)',
96
- 'Gradient(white:gray)',
97
- 'Gradient(white:pink)',
98
- 'Gradient(white:blue)',
99
- 'Gradient(white:yellow)',
100
- 'Gradient(white:green)',
101
- 'Gradient(white:red)'
102
- ],
103
- 'chart.text.size': 12,
104
- 'chart.text.boxed': true,
105
- 'chart.text.halign': 'left',
106
- 'chart.text.color': 'black',
107
- 'chart.text.font': 'Segoe UI, Arial, Verdana, sans-serif',
108
- 'chart.text.accessible': true,
109
- 'chart.text.accessible.overflow': 'visible',
110
- 'chart.text.accessible.pointerevents': false,
111
- 'chart.contextmenu': null,
112
- 'chart.shadow': false,
113
- 'chart.shadow.color': '#666',
114
- 'chart.shadow.blur': 3,
115
- 'chart.shadow.offsetx': 3,
116
- 'chart.shadow.offsety': 3,
117
- 'chart.key': null,
118
- 'chart.key.background': 'white',
119
- 'chart.key.position': 'graph',
120
- 'chart.key.halign': 'right',
121
- 'chart.key.shadow': false,
122
- 'chart.key.shadow.color': '#666',
123
- 'chart.key.shadow.blur': 3,
124
- 'chart.key.shadow.offsetx': 2,
125
- 'chart.key.shadow.offsety': 2,
126
- 'chart.key.position.gutter.boxed': false,
127
- 'chart.key.position.x': null,
128
- 'chart.key.position.y': null,
129
- 'chart.key.color.shape': 'square',
130
- 'chart.key.rounded': true,
131
- 'chart.key.linewidth': 1,
132
- 'chart.key.colors': null,
133
- 'chart.key.interactive': false,
134
- 'chart.key.interactive.highlight.chart.stroke': 'black',
135
- 'chart.key.interactive.highlight.chart.fill': 'rgba(255,255,255,0.7)',
136
- 'chart.key.interactive.highlight.label': 'rgba(255,0,0,0.2)',
137
- 'chart.key.text.color': 'black',
138
- 'chart.tooltips': null,
139
- 'chart.tooltips.effect': 'fade',
140
- 'chart.tooltips.css.class': 'RGraph_tooltip',
141
- 'chart.tooltips.event': 'onclick',
142
- 'chart.highlight.stroke': 'rgba(0,0,0,0)',
143
- 'chart.highlight.fill': 'rgba(255,255,255,0.7)',
144
- 'chart.tooltips.highlight': true,
145
- 'chart.annotatable': false,
146
- 'chart.annotate.color': 'black',
147
- 'chart.zoom.factor': 1.5,
148
- 'chart.zoom.fade.in': true,
149
- 'chart.zoom.fade.out': true,
150
- 'chart.zoom.factor': 1.5,
151
- 'chart.zoom.fade.in': true,
152
- 'chart.zoom.fade.out': true,
153
- 'chart.zoom.hdir': 'right',
154
- 'chart.zoom.vdir': 'down',
155
- 'chart.zoom.frames': 25,
156
- 'chart.zoom.delay': 16.666,
157
- 'chart.zoom.shadow': true,
158
- 'chart.zoom.background': true,
159
- 'chart.zoom.action': 'zoom',
160
- 'chart.resizable': false,
161
- 'chart.events.click': null,
162
- 'chart.events.mousemove': null,
163
- 'chart.clearto': 'rgba(0,0,0,0)'
164
- }
165
-
166
- // Store the data
167
- for (var i=0; i<data.length; ++i) {
168
- data[i] = parseFloat(data[i]);
169
- }
170
- this.data = data;
171
-
172
-
173
- /**
174
- * Create the dollar objects so that functions can be added to them
175
- */
176
- for (var i=0; i<data.length; ++i) {
177
- this['$' + i] = {};
178
- }
179
-
180
-
181
- /**
182
- * Translate half a pixel for antialiasing purposes - but only if it hasn't beeen
183
- * done already
184
- */
185
- if (!this.canvas.__rgraph_aa_translated__) {
186
- this.context.translate(0.5,0.5);
187
-
188
- this.canvas.__rgraph_aa_translated__ = true;
189
- }
190
-
191
-
192
-
193
-
194
- // Short variable names
195
- var RG = RGraph,
196
- ca = this.canvas,
197
- co = ca.getContext('2d'),
198
- prop = this.properties,
199
- pa2 = RG.path2,
200
- win = window,
201
- doc = document,
202
- ma = Math
203
-
204
-
205
-
206
- /**
207
- * "Decorate" the object with the generic effects if the effects library has been included
208
- */
209
- if (RG.Effects && typeof RG.Effects.decorate === 'function') {
210
- RG.Effects.decorate(this);
211
- }
212
-
213
-
214
-
215
-
216
- /**
217
- * A setter
218
- *
219
- * @param name string The name of the property to set
220
- * @param value mixed The value of the property
221
- */
222
- this.set =
223
- this.Set = function (name)
224
- {
225
- var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
226
-
227
- /**
228
- * the number of arguments is only one and it's an
229
- * object - parse it for configuration data and return.
230
- */
231
- if (arguments.length === 1 && typeof name === 'object') {
232
- RG.parseObjectStyleConfig(this, name);
233
- return this;
234
- }
235
-
236
-
237
-
238
-
239
-
240
- /**
241
- * This should be done first - prepend the propertyy name with "chart." if necessary
242
- */
243
- if (name.substr(0,6) != 'chart.') {
244
- name = 'chart.' + name;
245
- }
246
-
247
-
248
-
249
-
250
- // Convert uppercase letters to dot+lower case letter
251
- while(name.match(/([A-Z])/)) {
252
- name = name.replace(/([A-Z])/, '.' + RegExp.$1.toLowerCase());
253
- }
254
-
255
-
256
-
257
-
258
-
259
-
260
- prop[name] = value;
261
-
262
- return this;
263
- };
264
-
265
-
266
-
267
-
268
- /**
269
- * A getter
270
- *
271
- * @param name string The name of the property to get
272
- */
273
- this.get =
274
- this.Get = function (name)
275
- {
276
- /**
277
- * This should be done first - prepend the property name with "chart." if necessary
278
- */
279
- if (name.substr(0,6) != 'chart.') {
280
- name = 'chart.' + name;
281
- }
282
-
283
- // Convert uppercase letters to dot+lower case letter
284
- name = name.replace(/([A-Z])/g, function (str)
285
- {
286
- return '.' + String(RegExp.$1).toLowerCase()
287
- });
288
-
289
- return prop[name.toLowerCase()];
290
- };
291
-
292
-
293
-
294
-
295
- /**
296
- * The function you call to draw the bar chart
297
- */
298
- this.draw =
299
- this.Draw = function ()
300
- {
301
- /**
302
- * Fire the onbeforedraw event
303
- */
304
- RG.FireCustomEvent(this, 'onbeforedraw');
305
-
306
-
307
- /**
308
- * Parse the colors. This allows for simple gradient syntax
309
- */
310
- if (!this.colorsParsed) {
311
- this.parseColors();
312
-
313
- // Don't want to do this again
314
- this.colorsParsed = true;
315
- }
316
-
317
-
318
- /**
319
- * This is new in May 2011 and facilitates indiviual gutter settings,
320
- * eg chart.gutter.left
321
- */
322
- this.gutterLeft = prop['chart.gutter.left'];
323
- this.gutterRight = prop['chart.gutter.right'];
324
- this.gutterTop = prop['chart.gutter.top'];
325
- this.gutterBottom = prop['chart.gutter.bottom'];
326
-
327
- // This stops the coords array from growing
328
- this.coords = [];
329
-
330
- /**
331
- * Stop this growing uncntrollably
332
- */
333
- this.coordsText = [];
334
-
335
- RG.DrawTitle(this, prop['chart.title'], this.gutterTop, null, prop['chart.title.size'] ? prop['chart.title.size'] : prop['chart.text.size'] + 2);
336
- this.DrawFunnel();
337
-
338
-
339
- /**
340
- * Setup the context menu if required
341
- */
342
- if (prop['chart.contextmenu']) {
343
- RG.ShowContext(this);
344
- }
345
-
346
-
347
-
348
- /**
349
- * Draw the labels on the chart
350
- */
351
- this.DrawLabels();
352
-
353
-
354
- /**
355
- * This function enables resizing
356
- */
357
- if (prop['chart.resizable']) {
358
- RG.AllowResizing(this);
359
- }
360
-
361
-
362
- /**
363
- * This installs the event listeners
364
- */
365
- RG.InstallEventListeners(this);
366
-
367
-
368
-
369
-
370
- /**
371
- * Fire the onfirstdraw event
372
- */
373
- if (this.firstDraw) {
374
- RG.fireCustomEvent(this, 'onfirstdraw');
375
- this.firstDraw = false;
376
- this.firstDrawFunc();
377
- }
378
-
379
-
380
-
381
-
382
- /**
383
- * Fire the RGraph ondraw event
384
- */
385
- RG.FireCustomEvent(this, 'ondraw');
386
-
387
- return this;
388
- };
389
-
390
-
391
-
392
- /**
393
- * Used in chaining. Runs a function there and then - not waiting for
394
- * the events to fire (eg the onbeforedraw event)
395
- *
396
- * @param function func The function to execute
397
- */
398
- this.exec = function (func)
399
- {
400
- func(this);
401
-
402
- return this;
403
- };
404
-
405
-
406
-
407
-
408
- /**
409
- * This function actually draws the chart
410
- */
411
- this.drawFunnel =
412
- this.DrawFunnel = function ()
413
- {
414
- var width = ca.width - this.gutterLeft - this.gutterRight;
415
- var height = ca.height - this.gutterTop - this.gutterBottom;
416
- var total = RG.array_max(this.data);
417
- var accheight = this.gutterTop;
418
-
419
-
420
- /**
421
- * Loop through each segment to draw
422
- */
423
-
424
- // Set a shadow if it's been requested
425
- if (prop['chart.shadow']) {
426
- co.shadowColor = prop['chart.shadow.color'];
427
- co.shadowBlur = prop['chart.shadow.blur'];
428
- co.shadowOffsetX = prop['chart.shadow.offsetx'];
429
- co.shadowOffsetY = prop['chart.shadow.offsety'];
430
- }
431
-
432
- for (i=0,len=this.data.length; i<len; ++i) {
433
-
434
- var firstvalue = this.data[0];
435
- var firstwidth = (firstvalue / total) * width;
436
- var curvalue = this.data[i];
437
- var curwidth = (curvalue / total) * width;
438
- var curheight = height / this.data.length;
439
- var halfCurWidth = (curwidth / 2);
440
- var nextvalue = this.data[i + 1];
441
- var nextwidth = this.data[i + 1] ? (nextvalue / total) * width : null;
442
- var halfNextWidth = (nextwidth / 2);
443
- var center = this.gutterLeft + (firstwidth / 2);
444
-
445
- var x1 = center - halfCurWidth;
446
- var y1 = accheight;
447
- var x2 = center + halfCurWidth;
448
- var y2 = accheight;
449
- var x3 = center + halfNextWidth;
450
- var y3 = accheight + curheight;
451
- var x4 = center - halfNextWidth;
452
- var y4 = accheight + curheight;
453
-
454
- if (nextwidth && i < this.data.length - 1) {
455
-
456
- co.beginPath();
457
-
458
- co.strokeStyle = prop['chart.strokestyle'];
459
- co.fillStyle = prop['chart.colors'][i];
460
-
461
- co.moveTo(x1, y1);
462
- co.lineTo(x2, y2);
463
- co.lineTo(x3, y3);
464
- co.lineTo(x4, y4);
465
-
466
- co.closePath();
467
-
468
- /**
469
- * Store the coordinates
470
- */
471
- this.coords.push([x1, y1, x2, y2, x3, y3, x4, y4]);
472
- }
473
-
474
-
475
- // The redrawing if the shadow is on will do the stroke
476
- if (!prop['chart.shadow']) {
477
- co.stroke();
478
- }
479
-
480
- co.fill();
481
-
482
- accheight += curheight;
483
- }
484
-
485
- /**
486
- * If the shadow is enabled, redraw every segment, in order to allow for shadows going upwards
487
- */
488
- if (prop['chart.shadow']) {
489
-
490
- RG.NoShadow(this);
491
-
492
- for (i=0; i<this.coords.length; ++i) {
493
-
494
- co.strokeStyle = prop['chart.strokestyle'];
495
- co.fillStyle = prop['chart.colors'][i];
496
-
497
- co.beginPath();
498
- co.moveTo(this.coords[i][0], this.coords[i][1]);
499
- co.lineTo(this.coords[i][2], this.coords[i][3]);
500
- co.lineTo(this.coords[i][4], this.coords[i][5]);
501
- co.lineTo(this.coords[i][6], this.coords[i][7]);
502
- co.closePath();
503
-
504
- co.stroke();
505
- co.fill();
506
- }
507
- }
508
-
509
- /**
510
- * Lastly, draw the key if necessary
511
- */
512
- if (prop['chart.key'] && prop['chart.key'].length) {
513
- RG.DrawKey(this, prop['chart.key'], prop['chart.colors']);
514
- }
515
- };
516
-
517
-
518
-
519
-
520
- /**
521
- * Draws the labels
522
- */
523
- this.drawLabels =
524
- this.DrawLabels = function ()
525
- {
526
- /**
527
- * Draws the labels
528
- */
529
- if (prop['chart.labels'] && prop['chart.labels'].length > 0) {
530
-
531
- var font = prop['chart.text.font'];
532
- var size = prop['chart.text.size'];
533
- var color = prop['chart.text.color'];
534
- var labels = prop['chart.labels'];
535
- var halign = prop['chart.text.halign'] == 'left' ? 'left' : 'center';
536
- var bgcolor = prop['chart.text.boxed'] ? 'white' : null;
537
-
538
- if (typeof prop['chart.labels.x'] == 'number') {
539
- var x = prop['chart.labels.x'];
540
- } else {
541
- var x = halign == 'left' ? (this.gutterLeft - 15) : ((ca.width - this.gutterLeft - this.gutterRight) / 2) + this.gutterLeft;
542
- }
543
-
544
- for (var j=0; j<this.coords.length; ++j) { // MUST be "j"
545
-
546
- co.beginPath();
547
-
548
- // Set the color back to black
549
- co.strokeStyle = 'black';
550
- co.fillStyle = color;
551
-
552
- // Turn off any shadow
553
- RG.NoShadow(this);
554
-
555
- var label = labels[j];
556
-
557
- RG.text2(this,{'font':font,
558
- 'size':size,
559
- 'x':x,
560
- 'y':this.coords[j][1],
561
- 'text':label,
562
- 'valign':'center',
563
- 'halign':halign,
564
- 'bounding': prop['chart.text.boxed'],
565
- 'boundingFill':bgcolor,
566
- 'tag': 'labels'
567
- });
568
-
569
- if (prop['chart.labels.sticks']) {
570
- /**
571
- * Measure the text
572
- */
573
- co.font = size + 'pt ' + font;
574
- var labelWidth = co.measureText(label).width;
575
-
576
- /**
577
- * Draw the horizontal indicator line
578
- */
579
- co.beginPath();
580
- co.strokeStyle = 'gray';
581
- co.moveTo(x + labelWidth + 10, ma.round(this.coords[j][1]));
582
- co.lineTo(this.coords[j][0] - 10, ma.round(this.coords[j][1]));
583
- co.stroke();
584
- }
585
- }
586
-
587
-
588
-
589
- /**
590
- * This draws the last labels if defined
591
- */
592
- var lastLabel = labels[j];
593
-
594
- if (lastLabel) {
595
-
596
- RG.text2(this,{'font':font,
597
- 'size':size,
598
- 'x':x,
599
- 'y':this.coords[j - 1][5],
600
- 'text':lastLabel,
601
- 'valign':'center',
602
- 'halign':halign,
603
- 'bounding': prop['chart.text.boxed'],
604
- 'boundingFill':bgcolor,
605
- 'tag': 'labels'
606
- });
607
-
608
- if (prop['chart.labels.sticks']) {
609
-
610
- /**
611
- * Measure the text
612
- */
613
- co.font = size + 'pt ' + font;
614
- var labelWidth = co.measureText(lastLabel).width;
615
-
616
- /**
617
- * Draw the horizontal indicator line
618
- */
619
- co.beginPath();
620
- co.strokeStyle = 'gray';
621
-
622
- //co.moveTo(x + labelWidth + 10, ma.round(this.coords[j][1]));
623
- //co.lineTo(this.coords[j][0] - 10, ma.round(this.coords[j][1]));
624
-
625
- co.moveTo(x + labelWidth + 10, Math.round(this.coords[j - 1][7]));
626
- co.lineTo(this.coords[j - 1][6] - 10, Math.round(this.coords[j - 1][7]));
627
- co.stroke();
628
- }
629
- }
630
- }
631
- };
632
-
633
-
634
-
635
-
636
- /**
637
- * Gets the appropriate segment that has been highlighted
638
- */
639
- this.getShape =
640
- this.getSegment = function (e)
641
- {
642
- //var canvas = ca = e.target;
643
- //var co = this.context;
644
- //var prop = this.properties;
645
- var coords = this.coords;
646
- var mouseCoords = RG.getMouseXY(e);
647
- var x = mouseCoords[0];
648
- var y = mouseCoords[1];
649
-
650
- for (i=0,len=coords.length; i<len; ++i) {
651
-
652
- var segment = coords[i]
653
-
654
- // Path testing
655
- co.beginPath();
656
- co.moveTo(segment[0], segment[1]);
657
- co.lineTo(segment[2], segment[3]);
658
- co.lineTo(segment[4], segment[5]);
659
- co.lineTo(segment[6], segment[7]);
660
- co.lineTo(segment[8], segment[9]);
661
-
662
- if (co.isPointInPath(x, y)) {
663
- var tooltip = RGraph.parseTooltipText(prop['chart.tooltips'], i);
664
- return {0: this, 1: coords, 2: i, 'object': this, 'coords': segment, 'index': i, 'tooltip': tooltip};
665
- }
666
- }
667
-
668
- return null;
669
- };
670
-
671
-
672
-
673
-
674
- /**
675
- * Each object type has its own Highlight() function which highlights the appropriate shape
676
- *
677
- * @param object shape The shape to highlight
678
- */
679
- this.highlight =
680
- this.Highlight = function (shape)
681
- {
682
- if (prop['chart.tooltips.highlight']) {
683
-
684
- if (typeof prop['chart.highlight.style'] === 'function') {
685
- (prop['chart.highlight.style'])(shape);
686
- return;
687
- }
688
-
689
-
690
-
691
- var coords = shape['coords'];
692
-
693
- pa2(
694
- co,
695
- 'b m % % l % % l % % l % % c s % f %',
696
- coords[0], coords[1],
697
- coords[2], coords[3],
698
- coords[4], coords[5],
699
- coords[6], coords[7],
700
- prop['chart.highlight.stroke'],
701
- prop['chart.highlight.fill']
702
- );
703
- }
704
- };
705
-
706
-
707
-
708
-
709
- /**
710
- * The getObjectByXY() worker method. Don't call this call:
711
- *
712
- * RGraph.ObjectRegistry.getObjectByXY(e)
713
- *
714
- * @param object e The event object
715
- */
716
- this.getObjectByXY = function (e)
717
- {
718
- var mouseXY = RGraph.getMouseXY(e);
719
-
720
- if (
721
- mouseXY[0] > prop['chart.gutter.left']
722
- && mouseXY[0] < (ca.width - prop['chart.gutter.right'])
723
- && mouseXY[1] > prop['chart.gutter.top']
724
- && mouseXY[1] < (ca.height - prop['chart.gutter.bottom'])
725
- ) {
726
-
727
- return this;
728
- }
729
- };
730
-
731
-
732
-
733
-
734
- /**
735
- * This function positions a tooltip when it is displayed
736
- *
737
- * @param obj object The chart object
738
- * @param int x The X coordinate specified for the tooltip
739
- * @param int y The Y coordinate specified for the tooltip
740
- * @param objec tooltip The tooltips DIV element
741
- */
742
- this.positionTooltip = function (obj, x, y, tooltip, idx)
743
- {
744
- var coords = obj.coords[tooltip.__index__];
745
-
746
- var x1 = coords[0];
747
- var y1 = coords[1];
748
- var x2 = coords[2];
749
- var y2 = coords[3];
750
- var x3 = coords[4];
751
- var y3 = coords[5];
752
- var x4 = coords[6];
753
- var y4 = coords[7];
754
-
755
- var coordW = x2 - x1;
756
- var coordX = x1 + (coordW / 2);
757
- var canvasXY = RG.getCanvasXY(ca);
758
- var mouseXY = RG.getMouseXY(window.event);
759
- var gutterLeft = prop['chart.gutter.left'];
760
- var gutterTop = prop['chart.gutter.top'];
761
- var width = tooltip.offsetWidth;
762
- var height = tooltip.offsetHeight;
763
-
764
- // Set the top position
765
- tooltip.style.left = 0;
766
- tooltip.style.top = window.event.pageY - height - 5 + 'px';
767
-
768
- // By default any overflow is hidden
769
- tooltip.style.overflow = '';
770
-
771
-
772
-
773
- // Reposition the tooltip if at the edges:
774
-
775
- // LEFT edge
776
- if (canvasXY[0] + mouseXY[0] - (width / 2) < 0) {
777
- tooltip.style.left = canvasXY[0] + mouseXY[0] - (width * 0.1) + 'px';
778
-
779
- // RIGHT edge
780
- } else if (canvasXY[0] + mouseXY[0] + (width / 2) > doc.body.offsetWidth) {
781
- tooltip.style.left = canvasXY[0] + mouseXY[0] - (width * 0.9) + 'px';
782
-
783
- // Default positioning - CENTERED
784
- } else {
785
- tooltip.style.left = canvasXY[0] + mouseXY[0] - (width / 2) + 'px';
786
- }
787
- };
788
-
789
-
790
-
791
-
792
- /**
793
- * This allows for easy specification of gradients
794
- */
795
- this.parseColors = function ()
796
- {
797
- // Save the original colors so that they can be restored when the canvas is reset
798
- if (this.original_colors.length === 0) {
799
- this.original_colors['chart.colors'] = RG.array_clone(prop['chart.colors']);
800
- this.original_colors['chart.key.colors'] = RG.array_clone(prop['chart.key.colors']);
801
- this.original_colors['chart.highlight.fill'] = RG.array_clone(prop['chart.highlight.fill']);
802
- this.original_colors['chart.highlight.stroke'] = RG.array_clone(prop['chart.highlight.stroke']);
803
- this.original_colors['chart.strokestyle'] = RG.array_clone(prop['chart.strokestyle']);
804
- }
805
-
806
- var colors = prop['chart.colors'];
807
-
808
- for (var i=0; i<colors.length; ++i) {
809
- colors[i] = this.parseSingleColorForHorizontalGradient(colors[i]);
810
- }
811
-
812
- var keyColors = prop['chart.key.colors'];
813
- if (keyColors) {
814
- for (var i=0; i<keyColors.length; ++i) {
815
- keyColors[i] = this.parseSingleColorForHorizontalGradient(keyColors[i]);
816
- }
817
- }
818
-
819
-
820
- prop['chart.strokestyle'] = this.parseSingleColorForVerticalGradient(prop['chart.strokestyle']);
821
- prop['chart.highlight.stroke'] = this.parseSingleColorForHorizontalGradient(prop['chart.highlight.stroke']);
822
- prop['chart.highlight.fill'] = this.parseSingleColorForHorizontalGradient(prop['chart.highlight.fill']);
823
- };
824
-
825
-
826
-
827
-
828
- /**
829
- * Use this function to reset the object to the post-constructor state. Eg reset colors if
830
- * need be etc
831
- */
832
- this.reset = function ()
833
- {
834
- };
835
-
836
-
837
-
838
-
839
- /**
840
- * This parses a single color value
841
- */
842
- this.parseSingleColorForHorizontalGradient = function (color)
843
- {
844
- if (!color || typeof(color) != 'string') {
845
- return color;
846
- }
847
-
848
- if (color.match(/^gradient\((.*)\)$/i)) {
849
-
850
- var parts = RegExp.$1.split(':');
851
-
852
- // Create the gradient
853
- var grad = co.createLinearGradient(prop['chart.gutter.left'],0,ca.width - prop['chart.gutter.right'],0);
854
-
855
- var diff = 1 / (parts.length - 1);
856
-
857
- grad.addColorStop(0, RGraph.trim(parts[0]));
858
-
859
- for (var j=1; j<parts.length; ++j) {
860
- grad.addColorStop(j * diff, RG.trim(parts[j]));
861
- }
862
- }
863
-
864
- return grad ? grad : color;
865
- };
866
-
867
-
868
-
869
-
870
- /**
871
- * This parses a single color value
872
- */
873
- this.parseSingleColorForVerticalGradient = function (color)
874
- {
875
- if (!color || typeof(color) != 'string') {
876
- return color;
877
- }
878
-
879
- if (color.match(/^gradient\((.*)\)$/i)) {
880
-
881
- var parts = RegExp.$1.split(':');
882
-
883
- // Create the gradient
884
- var grad = co.createLinearGradient(0, prop['chart.gutter.top'],0,ca.height - prop['chart.gutter.bottom']);
885
-
886
- var diff = 1 / (parts.length - 1);
887
-
888
- grad.addColorStop(0, RGraph.trim(parts[0]));
889
-
890
- for (var j=1; j<parts.length; ++j) {
891
- grad.addColorStop(j * diff, RG.trim(parts[j]));
892
- }
893
- }
894
-
895
- return grad ? grad : color;
896
- };
897
-
898
-
899
-
900
-
901
- /**
902
- * This function handles highlighting an entire data-series for the interactive
903
- * key
904
- *
905
- * @param int index The index of the data series to be highlighted
906
- */
907
- this.interactiveKeyHighlight = function (index)
908
- {
909
- var coords = this.coords[index];
910
-
911
- if (coords && coords.length == 8) {
912
- var pre_linewidth = co.lineWidth;
913
-
914
- co.lineWidth = 2;
915
- co.strokeStyle = prop['chart.key.interactive.highlight.chart.stroke'];
916
- co.fillStyle = prop['chart.key.interactive.highlight.chart.fill'];
917
-
918
- co.beginPath();
919
- co.moveTo(coords[0], coords[1]);
920
- co.lineTo(coords[2], coords[3]);
921
- co.lineTo(coords[4], coords[5]);
922
- co.lineTo(coords[6], coords[7]);
923
- co.closePath();
924
- co.fill();
925
- co.stroke();
926
-
927
- // Reset the linewidth
928
- co.lineWidth = pre_linewidth;
929
- }
930
- };
931
-
932
-
933
-
934
-
935
- /**
936
- * Using a function to add events makes it easier to facilitate method chaining
937
- *
938
- * @param string type The type of even to add
939
- * @param function func
940
- */
941
- this.on = function (type, func)
942
- {
943
- if (type.substr(0,2) !== 'on') {
944
- type = 'on' + type;
945
- }
946
-
947
- this[type] = func;
948
-
949
- return this;
950
- };
951
-
952
-
953
-
954
-
955
- /**
956
- * This function runs once only
957
- * (put at the end of the file (before any effects))
958
- */
959
- this.firstDrawFunc = function ()
960
- {
961
- };
962
-
963
-
964
-
965
- RG.att(ca);
966
-
967
-
968
-
969
-
970
- /**
971
- * Always now regsiter the object
972
- */
973
- RG.Register(this);
974
-
975
-
976
-
977
-
978
- /**
979
- * This is the 'end' of the constructor so if the first argument
980
- * contains configuration data - handle that.
981
- */
982
- if (parseConfObjectForOptions) {
983
- RG.parseObjectStyleConfig(this, conf.options);
984
- }
985
- };
2
+ RGraph=window.RGraph||{isRGraph:true};RGraph.Funnel=function(conf)
3
+ {if(typeof conf==='object'&&typeof conf.data==='object'&&typeof conf.id==='string'){var id=conf.id
4
+ var canvas=document.getElementById(id);var data=conf.data;var parseConfObjectForOptions=true;}else{var id=conf;var canvas=document.getElementById(id);var data=arguments[1];}
5
+ this.id=id;this.canvas=canvas;this.context=this.canvas.getContext?this.canvas.getContext("2d",{alpha:(typeof id==='object'&&id.alpha===false)?false:true}):null;this.canvas.__object__=this;this.type='funnel';this.coords=[];this.isRGraph=true;this.uid=RGraph.CreateUID();this.canvas.uid=this.canvas.uid?this.canvas.uid:RGraph.CreateUID();this.coordsText=[];this.original_colors=[];this.firstDraw=true;if(!this.canvas){alert('[FUNNEL] No canvas support');return;}
6
+ this.properties={'chart.strokestyle':'rgba(0,0,0,0)','chart.gutter.left':25,'chart.gutter.right':25,'chart.gutter.top':25,'chart.gutter.bottom':25,'chart.labels':null,'chart.labels.sticks':false,'chart.labels.x':null,'chart.title':'','chart.title.background':null,'chart.title.hpos':null,'chart.title.vpos':null,'chart.title.bold':true,'chart.title.font':null,'chart.title.x':null,'chart.title.y':null,'chart.title.halign':null,'chart.title.valign':null,'chart.colors':['Gradient(white:red)','Gradient(white:green)','Gradient(white:gray)','Gradient(white:blue)','Gradient(white:black)','Gradient(white:gray)','Gradient(white:pink)','Gradient(white:blue)','Gradient(white:yellow)','Gradient(white:green)','Gradient(white:red)'],'chart.text.size':12,'chart.text.boxed':true,'chart.text.halign':'left','chart.text.color':'black','chart.text.font':'Segoe UI, Arial, Verdana, sans-serif','chart.text.accessible':true,'chart.text.accessible.overflow':'visible','chart.text.accessible.pointerevents':true,'chart.contextmenu':null,'chart.shadow':false,'chart.shadow.color':'#666','chart.shadow.blur':3,'chart.shadow.offsetx':3,'chart.shadow.offsety':3,'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.stroke':'black','chart.key.interactive.highlight.chart.fill':'rgba(255,255,255,0.7)','chart.key.interactive.highlight.label':'rgba(255,0,0,0.2)','chart.key.text.color':'black','chart.tooltips':null,'chart.tooltips.effect':'fade','chart.tooltips.css.class':'RGraph_tooltip','chart.tooltips.event':'onclick','chart.highlight.stroke':'rgba(0,0,0,0)','chart.highlight.fill':'rgba(255,255,255,0.7)','chart.tooltips.highlight':true,'chart.annotatable':false,'chart.annotate.color':'black','chart.zoom.factor':1.5,'chart.zoom.fade.in':true,'chart.zoom.fade.out':true,'chart.zoom.factor':1.5,'chart.zoom.fade.in':true,'chart.zoom.fade.out':true,'chart.zoom.hdir':'right','chart.zoom.vdir':'down','chart.zoom.frames':25,'chart.zoom.delay':16.666,'chart.zoom.shadow':true,'chart.zoom.background':true,'chart.zoom.action':'zoom','chart.resizable':false,'chart.events.click':null,'chart.events.mousemove':null,'chart.clearto':'rgba(0,0,0,0)'}
7
+ for(var i=0;i<data.length;++i){data[i]=parseFloat(data[i]);}
8
+ this.data=data;for(var i=0;i<data.length;++i){this['$'+i]={};}
9
+ if(!this.canvas.__rgraph_aa_translated__){this.context.translate(0.5,0.5);this.canvas.__rgraph_aa_translated__=true;}
10
+ var RG=RGraph,ca=this.canvas,co=ca.getContext('2d'),prop=this.properties,pa2=RG.path2,win=window,doc=document,ma=Math
11
+ if(RG.Effects&&typeof RG.Effects.decorate==='function'){RG.Effects.decorate(this);}
12
+ this.set=this.Set=function(name)
13
+ {var value=typeof arguments[1]==='undefined'?null:arguments[1];if(arguments.length===1&&typeof name==='object'){RG.parseObjectStyleConfig(this,name);return this;}
14
+ if(name.substr(0,6)!='chart.'){name='chart.'+name;}
15
+ while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
16
+ prop[name]=value;return this;};this.get=this.Get=function(name)
17
+ {if(name.substr(0,6)!='chart.'){name='chart.'+name;}
18
+ while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
19
+ return prop[name.toLowerCase()];};this.draw=this.Draw=function()
20
+ {RG.FireCustomEvent(this,'onbeforedraw');if(!this.colorsParsed){this.parseColors();this.colorsParsed=true;}
21
+ this.gutterLeft=prop['chart.gutter.left'];this.gutterRight=prop['chart.gutter.right'];this.gutterTop=prop['chart.gutter.top'];this.gutterBottom=prop['chart.gutter.bottom'];this.coords=[];this.coordsText=[];RG.DrawTitle(this,prop['chart.title'],this.gutterTop,null,prop['chart.title.size']?prop['chart.title.size']:prop['chart.text.size']+2);this.DrawFunnel();if(prop['chart.contextmenu']){RG.ShowContext(this);}
22
+ this.DrawLabels();if(prop['chart.resizable']){RG.AllowResizing(this);}
23
+ RG.InstallEventListeners(this);if(this.firstDraw){RG.fireCustomEvent(this,'onfirstdraw');this.firstDraw=false;this.firstDrawFunc();}
24
+ RG.FireCustomEvent(this,'ondraw');return this;};this.exec=function(func)
25
+ {func(this);return this;};this.drawFunnel=this.DrawFunnel=function()
26
+ {var width=ca.width-this.gutterLeft-this.gutterRight;var height=ca.height-this.gutterTop-this.gutterBottom;var total=RG.array_max(this.data);var accheight=this.gutterTop;if(prop['chart.shadow']){co.shadowColor=prop['chart.shadow.color'];co.shadowBlur=prop['chart.shadow.blur'];co.shadowOffsetX=prop['chart.shadow.offsetx'];co.shadowOffsetY=prop['chart.shadow.offsety'];}
27
+ for(i=0,len=this.data.length;i<len;++i){var firstvalue=this.data[0];var firstwidth=(firstvalue/total)*width;var curvalue=this.data[i];var curwidth=(curvalue/total)*width;var curheight=height/this.data.length;var halfCurWidth=(curwidth/2);var nextvalue=this.data[i+1];var nextwidth=this.data[i+1]?(nextvalue/total)*width:null;var halfNextWidth=(nextwidth/2);var center=this.gutterLeft+(firstwidth/2);var x1=center-halfCurWidth;var y1=accheight;var x2=center+halfCurWidth;var y2=accheight;var x3=center+halfNextWidth;var y3=accheight+curheight;var x4=center-halfNextWidth;var y4=accheight+curheight;if(nextwidth&&i<this.data.length-1){co.beginPath();co.strokeStyle=prop['chart.strokestyle'];co.fillStyle=prop['chart.colors'][i];co.moveTo(x1,y1);co.lineTo(x2,y2);co.lineTo(x3,y3);co.lineTo(x4,y4);co.closePath();this.coords.push([x1,y1,x2,y2,x3,y3,x4,y4]);}
28
+ if(!prop['chart.shadow']){co.stroke();}
29
+ co.fill();accheight+=curheight;}
30
+ if(prop['chart.shadow']){RG.NoShadow(this);for(i=0;i<this.coords.length;++i){co.strokeStyle=prop['chart.strokestyle'];co.fillStyle=prop['chart.colors'][i];co.beginPath();co.moveTo(this.coords[i][0],this.coords[i][1]);co.lineTo(this.coords[i][2],this.coords[i][3]);co.lineTo(this.coords[i][4],this.coords[i][5]);co.lineTo(this.coords[i][6],this.coords[i][7]);co.closePath();co.stroke();co.fill();}}
31
+ if(prop['chart.key']&&prop['chart.key'].length){RG.DrawKey(this,prop['chart.key'],prop['chart.colors']);}};this.drawLabels=this.DrawLabels=function()
32
+ {if(prop['chart.labels']&&prop['chart.labels'].length>0){var font=prop['chart.text.font'];var size=prop['chart.text.size'];var color=prop['chart.text.color'];var labels=prop['chart.labels'];var halign=prop['chart.text.halign']=='left'?'left':'center';var bgcolor=prop['chart.text.boxed']?'white':null;if(typeof prop['chart.labels.x']=='number'){var x=prop['chart.labels.x'];}else{var x=halign=='left'?(this.gutterLeft-15):((ca.width-this.gutterLeft-this.gutterRight)/2)+this.gutterLeft;}
33
+ for(var j=0;j<this.coords.length;++j){co.beginPath();co.strokeStyle='black';co.fillStyle=color;RG.NoShadow(this);var label=labels[j];RG.text2(this,{'font':font,'size':size,'x':x,'y':this.coords[j][1],'text':label,'valign':'center','halign':halign,'bounding':prop['chart.text.boxed'],'boundingFill':bgcolor,'tag':'labels'});if(prop['chart.labels.sticks']){co.font=size+'pt '+font;var labelWidth=co.measureText(label).width;co.beginPath();co.strokeStyle='gray';co.moveTo(x+labelWidth+10,ma.round(this.coords[j][1]));co.lineTo(this.coords[j][0]-10,ma.round(this.coords[j][1]));co.stroke();}}
34
+ var lastLabel=labels[j];if(lastLabel){RG.text2(this,{'font':font,'size':size,'x':x,'y':this.coords[j-1][5],'text':lastLabel,'valign':'center','halign':halign,'bounding':prop['chart.text.boxed'],'boundingFill':bgcolor,'tag':'labels'});if(prop['chart.labels.sticks']){co.font=size+'pt '+font;var labelWidth=co.measureText(lastLabel).width;co.beginPath();co.strokeStyle='gray';co.moveTo(x+labelWidth+10,Math.round(this.coords[j-1][7]));co.lineTo(this.coords[j-1][6]-10,Math.round(this.coords[j-1][7]));co.stroke();}}}};this.getShape=this.getSegment=function(e)
35
+ {var coords=this.coords;var mouseCoords=RG.getMouseXY(e);var x=mouseCoords[0];var y=mouseCoords[1];for(i=0,len=coords.length;i<len;++i){var segment=coords[i]
36
+ co.beginPath();co.moveTo(segment[0],segment[1]);co.lineTo(segment[2],segment[3]);co.lineTo(segment[4],segment[5]);co.lineTo(segment[6],segment[7]);co.lineTo(segment[8],segment[9]);if(co.isPointInPath(x,y)){var tooltip=RGraph.parseTooltipText(prop['chart.tooltips'],i);return{0:this,1:coords,2:i,'object':this,'coords':segment,'index':i,'tooltip':tooltip};}}
37
+ return null;};this.highlight=this.Highlight=function(shape)
38
+ {if(prop['chart.tooltips.highlight']){if(typeof prop['chart.highlight.style']==='function'){(prop['chart.highlight.style'])(shape);return;}
39
+ var coords=shape['coords'];pa2(co,'b m % % l % % l % % l % % c s % f %',coords[0],coords[1],coords[2],coords[3],coords[4],coords[5],coords[6],coords[7],prop['chart.highlight.stroke'],prop['chart.highlight.fill']);}};this.getObjectByXY=function(e)
40
+ {var mouseXY=RGraph.getMouseXY(e);if(mouseXY[0]>prop['chart.gutter.left']&&mouseXY[0]<(ca.width-prop['chart.gutter.right'])&&mouseXY[1]>prop['chart.gutter.top']&&mouseXY[1]<(ca.height-prop['chart.gutter.bottom'])){return this;}};this.parseColors=function()
41
+ {if(this.original_colors.length===0){this.original_colors['chart.colors']=RG.array_clone(prop['chart.colors']);this.original_colors['chart.key.colors']=RG.array_clone(prop['chart.key.colors']);this.original_colors['chart.highlight.fill']=RG.array_clone(prop['chart.highlight.fill']);this.original_colors['chart.highlight.stroke']=RG.array_clone(prop['chart.highlight.stroke']);this.original_colors['chart.strokestyle']=RG.array_clone(prop['chart.strokestyle']);}
42
+ var colors=prop['chart.colors'];for(var i=0;i<colors.length;++i){colors[i]=this.parseSingleColorForHorizontalGradient(colors[i]);}
43
+ var keyColors=prop['chart.key.colors'];if(keyColors){for(var i=0;i<keyColors.length;++i){keyColors[i]=this.parseSingleColorForHorizontalGradient(keyColors[i]);}}
44
+ prop['chart.strokestyle']=this.parseSingleColorForVerticalGradient(prop['chart.strokestyle']);prop['chart.highlight.stroke']=this.parseSingleColorForHorizontalGradient(prop['chart.highlight.stroke']);prop['chart.highlight.fill']=this.parseSingleColorForHorizontalGradient(prop['chart.highlight.fill']);};this.reset=function()
45
+ {};this.parseSingleColorForHorizontalGradient=function(color)
46
+ {if(!color||typeof(color)!='string'){return color;}
47
+ if(color.match(/^gradient\((.*)\)$/i)){var parts=RegExp.$1.split(':');var grad=co.createLinearGradient(prop['chart.gutter.left'],0,ca.width-prop['chart.gutter.right'],0);var diff=1/(parts.length-1);grad.addColorStop(0,RGraph.trim(parts[0]));for(var j=1;j<parts.length;++j){grad.addColorStop(j*diff,RG.trim(parts[j]));}}
48
+ return grad?grad:color;};this.parseSingleColorForVerticalGradient=function(color)
49
+ {if(!color||typeof(color)!='string'){return color;}
50
+ if(color.match(/^gradient\((.*)\)$/i)){var parts=RegExp.$1.split(':');var grad=co.createLinearGradient(0,prop['chart.gutter.top'],0,ca.height-prop['chart.gutter.bottom']);var diff=1/(parts.length-1);grad.addColorStop(0,RGraph.trim(parts[0]));for(var j=1;j<parts.length;++j){grad.addColorStop(j*diff,RG.trim(parts[j]));}}
51
+ return grad?grad:color;};this.interactiveKeyHighlight=function(index)
52
+ {var coords=this.coords[index];if(coords&&coords.length==8){var pre_linewidth=co.lineWidth;co.lineWidth=2;co.strokeStyle=prop['chart.key.interactive.highlight.chart.stroke'];co.fillStyle=prop['chart.key.interactive.highlight.chart.fill'];co.beginPath();co.moveTo(coords[0],coords[1]);co.lineTo(coords[2],coords[3]);co.lineTo(coords[4],coords[5]);co.lineTo(coords[6],coords[7]);co.closePath();co.fill();co.stroke();co.lineWidth=pre_linewidth;}};this.on=function(type,func)
53
+ {if(type.substr(0,2)!=='on'){type='on'+type;}
54
+ if(typeof this[type]!=='function'){this[type]=func;}else{RG.addCustomEventListener(this,type,func);}
55
+ return this;};this.firstDrawFunc=function()
56
+ {};RG.att(ca);RG.Register(this);if(parseConfObjectForOptions){RG.parseObjectStyleConfig(this,conf.options);}};