rgraph-rails 1.0.1

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 (74) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +4 -0
  5. data/CODE_OF_CONDUCT.md +13 -0
  6. data/Gemfile +4 -0
  7. data/README.md +73 -0
  8. data/Rakefile +6 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +7 -0
  11. data/lib/rgraph-rails/version.rb +3 -0
  12. data/lib/rgraph-rails.rb +8 -0
  13. data/license.txt +19 -0
  14. data/rgraph-rails.gemspec +26 -0
  15. data/vendor/assets/images/bg.png +0 -0
  16. data/vendor/assets/images/bullet.png +0 -0
  17. data/vendor/assets/images/facebook-large.png +0 -0
  18. data/vendor/assets/images/google-plus-large.png +0 -0
  19. data/vendor/assets/images/logo.png +0 -0
  20. data/vendor/assets/images/meter-image-sd-needle.png +0 -0
  21. data/vendor/assets/images/meter-image-sd.png +0 -0
  22. data/vendor/assets/images/meter-sketch-needle.png +0 -0
  23. data/vendor/assets/images/meter-sketch.png +0 -0
  24. data/vendor/assets/images/odometer-background.png +0 -0
  25. data/vendor/assets/images/rgraph.jpg +0 -0
  26. data/vendor/assets/images/title.png +0 -0
  27. data/vendor/assets/images/twitter-large.png +0 -0
  28. data/vendor/assets/javascripts/RGraph.bar.js +3246 -0
  29. data/vendor/assets/javascripts/RGraph.bipolar.js +2003 -0
  30. data/vendor/assets/javascripts/RGraph.common.annotate.js +399 -0
  31. data/vendor/assets/javascripts/RGraph.common.context.js +600 -0
  32. data/vendor/assets/javascripts/RGraph.common.core.js +4751 -0
  33. data/vendor/assets/javascripts/RGraph.common.csv.js +275 -0
  34. data/vendor/assets/javascripts/RGraph.common.deprecated.js +454 -0
  35. data/vendor/assets/javascripts/RGraph.common.dynamic.js +1194 -0
  36. data/vendor/assets/javascripts/RGraph.common.effects.js +1524 -0
  37. data/vendor/assets/javascripts/RGraph.common.key.js +735 -0
  38. data/vendor/assets/javascripts/RGraph.common.resizing.js +550 -0
  39. data/vendor/assets/javascripts/RGraph.common.tooltips.js +605 -0
  40. data/vendor/assets/javascripts/RGraph.common.zoom.js +223 -0
  41. data/vendor/assets/javascripts/RGraph.drawing.background.js +636 -0
  42. data/vendor/assets/javascripts/RGraph.drawing.circle.js +579 -0
  43. data/vendor/assets/javascripts/RGraph.drawing.image.js +810 -0
  44. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +710 -0
  45. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +672 -0
  46. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +568 -0
  47. data/vendor/assets/javascripts/RGraph.drawing.poly.js +623 -0
  48. data/vendor/assets/javascripts/RGraph.drawing.rect.js +603 -0
  49. data/vendor/assets/javascripts/RGraph.drawing.text.js +648 -0
  50. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +815 -0
  51. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +860 -0
  52. data/vendor/assets/javascripts/RGraph.fuel.js +965 -0
  53. data/vendor/assets/javascripts/RGraph.funnel.js +988 -0
  54. data/vendor/assets/javascripts/RGraph.gantt.js +1242 -0
  55. data/vendor/assets/javascripts/RGraph.gauge.js +1391 -0
  56. data/vendor/assets/javascripts/RGraph.hbar.js +1794 -0
  57. data/vendor/assets/javascripts/RGraph.hprogress.js +1307 -0
  58. data/vendor/assets/javascripts/RGraph.line.js +3940 -0
  59. data/vendor/assets/javascripts/RGraph.meter.js +1242 -0
  60. data/vendor/assets/javascripts/RGraph.modaldialog.js +292 -0
  61. data/vendor/assets/javascripts/RGraph.odo.js +1265 -0
  62. data/vendor/assets/javascripts/RGraph.pie.js +1979 -0
  63. data/vendor/assets/javascripts/RGraph.radar.js +1840 -0
  64. data/vendor/assets/javascripts/RGraph.rose.js +1860 -0
  65. data/vendor/assets/javascripts/RGraph.rscatter.js +1332 -0
  66. data/vendor/assets/javascripts/RGraph.scatter.js +3029 -0
  67. data/vendor/assets/javascripts/RGraph.thermometer.js +1131 -0
  68. data/vendor/assets/javascripts/RGraph.vprogress.js +1326 -0
  69. data/vendor/assets/javascripts/RGraph.waterfall.js +1252 -0
  70. data/vendor/assets/javascripts/financial-data.js +1067 -0
  71. data/vendor/assets/stylesheets/ModalDialog.css +90 -0
  72. data/vendor/assets/stylesheets/animations.css +3347 -0
  73. data/vendor/assets/stylesheets/website.css +402 -0
  74. metadata +175 -0
