rgraph-rails 1.0.5 → 1.0.6

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 (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);}};