RGraph.common.resizing.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. // version: 2014-06-26
  2. /**
  3. * o--------------------------------------------------------------------------------o
  4. * | This file is part of the RGraph package. RGraph is Free Software, licensed |
  5. * | under the MIT license - so it's free to use for all purposes. If you want to |
  6. * | donate to help keep the project going then you can do so here: |
  7. * | |
  8. * | http://www.rgraph.net/donate |
  9. * o--------------------------------------------------------------------------------o
  10. */
  11. RGraph = window.RGraph || {isRGraph: true};
  12. // Module pattern
  13. (function (win, doc, undefined)
  14. {
  15. var RG = RGraph,
  16. ua = navigator.userAgent,
  17. ma = Math;
  18. /**
  19. * This function can be used to allow resizing
  20. *
  21. * @param object obj Your graph object
  22. */
  23. RGraph.allowResizing =
  24. RGraph.AllowResizing = function (obj)
  25. {
  26. if (obj.Get('chart.resizable')) {
  27. var canvas = obj.canvas;
  28. var context = obj.context;
  29. var resizeHandle = 15;
  30. RGraph.Resizing.canvas = canvas;
  31. RGraph.Resizing.placeHolders = [];
  32. /**
  33. * Add the original width and height to the canvas
  34. */
  35. if (!canvas.__original_width__ && !canvas.__original_height__) {
  36. canvas.__original_width__ = canvas.width;
  37. canvas.__original_height__ = canvas.height;
  38. }
  39. var adjustX = (typeof(obj.Get('chart.resize.handle.adjust')) == 'object' && typeof(obj.Get('chart.resize.handle.adjust')[0]) == 'number' ? obj.Get('chart.resize.handle.adjust')[0] : 0);
  40. var adjustY = (typeof(obj.Get('chart.resize.handle.adjust')) == 'object' && typeof(obj.Get('chart.resize.handle.adjust')[1]) == 'number' ? obj.Get('chart.resize.handle.adjust')[1] : 0);
  41. /**
  42. * Draw the resize handle
  43. */
  44. var textWidth = context.measureText('Reset').width + 2;
  45. // Draw the white background for the resize handle - OPTIONAL default is rgba(0,0,0,0);
  46. var bgcolor = obj.Get('chart.resize.handle.background');
  47. if (!bgcolor) {
  48. bgcolor = 'rgba(0,0,0,0)';
  49. }
  50. context.beginPath();
  51. context.fillStyle = bgcolor;
  52. context.moveTo(canvas.width - resizeHandle - resizeHandle + adjustX, canvas.height - resizeHandle);
  53. context.rect(canvas.width - resizeHandle - resizeHandle + adjustX, canvas.height - resizeHandle + adjustY, 2 * resizeHandle, resizeHandle);
  54. context.fill();
  55. obj.context.beginPath();
  56. obj.context.strokeStyle = 'gray';
  57. obj.context.fillStyle = 'rgba(0,0,0,0)';
  58. obj.context.lineWidth = 1;
  59. //obj.context.rect(obj.canvas.width - resizeHandle + adjustX, obj.canvas.height - resizeHandle - 2 + adjustY, resizeHandle, resizeHandle + 2);
  60. //obj.context.rect(obj.canvas.width - resizeHandle - textWidth + adjustX, obj.canvas.height - resizeHandle + adjustY, resizeHandle + textWidth, resizeHandle + 2);
  61. // Draw the arrows
  62. // Vertical line
  63. obj.context.moveTo(Math.round(obj.canvas.width - (resizeHandle / 2) + adjustX), obj.canvas.height - resizeHandle + adjustY);
  64. obj.context.lineTo(Math.round(obj.canvas.width - (resizeHandle / 2) + adjustX), obj.canvas.height + adjustY);
  65. // Horizontal line
  66. obj.context.moveTo(obj.canvas.width + adjustX, Math.round(obj.canvas.height - (resizeHandle / 2) + adjustY));
  67. obj.context.lineTo(obj.canvas.width - resizeHandle + adjustX, Math.round(obj.canvas.height - (resizeHandle / 2) + adjustY));
  68. context.stroke();
  69. context.fill();
  70. // Top arrow head
  71. context.fillStyle = 'gray';
  72. context.beginPath();
  73. context.moveTo(canvas.width - (resizeHandle / 2) + adjustX, canvas.height - resizeHandle + adjustY);
  74. context.lineTo(canvas.width - (resizeHandle / 2) + 3 + adjustX, canvas.height - resizeHandle + 3 + adjustY);
  75. context.lineTo(canvas.width - (resizeHandle / 2) - 3 + adjustX, canvas.height - resizeHandle + 3 + adjustY);
  76. context.closePath();
  77. context.fill();
  78. // Bottom arrow head
  79. context.beginPath();
  80. context.moveTo(canvas.width - (resizeHandle / 2) + adjustX, canvas.height + adjustY);
  81. context.lineTo(canvas.width - (resizeHandle / 2) + 3 + adjustX, canvas.height - 3 + adjustY);
  82. context.lineTo(canvas.width - (resizeHandle / 2) - 3 + adjustX, canvas.height - 3 + adjustY);
  83. context.closePath();
  84. context.fill();
  85. // Left arrow head
  86. context.beginPath();
  87. context.moveTo(canvas.width - resizeHandle + adjustX, canvas.height - (resizeHandle / 2) + adjustY);
  88. context.lineTo(canvas.width - resizeHandle + 3 + adjustX, canvas.height - (resizeHandle / 2) + 3 + adjustY);
  89. context.lineTo(canvas.width - resizeHandle + 3 + adjustX, canvas.height - (resizeHandle / 2) - 3 + adjustY);
  90. context.closePath();
  91. context.fill();
  92. // Right arrow head
  93. context.beginPath();
  94. context.moveTo(canvas.width + adjustX, canvas.height - (resizeHandle / 2) + adjustY);
  95. context.lineTo(canvas.width - 3 + adjustX, canvas.height - (resizeHandle / 2) + 3 + adjustY);
  96. context.lineTo(canvas.width - 3 + adjustX, canvas.height - (resizeHandle / 2) - 3 + adjustY);
  97. context.closePath();
  98. context.fill();
  99. // Square at the centre of the arrows
  100. context.beginPath();
  101. context.fillStyle = 'white';
  102. context.moveTo(canvas.width + adjustX, canvas.height - (resizeHandle / 2) + adjustY);
  103. context.rect(canvas.width - (resizeHandle / 2) - 2 + adjustX, canvas.height - (resizeHandle / 2) - 2 + adjustY, 4, 4);
  104. context.rect(canvas.width - (resizeHandle / 2) - 2 + adjustX, canvas.height - (resizeHandle / 2) - 2 + adjustY, 4, 4);
  105. context.stroke();
  106. context.fill();
  107. // Draw the "Reset" button
  108. context.beginPath();
  109. context.fillStyle = 'gray';
  110. context.moveTo(Math.round(canvas.width - resizeHandle - 3 + adjustX), canvas.height - resizeHandle / 2 + adjustY);
  111. context.lineTo(Math.round(canvas.width - resizeHandle - resizeHandle + adjustX), canvas.height - (resizeHandle / 2) + adjustY);
  112. context.lineTo(canvas.width - resizeHandle - resizeHandle + 2 + adjustX, canvas.height - (resizeHandle / 2) - 2 + adjustY);
  113. context.lineTo(canvas.width - resizeHandle - resizeHandle + 2 + adjustX, canvas.height - (resizeHandle / 2) + 2 + adjustY);
  114. context.lineTo(canvas.width - resizeHandle - resizeHandle + adjustX, canvas.height - (resizeHandle / 2) + adjustY);
  115. context.stroke();
  116. context.fill();
  117. context.beginPath();
  118. context.moveTo(Math.round(canvas.width - resizeHandle - resizeHandle - 1 + adjustX), canvas.height - (resizeHandle / 2) - 3 + adjustY);
  119. context.lineTo(Math.round(canvas.width - resizeHandle - resizeHandle - 1 + adjustX), canvas.height - (resizeHandle / 2) + 3 + adjustY);
  120. context.stroke();
  121. context.fill();
  122. var window_onmousemove = function (e)
  123. {
  124. e = RGraph.FixEventObject(e);
  125. var canvas = RGraph.Resizing.canvas;
  126. var newWidth = RGraph.Resizing.originalw - (RGraph.Resizing.originalx - e.pageX);// - 5
  127. var newHeight = RGraph.Resizing.originalh - (RGraph.Resizing.originaly - e.pageY);// - 5
  128. if (RGraph.Resizing.mousedown) {
  129. if (newWidth > (canvas.__original_width__ / 2)) RGraph.Resizing.div.style.width = newWidth + 'px';
  130. if (newHeight > (canvas.__original_height__ / 2)) RGraph.Resizing.div.style.height = newHeight + 'px';
  131. RGraph.FireCustomEvent(canvas.__object__, 'onresize');
  132. }
  133. }
  134. // Install the function as an event listener - but only once
  135. if (typeof(canvas.rgraph_resize_window_mousemove_listener_installed) != 'boolean') {
  136. window.addEventListener('mousemove', window_onmousemove, false);
  137. canvas.rgraph_resize_window_mousemove_listener_installed = true;
  138. }
  139. /**
  140. * The window onmouseup function
  141. */
  142. var MouseupFunc = function (e)
  143. {
  144. if (!RGraph.Resizing || !RGraph.Resizing.div || !RGraph.Resizing.mousedown) {
  145. return;
  146. }
  147. if (RGraph.Resizing.div) {
  148. var div = RGraph.Resizing.div;
  149. var canvas = div.__canvas__;
  150. var coords = RGraph.getCanvasXY(div.__canvas__);
  151. var parentNode = canvas.parentNode;
  152. if (canvas.style.position != 'absolute') {
  153. // Create a DIV to go in the canvases place
  154. var placeHolderDIV = document.createElement('DIV');
  155. placeHolderDIV.style.width = RGraph.Resizing.originalw + 'px';
  156. placeHolderDIV.style.height = RGraph.Resizing.originalh + 'px';
  157. //placeHolderDIV.style.backgroundColor = 'red';
  158. placeHolderDIV.style.display = 'inline-block'; // Added 5th Nov 2010
  159. placeHolderDIV.style.position = canvas.style.position;
  160. placeHolderDIV.style.left = canvas.style.left;
  161. placeHolderDIV.style.top = canvas.style.top;
  162. placeHolderDIV.style.cssFloat = canvas.style.cssFloat;
  163. parentNode.insertBefore(placeHolderDIV, canvas);
  164. }
  165. // Now set the canvas to be positioned absolutely
  166. canvas.style.backgroundColor = 'white';
  167. canvas.style.position = 'absolute';
  168. canvas.style.border = '1px dashed gray';
  169. canvas.style.left = (RGraph.Resizing.originalCanvasX - 1) + 'px';
  170. canvas.style.top = (RGraph.Resizing.originalCanvasY - 1) + 'px';
  171. /**
  172. * Set the dimensions of the canvas using the HTML attributes
  173. */
  174. canvas.width = parseInt(div.style.width);
  175. canvas.height = parseInt(div.style.height);
  176. /**
  177. * Because resizing the canvas resets any tranformation - the antialias fix needs to be reapplied.
  178. */
  179. canvas.getContext('2d').translate(0.5,0.5);
  180. /**
  181. * Reset the gradient parsing status by setting all of the color values back to their original
  182. * values before Draw was first called
  183. */
  184. var objects = RGraph.ObjectRegistry.getObjectsByCanvasID(canvas.id);
  185. for (var i=0,len=objects.length; i<len; i+=1) {
  186. RGraph.resetColorsToOriginalValues(objects[i]);
  187. }
  188. /**
  189. * Kill the background cache
  190. */
  191. RGraph.cache = [];
  192. /**
  193. * Fire the onresize event
  194. */
  195. RGraph.FireCustomEvent(canvas.__object__, 'onresizebeforedraw');
  196. RGraph.RedrawCanvas(canvas);
  197. // Get rid of transparent semi-opaque DIV
  198. RGraph.Resizing.mousedown = false;
  199. div.style.display = 'none';
  200. document.body.removeChild(div);
  201. }
  202. /**
  203. * If there is zoom enabled in thumbnail mode, lose the zoom image
  204. */
  205. if (RGraph.Registry.Get('chart.zoomed.div') || RGraph.Registry.Get('chart.zoomed.img')) {
  206. RGraph.Registry.Set('chart.zoomed.div', null);
  207. RGraph.Registry.Set('chart.zoomed.img', null);
  208. }
  209. /**
  210. * Fire the onresize event
  211. */
  212. RGraph.FireCustomEvent(canvas.__object__, 'onresizeend');
  213. }
  214. var window_onmouseup = MouseupFunc;
  215. // Install the function as an event listener - but only once
  216. if (typeof(canvas.rgraph_resize_window_mouseup_listener_installed) != 'boolean') {
  217. window.addEventListener('mouseup', window_onmouseup, false);
  218. canvas.rgraph_resize_window_mouseup_listener_installed = true;
  219. }
  220. var canvas_onmousemove = function (e)
  221. {
  222. e = RGraph.FixEventObject(e);
  223. var coords = RGraph.getMouseXY(e);
  224. var obj = e.target.__object__;
  225. var canvas = e.target;
  226. var context = canvas.getContext('2d');
  227. var cursor = canvas.style.cursor;
  228. // Save the original cursor
  229. if (!RGraph.Resizing.original_cursor) {
  230. RGraph.Resizing.original_cursor = cursor;
  231. }
  232. if ( (coords[0] > (canvas.width - resizeHandle)
  233. && coords[0] < canvas.width
  234. && coords[1] > (canvas.height - resizeHandle)
  235. && coords[1] < canvas.height)) {
  236. canvas.style.cursor = 'move';
  237. } else if ( coords[0] > (canvas.width - resizeHandle - resizeHandle)
  238. && coords[0] < canvas.width - resizeHandle
  239. && coords[1] > (canvas.height - resizeHandle)
  240. && coords[1] < canvas.height) {
  241. canvas.style.cursor = 'pointer';
  242. } else {
  243. if (RGraph.Resizing.original_cursor) {
  244. canvas.style.cursor = RGraph.Resizing.original_cursor;
  245. RGraph.Resizing.original_cursor = null;
  246. } else {
  247. canvas.style.cursor = 'default';
  248. }
  249. }
  250. };
  251. // Install the function as an event listener - but only once
  252. if (typeof(canvas.rgraph_resize_mousemove_listener_installed) != 'boolean') {
  253. canvas.addEventListener('mousemove', canvas_onmousemove, false);
  254. canvas.rgraph_resize_mousemove_listener_installed = true;
  255. }
  256. var canvas_onmouseout = function (e)
  257. {
  258. e.target.style.cursor = 'default';
  259. e.target.title = '';
  260. };
  261. // Install the function as an event listener - but only once
  262. if (typeof(canvas.rgraph_resize_mouseout_listener_installed) != 'boolean') {
  263. canvas.addEventListener('mouseout', canvas_onmouseout, false);
  264. canvas.rgraph_resize_mouseout_listener_installed = true;
  265. }
  266. var canvas_onmousedown = function (e)
  267. {
  268. e = RGraph.FixEventObject(e);
  269. var coords = RGraph.getMouseXY(e);
  270. var canvasCoords = RGraph.getCanvasXY(e.target);
  271. var canvas = e.target;
  272. if ( coords[0] > (obj.canvas.width - resizeHandle)
  273. && coords[0] < obj.canvas.width
  274. && coords[1] > (obj.canvas.height - resizeHandle)
  275. && coords[1] < obj.canvas.height) {
  276. RGraph.FireCustomEvent(obj, 'onresizebegin');
  277. // Save the existing border
  278. if (canvas.__original_css_border__ == null) {
  279. canvas.__original_css_border__ = canvas.style.border;
  280. }
  281. RGraph.Resizing.mousedown = true;
  282. /**
  283. * Create the semi-opaque DIV
  284. */
  285. var div = document.createElement('DIV');
  286. div.style.position = 'absolute';
  287. div.style.left = canvasCoords[0] + 'px';
  288. div.style.top = canvasCoords[1] + 'px';
  289. div.style.width = canvas.width + 'px';
  290. div.style.height = canvas.height + 'px';
  291. div.style.border = '1px dotted black';
  292. div.style.backgroundColor = 'gray';
  293. div.style.opacity = 0.5;
  294. div.__canvas__ = e.target;
  295. document.body.appendChild(div);
  296. RGraph.Resizing.div = div;
  297. RGraph.Resizing.placeHolders.push(div);
  298. // Hide the previous resize indicator layers. This is only necessary it seems for the Meter chart
  299. for (var i=0; i<(RGraph.Resizing.placeHolders.length - 1); ++i) {
  300. RGraph.Resizing.placeHolders[i].style.display = 'none';
  301. }
  302. // This is a repetition of the window.onmouseup function (No need to use DOM2 here)
  303. div.onmouseup = function (e)
  304. {
  305. MouseupFunc(e);
  306. }
  307. // No need to use DOM2 here
  308. RGraph.Resizing.div.onmouseover = function (e)
  309. {
  310. e = RGraph.FixEventObject(e);
  311. e.stopPropagation();
  312. }
  313. // The mouse
  314. RGraph.Resizing.originalx = e.pageX;
  315. RGraph.Resizing.originaly = e.pageY;
  316. RGraph.Resizing.originalw = obj.canvas.width;
  317. RGraph.Resizing.originalh = obj.canvas.height;
  318. RGraph.Resizing.originalCanvasX = RGraph.getCanvasXY(obj.canvas)[0];
  319. RGraph.Resizing.originalCanvasY = RGraph.getCanvasXY(obj.canvas)[1];
  320. }
  321. /**
  322. * This facilitates the reset button
  323. */
  324. if ( coords[0] > (canvas.width - resizeHandle - resizeHandle)
  325. && coords[0] < canvas.width - resizeHandle
  326. && coords[1] > (canvas.height - resizeHandle)
  327. && coords[1] < canvas.height) {
  328. /**
  329. * Fire the onresizebegin event
  330. */
  331. RGraph.FireCustomEvent(canvas.__object__, 'onresizebegin');
  332. // Restore the original width and height
  333. canvas.width = canvas.__original_width__;
  334. canvas.height = canvas.__original_height__;
  335. // Lose the border
  336. canvas.style.border = canvas.__original_css_border__;
  337. //canvas.__original_css_border__ = null;
  338. // Add 1 pixel to the top/left because the border is going
  339. canvas.style.left = (parseInt(canvas.style.left)) + 'px';
  340. canvas.style.top = (parseInt(canvas.style.top)) + 'px';
  341. /**
  342. * Because resetting the canvas resizes it - and so loses any translation - need to reapply the
  343. * antialiasing translation
  344. */
  345. canvas.getContext('2d').translate(0.5,0.5);
  346. RGraph.FireCustomEvent(canvas.__object__, 'onresizebeforedraw');
  347. // Since gradients are pre-parsed colors - this resets the colors to what they were
  348. // before the parsing.
  349. var objects = RGraph.ObjectRegistry.getObjectsByCanvasID(canvas.id);
  350. for (var i=0; i<objects.length; i+=1) {
  351. RGraph.resetColorsToOriginalValues(objects[i]);
  352. }
  353. /**
  354. * Redraw the canvas
  355. */
  356. RGraph.Redraw();
  357. /**
  358. * Set the width and height on the DIV
  359. */
  360. if (RGraph.Resizing.div) {
  361. RGraph.Resizing.div.style.width = canvas.__original_width__ + 'px';
  362. RGraph.Resizing.div.style.height = canvas.__original_height__ + 'px';
  363. }
  364. /**
  365. * Fire the resize event
  366. */
  367. RGraph.FireCustomEvent(canvas.__object__, 'onresize');
  368. RGraph.FireCustomEvent(canvas.__object__, 'onresizeend');
  369. }
  370. };
  371. // Install the function as an event listener - but only once
  372. if (typeof(canvas.rgraph_resize_mousedown_listener_installed) != 'boolean') {
  373. canvas.addEventListener('mousedown', canvas_onmousedown, false);
  374. canvas.rgraph_resize_mousedown_listener_installed = true;
  375. }
  376. /**
  377. * This function facilitates the reset button
  378. *
  379. * NOTE: 31st December 2010 - doesn't appear to be being used any more
  380. */
  381. /*
  382. canvas.onclick = function (e)
  383. {
  384. var coords = RGraph.getMouseXY(e);
  385. var canvas = e.target;
  386. if ( coords[0] > (canvas.width - resizeHandle - resizeHandle)
  387. && coords[0] < canvas.width - resizeHandle
  388. && coords[1] > (canvas.height - resizeHandle)
  389. && coords[1] < canvas.height) {
  390. // Restore the original width and height
  391. canvas.width = canvas.__original_width__;
  392. canvas.height = canvas.__original_height__;
  393. // Lose the border
  394. canvas.style.border = '';
  395. // Add 1 pixel to the top/left because the border is going
  396. canvas.style.left = (parseInt(canvas.style.left) + 1) + 'px';
  397. canvas.style.top = (parseInt(canvas.style.top) + 1) + 'px';
  398. // Fire the onresizebeforedraw event
  399. RGraph.FireCustomEvent(canvas.__object__, 'onresizebeforedraw');
  400. // Redraw the canvas
  401. canvas.__object__.Draw();
  402. // Set the width and height on the DIV
  403. RGraph.Resizing.div.style.width = canvas.__original_width__ + 'px';
  404. RGraph.Resizing.div.style.height = canvas.__original_height__ + 'px';
  405. // Fire the resize event
  406. RGraph.FireCustomEvent(canvas.__object__, 'onresize');
  407. }
  408. }
  409. */
  410. }
  411. };
  412. // End module pattern
  413. })(window, document);