rgraph-rails 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +0 -1
  3. data/README.md +3 -3
  4. data/lib/rgraph-rails/version.rb +1 -1
  5. data/vendor/assets/javascripts/RGraph.bar.js +239 -3764
  6. data/vendor/assets/javascripts/RGraph.bipolar.js +115 -1986
  7. data/vendor/assets/javascripts/RGraph.common.annotate.js +35 -399
  8. data/vendor/assets/javascripts/RGraph.common.context.js +30 -600
  9. data/vendor/assets/javascripts/RGraph.common.core.js +403 -5187
  10. data/vendor/assets/javascripts/RGraph.common.csv.js +19 -275
  11. data/vendor/assets/javascripts/RGraph.common.deprecated.js +35 -454
  12. data/vendor/assets/javascripts/RGraph.common.dynamic.js +84 -1189
  13. data/vendor/assets/javascripts/RGraph.common.effects.js +90 -1548
  14. data/vendor/assets/javascripts/RGraph.common.key.js +54 -755
  15. data/vendor/assets/javascripts/RGraph.common.resizing.js +37 -567
  16. data/vendor/assets/javascripts/RGraph.common.sheets.js +29 -356
  17. data/vendor/assets/javascripts/RGraph.common.tooltips.js +32 -614
  18. data/vendor/assets/javascripts/RGraph.common.zoom.js +14 -223
  19. data/vendor/assets/javascripts/RGraph.cornergauge.js +71 -0
  20. data/vendor/assets/javascripts/RGraph.drawing.background.js +35 -620
  21. data/vendor/assets/javascripts/RGraph.drawing.circle.js +35 -576
  22. data/vendor/assets/javascripts/RGraph.drawing.image.js +52 -807
  23. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +41 -717
  24. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +37 -668
  25. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +36 -563
  26. data/vendor/assets/javascripts/RGraph.drawing.poly.js +40 -608
  27. data/vendor/assets/javascripts/RGraph.drawing.rect.js +35 -597
  28. data/vendor/assets/javascripts/RGraph.drawing.text.js +34 -642
  29. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +50 -809
  30. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +51 -856
  31. data/vendor/assets/javascripts/RGraph.fuel.js +58 -964
  32. data/vendor/assets/javascripts/RGraph.funnel.js +55 -984
  33. data/vendor/assets/javascripts/RGraph.gantt.js +75 -1241
  34. data/vendor/assets/javascripts/RGraph.gauge.js +87 -1397
  35. data/vendor/assets/javascripts/RGraph.hbar.js +143 -2376
  36. data/vendor/assets/javascripts/RGraph.hprogress.js +80 -1397
  37. data/vendor/assets/javascripts/RGraph.line.js +241 -4162
  38. data/vendor/assets/javascripts/RGraph.meter.js +74 -1278
  39. metadata +3 -30
  40. data/vendor/assets/images/bg.png +0 -0
  41. data/vendor/assets/images/bullet.png +0 -0
  42. data/vendor/assets/images/facebook-large.png +0 -0
  43. data/vendor/assets/images/google-plus-large.png +0 -0
  44. data/vendor/assets/images/logo.png +0 -0
  45. data/vendor/assets/images/meter-image-sd-needle.png +0 -0
  46. data/vendor/assets/images/meter-image-sd.png +0 -0
  47. data/vendor/assets/images/meter-sketch-needle.png +0 -0
  48. data/vendor/assets/images/meter-sketch.png +0 -0
  49. data/vendor/assets/images/odometer-background.png +0 -0
  50. data/vendor/assets/images/rgraph.jpg +0 -0
  51. data/vendor/assets/images/title.png +0 -0
  52. data/vendor/assets/images/twitter-large.png +0 -0
  53. data/vendor/assets/javascripts/RGraph.modaldialog.js +0 -301
  54. data/vendor/assets/javascripts/RGraph.odo.js +0 -1265
  55. data/vendor/assets/javascripts/RGraph.pie.js +0 -2272
  56. data/vendor/assets/javascripts/RGraph.radar.js +0 -1847
  57. data/vendor/assets/javascripts/RGraph.rose.js +0 -1877
  58. data/vendor/assets/javascripts/RGraph.rscatter.js +0 -1425
  59. data/vendor/assets/javascripts/RGraph.scatter.js +0 -2970
  60. data/vendor/assets/javascripts/RGraph.semicircularprogress.js +0 -1015
  61. data/vendor/assets/javascripts/RGraph.thermometer.js +0 -1129
  62. data/vendor/assets/javascripts/RGraph.vprogress.js +0 -1452
  63. data/vendor/assets/javascripts/RGraph.waterfall.js +0 -1252
  64. data/vendor/assets/javascripts/financial-data.js +0 -1067
  65. data/vendor/assets/stylesheets/ModalDialog.css +0 -90
  66. data/vendor/assets/stylesheets/animations.css +0 -3347
  67. data/vendor/assets/stylesheets/website.css +0 -446
@@ -1,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);}};