rgraph-rails 1.0.5 → 1.0.6

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