@@ -0,0 +1,399 @@
1
+ // version: 2015-11-02
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
+ // Module pattern
19
+ (function (win, doc, undefined)
20
+ {
21
+ var RG = RGraph,
22
+ ua = navigator.userAgent,
23
+ ma = Math;
24
+
25
+
26
+
27
+
28
+ /**
29
+ * This installs some event handlers
30
+ *
31
+ * Checking the RGraph.Annotate flag means the annotate code only runs once
32
+ */
33
+ RG.annotating_canvas_onmousedown = function (e)
34
+ {
35
+ if (e.button === 0) {
36
+
37
+ e.target.__object__.Set('chart.mousedown', true);
38
+
39
+ // Get the object from the canvas. Annotating must be enabled on the
40
+ // last object defined
41
+ var obj = e.target.__object__,
42
+ prop = obj.properties
43
+
44
+ // This starts the annotating "path" and set the color
45
+ obj.context.beginPath();
46
+
47
+ obj.context.strokeStyle = obj.Get('chart.annotate.color');
48
+ obj.context.lineWidth = obj.Get('chart.annotate.linewidth');
49
+
50
+ var mouseXY = RG.getMouseXY(e),
51
+ mouseX = mouseXY[0],
52
+ mouseY = mouseXY[1]
53
+
54
+ // Allow for the Bar chart 3D
55
+ if (obj.type === 'bar' && prop['chart.variant'] === '3d') {
56
+ var adjustment = prop['chart.variant.threed.angle'] * mouseXY[0];
57
+ mouseY -= adjustment;
58
+ }
59
+
60
+ // Clear the annotation recording
61
+ RG.Registry.Set('annotate.actions', [obj.Get('chart.annotate.color')]);
62
+
63
+ // This sets the initial X/Y position
64
+ obj.context.moveTo(mouseX, mouseY);
65
+ RG.Registry.Set('annotate.last.coordinates', [mouseX,mouseY]);
66
+
67
+ RG.Registry.Set('started.annotating', false);
68
+ RG.Registry.Set('chart.annotating', obj);
69
+
70
+ // Fire the onannotatebegin event.
71
+ RG.FireCustomEvent(obj, 'onannotatebegin');
72
+ }
73
+
74
+ return false;
75
+ };
76
+
77
+
78
+
79
+
80
+ /**
81
+ * This cancels annotating for ALL canvases
82
+ */
83
+ RG.annotating_window_onmouseup = function (e)
84
+ {
85
+ var obj = RG.Registry.Get('chart.annotating');
86
+ var win = window;
87
+
88
+ if (e.button != 0 || !obj) {
89
+ return;
90
+ }
91
+
92
+ // This cancels annotating on ALL canvas tags on the page
93
+ var tags = doc.getElementsByTagName('canvas');
94
+
95
+ for (var i=0; i<tags.length; ++i) {
96
+ if (tags[i].__object__) {
97
+ tags[i].__object__.Set('chart.mousedown', false);
98
+ }
99
+ }
100
+
101
+ // Store the annotations in browser storage if it's available
102
+ if (RG.Registry.Get('annotate.actions') && RG.Registry.Get('annotate.actions').length > 0 && win.localStorage) {
103
+
104
+ var id = '__rgraph_annotations_' + e.target.id + '__';
105
+ var annotations = win.localStorage[id] ? win.localStorage[id] + '|' : '';
106
+ annotations += RG.Registry.Get('annotate.actions');
107
+
108
+ // Store the annotations information in HTML5 browser storage here
109
+ win.localStorage[id] = annotations;
110
+ }
111
+
112
+ // Clear the recorded annotations
113
+ RG.Registry.Set('annotate.actions', []);
114
+
115
+ // Fire the annotate event
116
+ RG.FireCustomEvent(obj, 'onannotateend');
117
+ };
118
+
119
+
120
+
121
+
122
+ /**
123
+ * The canvas onmousemove function
124
+ */
125
+ RGraph.annotating_canvas_onmousemove = function (e)
126
+ {
127
+ var obj = e.target.__object__;
128
+ var prop = obj.properties;
129
+ var mouseXY = RG.getMouseXY(e);
130
+ var mouseX = mouseXY[0];
131
+ var mouseY = mouseXY[1];
132
+ var lastXY = RG.Registry.Get('annotate.last.coordinates');
133
+
134
+ if (obj.Get('chart.mousedown')) {
135
+
136
+ // Allow for the Bar chart 3D
137
+ if (obj.type === 'bar' && prop['chart.variant'] === '3d') {
138
+ var adjustment = prop['chart.variant.threed.angle'] * mouseXY[0];
139
+ mouseY -= adjustment;
140
+ }
141
+
142
+ obj.context.beginPath();
143
+
144
+ if (!lastXY) {
145
+ obj.context.moveTo(mouseX, mouseY)
146
+ } else {
147
+ obj.context.strokeStyle = obj.properties['chart.annotate.color'];
148
+ obj.context.moveTo(lastXY[0], lastXY[1]);
149
+ obj.context.lineTo(mouseX, mouseY);
150
+ }
151
+
152
+ RG.Registry.Set('annotate.actions', RG.Registry.Get('annotate.actions') + '|' + mouseX + ',' + mouseY);
153
+ RG.Registry.Set('annotate.last.coordinates', [mouseX,mouseY]);
154
+
155
+ RG.FireCustomEvent(obj, 'onannotate');
156
+ obj.context.stroke();
157
+ }
158
+ };
159
+
160
+
161
+
162
+
163
+ /**
164
+ * Shows the mini palette used for annotations
165
+ *
166
+ * @param object e The event object
167
+ */
168
+ RG.ShowPalette =
169
+ RG.Showpalette = function (e)
170
+ {
171
+ var isSafari = navigator.userAgent.indexOf('Safari') ? true : false;
172
+
173
+ e = RG.FixEventObject(e);
174
+
175
+ var canvas = e.target.parentNode.__canvas__,
176
+ context = canvas.getContext('2d'),
177
+ obj = canvas.__object__,
178
+ div = document.createElement('DIV'),
179
+ coords = RG.getMouseXY(e)
180
+
181
+ div.__object__ = obj; // The graph object
182
+ div.className = 'RGraph_palette';
183
+ div.style.position = 'absolute';
184
+ div.style.backgroundColor = 'white';
185
+ div.style.border = '1px solid black';
186
+ div.style.left = 0;
187
+ div.style.top = 0;
188
+ div.style.padding = '3px';
189
+ div.style.paddingLeft = '5px';
190
+ div.style.opacity = 0;
191
+ div.style.boxShadow = 'rgba(96,96,96,0.5) 3px 3px 3px';
192
+ div.style.WebkitBoxShadow = 'rgba(96,96,96,0.5) 3px 3px 3px';
193
+ div.style.MozBoxShadow = 'rgba(96,96,96,0.5) 3px 3px 3px';
194
+
195
+
196
+ // MUST use named colors that are capitalised
197
+ var colors = [
198
+ 'Black',
199
+ 'Red',
200
+ 'Yellow',
201
+ 'Green',
202
+ 'Orange',
203
+ 'White',
204
+ 'Magenta',
205
+ 'Pink'
206
+ ];
207
+
208
+ // Add the colors to the palette
209
+ for (var i=0,len=colors.length; i<len; i+=1) {
210
+
211
+ var div2 = doc.createElement('DIV');
212
+ div2.cssClass = 'RGraph_palette_color';
213
+ div2.style.fontSize = '12pt';
214
+ div2.style.cursor = 'pointer';
215
+ div2.style.padding = '1px';
216
+ div2.style.paddingRight = '10px';
217
+ div2.style.textAlign = 'left';
218
+
219
+ var span = document.createElement('SPAN');
220
+ span.style.display = 'inline-block';
221
+ span.style.marginRight = '9px';
222
+ span.style.width = '17px';
223
+ span.style.height = '17px';
224
+ span.style.top = '2px';
225
+ span.style.position = 'relative';
226
+ span.style.backgroundColor = colors[i];
227
+ div2.appendChild(span);
228
+
229
+ div2.innerHTML += colors[i];
230
+
231
+
232
+ div2.onmouseover = function ()
233
+ {
234
+ this.style.backgroundColor = '#eee';
235
+ }
236
+
237
+ div2.onmouseout = function ()
238
+ {
239
+ this.style.backgroundColor = '';
240
+ }
241
+
242
+ div2.onclick = function (e)
243
+ {
244
+ var color = this.childNodes[0].style.backgroundColor;
245
+
246
+ obj.Set('chart.annotate.color', color);
247
+ }
248
+ div.appendChild(div2);
249
+ }
250
+
251
+
252
+ doc.body.appendChild(div);
253
+
254
+ /**
255
+ * Now the div has been added to the document, move it up and left
256
+ */
257
+ div.style.left = e.pageX + 'px';
258
+ div.style.top = e.pageY + 'px';
259
+
260
+ /**
261
+ * Chang the position if the cursor is near the right edge of the browser window
262
+ */
263
+ if ((e.pageX + (div.offsetWidth + 5) ) > document.body.offsetWidth) {
264
+ div.style.left = (e.pageX - div.offsetWidth) + 'px';
265
+ }
266
+
267
+ /**
268
+ * Store the palette div in the registry
269
+ */
270
+ RGraph.Registry.Set('chart.palette', div);
271
+
272
+ setTimeout(function () {div.style.opacity = 0.2;}, 50);
273
+ setTimeout(function () {div.style.opacity = 0.4;}, 100);
274
+ setTimeout(function () {div.style.opacity = 0.6;}, 150);
275
+ setTimeout(function () {div.style.opacity = 0.8;}, 200);
276
+ setTimeout(function () {div.style.opacity = 1;}, 250);
277
+
278
+ RGraph.hideContext();
279
+
280
+ window.onclick = function ()
281
+ {
282
+ RG.hidePalette();
283
+ }
284
+
285
+ // Should this be here? Yes. This function is being used as an event handler.
286
+ e.stopPropagation();
287
+ return false;
288
+ };
289
+
290
+
291
+
292
+
293
+ /**
294
+ * Clears any annotation data from global storage
295
+ *
296
+ * @param object canvas The canvas tag object
297
+ */
298
+ RG.clearAnnotations =
299
+ RG.ClearAnnotations = function (canvas)
300
+ {
301
+ /**
302
+ * For BC the argument can also be the ID of the canvas
303
+ */
304
+ if (typeof canvas === 'string') {
305
+ var id = canvas;
306
+ canvas = doc.getElementById(id);
307
+ } else {
308
+ var id = canvas.id
309
+ }
310
+
311
+ var obj = canvas.__object__;
312
+
313
+ if (win.localStorage && win.localStorage['__rgraph_annotations_' + id + '__'] && win.localStorage['__rgraph_annotations_' + id + '__'].length) {
314
+ win.localStorage['__rgraph_annotations_' + id + '__'] = [];
315
+
316
+ RGraph.FireCustomEvent(obj, 'onannotateclear');
317
+ }
318
+ };
319
+
320
+
321
+
322
+
323
+ /**
324
+ * Replays stored annotations
325
+ *
326
+ * @param object obj The graph object
327
+ */
328
+ RG.replayAnnotations =
329
+ RG.ReplayAnnotations = function (obj)
330
+ {
331
+ // Check for support
332
+ if (!win.localStorage) {
333
+ return;
334
+ }
335
+
336
+ var context = obj.context;
337
+ var annotations = win.localStorage['__rgraph_annotations_' + obj.id + '__'];
338
+ var i, len, move, coords;
339
+
340
+ context.beginPath();
341
+ context.lineWidth = obj.Get('annotate.linewidth');
342
+
343
+ if (annotations && annotations.length) {
344
+ annotations = annotations.split('|');
345
+ } else {
346
+ return;
347
+ }
348
+
349
+
350
+ for (i=0,len=annotations.length; i<len; ++i) {
351
+
352
+ // If the element of the array is a color - finish the path,
353
+ // stroke it and start a new one
354
+ if (annotations[i].match(/[a-z]+/)) {
355
+ context.stroke();
356
+ context.beginPath();
357
+
358
+ context.strokeStyle = annotations[i];
359
+ move = true;
360
+ continue;
361
+ }
362
+
363
+ coords = annotations[i].split(',');
364
+ coords[0] = Number(coords[0]);
365
+ coords[1] = Number(coords[1]);
366
+
367
+ if (move) {
368
+ context.moveTo(coords[0], coords[1]);
369
+ move = false;
370
+ } else {
371
+ context.lineTo(coords[0], coords[1]);
372
+ }
373
+ }
374
+
375
+ context.stroke();
376
+ };
377
+
378
+
379
+
380
+
381
+ window.addEventListener('load', function (e)
382
+ {
383
+ // This delay is necessary to allow the window.onload event listener to run
384
+ setTimeout(function ()
385
+ {
386
+ var tags = doc.getElementsByTagName('canvas');
387
+ for (var i=0; i<tags.length; ++i) {
388
+ if (tags[i].__object__ && tags[i].__object__.isRGraph && tags[i].__object__.Get('chart.annotatable')) {
389
+ RG.replayAnnotations(tags[i].__object__);
390
+ }
391
+ }
392
+ }, 100); // This delay is sufficient to wait before replaying the annotations
393
+ }, false);
394
+
395
+
396
+
397
+
398
+ // End module pattern
399
+ })(window, document);
@@ -0,0 +1,600 @@
1
+ // version: 2015-11-02
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
+ // Module pattern
19
+ (function (win, doc, undefined)
20
+ {
21
+ var RG = RGraph,
22
+ ua = navigator.userAgent,
23
+ ma = Math;
24
+
25
+
26
+
27
+ /**
28
+ * This gunction shows a context menu containing the parameters
29
+ * provided to it
30
+ *
31
+ * @param object canvas The canvas object
32
+ * @param array menuitems The context menu menuitems
33
+ * @param object e The event object
34
+ */
35
+ RG.contextmenu =
36
+ RG.Contextmenu = function (obj, menuitems, e)
37
+ {
38
+ var canvas = obj.canvas;
39
+
40
+ e = RG.FixEventObject(e);
41
+
42
+ /**
43
+ * Fire the custom RGraph event onbeforecontextmenu
44
+ */
45
+ RG.FireCustomEvent(obj, 'onbeforecontextmenu');
46
+
47
+ /**
48
+ * Hide any existing menu
49
+ */
50
+ if (RG.Registry.Get('chart.contextmenu')) {
51
+ RG.HideContext();
52
+ }
53
+
54
+ // Hide any zoomed canvas
55
+ RG.HideZoomedCanvas();
56
+
57
+ /**
58
+ * Hide the palette if necessary
59
+ */
60
+ RG.HidePalette();
61
+
62
+ /**
63
+ * This is here to ensure annotating is OFF
64
+ */
65
+ obj.Set('chart.mousedown', false);
66
+
67
+ var x = e.pageX;
68
+ var y = e.pageY;
69
+ var div = document.createElement('div');
70
+ var bg = document.createElement('div');
71
+
72
+ div.className = 'RGraph_contextmenu';
73
+ div.__canvas__ = canvas; /* Store a reference to the canvas on the contextmenu object */
74
+ div.style.position = 'absolute';
75
+ div.style.left = 0;
76
+ div.style.top = 0;
77
+ div.style.border = '1px solid black';
78
+ div.style.backgroundColor = 'white';
79
+ div.style.boxShadow = '3px 3px 3px rgba(96,96,96,0.5)';
80
+ div.style.MozBoxShadow = '3px 3px 3px rgba(96,96,96,0.5)';
81
+ div.style.WebkitBoxShadow = '3px 3px 3px rgba(96,96,96,0.5)';
82
+ div.style.filter = 'progid:DXImageTransform.Microsoft.Shadow(color=#aaaaaa,direction=135)';
83
+ div.style.opacity = 0;
84
+
85
+ bg.className = 'RGraph_contextmenu_background';
86
+ bg.style.position = 'absolute';
87
+ bg.style.backgroundColor = '#ccc';
88
+ bg.style.borderRight = '1px solid #aaa';
89
+ bg.style.top = 0;
90
+ bg.style.left = 0;
91
+ bg.style.width = '18px';
92
+ bg.style.height = '100%';
93
+ bg.style.opacity = 0;
94
+
95
+
96
+ div = document.body.appendChild(div);
97
+ bg = div.appendChild(bg);
98
+
99
+
100
+ /**
101
+ * Now add the context menu items
102
+ */
103
+ for (i=0; i<menuitems.length; ++i) {
104
+
105
+ var menuitem = document.createElement('div');
106
+
107
+ menuitem.__object__ = obj;
108
+ menuitem.__canvas__ = canvas;
109
+ menuitem.__contextmenu__ = div;
110
+ menuitem.className = 'RGraph_contextmenu_item';
111
+
112
+ if (menuitems[i]) {
113
+ menuitem.style.padding = '2px 5px 2px 23px';
114
+ menuitem.style.fontFamily = 'Arial';
115
+ menuitem.style.fontSize = '10pt';
116
+ menuitem.style.textAlign = 'left';
117
+ menuitem.style.fontWeight = 'normal';
118
+ menuitem.innerHTML = menuitems[i][0];
119
+
120
+ if (RG.is_array(menuitems[i][1])) {
121
+ menuitem.style.backgroundImage = 'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAQUlEQVQImY3NoQ2AMABE0ZewABMyGQ6mqWODzlAclBSFO8HZl8uf0FFxCHtwYkt4Y6ChYE44cGH9/fyae2p2LAleW9oVTQuVf6gAAAAASUVORK5CYII=)';
122
+ menuitem.style.backgroundRepeat = 'no-repeat';
123
+ menuitem.style.backgroundPosition = '97% center';
124
+ }
125
+
126
+ // Add the mouseover event
127
+ if (menuitems[i][1]) {
128
+ if (menuitem.addEventListener) {
129
+ menuitem.addEventListener("mouseover", function (e) {RG.HideContextSubmenu(); e.target.style.backgroundColor = 'rgba(0,0,0,0.2)'; e.target.style.cursor = 'pointer';}, false);
130
+ menuitem.addEventListener("mouseout", function (e) {e.target.style.backgroundColor = 'inherit'; e.target.style.cursor = 'default';}, false);
131
+ } else {
132
+ menuitem.attachEvent("onmouseover", function () {RG.HideContextSubmenu();event.srcElement.style.backgroundColor = '#eee';event.srcElement.style.cursor = 'pointer';}
133
+ , false);
134
+ menuitem.attachEvent("onmouseout", function () {event.srcElement.style.backgroundColor = 'inherit'; event.srcElement.style.cursor = 'default';}, false);
135
+ }
136
+ } else {
137
+ if (menuitem.addEventListener) {
138
+ menuitem.addEventListener("mouseover", function (e) {e.target.style.cursor = 'default';}, false);
139
+ menuitem.addEventListener("mouseout", function (e) {e.target.style.cursor = 'default';}, false);
140
+ } else {
141
+ menuitem.attachEvent("onmouseover", function () {event.srcElement.style.cursor = 'default'}, false);
142
+ menuitem.attachEvent("onmouseout", function () {event.srcElement.style.cursor = 'default';}, false);
143
+ }
144
+ }
145
+
146
+ } else {
147
+ menuitem.style.borderBottom = '1px solid #ddd';
148
+ menuitem.style.marginLeft = '25px';
149
+ }
150
+
151
+ div.appendChild(menuitem);
152
+
153
+ /**
154
+ * Install the event handler that calls the menuitem
155
+ */
156
+ if (menuitems[i] && menuitems[i][1] && typeof(menuitems[i][1]) == 'function') {
157
+
158
+ menuitem.addEventListener('click', menuitems[i][1], false);
159
+
160
+ // Submenu
161
+ } else if (menuitems[i] && menuitems[i][1] && RG.is_array(menuitems[i][1])) {
162
+ (function ()
163
+ {
164
+ var tmp = menuitems[i][1]; // This is here because of "references vs primitives" and how they're passed around in Javascript
165
+
166
+ // TODO This may need attention
167
+ menuitem.addEventListener('mouseover', function (e) {RG.Contextmenu_submenu(obj, tmp, e.target);}, false);
168
+ })();
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Now all the menu items have been added, set the shadow width
174
+ * Shadow now handled by CSS3
175
+ */
176
+ div.style.width = (div.offsetWidth + 10) + 'px';
177
+ div.style.height = (div.offsetHeight - 2) + 'px';
178
+
179
+ // Show the menu to the left or the right (normal) of the cursor?
180
+ if (x + div.offsetWidth > document.body.offsetWidth) {
181
+ x -= div.offsetWidth;
182
+ }
183
+
184
+ // Reposition the menu (now we have the real offsetWidth)
185
+ div.style.left = x + 'px';
186
+ div.style.top = y + 'px';
187
+
188
+ /**
189
+ * Do a little fade in effect
190
+ */
191
+ setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu')) obj.style.opacity = 0.2", 50);
192
+ setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu')) obj.style.opacity = 0.4", 100);
193
+ setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu')) obj.style.opacity = 0.6", 150);
194
+ setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu')) obj.style.opacity = 0.8", 200);
195
+ setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu')) obj.style.opacity = 1", 250);
196
+
197
+ // The fade in effect on the left gray bar
198
+ setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu.bg')) obj.style.opacity = 0.2", 50);
199
+ setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu.bg')) obj.style.opacity = 0.4", 100);
200
+ setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu.bg')) obj.style.opacity = 0.6", 150);
201
+ setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu.bg')) obj.style.opacity = 0.8", 200);
202
+ setTimeout("if (obj = RGraph.Registry.Get('chart.contextmenu.bg')) obj.style.opacity = 1", 250);
203
+
204
+ // Store the context menu in the registry
205
+ RG.Registry.Set('chart.contextmenu', div);
206
+ RG.Registry.Set('chart.contextmenu.bg', bg);
207
+ RG.Registry.Get('chart.contextmenu').oncontextmenu = function () {return false;};
208
+ RG.Registry.Get('chart.contextmenu.bg').oncontextmenu = function () {return false;};
209
+
210
+ /**
211
+ * Install the event handlers that hide the context menu
212
+ */
213
+ canvas.addEventListener('click', function () {RG.HideContext();}, false);
214
+
215
+ window.addEventListener('click', function ()
216
+ {
217
+ RG.HideContext();
218
+ }, false);
219
+
220
+ window.addEventListener('resize', function ()
221
+ {
222
+ RG.HideContext();
223
+ }, false);
224
+
225
+
226
+ /**
227
+ * Add the __shape__ object to the context menu
228
+ */
229
+
230
+ /**
231
+ * Set the shape coords from the .getShape() method
232
+ */
233
+ if (typeof(obj.getShape) == 'function') {
234
+ RG.Registry.Get('chart.contextmenu').__shape__ = obj.getShape(e);
235
+ }
236
+
237
+
238
+ e.stopPropagation();
239
+
240
+ /**
241
+ * Fire the (RGraph) oncontextmenu event
242
+ */
243
+ RG.FireCustomEvent(obj, 'oncontextmenu');
244
+
245
+ return false;
246
+ };
247
+
248
+
249
+
250
+
251
+ /**
252
+ * Hides the context menu if it's currently visible
253
+ */
254
+ RG.hideContext =
255
+ RG.HideContext = function ()
256
+ {
257
+ var cm = RG.Registry.Get('chart.contextmenu');
258
+ var cmbg = RG.Registry.Get('chart.contextmenu.bg');
259
+
260
+ //Hide any submenu currently being displayed
261
+ RG.HideContextSubmenu();
262
+
263
+ if (cm) {
264
+ cm.parentNode.removeChild(cm);
265
+ cmbg.parentNode.removeChild(cmbg);
266
+
267
+ cm.style.visibility = 'hidden';
268
+ cm.style.display = 'none';
269
+ RG.Registry.Set('chart.contextmenu', null);
270
+
271
+ cmbg.style.visibility = 'hidden';
272
+ cmbg.style.display = 'none';
273
+ RG.Registry.Set('chart.contextmenu.bg', null);
274
+ }
275
+ };
276
+
277
+
278
+
279
+
280
+ /**
281
+ * Hides the context menus SUBMENU if it's currently visible
282
+ */
283
+ RG.hideContextSubmenu =
284
+ RG.HideContextSubmenu = function ()
285
+ {
286
+ var sub = RG.Registry.Get('chart.contextmenu.submenu');
287
+
288
+ if (sub) {
289
+ sub.style.visibility = 'none';
290
+ sub.style.display = 'none';
291
+ RG.Registry.Set('chart.contextmenu.submenu', null);
292
+ }
293
+ };
294
+
295
+
296
+
297
+
298
+ /**
299
+ * Shows the context menu after making a few checks - not opera (doesn't support oncontextmenu,
300
+ * not safari (tempermentality), not chrome (hmmm)
301
+ */
302
+ RG.showContext =
303
+ RG.ShowContext = function (obj)
304
+ {
305
+ RG.HidePalette();
306
+
307
+ if (obj.Get('chart.contextmenu') && obj.Get('chart.contextmenu').length) {
308
+
309
+ var isOpera = navigator.userAgent.indexOf('Opera') >= 0;
310
+ var isSafari = navigator.userAgent.indexOf('Safari') >= 0;
311
+ var isChrome = navigator.userAgent.indexOf('Chrome') >= 0;
312
+ var isMacFirefox = navigator.userAgent.indexOf('Firefox') > 0 && navigator.userAgent.indexOf('Mac') > 0;
313
+ var isIE9 = navigator.userAgent.indexOf('MSIE 9') >= 0;
314
+
315
+ if (((!isOpera && !isSafari) || isChrome) && !isMacFirefox) {
316
+
317
+ obj.canvas.oncontextmenu = function (e)
318
+ {
319
+ e = RG.FixEventObject(e);
320
+
321
+ if (e.ctrlKey) return true;
322
+
323
+ RG.Contextmenu(obj, obj.Get('chart.contextmenu'), e);
324
+
325
+ return false;
326
+ }
327
+
328
+ // Accomodate Opera and Safari - use double click event
329
+ } else {
330
+
331
+ obj.canvas.addEventListener('dblclick', function (e)
332
+ {
333
+ if (e.ctrlKey) return true;
334
+
335
+ if (!RG.Registry.Get('chart.contextmenu')) {
336
+ RG.Contextmenu(obj, obj.Get('chart.contextmenu'), e);
337
+ }
338
+ }, false);
339
+ }
340
+ }
341
+ };
342
+
343
+
344
+
345
+
346
+ /**
347
+ * This draws a submenu should it be necessary
348
+ *
349
+ * @param object obj The graph object
350
+ * @param object menu The context menu
351
+ */
352
+ RG.contextmenu_submenu =
353
+ RG.Contextmenu_submenu = function (obj, menuitems, parentMenuItem)
354
+ {
355
+ RG.HideContextSubmenu();
356
+
357
+ var canvas = obj.canvas;
358
+ var context = obj.context;
359
+ var menu = parentMenuItem.parentNode;
360
+
361
+ var subMenu = document.createElement('DIV');
362
+ subMenu.style.position = 'absolute';
363
+ subMenu.style.width = '100px';
364
+ subMenu.style.top = menu.offsetTop + parentMenuItem.offsetTop + 'px';
365
+ subMenu.style.left = (menu.offsetLeft + menu.offsetWidth - (RG.ISOLD ? 9 : 0)) + 'px';
366
+ subMenu.style.backgroundColor = 'white';
367
+ subMenu.style.border = '1px solid black';
368
+ subMenu.className = 'RGraph_contextmenu';
369
+ subMenu.__contextmenu__ = menu;
370
+ subMenu.style.boxShadow = '3px 3px 3px rgba(96,96,96,0.5)';
371
+ subMenu.style.MozBoxShadow = '3px 3px 3px rgba(96,96,96,0.5)';
372
+ subMenu.style.WebkitBoxShadow = '3px 3px 3px rgba(96,96,96,0.5)';
373
+ subMenu.style.filter = 'progid:DXImageTransform.Microsoft.Shadow(color=#aaaaaa,direction=135)';
374
+ document.body.appendChild(subMenu);
375
+
376
+ for (var i=0; i<menuitems.length; ++i) {
377
+
378
+ var menuitem = document.createElement('DIV');
379
+
380
+ menuitem.__canvas__ = canvas;
381
+ menuitem.__contextmenu__ = menu;
382
+ menuitem.className = 'RGraph_contextmenu_item';
383
+
384
+ if (menuitems[i]) {
385
+ menuitem.style.padding = '2px 5px 2px 23px';
386
+ menuitem.style.fontFamily = 'Arial';
387
+ menuitem.style.fontSize = '10pt';
388
+ menuitem.style.fontWeight = 'normal';
389
+ menuitem.style.textAlign = 'left';
390
+ menuitem.innerHTML = menuitems[i][0];
391
+
392
+ if (menuitems[i][1]) {
393
+ if (menuitem.addEventListener) {
394
+ menuitem.addEventListener("mouseover", function (e) {e.target.style.backgroundColor = 'rgba(0,0,0,0.2)'; e.target.style.cursor = 'pointer';}, false);
395
+ menuitem.addEventListener("mouseout", function (e) {e.target.style.backgroundColor = 'inherit'; e.target.style.cursor = 'default';}, false);
396
+ } else {
397
+ menuitem.attachEvent("onmouseover", function () {event.srcElement.style.backgroundColor = 'rgba(0,0,0,0.2)'; event.srcElement.style.cursor = 'pointer'}, false);
398
+ menuitem.attachEvent("onmouseout", function () {event.srcElement.style.backgroundColor = 'inherit'; event.srcElement.style.cursor = 'default';}, false);
399
+ }
400
+ } else {
401
+ if (menuitem.addEventListener) {
402
+ menuitem.addEventListener("mouseover", function (e) {e.target.style.cursor = 'default';}, false);
403
+ menuitem.addEventListener("mouseout", function (e) {e.target.style.cursor = 'default';}, false);
404
+ } else {
405
+ menuitem.attachEvent("onmouseover", function () {event.srcElement.style.cursor = 'default'}, false);
406
+ menuitem.attachEvent("onmouseout", function () {event.srcElement.style.cursor = 'default';}, false);
407
+ }
408
+ }
409
+ } else {
410
+ menuitem.style.borderBottom = '1px solid #ddd';
411
+ menuitem.style.marginLeft = '25px';
412
+ }
413
+
414
+ subMenu.appendChild(menuitem);
415
+
416
+ if (menuitems[i] && menuitems[i][1]) {
417
+ if (document.all) {
418
+ menuitem.attachEvent('onclick', menuitems[i][1]);
419
+ } else {
420
+ menuitem.addEventListener('click', menuitems[i][1], false);
421
+ }
422
+ }
423
+ }
424
+
425
+
426
+ var bg = document.createElement('DIV');
427
+ bg.className = 'RGraph_contextmenu_background';
428
+ bg.style.position = 'absolute';
429
+ bg.style.backgroundColor = '#ccc';
430
+ bg.style.borderRight = '1px solid #aaa';
431
+ bg.style.top = 0;
432
+ bg.style.left = 0;
433
+ bg.style.width = '18px';
434
+ bg.style.height = '100%';
435
+
436
+ bg = subMenu.appendChild(bg);
437
+
438
+ RG.Registry.Set('chart.contextmenu.submenu', subMenu);
439
+ };
440
+
441
+
442
+
443
+
444
+ /**
445
+ * A function designed to be used in conjunction with thed context menu
446
+ * to allow people to get image versions of canvases.
447
+ *
448
+ * @param canvas Optionally you can pass in the canvas, which will be used
449
+ */
450
+ RG.showPNG = function ()
451
+ {
452
+ if (RG.ISIE8) {
453
+ alert('[RGRAPH PNG] Sorry, showing a PNG is not supported on MSIE8.');
454
+ return;
455
+ }
456
+
457
+ if (arguments[0] && arguments[0].id) {
458
+ var canvas = arguments[0];
459
+ var event = arguments[1];
460
+
461
+ } else if (RG.Registry.Get('chart.contextmenu')) {
462
+ var canvas = RG.Registry.Get('chart.contextmenu').__canvas__;
463
+
464
+ } else {
465
+ alert('[RGRAPH SHOWPNG] Could not find canvas!');
466
+ }
467
+
468
+ var obj = canvas.__object__;
469
+
470
+ /**
471
+ * Create the gray background DIV to cover the page
472
+ */
473
+ var bg = document.createElement('DIV');
474
+ bg.id = '__rgraph_image_bg__';
475
+ bg.style.position = 'fixed';
476
+ bg.style.top = '-10px';
477
+ bg.style.left = '-10px';
478
+ bg.style.width = '5000px';
479
+ bg.style.height = '5000px';
480
+ bg.style.backgroundColor = 'rgb(204,204,204)';
481
+ bg.style.opacity = 0;
482
+ document.body.appendChild(bg);
483
+
484
+
485
+ /**
486
+ * Create the div that the graph sits in
487
+ */
488
+ var div = document.createElement('DIV');
489
+ div.style.backgroundColor = 'white';
490
+ div.style.opacity = 0;
491
+ div.style.border = '1px solid black';
492
+ div.style.position = 'fixed';
493
+ div.style.top = '20%';
494
+ div.style.width = canvas.width + 'px';
495
+ div.style.height = canvas.height + 35 + 'px';
496
+ div.style.left = (document.body.clientWidth / 2) - (canvas.width / 2) + 'px';
497
+ div.style.padding = '5px';
498
+
499
+ div.style.borderRadius = '10px';
500
+ div.style.MozBorderRadius = '10px';
501
+ div.style.WebkitBorderRadius = '10px';
502
+
503
+ div.style.boxShadow = '0 0 15px rgba(96,96,96,0.5)';
504
+ div.style.MozBoxShadow = '0 0 15px rgba(96,96,96,0.5)';
505
+ div.style.WebkitBoxShadow = 'rgba(96,96,96,0.5) 0 0 15px';
506
+
507
+ div.__canvas__ = canvas;
508
+ div.__object__ = obj;
509
+ div.id = '__rgraph_image_div__';
510
+ document.body.appendChild(div);
511
+
512
+
513
+ /**
514
+ * Add the HTML text inputs
515
+ */
516
+ div.innerHTML += '<div style="position: absolute; margin-left: 10px; top: ' + canvas.height + 'px; width: ' + (canvas.width - 50) + 'px; height: 25px"><span style="font-size: 12pt;display: inline; display: inline-block; width: 65px; text-align: right">URL:</span><textarea style="float: right; overflow: hidden; height: 20px; width: ' + (canvas.width - obj.gutterLeft - obj.gutterRight - 80) + 'px" onclick="this.select()" readonly="readonly" id="__rgraph_dataurl__">' + canvas.toDataURL() + '</textarea></div>';
517
+ div.innerHTML += '<div style="position: absolute; top: ' + (canvas.height + 25) + 'px; left: ' + (obj.gutterLeft - 65 + (canvas.width / 2)) + 'px; width: ' + (canvas.width - obj.gutterRight) + 'px; font-size: 65%">A link using the URL: <a href="' + canvas.toDataURL() + '">View</a></div>'
518
+
519
+
520
+
521
+ /**
522
+ * Create the image rendition of the graph
523
+ */
524
+ var img = document.createElement('IMG');
525
+ RG.Registry.Set('chart.png', img);
526
+ img.__canvas__ = canvas;
527
+ img.__object__ = obj;
528
+ img.id = '__rgraph_image_img__';
529
+ img.className = 'RGraph_png';
530
+
531
+ img.src = canvas.toDataURL();
532
+
533
+ div.appendChild(img);
534
+
535
+ setTimeout(function () {document.getElementById("__rgraph_dataurl__").select();}, 50);
536
+
537
+ window.addEventListener('resize', function (e){var img = RG.Registry.Get('chart.png');img.style.left = (document.body.clientWidth / 2) - (img.width / 2) + 'px';}, false);
538
+
539
+ bg.onclick = function (e)
540
+ {
541
+ var div = document.getElementById("__rgraph_image_div__");
542
+ var bg = document.getElementById("__rgraph_image_bg__");
543
+
544
+ if (div) {
545
+ div.style.opacity = 0;
546
+
547
+ div.parentNode.removeChild(div);
548
+
549
+ div.id = '';
550
+ div.style.display = 'none';
551
+ div = null;
552
+ }
553
+
554
+ if (bg) {
555
+ bg.style.opacity = 0;
556
+
557
+ bg.id = '';
558
+ bg.style.display = 'none';
559
+ bg = null;
560
+ }
561
+ }
562
+
563
+ window.addEventListener('resize', function (e) {bg.onclick(e);}, false)
564
+
565
+ /**
566
+ * This sets the image BG and the DIV as global variables, circumventing repeated calls to document.getElementById()
567
+ */
568
+ RG.showpng_image_bg = bg;
569
+ RG.showpng_image_div = div;
570
+
571
+ setTimeout('RGraph.showpng_image_div.style.opacity = 0.2', 50);
572
+ setTimeout('RGraph.showpng_image_div.style.opacity = 0.4', 100);
573
+ setTimeout('RGraph.showpng_image_div.style.opacity = 0.6', 150);
574
+ setTimeout('RGraph.showpng_image_div.style.opacity = 0.8', 200);
575
+ setTimeout('RGraph.showpng_image_div.style.opacity = 1', 250);
576
+
577
+ setTimeout('RGraph.showpng_image_bg.style.opacity = 0.1', 50);
578
+ setTimeout('RGraph.showpng_image_bg.style.opacity = 0.2', 100);
579
+ setTimeout('RGraph.showpng_image_bg.style.opacity = 0.3', 150);
580
+ setTimeout('RGraph.showpng_image_bg.style.opacity = 0.4', 200);
581
+ setTimeout('RGraph.showpng_image_bg.style.opacity = 0.5', 250);
582
+
583
+
584
+
585
+ img.onclick = function (e)
586
+ {
587
+ if (e.stopPropagation) e.stopPropagation();
588
+ else event.cancelBubble = true;
589
+ }
590
+
591
+ if (event && event.stopPropagation) {
592
+ event.stopPropagation();
593
+ }
594
+ };
595
+
596
+
597
+
598
+
599
+ // End module pattern
600
+ })(window, document);