rgraph-rails 4.62 → 4.64

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