rgraph-rails 1.0.5 → 1.0.6

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