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,1987 +1,116 @@
|
|
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 starts at just 99 GBP and |
|
11
|
-
* | you can read about it here: |
|
12
|
-
* | |
|
13
|
-
* | http://www.rgraph.net/license |
|
14
|
-
* o--------------------------------------------------------------------------------o
|
15
|
-
*/
|
16
1
|
|
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
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
'chart.highlight.stroke': 'rgba(0,0,0,0)',
|
133
|
-
'chart.highlight.fill': 'rgba(255,255,255,0.7)',
|
134
|
-
'chart.units.pre': '',
|
135
|
-
'chart.units.post': '',
|
136
|
-
'chart.shadow': false,
|
137
|
-
'chart.shadow.color': '#666',
|
138
|
-
'chart.shadow.offsetx': 3,
|
139
|
-
'chart.shadow.offsety': 3,
|
140
|
-
'chart.shadow.blur': 3,
|
141
|
-
'chart.annotatable': false,
|
142
|
-
'chart.annotate.color': 'black',
|
143
|
-
'chart.xmax': null,
|
144
|
-
'chart.xmin': 0,
|
145
|
-
'chart.scale.zerostart': true,
|
146
|
-
'chart.scale.decimals': null,
|
147
|
-
'chart.scale.point': '.',
|
148
|
-
'chart.scale.thousand': ',',
|
149
|
-
'chart.axis.color': 'black',
|
150
|
-
'chart.zoom.factor': 1.5,
|
151
|
-
'chart.zoom.fade.in': true,
|
152
|
-
'chart.zoom.fade.out': true,
|
153
|
-
'chart.zoom.hdir': 'right',
|
154
|
-
'chart.zoom.vdir': 'down',
|
155
|
-
'chart.zoom.frames': 25,
|
156
|
-
'chart.zoom.delay': 16.666,
|
157
|
-
'chart.zoom.shadow': true,
|
158
|
-
'chart.zoom.background': true,
|
159
|
-
'chart.zoom.action': 'zoom',
|
160
|
-
'chart.resizable': false,
|
161
|
-
'chart.resize.handle.background': null,
|
162
|
-
'chart.strokestyle': 'rgba(0,0,0,0)',
|
163
|
-
'chart.events.mousemove': null,
|
164
|
-
'chart.events.click': null,
|
165
|
-
'chart.linewidth': 1,
|
166
|
-
'chart.noaxes': false,
|
167
|
-
'chart.xlabels': true,
|
168
|
-
'chart.numyticks': null,
|
169
|
-
'chart.numxticks': 5,
|
170
|
-
'chart.axis.linewidth': 1,
|
171
|
-
'chart.labels.count': 5,
|
172
|
-
'chart.variant.threed.offsetx': 10,
|
173
|
-
'chart.variant.threed.offsety': 5,
|
174
|
-
'chart.variant.threed.angle': 0.1,
|
175
|
-
'chart.clearto': 'rgba(0,0,0,0)'
|
176
|
-
}
|
177
|
-
|
178
|
-
// Pad the arrays so they're the same size
|
179
|
-
while (this.left.length < this.right.length) this.left.push(null);
|
180
|
-
while (this.left.length > this.right.length) this.right.push(null);
|
181
|
-
|
182
|
-
/**
|
183
|
-
* Set the default for the number of Y tickmarks
|
184
|
-
*/
|
185
|
-
this.properties['chart.numyticks'] = this.left.length;
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
/**
|
191
|
-
* Create the dollar objects so that functions can be added to them
|
192
|
-
*/
|
193
|
-
var linear_data = RGraph.arrayLinearize(this.left, this.right);
|
194
|
-
|
195
|
-
for (var i=0; i<linear_data.length; ++i) {
|
196
|
-
this['$' + i] = {};
|
197
|
-
}
|
198
|
-
|
199
|
-
|
200
|
-
/**
|
201
|
-
* Translate half a pixel for antialiasing purposes - but only if it hasn't beeen
|
202
|
-
* done already
|
203
|
-
*/
|
204
|
-
if (!this.canvas.__rgraph_aa_translated__) {
|
205
|
-
this.context.translate(0.5,0.5);
|
206
|
-
|
207
|
-
this.canvas.__rgraph_aa_translated__ = true;
|
208
|
-
}
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
// Short variable names
|
214
|
-
var RG = RGraph,
|
215
|
-
ca = this.canvas,
|
216
|
-
co = ca.getContext('2d'),
|
217
|
-
prop = this.properties,
|
218
|
-
pa2 = RG.path2,
|
219
|
-
win = window,
|
220
|
-
doc = document,
|
221
|
-
ma = Math
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
/**
|
226
|
-
* "Decorate" the object with the generic effects if the effects library has been included
|
227
|
-
*/
|
228
|
-
if (RG.Effects && typeof RG.Effects.decorate === 'function') {
|
229
|
-
RG.Effects.decorate(this);
|
230
|
-
}
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
/**
|
239
|
-
* The setter
|
240
|
-
*
|
241
|
-
* @param name string The name of the parameter to set
|
242
|
-
* @param value mixed The value of the paraneter
|
243
|
-
*/
|
244
|
-
this.set =
|
245
|
-
this.Set = function (name)
|
246
|
-
{
|
247
|
-
var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
|
248
|
-
|
249
|
-
|
250
|
-
/**
|
251
|
-
* the number of arguments is only one and it's an
|
252
|
-
* object - parse it for configuration data and return.
|
253
|
-
*/
|
254
|
-
if (arguments.length === 1 && typeof name === 'object') {
|
255
|
-
RG.parseObjectStyleConfig(this, name);
|
256
|
-
return this;
|
257
|
-
}
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
/**
|
264
|
-
* This should be done first - prepend the propertyy name with "chart." if necessary
|
265
|
-
*/
|
266
|
-
if (name.substr(0,6) != 'chart.') {
|
267
|
-
name = 'chart.' + name;
|
268
|
-
}
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
// Convert uppercase letters to dot+lower case letter
|
274
|
-
while(name.match(/([A-Z])/)) {
|
275
|
-
name = name.replace(/([A-Z])/, '.' + RegExp.$1.toLowerCase());
|
276
|
-
}
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
prop[name] = value;
|
284
|
-
|
285
|
-
return this;
|
286
|
-
};
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
/**
|
292
|
-
* The getter
|
293
|
-
*
|
294
|
-
* @param name string The name of the parameter to get
|
295
|
-
*/
|
296
|
-
this.get =
|
297
|
-
this.Get = function (name)
|
298
|
-
{
|
299
|
-
/**
|
300
|
-
* This should be done first - prepend the property name with "chart." if necessary
|
301
|
-
*/
|
302
|
-
if (name.substr(0,6) != 'chart.') {
|
303
|
-
name = 'chart.' + name;
|
304
|
-
}
|
305
|
-
|
306
|
-
// Convert uppercase letters to dot+lower case letter
|
307
|
-
name = name.replace(/([A-Z])/g, function (str)
|
308
|
-
{
|
309
|
-
return '.' + String(RegExp.$1).toLowerCase()
|
310
|
-
});
|
311
|
-
|
312
|
-
return this.properties[name.toLowerCase()];
|
313
|
-
};
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
/**
|
319
|
-
* Draws the graph
|
320
|
-
*/
|
321
|
-
this.draw =
|
322
|
-
this.Draw = function ()
|
323
|
-
{
|
324
|
-
/**
|
325
|
-
* Fire the onbeforedraw event
|
326
|
-
*/
|
327
|
-
RG.FireCustomEvent(this, 'onbeforedraw');
|
328
|
-
|
329
|
-
|
330
|
-
/**
|
331
|
-
* Parse the colors. This allows for simple gradient syntax
|
332
|
-
*/
|
333
|
-
if (!this.colorsParsed) {
|
334
|
-
this.parseColors();
|
335
|
-
|
336
|
-
// Don't want to do this again
|
337
|
-
this.colorsParsed = true;
|
338
|
-
}
|
339
|
-
|
340
|
-
|
341
|
-
/**
|
342
|
-
* This is new in May 2011 and facilitates indiviual gutter settings,
|
343
|
-
* eg chart.gutter.left
|
344
|
-
*/
|
345
|
-
this.gutterLeft = prop['chart.gutter.left'];
|
346
|
-
this.gutterRight = prop['chart.gutter.right'];
|
347
|
-
this.gutterTop = prop['chart.gutter.top'];
|
348
|
-
this.gutterBottom = prop['chart.gutter.bottom'];
|
349
|
-
this.gutterCenter = prop['chart.gutter.center'];
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
// Reset the data to what was initially supplied
|
354
|
-
this.left = this.data[0];
|
355
|
-
this.right = this.data[1];
|
356
|
-
|
357
|
-
|
358
|
-
/**
|
359
|
-
* Reset the coords array
|
360
|
-
*/
|
361
|
-
this.coords = [];
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
/**
|
366
|
-
* Stop this growing uncontrollably
|
367
|
-
*/
|
368
|
-
this.coordsText = [];
|
369
|
-
|
370
|
-
|
371
|
-
if (prop['chart.variant'] === '3d') {
|
372
|
-
if (prop['chart.text.accessible']) {
|
373
|
-
// Nada
|
374
|
-
} else {
|
375
|
-
co.setTransform(1,prop['chart.variant.threed.angle'],0,1,0.5,0.5);
|
376
|
-
}
|
377
|
-
}
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
// Some necessary variables
|
382
|
-
this.axisWidth = (ca.width - prop['chart.gutter.center'] - this.gutterLeft - this.gutterRight) / 2;
|
383
|
-
this.axisHeight = ca.height - this.gutterTop - this.gutterBottom;
|
384
|
-
|
385
|
-
|
386
|
-
// Reset the sequential index
|
387
|
-
this.sequentialFullIndex = 0;
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
this.getMax();
|
392
|
-
this.drawBackgroundGrid();
|
393
|
-
this.draw3DAxes();
|
394
|
-
this.drawAxes();
|
395
|
-
this.drawTicks();
|
396
|
-
|
397
|
-
co.save();
|
398
|
-
co.beginPath();
|
399
|
-
co.rect(this.gutterLeft, this.gutterTop - (prop['chart.variant.threed.offsety'] || 0), ca.width - this.gutterLeft - this.gutterRight, ca.height - this.gutterTop - this.gutterBottom + (2 * (prop['chart.variant.threed.offsety'] || 0)) );
|
400
|
-
co.clip();
|
401
|
-
|
402
|
-
this.drawLeftBars();
|
403
|
-
this.drawRightBars();
|
404
|
-
|
405
|
-
// Redraw the bars so that shadows on not on top
|
406
|
-
this.drawLeftBars({shadow: false});
|
407
|
-
this.drawRightBars({shadow: false});
|
408
|
-
co.restore();
|
409
|
-
|
410
|
-
this.drawAxes();
|
411
|
-
|
412
|
-
this.drawLabels();
|
413
|
-
this.drawTitles();
|
414
|
-
|
415
|
-
|
416
|
-
/**
|
417
|
-
* Setup the context menu if required
|
418
|
-
*/
|
419
|
-
if (prop['chart.contextmenu']) {
|
420
|
-
RG.ShowContext(this);
|
421
|
-
}
|
422
|
-
|
423
|
-
|
424
|
-
/**
|
425
|
-
* This function enables resizing
|
426
|
-
*/
|
427
|
-
if (prop['chart.resizable']) {
|
428
|
-
RG.AllowResizing(this);
|
429
|
-
}
|
430
|
-
|
431
|
-
|
432
|
-
/**
|
433
|
-
* This installs the event listeners
|
434
|
-
*/
|
435
|
-
RG.InstallEventListeners(this);
|
436
|
-
|
437
|
-
|
438
|
-
/**
|
439
|
-
* Fire the onfirstdraw event
|
440
|
-
*/
|
441
|
-
if (this.firstDraw) {
|
442
|
-
RG.fireCustomEvent(this, 'onfirstdraw');
|
443
|
-
this.firstDraw = false;
|
444
|
-
this.firstDrawFunc();
|
445
|
-
}
|
446
|
-
|
447
|
-
|
448
|
-
/**
|
449
|
-
* Fire the RGraph ondraw event
|
450
|
-
*/
|
451
|
-
RG.FireCustomEvent(this, 'ondraw');
|
452
|
-
|
453
|
-
return this;
|
454
|
-
};
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
/**
|
459
|
-
* Used in chaining. Runs a function there and then - not waiting for
|
460
|
-
* the events to fire (eg the onbeforedraw event)
|
461
|
-
*
|
462
|
-
* @param function func The function to execute
|
463
|
-
*/
|
464
|
-
this.exec = function (func)
|
465
|
-
{
|
466
|
-
func(this);
|
467
|
-
|
468
|
-
return this;
|
469
|
-
};
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
/**
|
475
|
-
* Draws the axes
|
476
|
-
*/
|
477
|
-
this.draw3DAxes = function ()
|
478
|
-
{
|
479
|
-
if (prop['chart.variant'] === '3d') {
|
480
|
-
var offsetx = prop['chart.variant.threed.offsetx'],
|
481
|
-
offsety = prop['chart.variant.threed.offsety'];
|
482
|
-
|
483
|
-
// Set the linewidth
|
484
|
-
co.lineWidth = prop['chart.axis.linewidth'] + 0.001;
|
485
|
-
|
486
|
-
|
487
|
-
// Draw the left set of axes
|
488
|
-
co.beginPath();
|
489
|
-
co.strokeStyle = prop['chart.axis.color'];
|
490
|
-
|
491
|
-
// Draw the horizontal 3d axis
|
492
|
-
// The left horizontal axis
|
493
|
-
pa2(co,
|
494
|
-
'b m % % l % % l % % l % % s #aaa f #ddd',
|
495
|
-
this.gutterLeft, ma.round( ca.height - this.gutterBottom),
|
496
|
-
this.gutterLeft + offsetx, ma.round( ca.height - this.gutterBottom - offsety),
|
497
|
-
this.gutterLeft + offsetx + this.axisWidth, ma.round( ca.height - this.gutterBottom - offsety),
|
498
|
-
this.gutterLeft + this.axisWidth, ma.round( ca.height - this.gutterBottom)
|
499
|
-
);
|
500
|
-
|
501
|
-
// The left vertical axis
|
502
|
-
this.draw3DLeftVerticalAxis();
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
// Draw the right horizontal axes
|
508
|
-
pa2(co,
|
509
|
-
'b m % % l % % l % % l % % s #aaa f #ddd',
|
510
|
-
this.gutterLeft + this.gutterCenter + this.axisWidth, ma.round( ca.height - this.gutterBottom),
|
511
|
-
this.gutterLeft + this.gutterCenter + this.axisWidth + offsetx, ma.round( ca.height - this.gutterBottom - offsety),
|
512
|
-
this.gutterLeft + this.gutterCenter + this.axisWidth + this.axisWidth + offsetx, ma.round( ca.height - this.gutterBottom - offsety),
|
513
|
-
this.gutterLeft + this.gutterCenter + this.axisWidth + this.axisWidth, ma.round( ca.height - this.gutterBottom)
|
514
|
-
);
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
// Draw the right vertical axes
|
520
|
-
pa2(co,
|
521
|
-
'b m % % l % % l % % l % % s #aaa f #ddd',
|
522
|
-
this.gutterLeft + this.gutterCenter + this.axisWidth, ca.height - this.gutterBottom,
|
523
|
-
this.gutterLeft + this.gutterCenter + this.axisWidth, ca.height - this.gutterBottom - this.axisHeight,
|
524
|
-
this.gutterLeft + this.gutterCenter + this.axisWidth + offsetx, ca.height - this.gutterBottom - this.axisHeight - offsety,
|
525
|
-
this.gutterLeft + this.gutterCenter + this.axisWidth + offsetx, ca.height - this.gutterBottom - offsety
|
526
|
-
);
|
527
|
-
}
|
528
|
-
}
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
this.draw3DLeftVerticalAxis = function ()
|
534
|
-
{
|
535
|
-
if (prop['chart.variant'] === '3d') {
|
536
|
-
var offsetx = prop['chart.variant.threed.offsetx'],
|
537
|
-
offsety = prop['chart.variant.threed.offsety'];
|
538
|
-
|
539
|
-
// The left vertical axis
|
540
|
-
pa2(co,
|
541
|
-
'b m % % l % % l % % l % % s #aaa f #ddd',
|
542
|
-
this.gutterLeft + this.axisWidth, this.gutterTop,
|
543
|
-
this.gutterLeft + this.axisWidth + offsetx, this.gutterTop - offsety,
|
544
|
-
this.gutterLeft + this.axisWidth + offsetx, ca.height - this.gutterBottom - offsety,
|
545
|
-
this.gutterLeft + this.axisWidth, ca.height - this.gutterBottom
|
546
|
-
);
|
547
|
-
}
|
548
|
-
};
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
/**
|
554
|
-
* Draws the axes
|
555
|
-
*/
|
556
|
-
this.drawAxes =
|
557
|
-
this.DrawAxes = function ()
|
558
|
-
{
|
559
|
-
// Set the linewidth
|
560
|
-
co.lineWidth = prop['chart.axis.linewidth'] + 0.001;
|
561
|
-
|
562
|
-
|
563
|
-
// Draw the left set of axes
|
564
|
-
co.beginPath();
|
565
|
-
co.strokeStyle = prop['chart.axis.color'];
|
566
|
-
|
567
|
-
this.axisWidth = (ca.width - prop['chart.gutter.center'] - this.gutterLeft - this.gutterRight) / 2;
|
568
|
-
this.axisHeight = ca.height - this.gutterTop - this.gutterBottom;
|
569
|
-
|
570
|
-
|
571
|
-
// This must be here so that the two above variables are calculated
|
572
|
-
if (prop['chart.noaxes']) {
|
573
|
-
return;
|
574
|
-
}
|
575
|
-
|
576
|
-
co.moveTo(this.gutterLeft, Math.round( ca.height - this.gutterBottom));
|
577
|
-
co.lineTo(this.gutterLeft + this.axisWidth, Math.round( ca.height - this.gutterBottom));
|
578
|
-
|
579
|
-
co.moveTo(ma.round( this.gutterLeft + this.axisWidth), ca.height - this.gutterBottom);
|
580
|
-
co.lineTo(ma.round( this.gutterLeft + this.axisWidth), this.gutterTop);
|
581
|
-
|
582
|
-
co.stroke();
|
583
|
-
|
584
|
-
|
585
|
-
// Draw the right set of axes
|
586
|
-
co.beginPath();
|
587
|
-
|
588
|
-
var x = this.gutterLeft + this.axisWidth + prop['chart.gutter.center'];
|
589
|
-
|
590
|
-
co.moveTo(Math.round( x), this.gutterTop);
|
591
|
-
co.lineTo(Math.round( x), ca.height - this.gutterBottom);
|
592
|
-
|
593
|
-
co.moveTo(Math.round( x), Math.round( ca.height - this.gutterBottom));
|
594
|
-
co.lineTo(ca.width - this.gutterRight, Math.round( ca.height - this.gutterBottom));
|
595
|
-
|
596
|
-
co.stroke();
|
597
|
-
};
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
/**
|
603
|
-
* Draws the tick marks on the axes
|
604
|
-
*/
|
605
|
-
this.drawTicks =
|
606
|
-
this.DrawTicks = function ()
|
607
|
-
{
|
608
|
-
// Set the linewidth
|
609
|
-
co.lineWidth = prop['chart.axis.linewidth'] + 0.001;
|
610
|
-
|
611
|
-
var numDataPoints = this.left.length;
|
612
|
-
var barHeight = ( (ca.height - this.gutterTop - this.gutterBottom)- (this.left.length * (prop['chart.margin'] * 2) )) / numDataPoints;
|
613
|
-
|
614
|
-
// Store this for later
|
615
|
-
this.barHeight = barHeight;
|
616
|
-
|
617
|
-
// If no axes - no tickmarks
|
618
|
-
if (prop['chart.noaxes']) {
|
619
|
-
return;
|
620
|
-
}
|
621
|
-
|
622
|
-
// Draw the left Y tick marks
|
623
|
-
if (prop['chart.numyticks'] > 0) {
|
624
|
-
co.beginPath();
|
625
|
-
for (var i=0; i<prop['chart.numyticks']; ++i) {
|
626
|
-
var y = prop['chart.gutter.top'] + (((ca.height - this.gutterTop - this.gutterBottom) / prop['chart.numyticks']) * i);
|
627
|
-
co.moveTo(this.gutterLeft + this.axisWidth , y);
|
628
|
-
co.lineTo(this.gutterLeft + this.axisWidth + 3, y);
|
629
|
-
}
|
630
|
-
co.stroke();
|
631
|
-
|
632
|
-
//Draw the right axis Y tick marks
|
633
|
-
co.beginPath();
|
634
|
-
for (var i=0; i<prop['chart.numyticks']; ++i) {
|
635
|
-
var y = prop['chart.gutter.top'] + (((ca.height - this.gutterTop - this.gutterBottom) / prop['chart.numyticks']) * i);
|
636
|
-
co.moveTo(this.gutterLeft + this.axisWidth + prop['chart.gutter.center'], y);
|
637
|
-
co.lineTo(this.gutterLeft + this.axisWidth + prop['chart.gutter.center'] - 3, y);
|
638
|
-
}
|
639
|
-
co.stroke();
|
640
|
-
}
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
/**
|
645
|
-
* X tickmarks
|
646
|
-
*/
|
647
|
-
if (prop['chart.numxticks'] > 0) {
|
648
|
-
var xInterval = this.axisWidth / prop['chart.numxticks'];
|
649
|
-
|
650
|
-
// Is chart.xtickinterval specified ? If so, use that.
|
651
|
-
if (typeof(prop['chart.xtickinterval']) == 'number') {
|
652
|
-
xInterval = prop['chart.xtickinterval'];
|
653
|
-
}
|
654
|
-
|
655
|
-
|
656
|
-
// Draw the left sides X tick marks
|
657
|
-
for (i=this.gutterLeft; i<(this.gutterLeft + this.axisWidth); i+=xInterval) {
|
658
|
-
co.beginPath();
|
659
|
-
co.moveTo(Math.round( i), ca.height - this.gutterBottom);
|
660
|
-
co.lineTo(Math.round( i), (ca.height - this.gutterBottom) + 4);
|
661
|
-
co.closePath();
|
662
|
-
|
663
|
-
co.stroke();
|
664
|
-
}
|
665
|
-
|
666
|
-
// Draw the right sides X tick marks
|
667
|
-
var stoppingPoint = ca.width - this.gutterRight;
|
668
|
-
|
669
|
-
for (i=(this.gutterLeft + this.axisWidth + prop['chart.gutter.center'] + xInterval); i<=stoppingPoint; i+=xInterval) {
|
670
|
-
co.beginPath();
|
671
|
-
co.moveTo(Math.round(i), ca.height - this.gutterBottom);
|
672
|
-
co.lineTo(Math.round(i), (ca.height - this.gutterBottom) + 4);
|
673
|
-
co.closePath();
|
674
|
-
|
675
|
-
co.stroke();
|
676
|
-
}
|
677
|
-
}
|
678
|
-
};
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
/**
|
684
|
-
* Figures out the maximum value, or if defined, uses xmax
|
685
|
-
*/
|
686
|
-
this.getMax =
|
687
|
-
this.GetMax = function()
|
688
|
-
{
|
689
|
-
var dec = prop['chart.scale.decimals'];
|
690
|
-
|
691
|
-
// chart.xmax defined
|
692
|
-
if (prop['chart.xmax']) {
|
693
|
-
|
694
|
-
var max = prop['chart.xmax'];
|
695
|
-
var min = prop['chart.xmin'];
|
696
|
-
|
697
|
-
this.scale2 = RG.getScale2(this, {
|
698
|
-
'max':max,
|
699
|
-
'min':min,
|
700
|
-
'strict': true,
|
701
|
-
'scale.thousand':prop['chart.scale.thousand'],
|
702
|
-
'scale.point':prop['chart.scale.point'],
|
703
|
-
'scale.decimals':prop['chart.scale.decimals'],
|
704
|
-
'ylabels.count':prop['chart.labels.count'],
|
705
|
-
'scale.round':prop['chart.scale.round'],
|
706
|
-
'units.pre': prop['chart.units.pre'],
|
707
|
-
'units.post': prop['chart.units.post']
|
708
|
-
});
|
709
|
-
this.max = this.scale2.max;
|
710
|
-
this.min = this.scale2.min;
|
711
|
-
|
712
|
-
|
713
|
-
/**
|
714
|
-
* Generate the scale ourselves
|
715
|
-
*/
|
716
|
-
} else {
|
717
|
-
|
718
|
-
var max = Math.max(RG.array_max(this.left), RG.array_max(this.right));
|
719
|
-
|
720
|
-
this.scale2 = RG.getScale2(this, {
|
721
|
-
'max':max,
|
722
|
-
//'strict': true,
|
723
|
-
'min':prop['chart.xmin'],
|
724
|
-
'scale.thousand':prop['chart.scale.thousand'],
|
725
|
-
'scale.point':prop['chart.scale.point'],
|
726
|
-
'scale.decimals':prop['chart.scale.decimals'],
|
727
|
-
'ylabels.count':prop['chart.labels.count'],
|
728
|
-
'scale.round':prop['chart.scale.round'],
|
729
|
-
'units.pre': prop['chart.units.pre'],
|
730
|
-
'units.post': prop['chart.units.post']
|
731
|
-
});
|
732
|
-
|
733
|
-
|
734
|
-
this.max = this.scale2.max;
|
735
|
-
this.min = this.scale2.min;
|
736
|
-
}
|
737
|
-
|
738
|
-
// Don't need to return it as it is stored in this.max
|
739
|
-
};
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
/**
|
745
|
-
* Function to draw the left hand bars
|
746
|
-
*/
|
747
|
-
this.drawLeftBars =
|
748
|
-
this.DrawLeftBars = function ()
|
749
|
-
{
|
750
|
-
var opt = {};
|
751
|
-
|
752
|
-
if (typeof arguments[0] === 'object') {
|
753
|
-
opt.shadow = arguments[0].shadow;
|
754
|
-
} else {
|
755
|
-
opt.shadow = true;
|
756
|
-
}
|
757
|
-
|
758
|
-
var offsetx = prop['chart.variant.threed.offsetx'],
|
759
|
-
offsety = prop['chart.variant.threed.offsety'];
|
760
|
-
|
761
|
-
// Set the stroke colour
|
762
|
-
co.strokeStyle = prop['chart.strokestyle'];
|
763
|
-
|
764
|
-
// Set the linewidth
|
765
|
-
co.lineWidth = prop['chart.linewidth'];
|
766
|
-
|
767
|
-
for (var i=(this.left.length - 1); i>=0; i-=1) {
|
768
|
-
|
769
|
-
/**
|
770
|
-
* Turn on a shadow if requested
|
771
|
-
*/
|
772
|
-
if (prop['chart.shadow'] && prop['chart.variant'] !== '3d' && opt.shadow) {
|
773
|
-
co.shadowColor = prop['chart.shadow.color'];
|
774
|
-
co.shadowBlur = prop['chart.shadow.blur'];
|
775
|
-
co.shadowOffsetX = prop['chart.shadow.offsetx'];
|
776
|
-
co.shadowOffsetY = prop['chart.shadow.offsety'];
|
777
|
-
}
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
// If chart.colors.sequential is specified - handle that
|
783
|
-
// ** There's another instance of this further down **
|
784
|
-
if (prop['chart.colors.sequential']) {
|
785
|
-
co.fillStyle = prop['chart.colors'][i];
|
786
|
-
|
787
|
-
} else {
|
788
|
-
co.fillStyle = prop['chart.colors'][0];
|
789
|
-
}
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
/**
|
795
|
-
* Work out the coordinates
|
796
|
-
*/
|
797
|
-
|
798
|
-
var width = (( (this.left[i] - this.min) / (this.max - this.min)) * this.axisWidth);
|
799
|
-
|
800
|
-
var coords = [
|
801
|
-
ma.round( this.gutterLeft + this.axisWidth - width),
|
802
|
-
ma.round( this.gutterTop + (i * ( this.axisHeight / this.left.length)) + prop['chart.margin']),
|
803
|
-
width,
|
804
|
-
this.barHeight
|
805
|
-
];
|
806
|
-
|
807
|
-
// Draw the IE shadow if necessary
|
808
|
-
if (RG.ISOLD && prop['chart.shadow']) {
|
809
|
-
this.drawIEShadow(coords);
|
810
|
-
}
|
811
|
-
|
812
|
-
|
813
|
-
if (this.left[i] !== null) {
|
814
|
-
co.strokeRect(coords[0], coords[1], coords[2], coords[3]);
|
815
|
-
co.fillRect(coords[0], coords[1], coords[2], coords[3]);
|
816
|
-
}
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
// Draw the 3D sides if required
|
834
|
-
if (prop['chart.variant'] === '3d' && this.left[i] !== null) {
|
835
|
-
|
836
|
-
// If the shadow is enabled draw the backface for
|
837
|
-
// (that we don't actually see
|
838
|
-
if (prop['chart.shadow'] && opt.shadow) {
|
839
|
-
|
840
|
-
co.shadowColor = prop['chart.shadow.color'];
|
841
|
-
co.shadowBlur = prop['chart.shadow.blur'];
|
842
|
-
co.shadowOffsetX = prop['chart.shadow.offsetx'];
|
843
|
-
co.shadowOffsetY = prop['chart.shadow.offsety'];
|
844
|
-
|
845
|
-
|
846
|
-
pa2(co,
|
847
|
-
'b m % % l % % l % % l % % f black sc rgba(0,0,0,0) sx 0 sy 0 sb 0',
|
848
|
-
coords[0] + offsetx, coords[1] - offsety,
|
849
|
-
coords[0] + offsetx + coords[2], coords[1] - offsety,
|
850
|
-
coords[0] + offsetx + coords[2], coords[1] - offsety + coords[3],
|
851
|
-
coords[0] + offsetx,coords[1] - offsety + coords[3]
|
852
|
-
);
|
853
|
-
}
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
// If chart.colors.sequential is specified - handle that (again)
|
858
|
-
//
|
859
|
-
// ** There's another instance of this further up **
|
860
|
-
if (prop['chart.colors.sequential']) {
|
861
|
-
co.fillStyle = prop['chart.colors'][i];
|
862
|
-
|
863
|
-
} else {
|
864
|
-
co.fillStyle = prop['chart.colors'][0];
|
865
|
-
}
|
866
|
-
|
867
|
-
pa2(co,
|
868
|
-
'b m % % l % % l % % l % % f %',
|
869
|
-
coords[0],coords[1],
|
870
|
-
coords[0] + offsetx, coords[1] - offsety,
|
871
|
-
coords[0] + offsetx + coords[2], coords[1] - offsety,
|
872
|
-
coords[0] + coords[2], coords[1]
|
873
|
-
);
|
874
|
-
|
875
|
-
pa2(co,
|
876
|
-
'b m % % l % % l % % l % % f rgba(255,255,255,0.4)',
|
877
|
-
coords[0],coords[1],
|
878
|
-
coords[0] + offsetx, coords[1] - offsety,
|
879
|
-
coords[0] + offsetx + coords[2], coords[1] - offsety,
|
880
|
-
coords[0] + coords[2], coords[1]
|
881
|
-
);
|
882
|
-
}
|
883
|
-
|
884
|
-
this.draw3DLeftVerticalAxis();
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
// Add the coordinates to the coords array
|
901
|
-
this.coords.push([coords[0],coords[1],coords[2],coords[3]]);
|
902
|
-
this.coordsLeft.push([coords[0],coords[1],coords[2],coords[3]]);
|
903
|
-
}
|
904
|
-
|
905
|
-
/**
|
906
|
-
* Turn off any shadow
|
907
|
-
*/
|
908
|
-
RG.noShadow(this);
|
909
|
-
|
910
|
-
// Reset the linewidth
|
911
|
-
co.lineWidth = 1;
|
912
|
-
};
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
/**
|
918
|
-
* Function to draw the right hand bars
|
919
|
-
*/
|
920
|
-
this.drawRightBars =
|
921
|
-
this.DrawRightBars = function ()
|
922
|
-
{
|
923
|
-
var opt = {};
|
924
|
-
|
925
|
-
if (typeof arguments[0] === 'object') {
|
926
|
-
opt.shadow = arguments[0].shadow;
|
927
|
-
} else {
|
928
|
-
opt.shadow = true;
|
929
|
-
}
|
930
|
-
|
931
|
-
var offsetx = prop['chart.variant.threed.offsetx'],
|
932
|
-
offsety = prop['chart.variant.threed.offsety'];
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
// Set the stroke colour
|
938
|
-
co.strokeStyle = prop['chart.strokestyle'];
|
939
|
-
|
940
|
-
// Set the linewidth
|
941
|
-
co.lineWidth = prop['chart.linewidth'];
|
942
|
-
|
943
|
-
/**
|
944
|
-
* Turn on a shadow if requested
|
945
|
-
*/
|
946
|
-
if (prop['chart.shadow'] && prop['chart.variant'] !== '3d' && opt.shadow) {
|
947
|
-
co.shadowColor = prop['chart.shadow.color'];
|
948
|
-
co.shadowBlur = prop['chart.shadow.blur'];
|
949
|
-
co.shadowOffsetX = prop['chart.shadow.offsetx'];
|
950
|
-
co.shadowOffsetY = prop['chart.shadow.offsety'];
|
951
|
-
}
|
952
|
-
|
953
|
-
for (var i=(this.right.length - 1); i>=0; i-=1) {
|
954
|
-
|
955
|
-
|
956
|
-
// If chart.colors.sequential is specified - handle that
|
957
|
-
if (prop['chart.colors.sequential']) {
|
958
|
-
co.fillStyle = prop['chart.colors'][i];
|
959
|
-
|
960
|
-
} else {
|
961
|
-
co.fillStyle = prop['chart.colors'][0];
|
962
|
-
}
|
963
|
-
|
964
|
-
|
965
|
-
var width = (((this.right[i] - this.min) / (this.max - this.min)) * this.axisWidth);
|
966
|
-
|
967
|
-
var coords = [
|
968
|
-
ma.round( this.gutterLeft + this.axisWidth + prop['chart.gutter.center']),
|
969
|
-
ma.round( prop['chart.margin'] + (i * (this.axisHeight / this.right.length)) + this.gutterTop),
|
970
|
-
width,
|
971
|
-
this.barHeight
|
972
|
-
];
|
973
|
-
|
974
|
-
// Draw the IE shadow if necessary
|
975
|
-
if (RG.ISOLD && prop['chart.shadow']) {
|
976
|
-
this.DrawIEShadow(coords);
|
977
|
-
}
|
978
|
-
|
979
|
-
if (this.right[i] !== null) {
|
980
|
-
co.strokeRect(ma.round( coords[0]), Math.round( coords[1]), coords[2], coords[3]);
|
981
|
-
co.fillRect(ma.round( coords[0]), Math.round( coords[1]), coords[2], coords[3]);
|
982
|
-
}
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
// Draw the 3D sides if required
|
997
|
-
if (prop['chart.variant'] === '3d' && this.right[i] !== null) {
|
998
|
-
|
999
|
-
var color = co.fillStyle;
|
1000
|
-
|
1001
|
-
|
1002
|
-
// If the shadow is enabled draw the backface for
|
1003
|
-
// (that we don't actually see
|
1004
|
-
if (prop['chart.shadow'] && opt.shadow) {
|
1005
|
-
|
1006
|
-
co.shadowColor = prop['chart.shadow.color'];
|
1007
|
-
co.shadowBlur = prop['chart.shadow.blur'];
|
1008
|
-
co.shadowOffsetX = prop['chart.shadow.offsetx'];
|
1009
|
-
co.shadowOffsetY = prop['chart.shadow.offsety'];
|
1010
|
-
|
1011
|
-
pa2(co,
|
1012
|
-
'b m % % l % % l % % l % % f black sc rgba(0,0,0,0) sx 0 sy 0 sb 0',
|
1013
|
-
coords[0] + offsetx, coords[1] - offsety,
|
1014
|
-
coords[0] + offsetx + coords[2], coords[1] - offsety,
|
1015
|
-
coords[0] + offsetx + coords[2], coords[1] - offsety + coords[3],
|
1016
|
-
coords[0] + offsetx,coords[1] - offsety + coords[3]
|
1017
|
-
);
|
1018
|
-
}
|
1019
|
-
|
1020
|
-
// Draw the top
|
1021
|
-
pa2(co,
|
1022
|
-
'b m % % l % % l % % l % % f %',
|
1023
|
-
coords[0],coords[1],
|
1024
|
-
coords[0] + offsetx, coords[1] - offsety,
|
1025
|
-
coords[0] + offsetx + coords[2], coords[1] - offsety,
|
1026
|
-
coords[0] + coords[2], coords[1],
|
1027
|
-
color
|
1028
|
-
);
|
1029
|
-
|
1030
|
-
|
1031
|
-
// Draw the right hand side
|
1032
|
-
pa2(co,
|
1033
|
-
'b m % % l % % l % % l % % f %',
|
1034
|
-
coords[0] + coords[2],coords[1],
|
1035
|
-
coords[0] + coords[2] + offsetx, coords[1] - offsety,
|
1036
|
-
coords[0] + coords[2] + offsetx, coords[1] - offsety + coords[3],
|
1037
|
-
coords[0] + coords[2],coords[1] + coords[3],
|
1038
|
-
color
|
1039
|
-
);
|
1040
|
-
|
1041
|
-
// Draw the LIGHTER top
|
1042
|
-
pa2(co,
|
1043
|
-
'b m % % l % % l % % l % % f rgba(255,255,255,0.6)',
|
1044
|
-
coords[0],coords[1],
|
1045
|
-
coords[0] + offsetx, coords[1] - offsety,
|
1046
|
-
coords[0] + offsetx + coords[2], coords[1] - offsety,
|
1047
|
-
coords[0] + coords[2], coords[1]
|
1048
|
-
);
|
1049
|
-
|
1050
|
-
|
1051
|
-
// Draw the DARKER right hand side
|
1052
|
-
pa2(co,
|
1053
|
-
'b m % % l % % l % % l % % f rgba(0,0,0,0.3)',
|
1054
|
-
coords[0] + coords[2],coords[1],
|
1055
|
-
coords[0] + coords[2] + offsetx, coords[1] - offsety,
|
1056
|
-
coords[0] + coords[2] + offsetx, coords[1] - offsety + coords[3],
|
1057
|
-
coords[0] + coords[2],coords[1] + coords[3]
|
1058
|
-
);
|
1059
|
-
}
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
/**
|
1074
|
-
* Add the coordinates to the coords array
|
1075
|
-
*/
|
1076
|
-
this.coords.push([coords[0],coords[1],coords[2],coords[3]]);
|
1077
|
-
this.coordsRight.push([coords[0],coords[1],coords[2],coords[3]]);
|
1078
|
-
}
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
/**
|
1107
|
-
* Turn off any shadow
|
1108
|
-
*/
|
1109
|
-
RG.NoShadow(this);
|
1110
|
-
|
1111
|
-
// Reset the linewidth
|
1112
|
-
co.lineWidth = 1;
|
1113
|
-
};
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
/**
|
1119
|
-
* Draws the titles
|
1120
|
-
*/
|
1121
|
-
this.drawLabels =
|
1122
|
-
this.DrawLabels = function ()
|
1123
|
-
{
|
1124
|
-
|
1125
|
-
var font = prop['chart.text.font'],
|
1126
|
-
color = prop['chart.labels.color'] || prop['chart.text.color'],
|
1127
|
-
size = prop['chart.text.size'],
|
1128
|
-
labels = prop['chart.labels'],
|
1129
|
-
barAreaHeight = ca.height - this.gutterTop - this.gutterBottom
|
1130
|
-
|
1131
|
-
co.fillStyle = color;
|
1132
|
-
|
1133
|
-
for (var i=0,len=labels.length; i<len; i+=1) {
|
1134
|
-
RG.Text2(this, {
|
1135
|
-
'color': color,
|
1136
|
-
'font':font,
|
1137
|
-
'size':size,
|
1138
|
-
'x':this.gutterLeft + this.axisWidth + (prop['chart.gutter.center'] / 2),
|
1139
|
-
'y':this.gutterTop + ((barAreaHeight / labels.length) * (i)) + ((barAreaHeight / labels.length) / 2),
|
1140
|
-
'text':String(labels[i] ? String(labels[i]) : ''),
|
1141
|
-
'halign':'center',
|
1142
|
-
'valign':'center',
|
1143
|
-
'marker':false,
|
1144
|
-
'tag': 'labels'
|
1145
|
-
});
|
1146
|
-
}
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
co.fillStyle = prop['chart.text.color'];
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
if (prop['chart.xlabels']) {
|
1155
|
-
|
1156
|
-
var grapharea = (ca.width - prop['chart.gutter.center'] - this.gutterLeft - this.gutterRight) / 2;
|
1157
|
-
|
1158
|
-
// Now draw the X labels for the left hand side
|
1159
|
-
for (var i=0; i<this.scale2.labels.length; ++i) {
|
1160
|
-
RG.text2(this, {
|
1161
|
-
'font':font,
|
1162
|
-
'size':size,
|
1163
|
-
'x':this.gutterLeft + ((grapharea / this.scale2.labels.length) * i),
|
1164
|
-
'y':ca.height - this.gutterBottom + 3,
|
1165
|
-
'text':this.scale2.labels[this.scale2.labels.length - i - 1],
|
1166
|
-
'valign':'top',
|
1167
|
-
'halign':'center',
|
1168
|
-
'tag': 'scale'
|
1169
|
-
});
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
-
// Draw the scale for the right hand side
|
1175
|
-
RG.text2(this, {
|
1176
|
-
'font':font,
|
1177
|
-
'size':size,
|
1178
|
-
'x':this.gutterLeft+ grapharea + prop['chart.gutter.center'] + ((grapharea / this.scale2.labels.length) * (i + 1)),
|
1179
|
-
'y':ca.height - this.gutterBottom + 3,
|
1180
|
-
'text':this.scale2.labels[i],
|
1181
|
-
'valign':'top',
|
1182
|
-
'halign':'center',
|
1183
|
-
'tag': 'scale'
|
1184
|
-
});
|
1185
|
-
}
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
// Draw zero?
|
1191
|
-
if (prop['chart.scale.zerostart']) {
|
1192
|
-
RG.text2(this, {
|
1193
|
-
'font':font,
|
1194
|
-
'size':size,
|
1195
|
-
'x':this.gutterLeft + this.axisWidth,
|
1196
|
-
'y':ca.height - this.gutterBottom + 3,
|
1197
|
-
'text':'0',
|
1198
|
-
'valign':'top',
|
1199
|
-
'halign':'center',
|
1200
|
-
'tag': 'scale'
|
1201
|
-
});
|
1202
|
-
|
1203
|
-
|
1204
|
-
RG.text2(this, {
|
1205
|
-
'font':font,
|
1206
|
-
'size':size,
|
1207
|
-
'x':this.gutterLeft + this.axisWidth + this.gutterCenter,
|
1208
|
-
'y':ca.height - this.gutterBottom + 3,
|
1209
|
-
'text':'0',
|
1210
|
-
'valign':'top',
|
1211
|
-
'halign':'center',
|
1212
|
-
'tag': 'scale'
|
1213
|
-
});
|
1214
|
-
}
|
1215
|
-
}
|
1216
|
-
|
1217
|
-
/**
|
1218
|
-
* Draw above labels
|
1219
|
-
*/
|
1220
|
-
if (prop['chart.labels.above']) {
|
1221
|
-
|
1222
|
-
// Draw the left sides above labels
|
1223
|
-
for (var i=0; i<this.coordsLeft.length; ++i) {
|
1224
|
-
|
1225
|
-
if (typeof(this.left[i]) != 'number') {
|
1226
|
-
continue;
|
1227
|
-
}
|
1228
|
-
|
1229
|
-
var coords = this.coordsLeft[i];
|
1230
|
-
RG.Text2(this, {'font':font,
|
1231
|
-
'size':size,
|
1232
|
-
'x':coords[0] - 5,
|
1233
|
-
'y':coords[1] + (coords[3] / 2),
|
1234
|
-
'text':RG.number_format(this, this.left[i], prop['chart.units.pre'], prop['chart.units.post']),
|
1235
|
-
'valign':'center',
|
1236
|
-
'halign':'right',
|
1237
|
-
'tag':'labels.above'
|
1238
|
-
});
|
1239
|
-
}
|
1240
|
-
|
1241
|
-
// Draw the right sides above labels
|
1242
|
-
for (i=0; i<this.coordsRight.length; ++i) {
|
1243
|
-
|
1244
|
-
if (typeof(this.right[i]) != 'number') {
|
1245
|
-
continue;
|
1246
|
-
}
|
1247
|
-
|
1248
|
-
var coords = this.coordsRight[i];
|
1249
|
-
|
1250
|
-
RG.Text2(this, {
|
1251
|
-
'font':font,
|
1252
|
-
'size':size,
|
1253
|
-
'x':coords[0] + coords[2] + 5,
|
1254
|
-
'y':coords[1] + (coords[3] / 2),
|
1255
|
-
'text':RG.number_format(this, this.right[i], prop['chart.units.pre'], prop['chart.units.post']),
|
1256
|
-
'valign':'center',
|
1257
|
-
'halign':'left',
|
1258
|
-
'tag': 'labels.above'
|
1259
|
-
});
|
1260
|
-
}
|
1261
|
-
}
|
1262
|
-
};
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
/**
|
1268
|
-
* Draws the titles
|
1269
|
-
*/
|
1270
|
-
this.drawTitles =
|
1271
|
-
this.DrawTitles = function ()
|
1272
|
-
{
|
1273
|
-
RG.Text2(this, {
|
1274
|
-
'font':prop['chart.text.font'],
|
1275
|
-
'size':prop['chart.text.size'],
|
1276
|
-
'x':this.gutterLeft + 5,
|
1277
|
-
'y':this.gutterTop - 5,
|
1278
|
-
'text':String(prop['chart.title.left']),
|
1279
|
-
'halign':'left',
|
1280
|
-
'valign':'bottom',
|
1281
|
-
'tag': 'title.left'
|
1282
|
-
});
|
1283
|
-
|
1284
|
-
RG.Text2(this, {
|
1285
|
-
'font':prop['chart.text.font'],
|
1286
|
-
'size':prop['chart.text.size'],
|
1287
|
-
'x': ca.width - this.gutterRight - 5,
|
1288
|
-
'y':this.gutterTop - 5,
|
1289
|
-
'text':String(prop['chart.title.right']),
|
1290
|
-
'halign':'right',
|
1291
|
-
'valign':'bottom',
|
1292
|
-
'tag': 'title.right'
|
1293
|
-
});
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1297
|
-
// Draw the main title for the whole chart
|
1298
|
-
RG.drawTitle(
|
1299
|
-
this,
|
1300
|
-
prop['chart.title'],
|
1301
|
-
this.gutterTop,
|
1302
|
-
null,
|
1303
|
-
prop['chart.title.size'] ? prop['chart.title.size'] : null
|
1304
|
-
);
|
1305
|
-
};
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
/**
|
1311
|
-
* This function is used by MSIE only to manually draw the shadow
|
1312
|
-
*
|
1313
|
-
* @param array coords The coords for the bar
|
1314
|
-
*/
|
1315
|
-
this.drawIEShadow =
|
1316
|
-
this.DrawIEShadow = function (coords)
|
1317
|
-
{
|
1318
|
-
var prevFillStyle = co.fillStyle;
|
1319
|
-
var offsetx = prop['chart.shadow.offsetx'];
|
1320
|
-
var offsety = prop['chart.shadow.offsety'];
|
1321
|
-
|
1322
|
-
co.lineWidth = prop['chart.linewidth'];
|
1323
|
-
co.fillStyle = prop['chart.shadow.color'];
|
1324
|
-
co.beginPath();
|
1325
|
-
|
1326
|
-
// Draw shadow here
|
1327
|
-
co.fillRect(coords[0] + offsetx, coords[1] + offsety, coords[2],coords[3]);
|
1328
|
-
|
1329
|
-
co.fill();
|
1330
|
-
|
1331
|
-
// Change the fillstyle back to what it was
|
1332
|
-
co.fillStyle = prevFillStyle;
|
1333
|
-
}
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1338
|
-
/**
|
1339
|
-
* Returns the appropriate focussed bar coordinates
|
1340
|
-
*
|
1341
|
-
* @param e object The event object
|
1342
|
-
*/
|
1343
|
-
this.getShape =
|
1344
|
-
this.getBar = function (e)
|
1345
|
-
{
|
1346
|
-
var canvas = this.canvas,
|
1347
|
-
context = this.context,
|
1348
|
-
mouseCoords = RG.getMouseXY(e)
|
1349
|
-
|
1350
|
-
/**
|
1351
|
-
* Loop through the bars determining if the mouse is over a bar
|
1352
|
-
*/
|
1353
|
-
for (var i=0; i<this.coords.length; i++) {
|
1354
|
-
|
1355
|
-
var mouseX = mouseCoords[0],
|
1356
|
-
mouseY = mouseCoords[1],
|
1357
|
-
left = this.coords[i][0],
|
1358
|
-
top = this.coords[i][1],
|
1359
|
-
width = this.coords[i][2],
|
1360
|
-
height = this.coords[i][3]
|
1361
|
-
|
1362
|
-
//if (mouseX >= left && mouseX <= (left + width) && mouseY >= top && mouseY <= (top + height) ) {
|
1363
|
-
pa2(co,
|
1364
|
-
'b r % % % %',
|
1365
|
-
left,
|
1366
|
-
top,
|
1367
|
-
width,
|
1368
|
-
height
|
1369
|
-
);
|
1370
|
-
|
1371
|
-
if (co.isPointInPath(mouseX, mouseY)) {
|
1372
|
-
|
1373
|
-
var tooltip = RG.parseTooltipText(prop['chart.tooltips'], i);
|
1374
|
-
|
1375
|
-
return {
|
1376
|
-
0: this,1: left,2: top,3: width,4: height,5: i,
|
1377
|
-
'object': this, 'x': left, 'y': top, 'width': width, 'height': height, 'index': i, 'tooltip': tooltip
|
1378
|
-
};
|
1379
|
-
}
|
1380
|
-
}
|
1381
|
-
|
1382
|
-
return null;
|
1383
|
-
};
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
/**
|
1389
|
-
* Each object type has its own Highlight() function which highlights the appropriate shape
|
1390
|
-
*
|
1391
|
-
* @param object shape The shape to highlight
|
1392
|
-
*/
|
1393
|
-
this.highlight =
|
1394
|
-
this.Highlight = function (shape)
|
1395
|
-
{
|
1396
|
-
if (typeof prop['chart.highlight.style'] === 'function') {
|
1397
|
-
(prop['chart.highlight.style'])(shape);
|
1398
|
-
} else {
|
1399
|
-
RG.Highlight.Rect(this, shape);
|
1400
|
-
}
|
1401
|
-
};
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
/**
|
1407
|
-
* When you click on the canvas, this will return the relevant value (if any)
|
1408
|
-
*
|
1409
|
-
* REMEMBER This function will need updating if the Bipolar ever gets chart.ymin
|
1410
|
-
*
|
1411
|
-
* @param object e The event object
|
1412
|
-
*/
|
1413
|
-
this.getValue = function (e)
|
1414
|
-
{
|
1415
|
-
var obj = e.target.__object__;
|
1416
|
-
var mouseXY = RG.getMouseXY(e);
|
1417
|
-
var mouseX = mouseXY[0];
|
1418
|
-
|
1419
|
-
/**
|
1420
|
-
* Left hand side
|
1421
|
-
*/
|
1422
|
-
if (mouseX > this.gutterLeft && mouseX < ( (ca.width / 2) - (prop['chart.gutter.center'] / 2) )) {
|
1423
|
-
var value = (mouseX - prop['chart.gutter.left']) / this.axisWidth;
|
1424
|
-
value = this.max - (value * this.max);
|
1425
|
-
}
|
1426
|
-
|
1427
|
-
/**
|
1428
|
-
* Right hand side
|
1429
|
-
*/
|
1430
|
-
if (mouseX < (ca.width - this.gutterRight) && mouseX > ( (ca.width / 2) + (prop['chart.gutter.center'] / 2) )) {
|
1431
|
-
var value = (mouseX - prop['chart.gutter.left'] - this.axisWidth - prop['chart.gutter.center']) / this.axisWidth;
|
1432
|
-
value = (value * this.max);
|
1433
|
-
}
|
1434
|
-
|
1435
|
-
return value;
|
1436
|
-
};
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
/**
|
1442
|
-
* The getObjectByXY() worker method. Don't call this call:
|
1443
|
-
*
|
1444
|
-
* RGraph.ObjectRegistry.getObjectByXY(e)
|
1445
|
-
*
|
1446
|
-
* @param object e The event object
|
1447
|
-
*/
|
1448
|
-
this.getObjectByXY = function (e)
|
1449
|
-
{
|
1450
|
-
var mouseXY = RG.getMouseXY(e);
|
1451
|
-
|
1452
|
-
// Adjust the mouse Y coordinate for when the bar chart is
|
1453
|
-
// a 3D variant
|
1454
|
-
|
1455
|
-
if (prop['chart.variant'] === '3d') {
|
1456
|
-
var adjustment = prop['chart.variant.threed.angle'] * mouseXY[0];
|
1457
|
-
mouseXY[1] -= adjustment;
|
1458
|
-
}
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
if (
|
1463
|
-
mouseXY[0] > prop['chart.gutter.left']
|
1464
|
-
&& mouseXY[0] < (ca.width - prop['chart.gutter.right'])
|
1465
|
-
&& mouseXY[1] > prop['chart.gutter.top']
|
1466
|
-
&& mouseXY[1] < (ca.height - prop['chart.gutter.bottom'])
|
1467
|
-
) {
|
1468
|
-
|
1469
|
-
return this;
|
1470
|
-
}
|
1471
|
-
};
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
/**
|
1477
|
-
* This function positions a tooltip when it is displayed
|
1478
|
-
*
|
1479
|
-
* @param obj object The chart object
|
1480
|
-
* @param int x The X coordinate specified for the tooltip
|
1481
|
-
* @param int y The Y coordinate specified for the tooltip
|
1482
|
-
* @param objec tooltip The tooltips DIV element
|
1483
|
-
*/
|
1484
|
-
this.positionTooltip = function (obj, x, y, tooltip, idx)
|
1485
|
-
{
|
1486
|
-
var coordX = obj.coords[tooltip.__index__][0],
|
1487
|
-
coordY = obj.coords[tooltip.__index__][1],
|
1488
|
-
coordW = obj.coords[tooltip.__index__][2],
|
1489
|
-
coordH = obj.coords[tooltip.__index__][3],
|
1490
|
-
canvasXY = RG.getCanvasXY(obj.canvas),
|
1491
|
-
mouseXY = RG.getMouseXY(window.event),
|
1492
|
-
gutterLeft = obj.Get('chart.gutter.left'),
|
1493
|
-
gutterTop = obj.Get('chart.gutter.top'),
|
1494
|
-
width = tooltip.offsetWidth,
|
1495
|
-
height = tooltip.offsetHeight
|
1496
|
-
|
1497
|
-
// If the chart is a 3D version the tooltip Y position needs this
|
1498
|
-
// adjustment
|
1499
|
-
if (prop['chart.variant'] === '3d' && mouseXY) {
|
1500
|
-
var adjustment = (prop['chart.variant.threed.angle'] * mouseXY[0]);
|
1501
|
-
}
|
1502
|
-
|
1503
|
-
// Set the top position
|
1504
|
-
tooltip.style.left = 0;
|
1505
|
-
tooltip.style.top = window.event.pageY - height - 5 + 'px';
|
1506
|
-
|
1507
|
-
|
1508
|
-
// By default any overflow is hidden
|
1509
|
-
tooltip.style.overflow = '';
|
1510
|
-
|
1511
|
-
// LEFT edge
|
1512
|
-
if (canvasXY[0] + mouseXY[0] - (width / 2) < 0) {
|
1513
|
-
tooltip.style.left = canvasXY[0] + mouseXY[0] - (width * 0.1) + 'px';
|
1514
|
-
|
1515
|
-
// RIGHT edge
|
1516
|
-
} else if (canvasXY[0] + mouseXY[0] + (width / 2) > doc.body.offsetWidth) {
|
1517
|
-
tooltip.style.left = canvasXY[0] + mouseXY[0] - (width * 0.9) + 'px';
|
1518
|
-
|
1519
|
-
// Default positioning - CENTERED
|
1520
|
-
} else {
|
1521
|
-
tooltip.style.left = canvasXY[0] + mouseXY[0] - (width / 2) + 'px';
|
1522
|
-
}
|
1523
|
-
};
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
/**
|
1529
|
-
* Returns the X coords for a value. Returns two coords because there are... two scales.
|
1530
|
-
*
|
1531
|
-
* @param number value The value to get the coord for
|
1532
|
-
*/
|
1533
|
-
this.getXCoord = function (value)
|
1534
|
-
{
|
1535
|
-
if (value > this.max || value < 0) {
|
1536
|
-
return null;
|
1537
|
-
}
|
1538
|
-
|
1539
|
-
var ret = [];
|
1540
|
-
|
1541
|
-
// The offset into the graph area
|
1542
|
-
var offset = ((value / this.max) * this.axisWidth);
|
1543
|
-
|
1544
|
-
// Get the coords (one fo each side)
|
1545
|
-
ret[0] = (this.gutterLeft + this.axisWidth) - offset;
|
1546
|
-
ret[1] = (ca.width - this.gutterRight - this.axisWidth) + offset;
|
1547
|
-
|
1548
|
-
return ret;
|
1549
|
-
};
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
/**
|
1555
|
-
* This allows for easy specification of gradients
|
1556
|
-
*/
|
1557
|
-
this.parseColors = function ()
|
1558
|
-
{
|
1559
|
-
// Save the original colors so that they can be restored when the canvas is reset
|
1560
|
-
if (this.original_colors.length === 0) {
|
1561
|
-
this.original_colors['chart.colors'] = RG.array_clone(prop['chart.colors']);
|
1562
|
-
this.original_colors['chart.highlight.stroke'] = RG.array_clone(prop['chart.highlight.fill']);
|
1563
|
-
this.original_colors['chart.highlight.fill'] = RG.array_clone(prop['chart.highlight.fill']);
|
1564
|
-
this.original_colors['chart.axis.color'] = RG.array_clone(prop['chart.axis.color']);
|
1565
|
-
this.original_colors['chart.strokestyle'] = RG.array_clone(prop['chart.strokestyle']);
|
1566
|
-
}
|
1567
|
-
|
1568
|
-
var props = this.properties;
|
1569
|
-
var colors = props['chart.colors'];
|
1570
|
-
|
1571
|
-
for (var i=0; i<colors.length; ++i) {
|
1572
|
-
colors[i] = this.parseSingleColorForGradient(colors[i]);
|
1573
|
-
}
|
1574
|
-
|
1575
|
-
props['chart.highlight.stroke'] = this.parseSingleColorForGradient(props['chart.highlight.stroke']);
|
1576
|
-
props['chart.highlight.fill'] = this.parseSingleColorForGradient(props['chart.highlight.fill']);
|
1577
|
-
props['chart.axis.color'] = this.parseSingleColorForGradient(props['chart.axis.color']);
|
1578
|
-
props['chart.strokestyle'] = this.parseSingleColorForGradient(props['chart.strokestyle']);
|
1579
|
-
};
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
/**
|
1585
|
-
* Use this function to reset the object to the post-constructor state. Eg reset colors if
|
1586
|
-
* need be etc
|
1587
|
-
*/
|
1588
|
-
this.reset = function ()
|
1589
|
-
{
|
1590
|
-
};
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1594
|
-
|
1595
|
-
/**
|
1596
|
-
* This parses a single color value
|
1597
|
-
*/
|
1598
|
-
this.parseSingleColorForGradient = function (color)
|
1599
|
-
{
|
1600
|
-
if (!color || typeof(color) != 'string') {
|
1601
|
-
return color;
|
1602
|
-
}
|
1603
|
-
|
1604
|
-
if (color.match(/^gradient\((.*)\)$/i)) {
|
1605
|
-
|
1606
|
-
var parts = RegExp.$1.split(':');
|
1607
|
-
|
1608
|
-
// Create the gradient
|
1609
|
-
var grad = co.createLinearGradient(prop['chart.gutter.left'],0,ca.width - prop['chart.gutter.right'],0);
|
1610
|
-
|
1611
|
-
var diff = 1 / (parts.length - 1);
|
1612
|
-
|
1613
|
-
grad.addColorStop(0, RG.trim(parts[0]));
|
1614
|
-
|
1615
|
-
for (var j=1; j<parts.length; ++j) {
|
1616
|
-
grad.addColorStop(j * diff, RG.trim(parts[j]));
|
1617
|
-
}
|
1618
|
-
}
|
1619
|
-
|
1620
|
-
return grad ? grad : color;
|
1621
|
-
};
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
/**
|
1627
|
-
* Using a function to add events makes it easier to facilitate method chaining
|
1628
|
-
*
|
1629
|
-
* @param string type The type of even to add
|
1630
|
-
* @param function func
|
1631
|
-
*/
|
1632
|
-
this.on = function (type, func)
|
1633
|
-
{
|
1634
|
-
if (type.substr(0,2) !== 'on') {
|
1635
|
-
type = 'on' + type;
|
1636
|
-
}
|
1637
|
-
|
1638
|
-
this[type] = func;
|
1639
|
-
|
1640
|
-
return this;
|
1641
|
-
};
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
//
|
1647
|
-
// Draw the background grid
|
1648
|
-
//
|
1649
|
-
this.drawBackgroundGrid = function ()
|
1650
|
-
{
|
1651
|
-
if (prop['chart.background.grid']) {
|
1652
|
-
|
1653
|
-
var variant = prop['chart.variant'],
|
1654
|
-
color = prop['chart.background.grid.color'],
|
1655
|
-
numvlines = prop['chart.labels.count'],
|
1656
|
-
numhlines = this.left.length,
|
1657
|
-
vlines = prop['chart.background.grid.vlines'],
|
1658
|
-
hlines = prop['chart.background.grid.hlines'],
|
1659
|
-
linewidth = prop['chart.background.grid.linewidth'];
|
1660
|
-
|
1661
|
-
// Autofit
|
1662
|
-
if (typeof prop['chart.background.grid.autofit.numhlines'] === 'number') {
|
1663
|
-
numhlines = prop['chart.background.grid.autofit.numhlines'];
|
1664
|
-
}
|
1665
|
-
|
1666
|
-
if (typeof prop['chart.background.grid.autofit.numvlines'] === 'number') {
|
1667
|
-
numvlines = prop['chart.background.grid.autofit.numvlines'];
|
1668
|
-
}
|
1669
|
-
|
1670
|
-
co.lineWidth = linewidth;
|
1671
|
-
|
1672
|
-
// If it's a bar and 3D variant, translate
|
1673
|
-
if (variant == '3d') {
|
1674
|
-
co.save();
|
1675
|
-
co.translate(
|
1676
|
-
prop['chart.variant.threed.offsetx'],
|
1677
|
-
-1 * prop['chart.variant.threed.offsety']
|
1678
|
-
);
|
1679
|
-
}
|
1680
|
-
|
1681
|
-
// Draw vertical grid lines for the left side
|
1682
|
-
if (vlines) {
|
1683
|
-
for (var i=0; i<=numvlines; i+=1) {
|
1684
|
-
pa2(co,
|
1685
|
-
'b m % % l % % s %',
|
1686
|
-
this.gutterLeft + (this.axisWidth / numvlines) * i, this.gutterTop,
|
1687
|
-
this.gutterLeft + (this.axisWidth / numvlines) * i, this.gutterTop + this.axisHeight,
|
1688
|
-
color
|
1689
|
-
);
|
1690
|
-
|
1691
|
-
}
|
1692
|
-
}
|
1693
|
-
|
1694
|
-
// Draw horizontal grid lines for the left side
|
1695
|
-
if (hlines) {
|
1696
|
-
for (var i=0; i<=numhlines; i+=1) {
|
1697
|
-
pa2(co,
|
1698
|
-
'b m % % l % % s %',
|
1699
|
-
this.gutterLeft, this.gutterTop + (this.axisHeight / numhlines) * i,
|
1700
|
-
this.gutterLeft + this.axisWidth, this.gutterTop + (this.axisHeight / numhlines) * i,
|
1701
|
-
color
|
1702
|
-
);
|
1703
|
-
}
|
1704
|
-
}
|
1705
|
-
|
1706
|
-
|
1707
|
-
// Draw vertical grid lines for the right side
|
1708
|
-
if (vlines) {
|
1709
|
-
for (var i=0; i<=numvlines; i+=1) {
|
1710
|
-
pa2(co,
|
1711
|
-
'b m % % l % % s %',
|
1712
|
-
this.gutterLeft + this.gutterCenter + this.axisWidth + (this.axisWidth / numvlines) * i, this.gutterTop,
|
1713
|
-
this.gutterLeft + this.gutterCenter + this.axisWidth + (this.axisWidth / numvlines) * i, this.gutterTop + this.axisHeight,
|
1714
|
-
color
|
1715
|
-
);
|
1716
|
-
}
|
1717
|
-
}
|
1718
|
-
|
1719
|
-
// Draw horizontal grid lines for the right side
|
1720
|
-
if (hlines) {
|
1721
|
-
for (var i=0; i<=numhlines; i+=1) {
|
1722
|
-
pa2(co,
|
1723
|
-
'b m % % l % % s %',
|
1724
|
-
this.gutterLeft + this.axisWidth + this.gutterCenter, this.gutterTop + (this.axisHeight / numhlines) * i,
|
1725
|
-
this.gutterLeft + this.axisWidth + this.gutterCenter + this.axisWidth, this.gutterTop + (this.axisHeight / numhlines) * i,
|
1726
|
-
color
|
1727
|
-
);
|
1728
|
-
}
|
1729
|
-
}
|
1730
|
-
|
1731
|
-
|
1732
|
-
// If it's a bar and 3D variant, translate
|
1733
|
-
if (variant == '3d') {
|
1734
|
-
co.restore();
|
1735
|
-
}
|
1736
|
-
}
|
1737
|
-
};
|
1738
|
-
|
1739
|
-
|
1740
|
-
|
1741
|
-
|
1742
|
-
/**
|
1743
|
-
* This function runs once only
|
1744
|
-
* (put at the end of the file (before any effects))
|
1745
|
-
*/
|
1746
|
-
this.firstDrawFunc = function ()
|
1747
|
-
{
|
1748
|
-
// Tooltips need reversing now because the bars
|
1749
|
-
// are drawn from the bottom up
|
1750
|
-
if (prop['chart.tooltips']) {
|
1751
|
-
prop['chart.tooltips'] = RG.arrayReverse(prop['chart.tooltips']);
|
1752
|
-
}
|
1753
|
-
};
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
1760
|
-
|
1761
|
-
|
1762
|
-
/**
|
1763
|
-
* Objects are now always registered so that when RGraph.Redraw()
|
1764
|
-
* is called this chart will be redrawn.
|
1765
|
-
*/
|
1766
|
-
RG.Register(this);
|
1767
|
-
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1771
|
-
/**
|
1772
|
-
* This is the 'end' of the constructor so if the first argument
|
1773
|
-
* contains configuration dsta - handle that.
|
1774
|
-
*/
|
1775
|
-
if (parseConfObjectForOptions) {
|
1776
|
-
RG.parseObjectStyleConfig(this, conf.options);
|
1777
|
-
}
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1782
|
-
/**
|
1783
|
-
* Grow
|
1784
|
-
*
|
1785
|
-
* The Bipolar chart Grow effect gradually increases the values of the bars
|
1786
|
-
*
|
1787
|
-
* @param object An object of options - eg: {frames: 30}
|
1788
|
-
* @param function A function to call when the effect is complete
|
1789
|
-
*/
|
1790
|
-
this.grow = function ()
|
1791
|
-
{
|
1792
|
-
// Callback
|
1793
|
-
var opt = arguments[0] || {};
|
1794
|
-
var frames = opt.frames || 30;
|
1795
|
-
var frame = 0;
|
1796
|
-
var callback = arguments[1] || function () {};
|
1797
|
-
var obj = this;
|
1798
|
-
|
1799
|
-
// Save the data
|
1800
|
-
var originalLeft = RG.arrayClone(this.left);
|
1801
|
-
var originalRight = RG.arrayClone(this.right);
|
1802
|
-
|
1803
|
-
|
1804
|
-
// Stop the scale from changing by setting xmax (if it's not already set)
|
1805
|
-
if (RG.isNull(prop['chart.xmax'])) {
|
1806
|
-
|
1807
|
-
var xmax = 0;
|
1808
|
-
|
1809
|
-
// Go through the left and right data
|
1810
|
-
for (var i=0; i<this.left.length; i+=1) { xmax = ma.max(xmax, ma.abs(this.left[i])); }
|
1811
|
-
for (var i=0; i<this.right.length; i+=1) { xmax = ma.max(xmax, ma.abs(this.right[i])); }
|
1812
|
-
|
1813
|
-
var scale = RG.getScale2(obj, {'max':xmax});
|
1814
|
-
this.Set('chart.xmax', scale.max);
|
1815
|
-
}
|
1816
|
-
|
1817
|
-
|
1818
|
-
|
1819
|
-
|
1820
|
-
|
1821
|
-
|
1822
|
-
|
1823
|
-
|
1824
|
-
|
1825
|
-
|
1826
|
-
|
1827
|
-
|
1828
|
-
var iterator = function ()
|
1829
|
-
{
|
1830
|
-
var easingMultiplier = RG.Effects.getEasingMultiplier(frames, frame);
|
1831
|
-
|
1832
|
-
for (var i=0; i<obj.left.length; i+=1) { obj.left[i] = easingMultiplier * originalLeft[i]; }
|
1833
|
-
for (var i=0; i<obj.right.length; i+=1) { obj.right[i] = easingMultiplier * originalRight[i]; }
|
1834
|
-
|
1835
|
-
RG.redrawCanvas(obj.canvas);
|
1836
|
-
|
1837
|
-
// Repeat or call the end function if one is defined
|
1838
|
-
if (frame < frames) {
|
1839
|
-
frame += 1;
|
1840
|
-
RG.Effects.updateCanvas(iterator);
|
1841
|
-
} else {
|
1842
|
-
callback(obj);
|
1843
|
-
}
|
1844
|
-
};
|
1845
|
-
|
1846
|
-
iterator();
|
1847
|
-
|
1848
|
-
return this;
|
1849
|
-
};
|
1850
|
-
|
1851
|
-
|
1852
|
-
|
1853
|
-
|
1854
|
-
/**
|
1855
|
-
* Bipolar chart Wave effect.
|
1856
|
-
*
|
1857
|
-
* @param object OPTIONAL An object map of options. You specify 'frames' here to give the number of frames in the effect
|
1858
|
-
* @param function OPTIONAL A function that will be called when the effect is complete
|
1859
|
-
*/
|
1860
|
-
this.wave = function ()
|
1861
|
-
{
|
1862
|
-
var obj = this,
|
1863
|
-
opt = arguments[0] || {};
|
1864
|
-
opt.frames = opt.frames || 60;
|
1865
|
-
opt.startFrames_left = [];
|
1866
|
-
opt.startFrames_right = [];
|
1867
|
-
opt.counters_left = [];
|
1868
|
-
opt.counters_right = [];
|
1869
|
-
|
1870
|
-
var framesperbar = opt.frames / 3,
|
1871
|
-
frame_left = -1,
|
1872
|
-
frame_right = -1,
|
1873
|
-
callback = arguments[1] || function () {},
|
1874
|
-
original_left = RG.arrayClone(obj.left),
|
1875
|
-
original_right = RG.arrayClone(obj.right);
|
1876
|
-
|
1877
|
-
for (var i=0,len=obj.left.length; i<len; i+=1) {
|
1878
|
-
opt.startFrames_left[i] = ((opt.frames / 2) / (obj.left.length - 1)) * i;
|
1879
|
-
opt.startFrames_right[i] = ((opt.frames / 2) / (obj.right.length - 1)) * i;
|
1880
|
-
opt.counters_left[i] = 0;
|
1881
|
-
opt.counters_right[i] = 0;
|
1882
|
-
}
|
1883
|
-
|
1884
|
-
// This stops the chart from jumping
|
1885
|
-
obj.draw();
|
1886
|
-
obj.set('xmax', obj.scale2.max);
|
1887
|
-
RG.clear(obj.canvas);
|
1888
|
-
|
1889
|
-
|
1890
|
-
// Zero all of the data
|
1891
|
-
for (var i=0,len=obj.left.length; i<len; i+=1) {
|
1892
|
-
if (typeof obj.left[i] === 'number') obj.left[i] = 0;
|
1893
|
-
if (typeof obj.right[i] === 'number') obj.right[i] = 0;
|
1894
|
-
}
|
1895
|
-
|
1896
|
-
//
|
1897
|
-
// Iterate over the left side
|
1898
|
-
//
|
1899
|
-
function iteratorLeft ()
|
1900
|
-
{
|
1901
|
-
++frame_left;
|
1902
|
-
|
1903
|
-
for (var i=0,len=obj.left.length; i<len; i+=1) {
|
1904
|
-
if (frame_left > opt.startFrames_left[i]) {
|
1905
|
-
|
1906
|
-
var isNull = RG.isNull(obj.left[i]);
|
1907
|
-
|
1908
|
-
obj.left[i] = ma.min(
|
1909
|
-
ma.abs(original_left[i]),
|
1910
|
-
ma.abs(original_left[i] * ( (opt.counters_left[i]++) / framesperbar))
|
1911
|
-
);
|
1912
|
-
|
1913
|
-
// Make the number negative if the original was
|
1914
|
-
if (original_left[i] < 0) {
|
1915
|
-
obj.left[i] *= -1;
|
1916
|
-
}
|
1917
|
-
|
1918
|
-
if (isNull) {
|
1919
|
-
obj.left[i] = null;
|
1920
|
-
}
|
1921
|
-
} else {
|
1922
|
-
obj.left[i] = typeof obj.left[i] === 'object' && obj.left[i] ? RG.arrayPad([], obj.left[i].length, 0) : (RG.isNull(obj.left[i]) ? null : 0);
|
1923
|
-
}
|
1924
|
-
|
1925
|
-
}
|
1926
|
-
|
1927
|
-
|
1928
|
-
// No callback here - only called by the right function
|
1929
|
-
if (frame_left < opt.frames) {
|
1930
|
-
RG.redrawCanvas(obj.canvas);
|
1931
|
-
RG.Effects.updateCanvas(iteratorLeft);
|
1932
|
-
}
|
1933
|
-
}
|
1934
|
-
|
1935
|
-
|
1936
|
-
|
1937
|
-
|
1938
|
-
//
|
1939
|
-
// Iterate over the right side
|
1940
|
-
//
|
1941
|
-
function iteratorRight ()
|
1942
|
-
{
|
1943
|
-
++frame_right;
|
1944
|
-
|
1945
|
-
for (var i=0,len=obj.right.length; i<len; i+=1) {
|
1946
|
-
if (frame_right > opt.startFrames_right[i]) {
|
1947
|
-
|
1948
|
-
var isNull = RG.isNull(obj.right[i]);
|
1949
|
-
|
1950
|
-
obj.right[i] = ma.min(
|
1951
|
-
ma.abs(original_right[i]),
|
1952
|
-
ma.abs(original_right[i] * ( (opt.counters_right[i]++) / framesperbar))
|
1953
|
-
);
|
1954
|
-
|
1955
|
-
// Make the number negative if the original was
|
1956
|
-
if (original_right[i] < 0) {
|
1957
|
-
obj.right[i] *= -1;
|
1958
|
-
}
|
1959
|
-
|
1960
|
-
if (isNull) {
|
1961
|
-
obj.right[i] = null;
|
1962
|
-
}
|
1963
|
-
|
1964
|
-
} else {
|
1965
|
-
obj.right[i] = typeof obj.right[i] === 'object' && obj.right[i] ? RG.arrayPad([], obj.right[i].length, 0) : (RG.isNull(obj.right[i]) ? null : 0);
|
1966
|
-
}
|
1967
|
-
}
|
1968
|
-
|
1969
|
-
|
1970
|
-
// No callback here - only called by the right function
|
1971
|
-
if (frame_right < opt.frames) {
|
1972
|
-
RG.redrawCanvas(obj.canvas);
|
1973
|
-
RG.Effects.updateCanvas(iteratorRight);
|
1974
|
-
} else {
|
1975
|
-
callback(this);
|
1976
|
-
}
|
1977
|
-
}
|
1978
|
-
|
1979
|
-
|
1980
|
-
|
1981
|
-
|
1982
|
-
iteratorLeft();
|
1983
|
-
iteratorRight();
|
1984
|
-
|
1985
|
-
return this;
|
1986
|
-
};
|
1987
|
-
};
|
2
|
+
RGraph=window.RGraph||{isRGraph:true};RGraph.Bipolar=function(conf)
|
3
|
+
{if(typeof conf==='object'&&typeof conf.left==='object'&&typeof conf.right==='object'&&typeof conf.id==='string'){var id=conf.id,canvas=document.getElementById(id),left=conf.left,right=conf.right,parseConfObjectForOptions=true}else{var id=conf,canvas=document.getElementById(id),left=arguments[1],right=arguments[2]}
|
4
|
+
this.id=id;this.canvas=canvas;this.context=this.canvas.getContext('2d');this.canvas.__object__=this;this.type='bipolar';this.coords=[];this.coordsLeft=[];this.coordsRight=[];this.max=0;this.isRGraph=true;this.uid=RGraph.CreateUID();this.canvas.uid=this.canvas.uid?this.canvas.uid:RGraph.CreateUID();this.coordsText=[];this.original_colors=[];this.firstDraw=true;for(var i=0;i<left.length;++i)left[i]=parseFloat(left[i]);for(var i=0;i<right.length;++i)right[i]=parseFloat(right[i]);this.left=left;this.right=right;this.data=[left,right];this.properties={'chart.background.grid':true,'chart.background.grid.color':'#ddd','chart.background.grid.vlines':true,'chart.background.grid.hlines':true,'chart.background.grid.linewidth':1,'chart.background.grid.autofit.numvlines':null,'chart.background.grid.autofit.numhlines':null,'chart.margin':2,'chart.xtickinterval':null,'chart.labels':[],'chart.labels.color':null,'chart.labels.above':false,'chart.text.size':12,'chart.text.color':'black','chart.text.font':'Segoe UI, Arial, Verdana, sans-serif','chart.text.accessible':true,'chart.text.accessible.overflow':'visible','chart.text.accessible.pointerevents':true,'chart.title.left':'','chart.title.right':'','chart.gutter.center':60,'chart.gutter.left':25,'chart.gutter.right':25,'chart.gutter.top':25,'chart.gutter.bottom':30,'chart.title':'','chart.title.background':null,'chart.title.hpos':null,'chart.title.vpos':null,'chart.title.bold':true,'chart.title.font':null,'chart.title.x':null,'chart.title.y':null,'chart.title.halign':null,'chart.title.valign':null,'chart.colors':['#0f0'],'chart.colors.sequential':false,'chart.contextmenu':null,'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.units.pre':'','chart.units.post':'','chart.shadow':false,'chart.shadow.color':'#666','chart.shadow.offsetx':3,'chart.shadow.offsety':3,'chart.shadow.blur':3,'chart.annotatable':false,'chart.annotate.color':'black','chart.xmax':null,'chart.xmin':0,'chart.scale.zerostart':true,'chart.scale.decimals':null,'chart.scale.point':'.','chart.scale.thousand':',','chart.axis.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.background':null,'chart.strokestyle':'rgba(0,0,0,0)','chart.events.mousemove':null,'chart.events.click':null,'chart.linewidth':1,'chart.noaxes':false,'chart.xlabels':true,'chart.numyticks':null,'chart.numxticks':5,'chart.axis.linewidth':1,'chart.labels.count':5,'chart.variant.threed.offsetx':10,'chart.variant.threed.offsety':5,'chart.variant.threed.angle':0.1,'chart.clearto':'rgba(0,0,0,0)'}
|
5
|
+
while(this.left.length<this.right.length)this.left.push(null);while(this.left.length>this.right.length)this.right.push(null);this.properties['chart.numyticks']=this.left.length;var linear_data=RGraph.arrayLinearize(this.left,this.right);for(var i=0;i<linear_data.length;++i){this['$'+i]={};}
|
6
|
+
if(!this.canvas.__rgraph_aa_translated__){this.context.translate(0.5,0.5);this.canvas.__rgraph_aa_translated__=true;}
|
7
|
+
var RG=RGraph,ca=this.canvas,co=ca.getContext('2d'),prop=this.properties,pa2=RG.path2,win=window,doc=document,ma=Math
|
8
|
+
if(RG.Effects&&typeof RG.Effects.decorate==='function'){RG.Effects.decorate(this);}
|
9
|
+
this.set=this.Set=function(name)
|
10
|
+
{var value=typeof arguments[1]==='undefined'?null:arguments[1];if(arguments.length===1&&typeof name==='object'){RG.parseObjectStyleConfig(this,name);return this;}
|
11
|
+
if(name.substr(0,6)!='chart.'){name='chart.'+name;}
|
12
|
+
while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
|
13
|
+
prop[name]=value;return this;};this.get=this.Get=function(name)
|
14
|
+
{if(name.substr(0,6)!='chart.'){name='chart.'+name;}
|
15
|
+
while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
|
16
|
+
return this.properties[name.toLowerCase()];};this.draw=this.Draw=function()
|
17
|
+
{RG.FireCustomEvent(this,'onbeforedraw');if(!this.colorsParsed){this.parseColors();this.colorsParsed=true;}
|
18
|
+
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.gutterCenter=prop['chart.gutter.center'];this.left=this.data[0];this.right=this.data[1];this.coords=[];this.coordsText=[];if(prop['chart.variant']==='3d'){if(prop['chart.text.accessible']){}else{co.setTransform(1,prop['chart.variant.threed.angle'],0,1,0.5,0.5);}}
|
19
|
+
this.axisWidth=(ca.width-prop['chart.gutter.center']-this.gutterLeft-this.gutterRight)/2;this.axisHeight=ca.height-this.gutterTop-this.gutterBottom;this.sequentialFullIndex=0;this.getMax();this.drawBackgroundGrid();this.draw3DAxes();this.drawAxes();this.drawTicks();co.save();co.beginPath();co.rect(this.gutterLeft,this.gutterTop-(prop['chart.variant.threed.offsety']||0),ca.width-this.gutterLeft-this.gutterRight,ca.height-this.gutterTop-this.gutterBottom+(2*(prop['chart.variant.threed.offsety']||0)));co.clip();this.drawLeftBars();this.drawRightBars();this.drawLeftBars({shadow:false});this.drawRightBars({shadow:false});co.restore();this.drawAxes();this.drawLabels();this.drawTitles();if(prop['chart.contextmenu']){RG.ShowContext(this);}
|
20
|
+
if(prop['chart.resizable']){RG.AllowResizing(this);}
|
21
|
+
RG.InstallEventListeners(this);if(this.firstDraw){RG.fireCustomEvent(this,'onfirstdraw');this.firstDraw=false;this.firstDrawFunc();}
|
22
|
+
RG.FireCustomEvent(this,'ondraw');return this;};this.exec=function(func)
|
23
|
+
{func(this);return this;};this.draw3DAxes=function()
|
24
|
+
{if(prop['chart.variant']==='3d'){var offsetx=prop['chart.variant.threed.offsetx'],offsety=prop['chart.variant.threed.offsety'];co.lineWidth=prop['chart.axis.linewidth']+0.001;co.beginPath();co.strokeStyle=prop['chart.axis.color'];pa2(co,'b m % % l % % l % % l % % s #aaa f #ddd',this.gutterLeft,ma.round(ca.height-this.gutterBottom),this.gutterLeft+offsetx,ma.round(ca.height-this.gutterBottom-offsety),this.gutterLeft+offsetx+this.axisWidth,ma.round(ca.height-this.gutterBottom-offsety),this.gutterLeft+this.axisWidth,ma.round(ca.height-this.gutterBottom));this.draw3DLeftVerticalAxis();pa2(co,'b m % % l % % l % % l % % s #aaa f #ddd',this.gutterLeft+this.gutterCenter+this.axisWidth,ma.round(ca.height-this.gutterBottom),this.gutterLeft+this.gutterCenter+this.axisWidth+offsetx,ma.round(ca.height-this.gutterBottom-offsety),this.gutterLeft+this.gutterCenter+this.axisWidth+this.axisWidth+offsetx,ma.round(ca.height-this.gutterBottom-offsety),this.gutterLeft+this.gutterCenter+this.axisWidth+this.axisWidth,ma.round(ca.height-this.gutterBottom));pa2(co,'b m % % l % % l % % l % % s #aaa f #ddd',this.gutterLeft+this.gutterCenter+this.axisWidth,ca.height-this.gutterBottom,this.gutterLeft+this.gutterCenter+this.axisWidth,ca.height-this.gutterBottom-this.axisHeight,this.gutterLeft+this.gutterCenter+this.axisWidth+offsetx,ca.height-this.gutterBottom-this.axisHeight-offsety,this.gutterLeft+this.gutterCenter+this.axisWidth+offsetx,ca.height-this.gutterBottom-offsety);}}
|
25
|
+
this.draw3DLeftVerticalAxis=function()
|
26
|
+
{if(prop['chart.variant']==='3d'){var offsetx=prop['chart.variant.threed.offsetx'],offsety=prop['chart.variant.threed.offsety'];pa2(co,'b m % % l % % l % % l % % s #aaa f #ddd',this.gutterLeft+this.axisWidth,this.gutterTop,this.gutterLeft+this.axisWidth+offsetx,this.gutterTop-offsety,this.gutterLeft+this.axisWidth+offsetx,ca.height-this.gutterBottom-offsety,this.gutterLeft+this.axisWidth,ca.height-this.gutterBottom);}};this.drawAxes=this.DrawAxes=function()
|
27
|
+
{co.lineWidth=prop['chart.axis.linewidth']+0.001;co.beginPath();co.strokeStyle=prop['chart.axis.color'];this.axisWidth=(ca.width-prop['chart.gutter.center']-this.gutterLeft-this.gutterRight)/2;this.axisHeight=ca.height-this.gutterTop-this.gutterBottom;if(prop['chart.noaxes']){return;}
|
28
|
+
co.moveTo(this.gutterLeft,Math.round(ca.height-this.gutterBottom));co.lineTo(this.gutterLeft+this.axisWidth,Math.round(ca.height-this.gutterBottom));co.moveTo(ma.round(this.gutterLeft+this.axisWidth),ca.height-this.gutterBottom);co.lineTo(ma.round(this.gutterLeft+this.axisWidth),this.gutterTop);co.stroke();co.beginPath();var x=this.gutterLeft+this.axisWidth+prop['chart.gutter.center'];co.moveTo(Math.round(x),this.gutterTop);co.lineTo(Math.round(x),ca.height-this.gutterBottom);co.moveTo(Math.round(x),Math.round(ca.height-this.gutterBottom));co.lineTo(ca.width-this.gutterRight,Math.round(ca.height-this.gutterBottom));co.stroke();};this.drawTicks=this.DrawTicks=function()
|
29
|
+
{co.lineWidth=prop['chart.axis.linewidth']+0.001;var numDataPoints=this.left.length;var barHeight=((ca.height-this.gutterTop-this.gutterBottom)-(this.left.length*(prop['chart.margin']*2)))/numDataPoints;this.barHeight=barHeight;if(prop['chart.noaxes']){return;}
|
30
|
+
if(prop['chart.numyticks']>0){co.beginPath();for(var i=0;i<prop['chart.numyticks'];++i){var y=prop['chart.gutter.top']+(((ca.height-this.gutterTop-this.gutterBottom)/prop['chart.numyticks'])*i);co.moveTo(this.gutterLeft+this.axisWidth,y);co.lineTo(this.gutterLeft+this.axisWidth+3,y);}
|
31
|
+
co.stroke();co.beginPath();for(var i=0;i<prop['chart.numyticks'];++i){var y=prop['chart.gutter.top']+(((ca.height-this.gutterTop-this.gutterBottom)/prop['chart.numyticks'])*i);co.moveTo(this.gutterLeft+this.axisWidth+prop['chart.gutter.center'],y);co.lineTo(this.gutterLeft+this.axisWidth+prop['chart.gutter.center']-3,y);}
|
32
|
+
co.stroke();}
|
33
|
+
if(prop['chart.numxticks']>0){var xInterval=this.axisWidth/prop['chart.numxticks'];if(typeof(prop['chart.xtickinterval'])=='number'){xInterval=prop['chart.xtickinterval'];}
|
34
|
+
for(i=this.gutterLeft;i<(this.gutterLeft+this.axisWidth);i+=xInterval){co.beginPath();co.moveTo(Math.round(i),ca.height-this.gutterBottom);co.lineTo(Math.round(i),(ca.height-this.gutterBottom)+4);co.closePath();co.stroke();}
|
35
|
+
var stoppingPoint=ca.width-this.gutterRight;for(i=(this.gutterLeft+this.axisWidth+prop['chart.gutter.center']+xInterval);i<=stoppingPoint;i+=xInterval){co.beginPath();co.moveTo(Math.round(i),ca.height-this.gutterBottom);co.lineTo(Math.round(i),(ca.height-this.gutterBottom)+4);co.closePath();co.stroke();}}};this.getMax=this.GetMax=function()
|
36
|
+
{var dec=prop['chart.scale.decimals'];if(prop['chart.xmax']){var max=prop['chart.xmax'];var min=prop['chart.xmin'];this.scale2=RG.getScale2(this,{'max':max,'min':min,'strict':true,'scale.thousand':prop['chart.scale.thousand'],'scale.point':prop['chart.scale.point'],'scale.decimals':prop['chart.scale.decimals'],'ylabels.count':prop['chart.labels.count'],'scale.round':prop['chart.scale.round'],'units.pre':prop['chart.units.pre'],'units.post':prop['chart.units.post']});this.max=this.scale2.max;this.min=this.scale2.min;}else{var max=Math.max(RG.array_max(this.left),RG.array_max(this.right));this.scale2=RG.getScale2(this,{'max':max,'min':prop['chart.xmin'],'scale.thousand':prop['chart.scale.thousand'],'scale.point':prop['chart.scale.point'],'scale.decimals':prop['chart.scale.decimals'],'ylabels.count':prop['chart.labels.count'],'scale.round':prop['chart.scale.round'],'units.pre':prop['chart.units.pre'],'units.post':prop['chart.units.post']});this.max=this.scale2.max;this.min=this.scale2.min;}};this.drawLeftBars=this.DrawLeftBars=function()
|
37
|
+
{var opt={};if(typeof arguments[0]==='object'){opt.shadow=arguments[0].shadow;}else{opt.shadow=true;}
|
38
|
+
var offsetx=prop['chart.variant.threed.offsetx'],offsety=prop['chart.variant.threed.offsety'];co.strokeStyle=prop['chart.strokestyle'];co.lineWidth=prop['chart.linewidth'];for(var i=(this.left.length-1);i>=0;i-=1){if(prop['chart.shadow']&&prop['chart.variant']!=='3d'&&opt.shadow){co.shadowColor=prop['chart.shadow.color'];co.shadowBlur=prop['chart.shadow.blur'];co.shadowOffsetX=prop['chart.shadow.offsetx'];co.shadowOffsetY=prop['chart.shadow.offsety'];}
|
39
|
+
if(prop['chart.colors.sequential']){co.fillStyle=prop['chart.colors'][i];}else{co.fillStyle=prop['chart.colors'][0];}
|
40
|
+
var width=(((this.left[i]-this.min)/(this.max-this.min))*this.axisWidth);var coords=[ma.round(this.gutterLeft+this.axisWidth-width),ma.round(this.gutterTop+(i*(this.axisHeight/this.left.length))+prop['chart.margin']),width,this.barHeight];if(RG.ISOLD&&prop['chart.shadow']){this.drawIEShadow(coords);}
|
41
|
+
if(this.left[i]!==null){co.strokeRect(coords[0],coords[1],coords[2],coords[3]);co.fillRect(coords[0],coords[1],coords[2],coords[3]);}
|
42
|
+
if(prop['chart.variant']==='3d'&&this.left[i]!==null){if(prop['chart.shadow']&&opt.shadow){co.shadowColor=prop['chart.shadow.color'];co.shadowBlur=prop['chart.shadow.blur'];co.shadowOffsetX=prop['chart.shadow.offsetx'];co.shadowOffsetY=prop['chart.shadow.offsety'];pa2(co,'b m % % l % % l % % l % % f black sc rgba(0,0,0,0) sx 0 sy 0 sb 0',coords[0]+offsetx,coords[1]-offsety,coords[0]+offsetx+coords[2],coords[1]-offsety,coords[0]+offsetx+coords[2],coords[1]-offsety+coords[3],coords[0]+offsetx,coords[1]-offsety+coords[3]);}
|
43
|
+
if(prop['chart.colors.sequential']){co.fillStyle=prop['chart.colors'][i];}else{co.fillStyle=prop['chart.colors'][0];}
|
44
|
+
pa2(co,'b m % % l % % l % % l % % f %',coords[0],coords[1],coords[0]+offsetx,coords[1]-offsety,coords[0]+offsetx+coords[2],coords[1]-offsety,coords[0]+coords[2],coords[1]);pa2(co,'b m % % l % % l % % l % % f rgba(255,255,255,0.4)',coords[0],coords[1],coords[0]+offsetx,coords[1]-offsety,coords[0]+offsetx+coords[2],coords[1]-offsety,coords[0]+coords[2],coords[1]);}
|
45
|
+
this.draw3DLeftVerticalAxis();this.coords.push([coords[0],coords[1],coords[2],coords[3]]);this.coordsLeft.push([coords[0],coords[1],coords[2],coords[3]]);}
|
46
|
+
RG.noShadow(this);co.lineWidth=1;};this.drawRightBars=this.DrawRightBars=function()
|
47
|
+
{var opt={};if(typeof arguments[0]==='object'){opt.shadow=arguments[0].shadow;}else{opt.shadow=true;}
|
48
|
+
var offsetx=prop['chart.variant.threed.offsetx'],offsety=prop['chart.variant.threed.offsety'];co.strokeStyle=prop['chart.strokestyle'];co.lineWidth=prop['chart.linewidth'];if(prop['chart.shadow']&&prop['chart.variant']!=='3d'&&opt.shadow){co.shadowColor=prop['chart.shadow.color'];co.shadowBlur=prop['chart.shadow.blur'];co.shadowOffsetX=prop['chart.shadow.offsetx'];co.shadowOffsetY=prop['chart.shadow.offsety'];}
|
49
|
+
for(var i=(this.right.length-1);i>=0;i-=1){if(prop['chart.colors.sequential']){co.fillStyle=prop['chart.colors'][i];}else{co.fillStyle=prop['chart.colors'][0];}
|
50
|
+
var width=(((this.right[i]-this.min)/(this.max-this.min))*this.axisWidth);var coords=[ma.round(this.gutterLeft+this.axisWidth+prop['chart.gutter.center']),ma.round(prop['chart.margin']+(i*(this.axisHeight/this.right.length))+this.gutterTop),width,this.barHeight];if(RG.ISOLD&&prop['chart.shadow']){this.DrawIEShadow(coords);}
|
51
|
+
if(this.right[i]!==null){co.strokeRect(ma.round(coords[0]),Math.round(coords[1]),coords[2],coords[3]);co.fillRect(ma.round(coords[0]),Math.round(coords[1]),coords[2],coords[3]);}
|
52
|
+
if(prop['chart.variant']==='3d'&&this.right[i]!==null){var color=co.fillStyle;if(prop['chart.shadow']&&opt.shadow){co.shadowColor=prop['chart.shadow.color'];co.shadowBlur=prop['chart.shadow.blur'];co.shadowOffsetX=prop['chart.shadow.offsetx'];co.shadowOffsetY=prop['chart.shadow.offsety'];pa2(co,'b m % % l % % l % % l % % f black sc rgba(0,0,0,0) sx 0 sy 0 sb 0',coords[0]+offsetx,coords[1]-offsety,coords[0]+offsetx+coords[2],coords[1]-offsety,coords[0]+offsetx+coords[2],coords[1]-offsety+coords[3],coords[0]+offsetx,coords[1]-offsety+coords[3]);}
|
53
|
+
pa2(co,'b m % % l % % l % % l % % f %',coords[0],coords[1],coords[0]+offsetx,coords[1]-offsety,coords[0]+offsetx+coords[2],coords[1]-offsety,coords[0]+coords[2],coords[1],color);pa2(co,'b m % % l % % l % % l % % f %',coords[0]+coords[2],coords[1],coords[0]+coords[2]+offsetx,coords[1]-offsety,coords[0]+coords[2]+offsetx,coords[1]-offsety+coords[3],coords[0]+coords[2],coords[1]+coords[3],color);pa2(co,'b m % % l % % l % % l % % f rgba(255,255,255,0.6)',coords[0],coords[1],coords[0]+offsetx,coords[1]-offsety,coords[0]+offsetx+coords[2],coords[1]-offsety,coords[0]+coords[2],coords[1]);pa2(co,'b m % % l % % l % % l % % f rgba(0,0,0,0.3)',coords[0]+coords[2],coords[1],coords[0]+coords[2]+offsetx,coords[1]-offsety,coords[0]+coords[2]+offsetx,coords[1]-offsety+coords[3],coords[0]+coords[2],coords[1]+coords[3]);}
|
54
|
+
this.coords.push([coords[0],coords[1],coords[2],coords[3]]);this.coordsRight.push([coords[0],coords[1],coords[2],coords[3]]);}
|
55
|
+
RG.NoShadow(this);co.lineWidth=1;};this.drawLabels=this.DrawLabels=function()
|
56
|
+
{var font=prop['chart.text.font'],color=prop['chart.labels.color']||prop['chart.text.color'],size=prop['chart.text.size'],labels=prop['chart.labels'],barAreaHeight=ca.height-this.gutterTop-this.gutterBottom
|
57
|
+
co.fillStyle=color;for(var i=0,len=labels.length;i<len;i+=1){RG.Text2(this,{'color':color,'font':font,'size':size,'x':this.gutterLeft+this.axisWidth+(prop['chart.gutter.center']/2),'y':this.gutterTop+((barAreaHeight/labels.length)*(i))+((barAreaHeight/labels.length)/2),'text':String(labels[i]?String(labels[i]):''),'halign':'center','valign':'center','marker':false,'tag':'labels'});}
|
58
|
+
co.fillStyle=prop['chart.text.color'];if(prop['chart.xlabels']){var grapharea=(ca.width-prop['chart.gutter.center']-this.gutterLeft-this.gutterRight)/2;for(var i=0;i<this.scale2.labels.length;++i){RG.text2(this,{'font':font,'size':size,'x':this.gutterLeft+((grapharea/this.scale2.labels.length)*i),'y':ca.height-this.gutterBottom+3,'text':this.scale2.labels[this.scale2.labels.length-i-1],'valign':'top','halign':'center','tag':'scale'});RG.text2(this,{'font':font,'size':size,'x':this.gutterLeft+grapharea+prop['chart.gutter.center']+((grapharea/this.scale2.labels.length)*(i+1)),'y':ca.height-this.gutterBottom+3,'text':this.scale2.labels[i],'valign':'top','halign':'center','tag':'scale'});}
|
59
|
+
if(prop['chart.scale.zerostart']){RG.text2(this,{'font':font,'size':size,'x':this.gutterLeft+this.axisWidth,'y':ca.height-this.gutterBottom+3,'text':'0','valign':'top','halign':'center','tag':'scale'});RG.text2(this,{'font':font,'size':size,'x':this.gutterLeft+this.axisWidth+this.gutterCenter,'y':ca.height-this.gutterBottom+3,'text':'0','valign':'top','halign':'center','tag':'scale'});}}
|
60
|
+
if(prop['chart.labels.above']){for(var i=0;i<this.coordsLeft.length;++i){if(typeof(this.left[i])!='number'){continue;}
|
61
|
+
var coords=this.coordsLeft[i];RG.Text2(this,{'font':font,'size':size,'x':coords[0]-5,'y':coords[1]+(coords[3]/2),'text':RG.number_format(this,this.left[i],prop['chart.units.pre'],prop['chart.units.post']),'valign':'center','halign':'right','tag':'labels.above'});}
|
62
|
+
for(i=0;i<this.coordsRight.length;++i){if(typeof(this.right[i])!='number'){continue;}
|
63
|
+
var coords=this.coordsRight[i];RG.Text2(this,{'font':font,'size':size,'x':coords[0]+coords[2]+5,'y':coords[1]+(coords[3]/2),'text':RG.number_format(this,this.right[i],prop['chart.units.pre'],prop['chart.units.post']),'valign':'center','halign':'left','tag':'labels.above'});}}};this.drawTitles=this.DrawTitles=function()
|
64
|
+
{RG.Text2(this,{'font':prop['chart.text.font'],'size':prop['chart.text.size'],'x':this.gutterLeft+5,'y':this.gutterTop-5,'text':String(prop['chart.title.left']),'halign':'left','valign':'bottom','tag':'title.left'});RG.Text2(this,{'font':prop['chart.text.font'],'size':prop['chart.text.size'],'x':ca.width-this.gutterRight-5,'y':this.gutterTop-5,'text':String(prop['chart.title.right']),'halign':'right','valign':'bottom','tag':'title.right'});RG.drawTitle(this,prop['chart.title'],this.gutterTop,null,prop['chart.title.size']?prop['chart.title.size']:null);};this.drawIEShadow=this.DrawIEShadow=function(coords)
|
65
|
+
{var prevFillStyle=co.fillStyle;var offsetx=prop['chart.shadow.offsetx'];var offsety=prop['chart.shadow.offsety'];co.lineWidth=prop['chart.linewidth'];co.fillStyle=prop['chart.shadow.color'];co.beginPath();co.fillRect(coords[0]+offsetx,coords[1]+offsety,coords[2],coords[3]);co.fill();co.fillStyle=prevFillStyle;}
|
66
|
+
this.getShape=this.getBar=function(e)
|
67
|
+
{var canvas=this.canvas,context=this.context,mouseCoords=RG.getMouseXY(e)
|
68
|
+
for(var i=0;i<this.coords.length;i++){var mouseX=mouseCoords[0],mouseY=mouseCoords[1],left=this.coords[i][0],top=this.coords[i][1],width=this.coords[i][2],height=this.coords[i][3]
|
69
|
+
pa2(co,'b r % % % %',left,top,width,height);if(co.isPointInPath(mouseX,mouseY)){var tooltip=RG.parseTooltipText(prop['chart.tooltips'],i);return{0:this,1:left,2:top,3:width,4:height,5:i,'object':this,'x':left,'y':top,'width':width,'height':height,'index':i,'tooltip':tooltip};}}
|
70
|
+
return null;};this.highlight=this.Highlight=function(shape)
|
71
|
+
{if(typeof prop['chart.highlight.style']==='function'){(prop['chart.highlight.style'])(shape);}else{RG.Highlight.Rect(this,shape);}};this.getValue=function(e)
|
72
|
+
{var obj=e.target.__object__;var mouseXY=RG.getMouseXY(e);var mouseX=mouseXY[0];if(mouseX>this.gutterLeft&&mouseX<((ca.width/2)-(prop['chart.gutter.center']/2))){var value=(mouseX-prop['chart.gutter.left'])/this.axisWidth;value=this.max-(value*this.max);}
|
73
|
+
if(mouseX<(ca.width-this.gutterRight)&&mouseX>((ca.width/2)+(prop['chart.gutter.center']/2))){var value=(mouseX-prop['chart.gutter.left']-this.axisWidth-prop['chart.gutter.center'])/this.axisWidth;value=(value*this.max);}
|
74
|
+
return value;};this.getObjectByXY=function(e)
|
75
|
+
{var mouseXY=RG.getMouseXY(e);if(prop['chart.variant']==='3d'){var adjustment=prop['chart.variant.threed.angle']*mouseXY[0];mouseXY[1]-=adjustment;}
|
76
|
+
if(mouseXY[0]>prop['chart.gutter.left']&&mouseXY[0]<(ca.width-prop['chart.gutter.right'])&&mouseXY[1]>prop['chart.gutter.top']&&mouseXY[1]<(ca.height-prop['chart.gutter.bottom'])){return this;}};this.getXCoord=function(value)
|
77
|
+
{if(value>this.max||value<0){return null;}
|
78
|
+
var ret=[];var offset=((value/this.max)*this.axisWidth);ret[0]=(this.gutterLeft+this.axisWidth)-offset;ret[1]=(ca.width-this.gutterRight-this.axisWidth)+offset;return ret;};this.parseColors=function()
|
79
|
+
{if(this.original_colors.length===0){this.original_colors['chart.colors']=RG.array_clone(prop['chart.colors']);this.original_colors['chart.highlight.stroke']=RG.array_clone(prop['chart.highlight.fill']);this.original_colors['chart.highlight.fill']=RG.array_clone(prop['chart.highlight.fill']);this.original_colors['chart.axis.color']=RG.array_clone(prop['chart.axis.color']);this.original_colors['chart.strokestyle']=RG.array_clone(prop['chart.strokestyle']);}
|
80
|
+
var props=this.properties;var colors=props['chart.colors'];for(var i=0;i<colors.length;++i){colors[i]=this.parseSingleColorForGradient(colors[i]);}
|
81
|
+
props['chart.highlight.stroke']=this.parseSingleColorForGradient(props['chart.highlight.stroke']);props['chart.highlight.fill']=this.parseSingleColorForGradient(props['chart.highlight.fill']);props['chart.axis.color']=this.parseSingleColorForGradient(props['chart.axis.color']);props['chart.strokestyle']=this.parseSingleColorForGradient(props['chart.strokestyle']);};this.reset=function()
|
82
|
+
{};this.parseSingleColorForGradient=function(color)
|
83
|
+
{if(!color||typeof(color)!='string'){return color;}
|
84
|
+
if(color.match(/^gradient\((.*)\)$/i)){var parts=RegExp.$1.split(':');var grad=co.createLinearGradient(prop['chart.gutter.left'],0,ca.width-prop['chart.gutter.right'],0);var diff=1/(parts.length-1);grad.addColorStop(0,RG.trim(parts[0]));for(var j=1;j<parts.length;++j){grad.addColorStop(j*diff,RG.trim(parts[j]));}}
|
85
|
+
return grad?grad:color;};this.on=function(type,func)
|
86
|
+
{if(type.substr(0,2)!=='on'){type='on'+type;}
|
87
|
+
if(typeof this[type]!=='function'){this[type]=func;}else{RG.addCustomEventListener(this,type,func);}
|
88
|
+
return this;};this.drawBackgroundGrid=function()
|
89
|
+
{if(prop['chart.background.grid']){var variant=prop['chart.variant'],color=prop['chart.background.grid.color'],numvlines=prop['chart.labels.count'],numhlines=this.left.length,vlines=prop['chart.background.grid.vlines'],hlines=prop['chart.background.grid.hlines'],linewidth=prop['chart.background.grid.linewidth'];if(typeof prop['chart.background.grid.autofit.numhlines']==='number'){numhlines=prop['chart.background.grid.autofit.numhlines'];}
|
90
|
+
if(typeof prop['chart.background.grid.autofit.numvlines']==='number'){numvlines=prop['chart.background.grid.autofit.numvlines'];}
|
91
|
+
co.lineWidth=linewidth;if(variant=='3d'){co.save();co.translate(prop['chart.variant.threed.offsetx'],-1*prop['chart.variant.threed.offsety']);}
|
92
|
+
if(vlines){for(var i=0;i<=numvlines;i+=1){pa2(co,'b m % % l % % s %',this.gutterLeft+(this.axisWidth/numvlines)*i,this.gutterTop,this.gutterLeft+(this.axisWidth/numvlines)*i,this.gutterTop+this.axisHeight,color);}}
|
93
|
+
if(hlines){for(var i=0;i<=numhlines;i+=1){pa2(co,'b m % % l % % s %',this.gutterLeft,this.gutterTop+(this.axisHeight/numhlines)*i,this.gutterLeft+this.axisWidth,this.gutterTop+(this.axisHeight/numhlines)*i,color);}}
|
94
|
+
if(vlines){for(var i=0;i<=numvlines;i+=1){pa2(co,'b m % % l % % s %',this.gutterLeft+this.gutterCenter+this.axisWidth+(this.axisWidth/numvlines)*i,this.gutterTop,this.gutterLeft+this.gutterCenter+this.axisWidth+(this.axisWidth/numvlines)*i,this.gutterTop+this.axisHeight,color);}}
|
95
|
+
if(hlines){for(var i=0;i<=numhlines;i+=1){pa2(co,'b m % % l % % s %',this.gutterLeft+this.axisWidth+this.gutterCenter,this.gutterTop+(this.axisHeight/numhlines)*i,this.gutterLeft+this.axisWidth+this.gutterCenter+this.axisWidth,this.gutterTop+(this.axisHeight/numhlines)*i,color);}}
|
96
|
+
if(variant=='3d'){co.restore();}}};this.firstDrawFunc=function()
|
97
|
+
{if(prop['chart.tooltips']){prop['chart.tooltips']=RG.arrayReverse(prop['chart.tooltips']);}};RG.Register(this);if(parseConfObjectForOptions){RG.parseObjectStyleConfig(this,conf.options);}
|
98
|
+
this.grow=function()
|
99
|
+
{var opt=arguments[0]||{};var frames=opt.frames||30;var frame=0;var callback=arguments[1]||function(){};var obj=this;var originalLeft=RG.arrayClone(this.left);var originalRight=RG.arrayClone(this.right);if(RG.isNull(prop['chart.xmax'])){var xmax=0;for(var i=0;i<this.left.length;i+=1){xmax=ma.max(xmax,ma.abs(this.left[i]));}
|
100
|
+
for(var i=0;i<this.right.length;i+=1){xmax=ma.max(xmax,ma.abs(this.right[i]));}
|
101
|
+
var scale=RG.getScale2(obj,{'max':xmax});this.Set('chart.xmax',scale.max);}
|
102
|
+
var iterator=function()
|
103
|
+
{var easingMultiplier=RG.Effects.getEasingMultiplier(frames,frame);for(var i=0;i<obj.left.length;i+=1){obj.left[i]=easingMultiplier*originalLeft[i];}
|
104
|
+
for(var i=0;i<obj.right.length;i+=1){obj.right[i]=easingMultiplier*originalRight[i];}
|
105
|
+
RG.redrawCanvas(obj.canvas);if(frame<frames){frame+=1;RG.Effects.updateCanvas(iterator);}else{callback(obj);}};iterator();return this;};this.wave=function()
|
106
|
+
{var obj=this,opt=arguments[0]||{};opt.frames=opt.frames||60;opt.startFrames_left=[];opt.startFrames_right=[];opt.counters_left=[];opt.counters_right=[];var framesperbar=opt.frames/3,frame_left=-1,frame_right=-1,callback=arguments[1]||function(){},original_left=RG.arrayClone(obj.left),original_right=RG.arrayClone(obj.right);for(var i=0,len=obj.left.length;i<len;i+=1){opt.startFrames_left[i]=((opt.frames/2)/(obj.left.length-1))*i;opt.startFrames_right[i]=((opt.frames/2)/(obj.right.length-1))*i;opt.counters_left[i]=0;opt.counters_right[i]=0;}
|
107
|
+
obj.draw();obj.set('xmax',obj.scale2.max);RG.clear(obj.canvas);for(var i=0,len=obj.left.length;i<len;i+=1){if(typeof obj.left[i]==='number')obj.left[i]=0;if(typeof obj.right[i]==='number')obj.right[i]=0;}
|
108
|
+
function iteratorLeft()
|
109
|
+
{++frame_left;for(var i=0,len=obj.left.length;i<len;i+=1){if(frame_left>opt.startFrames_left[i]){var isNull=RG.isNull(obj.left[i]);obj.left[i]=ma.min(ma.abs(original_left[i]),ma.abs(original_left[i]*((opt.counters_left[i]++)/framesperbar)));if(original_left[i]<0){obj.left[i]*=-1;}
|
110
|
+
if(isNull){obj.left[i]=null;}}else{obj.left[i]=typeof obj.left[i]==='object'&&obj.left[i]?RG.arrayPad([],obj.left[i].length,0):(RG.isNull(obj.left[i])?null:0);}}
|
111
|
+
if(frame_left<opt.frames){RG.redrawCanvas(obj.canvas);RG.Effects.updateCanvas(iteratorLeft);}}
|
112
|
+
function iteratorRight()
|
113
|
+
{++frame_right;for(var i=0,len=obj.right.length;i<len;i+=1){if(frame_right>opt.startFrames_right[i]){var isNull=RG.isNull(obj.right[i]);obj.right[i]=ma.min(ma.abs(original_right[i]),ma.abs(original_right[i]*((opt.counters_right[i]++)/framesperbar)));if(original_right[i]<0){obj.right[i]*=-1;}
|
114
|
+
if(isNull){obj.right[i]=null;}}else{obj.right[i]=typeof obj.right[i]==='object'&&obj.right[i]?RG.arrayPad([],obj.right[i].length,0):(RG.isNull(obj.right[i])?null:0);}}
|
115
|
+
if(frame_right<opt.frames){RG.redrawCanvas(obj.canvas);RG.Effects.updateCanvas(iteratorRight);}else{callback(this);}}
|
116
|
+
iteratorLeft();iteratorRight();return this;};};
|