rgraph-rails 1.0.5 → 1.0.6

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