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,1355 +1,78 @@
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 gantt chart constructor
17
- *
18
- * @param object conf The configuration object. You can also give seperate arguments if you prefer:
19
- * var foo = new RGraph.Gantt('cvs', [[0,50],[25,50],[50,50]]);
20
- */
21
- RGraph.Gantt = 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
-
44
- this.id = id;
45
- this.canvas = canvas;
46
- this.context = this.canvas.getContext ? this.canvas.getContext("2d", {alpha: (typeof id === 'object' && id.alpha === false) ? false : true}) : null;
47
- this.canvas.__object__ = this;
48
- this.type = 'gantt';
49
- this.isRGraph = true;
50
- this.uid = RGraph.CreateUID();
51
- this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.CreateUID();
52
- this.data = data;
53
- this.colorsParsed = false;
54
- this.coordsText = [];
55
- this.original_colors = [];
56
- this.firstDraw = true; // After the first draw this will be false
57
-
58
-
59
-
60
-
61
- // Set some defaults
62
- this.properties =
63
- {
64
- 'chart.background.barcolor1': 'rgba(0,0,0,0)',
65
- 'chart.background.barcolor2': 'rgba(0,0,0,0)',
66
- 'chart.background.grid': true,
67
- 'chart.background.grid.width': 1,
68
- 'chart.background.grid.color': '#ddd',
69
- 'chart.background.grid.hsize': 20,
70
- 'chart.background.grid.vsize': 20,
71
- 'chart.background.grid.hlines': true,
72
- 'chart.background.grid.vlines': true,
73
- 'chart.background.grid.border': true,
74
- 'chart.background.grid.autofit':true,
75
- 'chart.background.grid.autofit.align':true,
76
- 'chart.background.grid.autofit.numhlines': 7,
77
- 'chart.background.grid.autofit.numvlines': null,
78
- 'chart.vbars': [],
79
- 'chart.hbars': [],
80
- 'chart.text.size': 12,
81
- 'chart.text.font': 'Segoe UI, Arial, Verdana, sans-serif',
82
- 'chart.text.color': 'black',
83
- 'chart.text.accessible': true,
84
- 'chart.text.accessible.overflow': 'visible',
85
- 'chart.text.accessible.pointerevents': true,
86
- 'chart.gutter.left': 75,
87
- 'chart.gutter.right': 25,
88
- 'chart.gutter.top': 35,
89
- 'chart.gutter.bottom': 25,
90
- 'chart.labels': [],
91
- 'chart.labels.color': null,
92
- 'chart.labels.align': 'bottom',
93
- 'chart.labels.inbar': null,
94
- 'chart.labels.inbar.color': 'black',
95
- 'chart.labels.inbar.bgcolor': null,
96
- 'chart.labels.inbar.align': 'left',
97
- 'chart.labels.inbar.size': 10,
98
- 'chart.labels.inbar.font': 'Segoe UI, Arial, Verdana, sans-serif',
99
- 'chart.labels.inbar.above': false,
100
- 'chart.labels.percent': true,
101
- 'chart.vmargin': 2,
102
- 'chart.title': '',
103
- 'chart.title.background': null,
104
- 'chart.title.x': null,
105
- 'chart.title.y': null,
106
- 'chart.title.bold': true,
107
- 'chart.title.font': null,
108
- 'chart.title.yaxis': '',
109
- 'chart.title.yaxis.bold': true,
110
- 'chart.title.yaxis.pos': null,
111
- 'chart.title.yaxis.color': null,
112
- 'chart.title.yaxis.position': 'right',
113
- 'chart.title.yaxis.x': null,
114
- 'chart.title.yaxis.y': null,
115
- 'chart.title.xaxis.x': null,
116
- 'chart.title.xaxis.y': null,
117
- 'chart.title.xaxis.bold': true,
118
- 'chart.title.xaxis.color': null,
119
- 'chart.title.x': null,
120
- 'chart.title.y': null,
121
- 'chart.title.halign': null,
122
- 'chart.title.valign': null,
123
- 'chart.borders': true,
124
- 'chart.defaultcolor': 'white',
125
- 'chart.coords': [],
126
- 'chart.tooltips': null,
127
- 'chart.tooltips.effect': 'fade',
128
- 'chart.tooltips.css.class': 'RGraph_tooltip',
129
- 'chart.tooltips.highlight': true,
130
- 'chart.tooltips.event': 'onclick',
131
- 'chart.highlight.stroke': 'rgba(0,0,0,0)',
132
- 'chart.highlight.fill': 'rgba(255,255,255,0.7)',
133
- 'chart.xmin': 0,
134
- 'chart.xmax': 0,
135
- 'chart.contextmenu': null,
136
- 'chart.annotatable': false,
137
- 'chart.annotate.color': 'black',
138
- 'chart.zoom.factor': 1.5,
139
- 'chart.zoom.fade.in': true,
140
- 'chart.zoom.fade.out': true,
141
- 'chart.zoom.hdir': 'right',
142
- 'chart.zoom.vdir': 'down',
143
- 'chart.zoom.frames': 25,
144
- 'chart.zoom.delay': 16.666,
145
- 'chart.zoom.shadow': true,
146
- 'chart.zoom.background': true,
147
- 'chart.zoom.action': 'zoom',
148
- 'chart.resizable': false,
149
- 'chart.resize.handle.adjust': [0,0],
150
- 'chart.resize.handle.background': null,
151
- 'chart.adjustable': false,
152
- 'chart.adjustable.only': null,
153
- 'chart.events.click': null,
154
- 'chart.events.mousemove': null,
155
- 'chart.clearto': 'rgba(0,0,0,0)'
156
- }
157
-
158
-
159
- /**
160
- * Create the dollar objects so that functions can be added to them
161
- */
162
- if (!data) {
163
- alert('[GANTT] The Gantt chart event data is now supplied as the second argument to the constructor - please update your code');
164
- } else {
165
- // Go through the data converting relevant args to numbers
166
- for (var i=0,idx=0; i<data.length; ++i) {
167
- if (typeof data[i][0] === 'string') data[i][0] = parseFloat(data[i][0]);
168
- if (typeof data[i][1] === 'string') data[i][1] = parseFloat(data[i][1]);
169
- if (typeof data[i][2] === 'string') data[i][2] = parseFloat(data[i][2]);
170
- if (typeof data[i][7] === 'string') data[i][7] = parseFloat(data[i][7]);
171
- }
172
- }
173
-
174
- // Linearize the data (DON'T use RGraph.arrayLinearize() here)
175
- for (var i=0,idx=0; i<data.length; ++i) {
176
- if (RGraph.isArray(this.data[i][0])) {
177
- for (var j=0; j<this.data[i].length; ++j) {
178
- this['$' + (idx++)] = {};
179
- }
180
- } else {
181
- this['$' + (idx++)] = {};
182
- }
183
- }
184
-
185
-
186
-
187
- /*
188
- * Translate half a pixel for antialiasing purposes - but only if it hasn't beeen
189
- * done already
190
- */
191
- if (!this.canvas.__rgraph_aa_translated__) {
192
- this.context.translate(0.5,0.5);
193
-
194
- this.canvas.__rgraph_aa_translated__ = true;
195
- }
196
-
197
-
198
-
199
-
200
- // Short variable names
201
- var RG = RGraph,
202
- ca = this.canvas,
203
- co = ca.getContext('2d'),
204
- prop = this.properties,
205
- pa2 = RG.path2,
206
- win = window,
207
- doc = document,
208
- ma = Math
209
-
210
-
211
-
212
- /**
213
- * "Decorate" the object with the generic effects if the effects library has been included
214
- */
215
- if (RG.Effects && typeof RG.Effects.decorate === 'function') {
216
- RG.Effects.decorate(this);
217
- }
218
-
219
-
220
-
221
-
222
- /**
223
- * A peudo setter
224
- *
225
- * @param name string The name of the property to set
226
- * @param value mixed The value of the property
227
- */
228
- this.set =
229
- this.Set = function (name)
230
- {
231
- var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
232
-
233
- /**
234
- * the number of arguments is only one and it's an
235
- * object - parse it for configuration data and return.
236
- */
237
- if (arguments.length === 1 && typeof name === 'object') {
238
- RG.parseObjectStyleConfig(this, name);
239
- return this;
240
- }
241
-
242
-
243
-
244
-
245
-
246
- /**
247
- * This should be done first - prepend the propertyy name with "chart." if necessary
248
- */
249
- if (name.substr(0,6) != 'chart.') {
250
- name = 'chart.' + name;
251
- }
252
-
253
-
254
-
255
-
256
- // Convert uppercase letters to dot+lower case letter
257
- while(name.match(/([A-Z])/)) {
258
- name = name.replace(/([A-Z])/, '.' + RegExp.$1.toLowerCase());
259
- }
260
-
261
- if (name == 'chart.margin') {
262
- name = 'chart.vmargin'
263
- }
264
-
265
- if (name == 'chart.events') {
266
- alert('[GANTT] The chart.events property is deprecated - supply the events data as an argument to the constructor instead');
267
- this.data = value;
268
- }
269
-
270
-
271
-
272
-
273
-
274
-
275
- prop[name] = value;
276
-
277
- return this;
278
- };
279
-
280
-
281
-
282
-
283
- /**
284
- * A peudo getter
285
- *
286
- * @param name string The name of the property to get
287
- */
288
- this.get =
289
- this.Get = function (name)
290
- {
291
- /**
292
- * This should be done first - prepend the property name with "chart." if necessary
293
- */
294
- if (name.substr(0,6) != 'chart.') {
295
- name = 'chart.' + name;
296
- }
297
-
298
- // Convert uppercase letters to dot+lower case letter
299
- while(name.match(/([A-Z])/)) {
300
- name = name.replace(/([A-Z])/, '.' + RegExp.$1.toLowerCase());
301
- }
302
-
303
- if (name == 'chart.margin') {
304
- name = 'chart.vmargin'
305
- }
306
-
307
- return prop[name.toLowerCase()];
308
- };
309
-
310
-
311
-
312
-
313
- /**
314
- * Draws the chart
315
- */
316
- this.draw =
317
- this.Draw = function ()
318
- {
319
- /**
320
- * Fire the onbeforedraw event
321
- */
322
- RG.FireCustomEvent(this, 'onbeforedraw');
323
-
324
-
325
-
326
- /**
327
- * This is new in May 2011 and facilitates indiviual gutter settings,
328
- * eg chart.gutter.left
329
- */
330
- this.gutterLeft = prop['chart.gutter.left'];
331
- this.gutterRight = prop['chart.gutter.right'];
332
- this.gutterTop = prop['chart.gutter.top'];
333
- this.gutterBottom = prop['chart.gutter.bottom'];
334
-
335
- /**
336
- * Stop this growing uncntrollably
337
- */
338
- this.coordsText = [];
339
-
340
-
341
- /**
342
- * Parse the colors. This allows for simple gradient syntax
343
- */
344
- if (!this.colorsParsed) {
345
-
346
- this.parseColors();
347
-
348
- // Don't want to do this again
349
- this.colorsParsed = true;
350
- }
351
-
352
- /**
353
- * Work out the graphArea
354
- */
355
- this.graphArea = ca.width - this.gutterLeft - this.gutterRight;
356
- this.graphHeight = ca.height - this.gutterTop - this.gutterBottom;
357
- this.numEvents = this.data.length
358
- this.barHeight = this.graphHeight / this.numEvents;
359
- this.halfBarHeight = this.barHeight / 2;
360
-
361
-
362
-
363
-
364
- /**
365
- * Draw the background
366
- */
367
- RG.background.Draw(this);
368
-
369
-
370
-
371
- /**
372
- * Draw the labels at the top
373
- */
374
- this.drawLabels();
375
-
376
-
377
-
378
- /**
379
- * Draw the events
380
- */
381
- this.DrawEvents();
382
-
383
-
384
-
385
- /**
386
- * Setup the context menu if required
387
- */
388
- if (prop['chart.contextmenu']) {
389
- RG.ShowContext(this);
390
- }
391
-
392
-
393
- /**
394
- * This function enables resizing
395
- */
396
- if (prop['chart.resizable']) {
397
- RG.AllowResizing(this);
398
- }
399
-
400
-
401
- /**
402
- * This installs the event listeners
403
- */
404
- RG.InstallEventListeners(this);
405
-
406
-
407
- /**
408
- * Fire the onfirstdraw event
409
- */
410
- if (this.firstDraw) {
411
- RG.fireCustomEvent(this, 'onfirstdraw');
412
- this.firstDraw = false;
413
- this.firstDrawFunc();
414
- }
415
-
416
-
417
-
418
-
419
- /**
420
- * Fire the RGraph ondraw event
421
- */
422
- RG.FireCustomEvent(this, 'ondraw');
423
-
424
- return this;
425
- };
426
-
427
-
428
-
429
- /**
430
- * Used in chaining. Runs a function there and then - not waiting for
431
- * the events to fire (eg the onbeforedraw event)
432
- *
433
- * @param function func The function to execute
434
- */
435
- this.exec = function (func)
436
- {
437
- func(this);
438
-
439
- return this;
440
- };
441
-
442
-
443
-
444
-
445
- /**
446
- * Draws the labels at the top and the left of the chart
447
- */
448
- this.drawLabels =
449
- this.DrawLabels = function ()
450
- {
451
- /**
452
- * Draw the X labels at the top/bottom of the chart.
453
- */
454
- var labels = prop['chart.labels'];
455
- var labelsColor = prop['chart.labels.color'] || prop['chart.text.color'];
456
- var labelSpace = (this.graphArea) / labels.length;
457
- var x = this.gutterLeft + (labelSpace / 2);
458
- var y = this.gutterTop - (prop['chart.text.size'] / 2) - 5;
459
- var font = prop['chart.text.font'];
460
- var size = prop['chart.text.size'];
461
-
462
- co.beginPath();
463
- co.fillStyle = prop['chart.text.color'];
464
- co.strokeStyle = 'black'
465
-
466
- /**
467
- * This facilitates chart.labels.align
468
- */
469
- if (prop['chart.labels.align'] == 'bottom') {
470
- y = ca.height - this.gutterBottom + size + 2;
471
- }
472
-
473
- /**
474
- * Draw the horizontal labels
475
- */
476
- for (i=0; i<labels.length; ++i) {
477
- RG.Text2(this,{'font': font,
478
- 'size':size,
479
- 'x': x + (i * labelSpace),
480
- 'y': y,
481
- 'text': String(labels[i]),
482
- 'halign':'center',
483
- 'valign':'center',
484
- 'tag': 'labels.horizontal'
485
- });
486
- }
487
-
488
- /**
489
- * Draw the vertical labels
490
- */
491
- for (var i=0,len=this.data.length; i<len; ++i) {
492
-
493
- var ev = this.data[i];
494
- var x = this.gutterLeft;
495
- var y = this.gutterTop + this.halfBarHeight + (i * this.barHeight);
496
-
497
- co.fillStyle = labelsColor || prop['chart.text.color'];
498
-
499
- RG.text2(this,{
500
- 'font': font,
501
- 'size':size,
502
- 'x': x - 5,
503
- 'y': y,
504
- 'text': RG.isArray(ev[0]) ? (ev[0][3] ? String(ev[0][3]) : '') : (typeof ev[3] == 'string' ? ev[3] : ''),
505
- 'halign':'right',
506
- 'valign':'center',
507
- 'tag': 'labels.vertical'
508
- });
509
- }
510
- };
511
-
512
-
513
-
514
-
515
- /**
516
- * Draws the events to the canvas
517
- */
518
- this.drawEvents =
519
- this.DrawEvents = function ()
520
- {
521
- var events = this.data;
522
-
523
- /**
524
- * Reset the coords array to prevent it growing
525
- */
526
- this.coords = [];
527
-
528
-
529
-
530
-
531
- /**
532
- * First draw the vertical bars that have been added
533
- */
534
- if (prop['chart.vbars']) {
535
-
536
- for (i=0,len=prop['chart.vbars'].length; i<len; ++i) {
537
-
538
- // Boundary checking
539
- if (prop['chart.vbars'][i][0] + prop['chart.vbars'][i][1] > prop['chart.xmax']) {
540
- prop['chart.vbars'][i][1] = 364 - prop['chart.vbars'][i][0];
541
- }
542
-
543
- var barX = this.gutterLeft + (( (prop['chart.vbars'][i][0] - prop['chart.xmin']) / (prop['chart.xmax'] - prop['chart.xmin']) ) * this.graphArea);
544
-
545
- var barY = this.gutterTop;
546
- var width = (this.graphArea / (prop['chart.xmax'] - prop['chart.xmin']) ) * prop['chart.vbars'][i][1];
547
- var height = ca.height - this.gutterTop - this.gutterBottom;
548
-
549
- // Right hand bounds checking
550
- if ( (barX + width) > (ca.width - this.gutterRight) ) {
551
- width = ca.width - this.gutterRight - barX;
552
- }
553
-
554
- co.fillStyle = prop['chart.vbars'][i][2];
555
- co.fillRect(barX, barY, width, height);
556
- }
557
- }
558
-
559
-
560
-
561
-
562
- /**
563
- * Now draw the horizontal bars
564
- */
565
- if (prop['chart.hbars']) {
566
-
567
- for (i=0,len=prop['chart.hbars'].length; i<len; ++i) {
568
-
569
- if (prop['chart.hbars'][i]) {
570
-
571
- var barX = this.gutterLeft,
572
- barY = ((ca.height - this.gutterTop - this.gutterBottom) / this.data.length) * i + this.gutterTop,
573
- width = this.graphArea,
574
- height = this.barHeight
575
-
576
- co.fillStyle = prop['chart.hbars'][i];
577
- co.fillRect(barX, barY, width, height);
578
- }
579
- }
580
- }
581
-
582
-
583
-
584
-
585
- /**
586
- * Draw the events
587
- */
588
- var sequentialIndex = 0;
589
-
590
- for (i=0; i<events.length; ++i) {
591
- if (typeof(events[i][0]) == 'number') {
592
- this.DrawSingleEvent(events[i], i, sequentialIndex++);
593
- } else {
594
- for (var j=0; j<events[i].length; ++j) {
595
- var subindex = j;
596
- this.DrawSingleEvent(events[i][j], i, sequentialIndex++, subindex);
597
-
598
- }
599
- }
600
-
601
- }
602
- };
603
-
604
-
605
-
606
-
607
- /**
608
- * Retrieves the bar (if any) that has been click on or is hovered over
609
- *
610
- * @param object e The event object
611
- */
612
- this.getShape =
613
- this.getBar = function (e)
614
- {
615
- e = RG.fixEventObject(e);
616
-
617
- var mouseXY = RG.getMouseXY(e),
618
- mouseX = mouseXY[0],
619
- mouseY = mouseXY[1];
620
-
621
- /**
622
- * Loop through the bars determining if the mouse is over a bar
623
- */
624
- for (var i=0,len=this.coords.length; i<len; i++) {
625
-
626
- var left = this.coords[i][0],
627
- top = this.coords[i][1],
628
- width = this.coords[i][2],
629
- height = this.coords[i][3];
630
-
631
- if ( mouseX >= left
632
- && mouseX <= (left + width)
633
- && mouseY >= top
634
- && mouseY <= (top + height)
635
- ) {
636
-
637
- var tooltip = RG.parseTooltipText(prop['chart.tooltips'], i);
638
-
639
-
640
- var ret = {
641
- 0: this, object: this,
642
- 1: left, x: left,
643
- 2: top, y: top,
644
- 3: width, width: width,
645
- 4: height, height: height,
646
- 5: i, index: this.coords[i][4].index,
647
- subindex: (this.coords[i][4] && typeof this.coords[i][4].subindex === 'number' ? this.coords[i][4].subindex : null),
648
- sequentialIndex: this.coords[i][5],
649
- tooltip: tooltip
650
- };
651
-
652
- return ret;
653
- }
654
- }
655
- };
656
-
657
-
658
-
659
-
660
- /**
661
- * Draws a single event
662
- */
663
- this.drawSingleEvent =
664
- this.DrawSingleEvent = function (ev, index, sequentialIndex)
665
- {
666
- // Store the indexes on the original data
667
- ev.index = index;
668
- if (typeof arguments[3] === 'number') {
669
- ev.subindex = arguments[3]
670
- }
671
-
672
- var min = prop['chart.xmin'];
673
-
674
- co.beginPath();
675
- co.strokeStyle = 'black';
676
- co.fillStyle = ev[4] ? ev[4] : prop['chart.defaultcolor'];
677
-
678
- var barStartX = this.gutterLeft + (((ev[0] - min) / (prop['chart.xmax'] - min)) * this.graphArea);
679
- var barStartY = this.gutterTop + (index * this.barHeight);
680
- var barWidth = (ev[1] / (prop['chart.xmax'] - min) ) * this.graphArea;
681
-
682
- /**
683
- * If the width is greater than the graph atrea, curtail it
684
- */
685
- if ( (barStartX + barWidth) > (ca.width - this.gutterRight) ) {
686
- barWidth = ca.width - this.gutterRight - barStartX;
687
- }
688
-
689
- /**
690
- * Draw the actual bar storing store the coordinates
691
- */
692
- this.coords.push([
693
- barStartX,
694
- barStartY + prop['chart.vmargin'],
695
- barWidth,
696
- this.barHeight - (2 * prop['chart.vmargin']),
697
- ev,
698
- sequentialIndex,
699
- ]);
700
-
701
- // draw the border around the bar
702
- if (prop['chart.borders'] || ev[6]) {
703
- co.strokeStyle = typeof(ev[6]) == 'string' ? ev[6] : 'black';
704
- co.lineWidth = (typeof(ev[7]) == 'number' ? ev[7] : 1);
705
- co.beginPath();
706
- co.strokeRect(barStartX, barStartY + prop['chart.vmargin'], barWidth, this.barHeight - (2 * prop['chart.vmargin']) );
707
- }
708
-
709
- co.beginPath();
710
- co.fillRect(barStartX, barStartY + prop['chart.vmargin'], barWidth, this.barHeight - (2 * prop['chart.vmargin']) );
711
- co.fill();
712
-
713
- // Work out the completeage indicator
714
- var complete = (ev[2] / 100) * barWidth;
715
-
716
- // Draw the % complete indicator. If it's greater than 0
717
- if (typeof(ev[2]) == 'number') {
718
- co.beginPath();
719
- co.fillStyle = ev[5] ? ev[5] : '#0c0';
720
- co.fillRect(barStartX,
721
- barStartY + prop['chart.vmargin'],
722
- (ev[2] / 100) * barWidth,
723
- this.barHeight - (2 * prop['chart.vmargin']) );
724
-
725
- // Don't necessarily have to draw the label
726
- if (prop['chart.labels.percent']) {
727
- co.beginPath();
728
- co.fillStyle = prop['chart.text.color'];
729
- RG.Text2(this,{
730
- 'font': prop['chart.text.font'],
731
- 'size': prop['chart.text.size'],
732
- 'x': barStartX + barWidth + 5,
733
- 'y': barStartY + this.halfBarHeight,
734
- 'text': String(ev[2]) + '%',
735
- 'valign':'center',
736
- 'tag': 'labels.complete'
737
- });
738
- }
739
- }
740
-
741
- /**
742
- * Draw the inbar label if it's defined
743
- */
744
- if (prop['chart.labels.inbar'] && prop['chart.labels.inbar'][sequentialIndex]) {
745
-
746
- var label = String(prop['chart.labels.inbar'][sequentialIndex]);
747
- var halign = prop['chart.labels.inbar.align'] == 'left' ? 'left' : 'center';
748
- halign = prop['chart.labels.inbar.align'] == 'right' ? 'right' : halign;
749
-
750
- // Work out the position of the text
751
- if (halign == 'right') {
752
- var x = (barStartX + barWidth) - 5;
753
- } else if (halign == 'center') {
754
- var x = barStartX + (barWidth / 2);
755
- } else {
756
- var x = barStartX + 5;
757
- }
758
-
759
-
760
- // Draw the labels "above" the bar
761
- if (prop['chart.labels.inbar.above']) {
762
- x = barStartX + barWidth + 5;
763
- halign = 'left';
764
- }
765
-
766
-
767
- // Set the color
768
- co.fillStyle = prop['chart.labels.inbar.color'];
769
- RG.text2(this,{
770
- 'font':prop['chart.labels.inbar.font'],
771
- 'size':prop['chart.labels.inbar.size'],
772
- 'x': x,
773
- 'y': barStartY + this.halfBarHeight,
774
- 'text': label,
775
- 'valign':'center',
776
- 'halign':halign,
777
- 'bounding': typeof(prop['chart.labels.inbar.bgcolor']) == 'string',
778
- 'boundingFill':typeof(prop['chart.labels.inbar.bgcolor']) == 'string' ? prop['chart.labels.inbar.bgcolor'] : null,
779
- 'tag': 'labels.inbar'
780
- });
781
- }
782
- };
783
-
784
-
785
-
786
-
787
- /**
788
- * Each object type has its own Highlight() function which highlights the appropriate shape
789
- *
790
- * @param object shape The shape to highlight
791
- */
792
- this.highlight =
793
- this.Highlight = function (shape)
794
- {
795
- if (typeof prop['chart.highlight.style'] === 'function') {
796
- (prop['chart.highlight.style'])(shape);
797
- } else {
798
- RG.Highlight.Rect(this, shape);
799
- }
800
- };
801
-
802
-
803
-
804
-
805
- /**
806
- * The getObjectByXY() worker method. Don't call this call:
807
- *
808
- * RGraph.ObjectRegistry.getObjectByXY(e)
809
- *
810
- * @param object e The event object
811
- */
812
- this.getObjectByXY = function (e)
813
- {
814
- var mouseXY = RG.getMouseXY(e);
815
-
816
- if (
817
- mouseXY[0] > this.gutterLeft
818
- && mouseXY[0] < (ca.width - this.gutterRight)
819
- && mouseXY[1] > this.gutterTop
820
- && mouseXY[1] < (ca.height - this.gutterBottom)
821
- ) {
822
-
823
- return this;
824
- }
825
- };
826
-
827
-
828
-
829
-
830
- /**
831
- * This method handles the adjusting calculation for when the mouse is moved
832
- *
833
- * @param object e The event object
834
- */
835
- this.adjusting_mousemove =
836
- this.Adjusting_mousemove = function (e)
837
- {
838
- /**
839
- * Handle adjusting for the Bar
840
- */
841
- if (prop['chart.adjustable'] && RG.Registry.get('chart.adjusting') && RG.Registry.Get('chart.adjusting').uid == this.uid) {
842
-
843
- var bar = RG.Registry.get('chart.adjusting.gantt');
844
-
845
- if (bar) {
846
-
847
- var mouseXY = RG.getMouseXY(e),
848
- obj = RG.Registry.get('chart.adjusting.gantt')['object'],
849
- index = bar['index'],
850
- subindex = bar['subindex'],
851
- diff = ((mouseXY[0] - RG.Registry.get('chart.adjusting.gantt')['mousex']) / (ca.width - obj.gutterLeft - obj.gutterRight)) * prop['chart.xmax'],
852
- eventStart = RG.Registry.get('chart.adjusting.gantt')['event_start'],
853
- duration = RG.Registry.get('chart.adjusting.gantt')['event_duration'],
854
- event = typeof subindex === 'number' ? obj.data[index][subindex] : obj.data[index]
855
-
856
- if (bar['mode'] == 'move') {
857
-
858
-
859
-
860
-
861
-
862
-
863
- diff = ma.round(diff);
864
-
865
-
866
-
867
-
868
-
869
- // Single event
870
- if (RG.isNull(subindex)) {
871
-
872
- event[0] = eventStart + diff;
873
-
874
- if (eventStart + diff < 0) {
875
- obj.data[index][0] = 0;
876
- //
877
- } else if ((eventStart + diff + obj.data[index][1]) > prop['chart.xmax']) {
878
- obj.data[index][0] = prop['chart.xmax'] - obj.data[index][1];
879
- }
880
-
881
-
882
-
883
-
884
-
885
-
886
-
887
-
888
-
889
-
890
- // Multiple events
891
- } else {
892
-
893
- var index = RG.Registry.get('chart.adjusting.gantt').index;
894
- var subindex = RG.Registry.get('chart.adjusting.gantt').subindex;
895
- var event = this.data[index][subindex];
896
-
897
- event[0] = eventStart + diff;
898
-
899
- if ( (eventStart + diff) < 0) {
900
- event[0] = 0;
901
- } else if ( (eventStart + diff + event[1]) > prop['chart.xmax'] ) {
902
- event[0] = prop['chart.xmax'] - event[1];
903
- }
904
-
905
- }
906
-
907
-
908
-
909
-
910
-
911
-
912
-
913
-
914
-
915
-
916
-
917
-
918
- } else if (bar['mode'] == 'resize') {
919
-
920
- /*
921
- * Account for the right hand gutter. Appears to be a FF bug
922
- */
923
- if (mouseXY[0] > (ca.width - obj.gutterRight)) {
924
- mouseXY[0] = ca.width - obj.gutterRight;
925
- }
926
-
927
- var diff = ((mouseXY[0] - RG.Registry.get('chart.adjusting.gantt')['mousex']) / (ca.width - obj.gutterLeft - obj.gutterRight)) * prop['chart.xmax'];
928
- diff = ma.round(diff);
929
-
930
-
931
-
932
-
933
-
934
-
935
- // Single event
936
- if (RG.isNull(subindex)) {
937
- obj.data[index][1] = duration + diff;
938
-
939
- if (obj.data[index][1] < 0) {
940
- obj.data[index][1] = 1;
941
- }
942
-
943
-
944
-
945
-
946
-
947
-
948
-
949
-
950
- // Multiple events
951
- } else {
952
- obj.data[index][subindex][1] = duration + diff;
953
-
954
- if (obj.data[index][subindex][1] < 0) {
955
- obj.data[index][subindex][1] = 1;
956
- }
957
- }
958
- }
959
-
960
- RG.resetColorsToOriginalValues(this);
961
-
962
- //RG.Clear(ca);
963
- RG.redrawCanvas(ca);
964
-
965
- RG.fireCustomEvent(obj, 'onadjust');
966
- }
967
- }
968
- };
969
-
970
-
971
-
972
-
973
- /**
974
- * This function positions a tooltip when it is displayed
975
- *
976
- * @param obj object The chart object
977
- * @param int x The X coordinate specified for the tooltip
978
- * @param int y The Y coordinate specified for the tooltip
979
- * @param objec tooltip The tooltips DIV element
980
- *
981
- this.positionTooltip = function (obj, x, y, tooltip, idx)
982
- {
983
- var coordX = obj.coords[tooltip.__index__][0];
984
- var coordY = obj.coords[tooltip.__index__][1];
985
- var coordW = obj.coords[tooltip.__index__][2];
986
- var coordH = obj.coords[tooltip.__index__][3];
987
- var canvasXY = RG.getCanvasXY(obj.canvas);
988
- var gutterLeft = obj.gutterLeft;
989
- var gutterTop = obj.gutterTop;
990
- var width = tooltip.offsetWidth;
991
- var height = tooltip.offsetHeight;
992
- var mouseXY = RG.getMouseXY(window.event);
993
-
994
- // Set the top position
995
- tooltip.style.left = 0;
996
- tooltip.style.top = window.event.pageY - height - 5 + 'px';
997
-
998
- // By default any overflow is hidden
999
- tooltip.style.overflow = '';
1000
-
1001
-
1002
- // Reposition the tooltip if at the edges:
1003
-
1004
- // LEFT edge
1005
- if (canvasXY[0] + mouseXY[0] - (width / 2) < 0) {
1006
- tooltip.style.left = canvasXY[0] + mouseXY[0] - (width * 0.1) + 'px';
1007
-
1008
- // RIGHT edge
1009
- } else if (canvasXY[0] + mouseXY[0] + (width / 2) > doc.body.offsetWidth) {
1010
- tooltip.style.left = canvasXY[0] + mouseXY[0] - (width * 0.9) + 'px';
1011
-
1012
- // Default positioning - CENTERED
1013
- } else {
1014
- tooltip.style.left = canvasXY[0] + mouseXY[0] - (width / 2) + 'px';
1015
- }
1016
- };*/
1017
-
1018
-
1019
-
1020
-
1021
- /**
1022
- * Returns the X coordinate for the given value
1023
- *
1024
- * @param number value The desired value (eg minute/hour/day etc)
1025
- */
1026
- this.getXCoord = function (value)
1027
- {
1028
- var min = prop['chart.xmin'];
1029
- var max = prop['chart.xmax'];
1030
- var graphArea = ca.width - this.gutterLeft - this.gutterRight;
1031
-
1032
- if (value > max || value < min) {
1033
- return null;
1034
- }
1035
-
1036
-
1037
- var x = (((value - min) / (max - min)) * graphArea) + this.gutterLeft;
1038
-
1039
- return x;
1040
- };
1041
-
1042
-
1043
-
1044
-
1045
- /**
1046
- * Returns the value given EITHER the event object OR a two element array containing the X/Y coords
1047
- */
1048
- this.getValue = function (arg)
1049
- {
1050
- if (arg.length == 2) {
1051
- var mouseXY = arg;
1052
- } else {
1053
- var mouseXY = RGraph.getMouseXY(arg);
1054
- }
1055
-
1056
- var mouseX = mouseXY[0];
1057
- var mouseY = mouseXY[1];
1058
-
1059
- var value = (mouseX - this.gutterLeft) / (ca.width - this.gutterLeft - this.gutterRight);
1060
- value *= (prop['chart.xmax'] - prop['chart.xmin']);
1061
-
1062
- // Bounds checking
1063
- if (value < prop['chart.xmin'] || value > prop['chart.xmax']) {
1064
- value = null;
1065
- }
1066
-
1067
- return value;
1068
- };
1069
-
1070
-
1071
-
1072
-
1073
- /**
1074
- * This allows for easy specification of gradients. Could optimise this not to repeatedly call parseSingleColors()
1075
- */
1076
- this.parseColors = function ()
1077
- {
1078
- // Save the original colors so that they can be restored when the canvas is reset
1079
- if (this.original_colors.length === 0) {
1080
-
1081
- this.original_colors['data'] = RG.arrayClone(this.data);
1082
-
1083
-
1084
- this.original_colors['chart.background.barcolor1'] = RG.array_clone(prop['chart.background.barcolor1']);
1085
- this.original_colors['chart.background.barcolor2'] = RG.array_clone(prop['chart.background.barcolor2']);
1086
- this.original_colors['chart.background.grid.color'] = RG.array_clone(prop['chart.background.grid.color']);
1087
- this.original_colors['chart.defaultcolor'] = RG.array_clone(prop['chart.defaultcolor']);
1088
- this.original_colors['chart.highlight.stroke'] = RG.array_clone(prop['chart.highlight.stroke']);
1089
- this.original_colors['chart.highlight.fill'] = RG.array_clone(prop['chart.highlight.fill']);
1090
- }
1091
-
1092
-
1093
-
1094
-
1095
- /**
1096
- * this.coords can be used here as gradients are only parsed on the SECOND draw - not the first.
1097
- * A .redraw() is downe at the end of the first draw.
1098
- */
1099
- for (var i=0,sequentialIndex=0; i<this.data.length; ++i) {
1100
-
1101
- if (typeof this.data[i][0] == 'object' && typeof this.data[i][0][0] === 'number') {
1102
-
1103
- for (var j=0,len=this.data[i].length; j<len; j+=1,sequentialIndex+=1) {
1104
- this.data[i][j][4] = this.parseSingleColorForGradient(this.data[i][j][4], {start: this.data[i][j][0],duration: this.data[i][j][1]});
1105
- this.data[i][j][5] = this.parseSingleColorForGradient(this.data[i][j][5], {start: this.data[i][j][0],duration: this.data[i][j][1]});
1106
- }
1107
-
1108
- } else {
1109
-
1110
- if (typeof this.data[i][4] == 'string') this.data[i][4] = this.parseSingleColorForGradient(this.data[i][4], {start: this.data[i][0],duration: this.data[i][1]});
1111
- if (typeof this.data[i][5] == 'string') this.data[i][5] = this.parseSingleColorForGradient(this.data[i][5], {start: this.data[i][0],duration: this.data[i][1]});
1112
- ++sequentialIndex;
1113
- }
1114
- }
1115
-
1116
- prop['chart.background.barcolor1'] = this.parseSingleColorForGradient(prop['chart.background.barcolor1']);
1117
- prop['chart.background.barcolor2'] = this.parseSingleColorForGradient(prop['chart.background.barcolor2']);
1118
- prop['chart.background.grid.color'] = this.parseSingleColorForGradient(prop['chart.background.grid.color']);
1119
- prop['chart.background.color'] = this.parseSingleColorForGradient(prop['chart.background.color']);
1120
- prop['chart.defaultcolor'] = this.parseSingleColorForGradient(prop['chart.defaultcolor']);
1121
- prop['chart.highlight.stroke'] = this.parseSingleColorForGradient(prop['chart.highlight.stroke']);
1122
- prop['chart.highlight.fill'] = this.parseSingleColorForGradient(prop['chart.highlight.fill']);
1123
- };
1124
-
1125
-
1126
-
1127
-
1128
- /**
1129
- * Use this function to reset the object to the post-constructor state. Eg reset colors if
1130
- * need be etc
1131
- */
1132
- this.reset = function ()
1133
- {
1134
- };
1135
-
1136
-
1137
-
1138
-
1139
- /**
1140
- * This parses a single color value
1141
- *
1142
- * @param string color The color to parse
1143
- */
1144
- this.parseSingleColorForGradient = function (color)
1145
- {
1146
- var opts = arguments[1] || {};
1147
-
1148
- if (!color || typeof(color) != 'string') {
1149
- return color;
1150
- }
1151
-
1152
-
1153
- if (color.match(/^gradient\((.*)\)$/i)) {
1154
-
1155
- var parts = RegExp.$1.split(':');
1156
- var value = (opts.start + opts.duration) > prop['chart.xmax'] ? prop['chart.xmax'] : (opts.start + opts.duration);
1157
-
1158
- // Create the gradient
1159
- var grad = co.createLinearGradient(
1160
- typeof opts.start === 'number' ? this.getXCoord(opts.start) : this.gutterLeft,
1161
- 0,
1162
- typeof opts.start === 'number' ? this.getXCoord(value) : ca.width - this.gutterRight,
1163
- 0
1164
- );
1165
-
1166
- var diff = 1 / (parts.length - 1);
1167
-
1168
- grad.addColorStop(0, RG.trim(parts[0]));
1169
- for (var j=1; j<parts.length; ++j) {
1170
- grad.addColorStop(j * diff, RG.trim(parts[j]));
1171
- }
1172
- }
1173
-
1174
- return grad ? grad : color;
1175
- };
1176
-
1177
-
1178
-
1179
-
1180
- /**
1181
- * Using a function to add events makes it easier to facilitate method chaining
1182
- *
1183
- * @param string type The type of even to add
1184
- * @param function func
1185
- */
1186
- this.on = function (type, func)
1187
- {
1188
- if (type.substr(0,2) !== 'on') {
1189
- type = 'on' + type;
1190
- }
1191
-
1192
- if (typeof this[type] !== 'function') {
1193
- this[type] = func;
1194
- } else {
1195
- RG.addCustomEventListener(this, type, func);
1196
- }
1197
-
1198
- return this;
1199
- };
1200
-
1201
-
1202
-
1203
-
1204
- /**
1205
- * This function runs once only
1206
- * (put at the end of the file (before any effects))
1207
- */
1208
- this.firstDrawFunc = function ()
1209
- {
1210
- };
1211
-
1212
-
1213
-
1214
-
1215
- /**
1216
- * Gantt chart Grow effect
1217
- *
1218
- * @param object obj Options for the grow effect
1219
- * @param function Optional callback (a function)
1220
- */
1221
- this.grow = function ()
1222
- {
1223
- var obj = this;
1224
- var opt = arguments[0] || {};
1225
- var callback = arguments[1] ? arguments[1] : function () {};
1226
- var canvas = obj.canvas;
1227
- var context = obj.context;
1228
- var numFrames = opt.frames || 30;
1229
- var frame = 0;
1230
-
1231
- var original_events = RG.arrayClone(obj.data);
1232
-
1233
- function iterator ()
1234
- {
1235
- RG.clear(obj.canvas);
1236
- RG.redrawCanvas(obj.canvas);
1237
-
1238
-
1239
- if (frame <= numFrames) {
1240
- // Update the events
1241
- for (var i=0,len=obj.data.length; i<len; ++i) {
1242
- if (typeof obj.data[i][0] === 'object') {
1243
- for (var j=0; j<obj.data[i].length; ++j) {
1244
- obj.data[i][j][1] = (frame / numFrames) * original_events[i][j][1];
1245
- }
1246
- } else {
1247
- obj.data[i][1] = (frame / numFrames) * original_events[i][1];
1248
- }
1249
- }
1250
-
1251
- obj.reset();
1252
-
1253
-
1254
-
1255
- frame++;
1256
-
1257
- RGraph.Effects.updateCanvas(iterator);
1258
-
1259
- } else {
1260
- callback(obj);
1261
- }
1262
- }
1263
-
1264
- iterator();
1265
-
1266
- return this;
1267
- };
1268
-
1269
-
1270
-
1271
-
1272
- /**
1273
- * This helps the Gantt reset colors when the reset function is called.
1274
- * It handles going through the data and resetting the colors.
1275
- */
1276
- this.resetColorsToOriginalValues = function ()
1277
- {
1278
- /**
1279
- * Copy the original colors over for single-event-per-line data
1280
- */
1281
- for (var i=0; i<this.original_colors['data'].length; ++i) {
1282
- if (this.original_colors['data'][i][4]) {
1283
- this.data[i][4] = RG.arrayClone(this.original_colors['data'][i][4]);
1284
- }
1285
-
1286
- if (this.original_colors['data'][i][5]) {
1287
- this.data[i][5] = RG.arrayClone(this.original_colors['data'][i][5]);
1288
- }
1289
-
1290
- if (typeof this.original_colors['data'][i][0] === 'object' && typeof this.original_colors['data'][i][0][0] === 'number') {
1291
- for (var j=0,len2=this.original_colors['data'][i].length; j<len2; ++j) {
1292
- this.data[i][j][4] = RG.arrayClone(this.original_colors['data'][i][j][4]);
1293
- this.data[i][j][5] = RG.arrayClone(this.original_colors['data'][i][j][5]);
1294
- }
1295
- }
1296
- }
1297
- };
1298
-
1299
-
1300
-
1301
-
1302
-
1303
- /**
1304
- * This function resets the object - clearing it of any previously gathered info
1305
- */
1306
- this.reset = function ()
1307
- {
1308
- this.resetColorsToOriginalValues();
1309
-
1310
- this.colorsParsed = false;
1311
- this.coordsText = [];
1312
- this.original_colors = [];
1313
- this.firstDraw = true;
1314
- this.coords = [];
1315
- };
1316
-
1317
-
1318
-
1319
-
1320
- this.sequentialIndex2Grouped=function(){alert('[RGRAPH] Please post in the forum if you see this alert');};
1321
-
1322
-
1323
-
1324
-
1325
- this.isAdjustable = function (shape)
1326
- {
1327
- if (RG.isNull(prop['chart.adjustable.only'])) {
1328
- return true;
1329
-
1330
- } else if (RG.isArray(prop['chart.adjustable.only']) && prop['chart.adjustable.only'][shape.sequentialIndex]) {
1331
- return true;
1332
- }
1333
-
1334
- return false;
1335
- };
1336
-
1337
-
1338
-
1339
-
1340
- /**
1341
- * Register the object
1342
- */
1343
- RG.Register(this);
1344
-
1345
-
1346
-
1347
-
1348
- /**
1349
- * This is the 'end' of the constructor so if the first argument
1350
- * contains configuration data - handle that.
1351
- */
1352
- if (parseConfObjectForOptions) {
1353
- RG.parseObjectStyleConfig(this, conf.options);
1354
- }
1355
- };
2
+ RGraph=window.RGraph||{isRGraph:true};RGraph.Gantt=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='gantt';this.isRGraph=true;this.uid=RGraph.CreateUID();this.canvas.uid=this.canvas.uid?this.canvas.uid:RGraph.CreateUID();this.data=data;this.colorsParsed=false;this.coordsText=[];this.original_colors=[];this.firstDraw=true;this.properties={'chart.background.barcolor1':'rgba(0,0,0,0)','chart.background.barcolor2':'rgba(0,0,0,0)','chart.background.grid':true,'chart.background.grid.width':1,'chart.background.grid.color':'#ddd','chart.background.grid.hsize':20,'chart.background.grid.vsize':20,'chart.background.grid.hlines':true,'chart.background.grid.vlines':true,'chart.background.grid.border':true,'chart.background.grid.autofit':true,'chart.background.grid.autofit.align':true,'chart.background.grid.autofit.numhlines':7,'chart.background.grid.autofit.numvlines':null,'chart.vbars':[],'chart.hbars':[],'chart.text.size':12,'chart.text.font':'Segoe UI, Arial, Verdana, sans-serif','chart.text.color':'black','chart.text.accessible':true,'chart.text.accessible.overflow':'visible','chart.text.accessible.pointerevents':true,'chart.gutter.left':75,'chart.gutter.right':25,'chart.gutter.top':35,'chart.gutter.bottom':25,'chart.labels':[],'chart.labels.color':null,'chart.labels.align':'bottom','chart.labels.inbar':null,'chart.labels.inbar.color':'black','chart.labels.inbar.bgcolor':null,'chart.labels.inbar.align':'left','chart.labels.inbar.size':10,'chart.labels.inbar.font':'Segoe UI, Arial, Verdana, sans-serif','chart.labels.inbar.above':false,'chart.labels.percent':true,'chart.vmargin':2,'chart.title':'','chart.title.background':null,'chart.title.x':null,'chart.title.y':null,'chart.title.bold':true,'chart.title.font':null,'chart.title.yaxis':'','chart.title.yaxis.bold':true,'chart.title.yaxis.pos':null,'chart.title.yaxis.color':null,'chart.title.yaxis.position':'right','chart.title.yaxis.x':null,'chart.title.yaxis.y':null,'chart.title.xaxis.x':null,'chart.title.xaxis.y':null,'chart.title.xaxis.bold':true,'chart.title.xaxis.color':null,'chart.title.x':null,'chart.title.y':null,'chart.title.halign':null,'chart.title.valign':null,'chart.borders':true,'chart.defaultcolor':'white','chart.coords':[],'chart.tooltips':null,'chart.tooltips.effect':'fade','chart.tooltips.css.class':'RGraph_tooltip','chart.tooltips.highlight':true,'chart.tooltips.event':'onclick','chart.highlight.stroke':'rgba(0,0,0,0)','chart.highlight.fill':'rgba(255,255,255,0.7)','chart.xmin':0,'chart.xmax':0,'chart.contextmenu':null,'chart.annotatable':false,'chart.annotate.color':'black','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.resize.handle.adjust':[0,0],'chart.resize.handle.background':null,'chart.adjustable':false,'chart.adjustable.only':null,'chart.events.click':null,'chart.events.mousemove':null,'chart.clearto':'rgba(0,0,0,0)'}
6
+ if(!data){alert('[GANTT] The Gantt chart event data is now supplied as the second argument to the constructor - please update your code');}else{for(var i=0,idx=0;i<data.length;++i){if(typeof data[i][0]==='string')data[i][0]=parseFloat(data[i][0]);if(typeof data[i][1]==='string')data[i][1]=parseFloat(data[i][1]);if(typeof data[i][2]==='string')data[i][2]=parseFloat(data[i][2]);if(typeof data[i][7]==='string')data[i][7]=parseFloat(data[i][7]);}}
7
+ for(var i=0,idx=0;i<data.length;++i){if(RGraph.isArray(this.data[i][0])){for(var j=0;j<this.data[i].length;++j){this['$'+(idx++)]={};}}else{this['$'+(idx++)]={};}}
8
+ if(!this.canvas.__rgraph_aa_translated__){this.context.translate(0.5,0.5);this.canvas.__rgraph_aa_translated__=true;}
9
+ var RG=RGraph,ca=this.canvas,co=ca.getContext('2d'),prop=this.properties,pa2=RG.path2,win=window,doc=document,ma=Math
10
+ if(RG.Effects&&typeof RG.Effects.decorate==='function'){RG.Effects.decorate(this);}
11
+ this.set=this.Set=function(name)
12
+ {var value=typeof arguments[1]==='undefined'?null:arguments[1];if(arguments.length===1&&typeof name==='object'){RG.parseObjectStyleConfig(this,name);return this;}
13
+ if(name.substr(0,6)!='chart.'){name='chart.'+name;}
14
+ while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
15
+ if(name=='chart.margin'){name='chart.vmargin'}
16
+ if(name=='chart.events'){alert('[GANTT] The chart.events property is deprecated - supply the events data as an argument to the constructor instead');this.data=value;}
17
+ prop[name]=value;return this;};this.get=this.Get=function(name)
18
+ {if(name.substr(0,6)!='chart.'){name='chart.'+name;}
19
+ while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
20
+ if(name=='chart.margin'){name='chart.vmargin'}
21
+ return prop[name.toLowerCase()];};this.draw=this.Draw=function()
22
+ {RG.FireCustomEvent(this,'onbeforedraw');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.coordsText=[];if(!this.colorsParsed){this.parseColors();this.colorsParsed=true;}
23
+ this.graphArea=ca.width-this.gutterLeft-this.gutterRight;this.graphHeight=ca.height-this.gutterTop-this.gutterBottom;this.numEvents=this.data.length
24
+ this.barHeight=this.graphHeight/this.numEvents;this.halfBarHeight=this.barHeight/2;RG.background.Draw(this);this.drawLabels();this.DrawEvents();if(prop['chart.contextmenu']){RG.ShowContext(this);}
25
+ if(prop['chart.resizable']){RG.AllowResizing(this);}
26
+ RG.InstallEventListeners(this);if(this.firstDraw){this.firstDraw=false;RG.fireCustomEvent(this,'onfirstdraw');this.firstDrawFunc();}
27
+ RG.FireCustomEvent(this,'ondraw');return this;};this.exec=function(func)
28
+ {func(this);return this;};this.drawLabels=this.DrawLabels=function()
29
+ {var labels=prop['chart.labels'];var labelsColor=prop['chart.labels.color']||prop['chart.text.color'];var labelSpace=(this.graphArea)/labels.length;var x=this.gutterLeft+(labelSpace/2);var y=this.gutterTop-(prop['chart.text.size']/2)-5;var font=prop['chart.text.font'];var size=prop['chart.text.size'];co.beginPath();co.fillStyle=prop['chart.text.color'];co.strokeStyle='black'
30
+ if(prop['chart.labels.align']=='bottom'){y=ca.height-this.gutterBottom+size+2;}
31
+ for(i=0;i<labels.length;++i){RG.Text2(this,{'font':font,'size':size,'x':x+(i*labelSpace),'y':y,'text':String(labels[i]),'halign':'center','valign':'center','tag':'labels.horizontal'});}
32
+ for(var i=0,len=this.data.length;i<len;++i){var ev=this.data[i];var x=this.gutterLeft;var y=this.gutterTop+this.halfBarHeight+(i*this.barHeight);co.fillStyle=labelsColor||prop['chart.text.color'];RG.text2(this,{'font':font,'size':size,'x':x-5,'y':y,'text':RG.isArray(ev[0])?(ev[0][3]?String(ev[0][3]):''):(typeof ev[3]=='string'?ev[3]:''),'halign':'right','valign':'center','tag':'labels.vertical'});}};this.drawEvents=this.DrawEvents=function()
33
+ {var events=this.data;this.coords=[];if(prop['chart.vbars']){for(i=0,len=prop['chart.vbars'].length;i<len;++i){if(prop['chart.vbars'][i][0]+prop['chart.vbars'][i][1]>prop['chart.xmax']){prop['chart.vbars'][i][1]=364-prop['chart.vbars'][i][0];}
34
+ var barX=this.gutterLeft+(((prop['chart.vbars'][i][0]-prop['chart.xmin'])/(prop['chart.xmax']-prop['chart.xmin']))*this.graphArea);var barY=this.gutterTop;var width=(this.graphArea/(prop['chart.xmax']-prop['chart.xmin']))*prop['chart.vbars'][i][1];var height=ca.height-this.gutterTop-this.gutterBottom;if((barX+width)>(ca.width-this.gutterRight)){width=ca.width-this.gutterRight-barX;}
35
+ co.fillStyle=prop['chart.vbars'][i][2];co.fillRect(barX,barY,width,height);}}
36
+ if(prop['chart.hbars']){for(i=0,len=prop['chart.hbars'].length;i<len;++i){if(prop['chart.hbars'][i]){var barX=this.gutterLeft,barY=((ca.height-this.gutterTop-this.gutterBottom)/this.data.length)*i+this.gutterTop,width=this.graphArea,height=this.barHeight
37
+ co.fillStyle=prop['chart.hbars'][i];co.fillRect(barX,barY,width,height);}}}
38
+ var sequentialIndex=0;for(i=0;i<events.length;++i){if(typeof(events[i][0])=='number'){this.DrawSingleEvent(events[i],i,sequentialIndex++);}else{for(var j=0;j<events[i].length;++j){var subindex=j;this.DrawSingleEvent(events[i][j],i,sequentialIndex++,subindex);}}}};this.getShape=this.getBar=function(e)
39
+ {e=RG.fixEventObject(e);var mouseXY=RG.getMouseXY(e),mouseX=mouseXY[0],mouseY=mouseXY[1];for(var i=0,len=this.coords.length;i<len;i++){var left=this.coords[i][0],top=this.coords[i][1],width=this.coords[i][2],height=this.coords[i][3];if(mouseX>=left&&mouseX<=(left+width)&&mouseY>=top&&mouseY<=(top+height)){var tooltip=RG.parseTooltipText(prop['chart.tooltips'],i);var ret={0:this,object:this,1:left,x:left,2:top,y:top,3:width,width:width,4:height,height:height,5:i,index:this.coords[i][4].index,subindex:(this.coords[i][4]&&typeof this.coords[i][4].subindex==='number'?this.coords[i][4].subindex:null),sequentialIndex:this.coords[i][5],tooltip:tooltip};return ret;}}};this.drawSingleEvent=this.DrawSingleEvent=function(ev,index,sequentialIndex)
40
+ {ev.index=index;if(typeof arguments[3]==='number'){ev.subindex=arguments[3]}
41
+ var min=prop['chart.xmin'];co.beginPath();co.strokeStyle='black';co.fillStyle=ev[4]?ev[4]:prop['chart.defaultcolor'];var barStartX=this.gutterLeft+(((ev[0]-min)/(prop['chart.xmax']-min))*this.graphArea);var barStartY=this.gutterTop+(index*this.barHeight);var barWidth=(ev[1]/(prop['chart.xmax']-min))*this.graphArea;if((barStartX+barWidth)>(ca.width-this.gutterRight)){barWidth=ca.width-this.gutterRight-barStartX;}
42
+ this.coords.push([barStartX,barStartY+prop['chart.vmargin'],barWidth,this.barHeight-(2*prop['chart.vmargin']),ev,sequentialIndex,]);if(prop['chart.borders']||ev[6]){co.strokeStyle=typeof(ev[6])=='string'?ev[6]:'black';co.lineWidth=(typeof(ev[7])=='number'?ev[7]:1);co.beginPath();co.strokeRect(barStartX,barStartY+prop['chart.vmargin'],barWidth,this.barHeight-(2*prop['chart.vmargin']));}
43
+ co.beginPath();co.fillRect(barStartX,barStartY+prop['chart.vmargin'],barWidth,this.barHeight-(2*prop['chart.vmargin']));co.fill();var complete=(ev[2]/100)*barWidth;if(typeof(ev[2])=='number'){co.beginPath();co.fillStyle=ev[5]?ev[5]:'#0c0';co.fillRect(barStartX,barStartY+prop['chart.vmargin'],(ev[2]/100)*barWidth,this.barHeight-(2*prop['chart.vmargin']));if(prop['chart.labels.percent']){co.beginPath();co.fillStyle=prop['chart.text.color'];RG.Text2(this,{'font':prop['chart.text.font'],'size':prop['chart.text.size'],'x':barStartX+barWidth+5,'y':barStartY+this.halfBarHeight,'text':String(ev[2])+'%','valign':'center','tag':'labels.complete'});}}
44
+ if(prop['chart.labels.inbar']&&prop['chart.labels.inbar'][sequentialIndex]){var label=String(prop['chart.labels.inbar'][sequentialIndex]);var halign=prop['chart.labels.inbar.align']=='left'?'left':'center';halign=prop['chart.labels.inbar.align']=='right'?'right':halign;if(halign=='right'){var x=(barStartX+barWidth)-5;}else if(halign=='center'){var x=barStartX+(barWidth/2);}else{var x=barStartX+5;}
45
+ if(prop['chart.labels.inbar.above']){x=barStartX+barWidth+5;halign='left';}
46
+ co.fillStyle=prop['chart.labels.inbar.color'];RG.text2(this,{'font':prop['chart.labels.inbar.font'],'size':prop['chart.labels.inbar.size'],'x':x,'y':barStartY+this.halfBarHeight,'text':label,'valign':'center','halign':halign,'bounding':typeof(prop['chart.labels.inbar.bgcolor'])=='string','boundingFill':typeof(prop['chart.labels.inbar.bgcolor'])=='string'?prop['chart.labels.inbar.bgcolor']:null,'tag':'labels.inbar'});}};this.highlight=this.Highlight=function(shape)
47
+ {if(typeof prop['chart.highlight.style']==='function'){(prop['chart.highlight.style'])(shape);}else{RG.Highlight.Rect(this,shape);}};this.getObjectByXY=function(e)
48
+ {var mouseXY=RG.getMouseXY(e);if(mouseXY[0]>this.gutterLeft&&mouseXY[0]<(ca.width-this.gutterRight)&&mouseXY[1]>this.gutterTop&&mouseXY[1]<(ca.height-this.gutterBottom)){return this;}};this.adjusting_mousemove=this.Adjusting_mousemove=function(e)
49
+ {if(prop['chart.adjustable']&&RG.Registry.get('chart.adjusting')&&RG.Registry.Get('chart.adjusting').uid==this.uid){var bar=RG.Registry.get('chart.adjusting.gantt');if(bar){var mouseXY=RG.getMouseXY(e),obj=RG.Registry.get('chart.adjusting.gantt')['object'],index=bar['index'],subindex=bar['subindex'],diff=((mouseXY[0]-RG.Registry.get('chart.adjusting.gantt')['mousex'])/(ca.width-obj.gutterLeft-obj.gutterRight))*prop['chart.xmax'],eventStart=RG.Registry.get('chart.adjusting.gantt')['event_start'],duration=RG.Registry.get('chart.adjusting.gantt')['event_duration'],event=typeof subindex==='number'?obj.data[index][subindex]:obj.data[index]
50
+ if(bar['mode']=='move'){diff=ma.round(diff);if(RG.isNull(subindex)){event[0]=eventStart+diff;if(eventStart+diff<0){obj.data[index][0]=0;}else if((eventStart+diff+obj.data[index][1])>prop['chart.xmax']){obj.data[index][0]=prop['chart.xmax']-obj.data[index][1];}}else{var index=RG.Registry.get('chart.adjusting.gantt').index;var subindex=RG.Registry.get('chart.adjusting.gantt').subindex;var event=this.data[index][subindex];event[0]=eventStart+diff;if((eventStart+diff)<0){event[0]=0;}else if((eventStart+diff+event[1])>prop['chart.xmax']){event[0]=prop['chart.xmax']-event[1];}}}else if(bar['mode']=='resize'){if(mouseXY[0]>(ca.width-obj.gutterRight)){mouseXY[0]=ca.width-obj.gutterRight;}
51
+ var diff=((mouseXY[0]-RG.Registry.get('chart.adjusting.gantt')['mousex'])/(ca.width-obj.gutterLeft-obj.gutterRight))*prop['chart.xmax'];diff=ma.round(diff);if(RG.isNull(subindex)){obj.data[index][1]=duration+diff;if(obj.data[index][1]<0){obj.data[index][1]=1;}}else{obj.data[index][subindex][1]=duration+diff;if(obj.data[index][subindex][1]<0){obj.data[index][subindex][1]=1;}}}
52
+ RG.resetColorsToOriginalValues(this);RG.redrawCanvas(ca);RG.fireCustomEvent(obj,'onadjust');}}};this.getXCoord=function(value)
53
+ {var min=prop['chart.xmin'];var max=prop['chart.xmax'];var graphArea=ca.width-this.gutterLeft-this.gutterRight;if(value>max||value<min){return null;}
54
+ var x=(((value-min)/(max-min))*graphArea)+this.gutterLeft;return x;};this.getValue=function(arg)
55
+ {if(arg.length==2){var mouseXY=arg;}else{var mouseXY=RGraph.getMouseXY(arg);}
56
+ var mouseX=mouseXY[0];var mouseY=mouseXY[1];var value=(mouseX-this.gutterLeft)/(ca.width-this.gutterLeft-this.gutterRight);value*=(prop['chart.xmax']-prop['chart.xmin']);if(value<prop['chart.xmin']||value>prop['chart.xmax']){value=null;}
57
+ return value;};this.parseColors=function()
58
+ {if(this.original_colors.length===0){this.original_colors['data']=RG.arrayClone(this.data);this.original_colors['chart.background.barcolor1']=RG.array_clone(prop['chart.background.barcolor1']);this.original_colors['chart.background.barcolor2']=RG.array_clone(prop['chart.background.barcolor2']);this.original_colors['chart.background.grid.color']=RG.array_clone(prop['chart.background.grid.color']);this.original_colors['chart.defaultcolor']=RG.array_clone(prop['chart.defaultcolor']);this.original_colors['chart.highlight.stroke']=RG.array_clone(prop['chart.highlight.stroke']);this.original_colors['chart.highlight.fill']=RG.array_clone(prop['chart.highlight.fill']);}
59
+ for(var i=0,sequentialIndex=0;i<this.data.length;++i){if(typeof this.data[i][0]=='object'&&typeof this.data[i][0][0]==='number'){for(var j=0,len=this.data[i].length;j<len;j+=1,sequentialIndex+=1){this.data[i][j][4]=this.parseSingleColorForGradient(this.data[i][j][4],{start:this.data[i][j][0],duration:this.data[i][j][1]});this.data[i][j][5]=this.parseSingleColorForGradient(this.data[i][j][5],{start:this.data[i][j][0],duration:this.data[i][j][1]});}}else{if(typeof this.data[i][4]=='string')this.data[i][4]=this.parseSingleColorForGradient(this.data[i][4],{start:this.data[i][0],duration:this.data[i][1]});if(typeof this.data[i][5]=='string')this.data[i][5]=this.parseSingleColorForGradient(this.data[i][5],{start:this.data[i][0],duration:this.data[i][1]});++sequentialIndex;}}
60
+ prop['chart.background.barcolor1']=this.parseSingleColorForGradient(prop['chart.background.barcolor1']);prop['chart.background.barcolor2']=this.parseSingleColorForGradient(prop['chart.background.barcolor2']);prop['chart.background.grid.color']=this.parseSingleColorForGradient(prop['chart.background.grid.color']);prop['chart.background.color']=this.parseSingleColorForGradient(prop['chart.background.color']);prop['chart.defaultcolor']=this.parseSingleColorForGradient(prop['chart.defaultcolor']);prop['chart.highlight.stroke']=this.parseSingleColorForGradient(prop['chart.highlight.stroke']);prop['chart.highlight.fill']=this.parseSingleColorForGradient(prop['chart.highlight.fill']);};this.reset=function()
61
+ {};this.parseSingleColorForGradient=function(color)
62
+ {var opts=arguments[1]||{};if(!color||typeof(color)!='string'){return color;}
63
+ if(color.match(/^gradient\((.*)\)$/i)){var parts=RegExp.$1.split(':');var value=(opts.start+opts.duration)>prop['chart.xmax']?prop['chart.xmax']:(opts.start+opts.duration);var grad=co.createLinearGradient(typeof opts.start==='number'?this.getXCoord(opts.start):this.gutterLeft,0,typeof opts.start==='number'?this.getXCoord(value):ca.width-this.gutterRight,0);var diff=1/(parts.length-1);grad.addColorStop(0,RG.trim(parts[0]));for(var j=1;j<parts.length;++j){grad.addColorStop(j*diff,RG.trim(parts[j]));}}
64
+ return grad?grad:color;};this.on=function(type,func)
65
+ {if(type.substr(0,2)!=='on'){type='on'+type;}
66
+ if(typeof this[type]!=='function'){this[type]=func;}else{RG.addCustomEventListener(this,type,func);}
67
+ return this;};this.firstDrawFunc=function()
68
+ {};this.grow=function()
69
+ {var obj=this;var opt=arguments[0]||{};var callback=arguments[1]?arguments[1]:function(){};var canvas=obj.canvas;var context=obj.context;var numFrames=opt.frames||30;var frame=0;var original_events=RG.arrayClone(obj.data);function iterator()
70
+ {RG.clear(obj.canvas);RG.redrawCanvas(obj.canvas);if(frame<=numFrames){for(var i=0,len=obj.data.length;i<len;++i){if(typeof obj.data[i][0]==='object'){for(var j=0;j<obj.data[i].length;++j){obj.data[i][j][1]=(frame/numFrames)*original_events[i][j][1];}}else{obj.data[i][1]=(frame/numFrames)*original_events[i][1];}}
71
+ obj.reset();frame++;RGraph.Effects.updateCanvas(iterator);}else{callback(obj);}}
72
+ iterator();return this;};this.resetColorsToOriginalValues=function()
73
+ {for(var i=0;i<this.original_colors['data'].length;++i){if(this.original_colors['data'][i][4]){this.data[i][4]=RG.arrayClone(this.original_colors['data'][i][4]);}
74
+ if(this.original_colors['data'][i][5]){this.data[i][5]=RG.arrayClone(this.original_colors['data'][i][5]);}
75
+ if(typeof this.original_colors['data'][i][0]==='object'&&typeof this.original_colors['data'][i][0][0]==='number'){for(var j=0,len2=this.original_colors['data'][i].length;j<len2;++j){this.data[i][j][4]=RG.arrayClone(this.original_colors['data'][i][j][4]);this.data[i][j][5]=RG.arrayClone(this.original_colors['data'][i][j][5]);}}}};this.reset=function()
76
+ {this.resetColorsToOriginalValues();this.colorsParsed=false;this.coordsText=[];this.original_colors=[];this.firstDraw=true;this.coords=[];};this.sequentialIndex2Grouped=function(){alert('[RGRAPH] Please post in the forum if you see this alert');};this.isAdjustable=function(shape)
77
+ {if(RG.isNull(prop['chart.adjustable.only'])){return true;}else if(RG.isArray(prop['chart.adjustable.only'])&&prop['chart.adjustable.only'][shape.sequentialIndex]){return true;}
78
+ return false;};RG.Register(this);if(parseConfObjectForOptions){RG.parseObjectStyleConfig(this,conf.options);}};