rgraph-rails 4.62 → 4.64

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