RGraph.common.annotate.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /**
  2. * o------------------------------------------------------------------------------o
  3. * | This file is part of the RGraph package - you can learn more at: |
  4. * | |
  5. * | http://www.rgraph.net |
  6. * | |
  7. * | This package is licensed under the RGraph license. For all kinds of business |
  8. * | purposes there is a small one-time licensing fee to pay and for non |
  9. * | commercial purposes it is free to use. You can read the full license here: |
  10. * | |
  11. * | http://www.rgraph.net/license |
  12. * o------------------------------------------------------------------------------o
  13. */
  14. if (typeof(RGraph) == 'undefined') RGraph = {isRGraph:true,type:'common'};
  15. /**
  16. * This installs some event handlers
  17. *
  18. * Checking the RGraph.Annotate flag means the annotate code only runs once
  19. */
  20. RGraph.Annotating_canvas_onmousedown = function (e)
  21. {
  22. if (e.button == 0) {
  23. e.target.__object__.Set('chart.mousedown', true);
  24. // Get the object from the canvas. Annotating must be enabled on the
  25. // last object defined
  26. var obj = e.target.__object__;
  27. // This starts the annotating "path" and set the color
  28. obj.context.beginPath();
  29. obj.context.strokeStyle = obj.Get('chart.annotate.color');
  30. obj.context.lineWidth = 1;
  31. var mouseXY = RGraph.getMouseXY(e);
  32. var mouseX = mouseXY[0];
  33. var mouseY = mouseXY[1];
  34. // Clear the annotation recording
  35. RGraph.Registry.Set('annotate.actions', [obj.Get('chart.annotate.color')]);
  36. // This sets the initial X/Y position
  37. obj.context.moveTo(mouseX, mouseY);
  38. RGraph.Registry.Set('annotate.last.coordinates', [mouseX,mouseY]);
  39. RGraph.Registry.Set('started.annotating', false);
  40. RGraph.Registry.Set('chart.annotating', obj);
  41. // Fire the onannotatebegin event.
  42. RGraph.FireCustomEvent(obj, 'onannotatebegin');
  43. }
  44. return false;
  45. }
  46. /**
  47. * This cancels annotating for ALL canvases
  48. */
  49. RGraph.Annotating_window_onmouseup = function (e)
  50. {
  51. var obj = RGraph.Registry.Get('chart.annotating');
  52. if (e.button != 0 || !obj) {
  53. return;
  54. }
  55. // This cancels annotating on ALL canvas tags on the page
  56. var tags = document.getElementsByTagName('canvas');
  57. for (var i=0; i<tags.length; ++i) {
  58. if (tags[i].__object__) {
  59. tags[i].__object__.Set('chart.mousedown', false);
  60. }
  61. }
  62. // Store the annotations in browser storage if it's available
  63. if (RGraph.Registry.Get('annotate.actions') && RGraph.Registry.Get('annotate.actions').length > 0 && window.localStorage) {
  64. var id = '__rgraph_annotations_' + e.target.id + '__';
  65. var annotations = window.localStorage[id] ? window.localStorage[id] + '|' : '';
  66. annotations += RGraph.Registry.Get('annotate.actions');
  67. // Store the annotations information in HTML5 browser storage here
  68. window.localStorage[id] = annotations;
  69. }
  70. // Clear the recorded annotations
  71. RGraph.Registry.Set('annotate.actions', []);
  72. // Fire the annotate event
  73. RGraph.FireCustomEvent(obj, 'onannotateend');
  74. }
  75. /**
  76. * The canvas onmousemove function
  77. */
  78. RGraph.Annotating_canvas_onmousemove = function (e)
  79. {
  80. var obj = e.target.__object__;
  81. var mouseXY = RGraph.getMouseXY(e);
  82. var mouseX = mouseXY[0];
  83. var mouseY = mouseXY[1];
  84. var lastXY = RGraph.Registry.Get('annotate.last.coordinates');
  85. if (obj.Get('chart.mousedown')) {
  86. obj.context.beginPath();
  87. if (!lastXY) {
  88. obj.context.moveTo(mouseX, mouseY)
  89. } else {
  90. obj.context.strokeStyle = obj.properties['chart.annotate.color'];
  91. obj.context.moveTo(lastXY[0], lastXY[1]);
  92. obj.context.lineTo(mouseX, mouseY);
  93. }
  94. RGraph.Registry.Set('annotate.actions', RGraph.Registry.Get('annotate.actions') + '|' + mouseX + ',' + mouseY);
  95. RGraph.Registry.Set('annotate.last.coordinates', [mouseX,mouseY]);
  96. RGraph.FireCustomEvent(obj, 'onannotate');
  97. obj.context.stroke();
  98. }
  99. }
  100. /**
  101. * Shows the mini palette used for annotations
  102. *
  103. * @param object e The event object
  104. */
  105. RGraph.ShowPalette =
  106. RGraph.Showpalette = function (e)
  107. {
  108. var isSafari = navigator.userAgent.indexOf('Safari') ? true : false;
  109. e = RGraph.FixEventObject(e);
  110. var canvas = e.target.parentNode.__canvas__;
  111. var context = canvas.getContext('2d');
  112. var obj = canvas.__object__;
  113. var div = document.createElement('DIV');
  114. var coords = RGraph.getMouseXY(e);
  115. div.__object__ = obj; // The graph object
  116. div.className = 'RGraph_palette';
  117. div.style.position = 'absolute';
  118. div.style.backgroundColor = 'white';
  119. div.style.border = '1px solid black';
  120. div.style.left = 0;
  121. div.style.top = 0;
  122. div.style.padding = '3px';
  123. div.style.opacity = 0;
  124. div.style.boxShadow = 'rgba(96,96,96,0.5) 3px 3px 3px';
  125. div.style.WebkitBoxShadow = 'rgba(96,96,96,0.5) 3px 3px 3px';
  126. div.style.MozBoxShadow = 'rgba(96,96,96,0.5) 3px 3px 3px';
  127. // MUST use named colors that are capitalised
  128. var colors = ['Black', 'Red', 'Magenta','Black','Yellow','Green','Orange', 'White', 'Cyan'];
  129. // Add the colors to the palette
  130. for (var i=0,len=colors.length; i<len; i+=1) {
  131. var div2 = document.createElement('DIV');
  132. div2.cssClass = 'RGraph_palette_color';
  133. div2.style.fontSize = '12pt';
  134. div2.style.cursor = 'pointer';
  135. div2.style.padding = '1px';
  136. div2.style.paddingRight = '10px';
  137. var span = document.createElement('SPAN');
  138. span.style.display = 'inline-block';
  139. span.style.marginRight = '3px';
  140. span.style.width = '17px';
  141. span.style.height = '17px';
  142. span.style.backgroundColor = colors[i];
  143. div2.appendChild(span);
  144. div2.innerHTML += colors[i];
  145. div2.onmouseover = function ()
  146. {
  147. this.style.backgroundColor = '#eee';
  148. }
  149. div2.onmouseout = function ()
  150. {
  151. this.style.backgroundColor = '';
  152. }
  153. div2.onclick = function (e)
  154. {
  155. var color = this.childNodes[0].style.backgroundColor;
  156. obj.Set('chart.annotate.color', color);
  157. }
  158. div.appendChild(div2);
  159. }
  160. document.body.appendChild(div);
  161. /**
  162. * Now the div has been added to the document, move it up and left
  163. */
  164. div.style.left = e.pageX + 'px';
  165. div.style.top = e.pageY + 'px';
  166. /**
  167. * Chang the position if the cursor is near the right edge of the browser window
  168. */
  169. if ((e.pageX + (div.offsetWidth + 5) ) > document.body.offsetWidth) {
  170. div.style.left = (e.pageX - div.offsetWidth) + 'px';
  171. }
  172. /**
  173. * Store the palette div in the registry
  174. */
  175. RGraph.Registry.Set('palette', div);
  176. setTimeout("RGraph.Registry.Get('palette').style.opacity = 0.2", 50);
  177. setTimeout("RGraph.Registry.Get('palette').style.opacity = 0.4", 100);
  178. setTimeout("RGraph.Registry.Get('palette').style.opacity = 0.6", 150);
  179. setTimeout("RGraph.Registry.Get('palette').style.opacity = 0.8", 200);
  180. setTimeout("RGraph.Registry.Get('palette').style.opacity = 1", 250);
  181. RGraph.HideContext();
  182. window.onclick = function ()
  183. {
  184. RGraph.HidePalette();
  185. }
  186. // Should this be here? Yes. This function is being used as an event handler.
  187. e.stopPropagation();
  188. return false;
  189. }
  190. /**
  191. * Clears any annotation data from global storage
  192. *
  193. * @param object canvas The canvas tag object
  194. */
  195. RGraph.ClearAnnotations = function (canvas)
  196. {
  197. /**
  198. * For BC the argument can also be the ID of the canvas
  199. */
  200. if (typeof(canvas) == 'string') {
  201. var id = canvas;
  202. canvas = document.getElementById(id);
  203. } else {
  204. var id = canvas.id
  205. }
  206. var obj = canvas.__object__;
  207. if (window.localStorage && window.localStorage['__rgraph_annotations_' + id + '__'] && window.localStorage['__rgraph_annotations_' + id + '__'].length) {
  208. window.localStorage['__rgraph_annotations_' + id + '__'] = [];
  209. RGraph.FireCustomEvent(obj, 'onannotateclear');
  210. }
  211. }
  212. /**
  213. * Replays stored annotations
  214. *
  215. * @param object obj The graph object
  216. */
  217. RGraph.ReplayAnnotations = function (obj)
  218. {
  219. // Check for support
  220. if (!window.localStorage) {
  221. return;
  222. }
  223. var context = obj.context;
  224. var annotations = window.localStorage['__rgraph_annotations_' + obj.id + '__'];
  225. var i, len, move, coords;
  226. context.beginPath();
  227. context.lineWidth = 2;
  228. if (annotations && annotations.length) {
  229. annotations = annotations.split('|');
  230. } else {
  231. return;
  232. }
  233. for (i=0,len=annotations.length; i<len; ++i) {
  234. // If the element of the array is a color - finish the path,
  235. // stroke it and start a new one
  236. if (annotations[i].match(/^[a-z]+$/)) {
  237. context.stroke();
  238. context.beginPath();
  239. context.strokeStyle = annotations[i];
  240. move = true;
  241. continue;
  242. }
  243. coords = annotations[i].split(',');
  244. coords[0] = Number(coords[0]);
  245. coords[1] = Number(coords[1]);
  246. if (move) {
  247. context.moveTo(coords[0], coords[1]);
  248. move = false;
  249. } else {
  250. context.lineTo(coords[0], coords[1]);
  251. }
  252. }
  253. context.stroke();
  254. }
  255. window.addEventListener('load', function (e)
  256. {
  257. // This delay is necessary to allow the window.onload event listener to run
  258. setTimeout(function ()
  259. {
  260. var tags = document.getElementsByTagName('canvas');
  261. for (var i=0; i<tags.length; ++i) {
  262. if (tags[i].__object__ && tags[i].__object__.isRGraph && tags[i].__object__.Get('chart.annotatable')) {
  263. RGraph.ReplayAnnotations(tags[i].__object__);
  264. }
  265. }
  266. }, 100); // This delay is sufficient to wait before replaying the annotations
  267. }, false);