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.
- checksums.yaml +8 -8
- data/.travis.yml +0 -1
- data/README.md +3 -3
- data/lib/rgraph-rails/version.rb +1 -1
- data/vendor/assets/javascripts/RGraph.bar.js +239 -3764
- data/vendor/assets/javascripts/RGraph.bipolar.js +115 -1986
- data/vendor/assets/javascripts/RGraph.common.annotate.js +35 -399
- data/vendor/assets/javascripts/RGraph.common.context.js +30 -600
- data/vendor/assets/javascripts/RGraph.common.core.js +403 -5187
- data/vendor/assets/javascripts/RGraph.common.csv.js +19 -275
- data/vendor/assets/javascripts/RGraph.common.deprecated.js +35 -454
- data/vendor/assets/javascripts/RGraph.common.dynamic.js +84 -1189
- data/vendor/assets/javascripts/RGraph.common.effects.js +90 -1548
- data/vendor/assets/javascripts/RGraph.common.key.js +54 -755
- data/vendor/assets/javascripts/RGraph.common.resizing.js +37 -567
- data/vendor/assets/javascripts/RGraph.common.sheets.js +29 -356
- data/vendor/assets/javascripts/RGraph.common.tooltips.js +32 -614
- data/vendor/assets/javascripts/RGraph.common.zoom.js +14 -223
- data/vendor/assets/javascripts/RGraph.cornergauge.js +71 -0
- data/vendor/assets/javascripts/RGraph.drawing.background.js +35 -620
- data/vendor/assets/javascripts/RGraph.drawing.circle.js +35 -576
- data/vendor/assets/javascripts/RGraph.drawing.image.js +52 -807
- data/vendor/assets/javascripts/RGraph.drawing.marker1.js +41 -717
- data/vendor/assets/javascripts/RGraph.drawing.marker2.js +37 -668
- data/vendor/assets/javascripts/RGraph.drawing.marker3.js +36 -563
- data/vendor/assets/javascripts/RGraph.drawing.poly.js +40 -608
- data/vendor/assets/javascripts/RGraph.drawing.rect.js +35 -597
- data/vendor/assets/javascripts/RGraph.drawing.text.js +34 -642
- data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +50 -809
- data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +51 -856
- data/vendor/assets/javascripts/RGraph.fuel.js +58 -964
- data/vendor/assets/javascripts/RGraph.funnel.js +55 -984
- data/vendor/assets/javascripts/RGraph.gantt.js +75 -1241
- data/vendor/assets/javascripts/RGraph.gauge.js +87 -1397
- data/vendor/assets/javascripts/RGraph.hbar.js +143 -2376
- data/vendor/assets/javascripts/RGraph.hprogress.js +80 -1397
- data/vendor/assets/javascripts/RGraph.line.js +241 -4162
- data/vendor/assets/javascripts/RGraph.meter.js +74 -1278
- metadata +3 -30
- data/vendor/assets/images/bg.png +0 -0
- data/vendor/assets/images/bullet.png +0 -0
- data/vendor/assets/images/facebook-large.png +0 -0
- data/vendor/assets/images/google-plus-large.png +0 -0
- data/vendor/assets/images/logo.png +0 -0
- data/vendor/assets/images/meter-image-sd-needle.png +0 -0
- data/vendor/assets/images/meter-image-sd.png +0 -0
- data/vendor/assets/images/meter-sketch-needle.png +0 -0
- data/vendor/assets/images/meter-sketch.png +0 -0
- data/vendor/assets/images/odometer-background.png +0 -0
- data/vendor/assets/images/rgraph.jpg +0 -0
- data/vendor/assets/images/title.png +0 -0
- data/vendor/assets/images/twitter-large.png +0 -0
- data/vendor/assets/javascripts/RGraph.modaldialog.js +0 -301
- data/vendor/assets/javascripts/RGraph.odo.js +0 -1265
- data/vendor/assets/javascripts/RGraph.pie.js +0 -2272
- data/vendor/assets/javascripts/RGraph.radar.js +0 -1847
- data/vendor/assets/javascripts/RGraph.rose.js +0 -1877
- data/vendor/assets/javascripts/RGraph.rscatter.js +0 -1425
- data/vendor/assets/javascripts/RGraph.scatter.js +0 -2970
- data/vendor/assets/javascripts/RGraph.semicircularprogress.js +0 -1015
- data/vendor/assets/javascripts/RGraph.thermometer.js +0 -1129
- data/vendor/assets/javascripts/RGraph.vprogress.js +0 -1452
- data/vendor/assets/javascripts/RGraph.waterfall.js +0 -1252
- data/vendor/assets/javascripts/financial-data.js +0 -1067
- data/vendor/assets/stylesheets/ModalDialog.css +0 -90
- data/vendor/assets/stylesheets/animations.css +0 -3347
- 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
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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);}};
|