PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/files/rgraph/20120601/libraries/RGraph.common.tooltips.js

https://gitlab.com/Mirros/jsdelivr
JavaScript | 653 lines | 242 code | 96 blank | 315 comment | 75 complexity | 53c38c58c05e81a6991ecc2c99192e1b MD5 | raw file
  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.txt |
  12. * o------------------------------------------------------------------------------o
  13. */
  14. if (typeof(RGraph) == 'undefined') RGraph = {isRGraph:true,type:'common'};
  15. /**
  16. * This is used in two functions, hence it's here
  17. */
  18. RGraph.Highlight = {};
  19. RGraph.tooltips = {};
  20. RGraph.tooltips.padding = '3px';
  21. RGraph.tooltips.font_face = 'Tahoma';
  22. RGraph.tooltips.font_size = '10pt';
  23. /**
  24. * Shows a tooltip next to the mouse pointer
  25. *
  26. * @param canvas object The canvas element object
  27. * @param text string The tooltip text
  28. * @param int x The X position that the tooltip should appear at. Combined with the canvases offsetLeft
  29. * gives the absolute X position
  30. * @param int y The Y position the tooltip should appear at. Combined with the canvases offsetTop
  31. * gives the absolute Y position
  32. * @param int idx The index of the tooltip in the graph objects tooltip array
  33. * @param object e The event object
  34. */
  35. RGraph.Tooltip = function (obj, text, x, y, idx, e)
  36. {
  37. /**
  38. * chart.tooltip.override allows you to totally take control of rendering the tooltip yourself
  39. */
  40. if (typeof(obj.Get('chart.tooltips.override')) == 'function') {
  41. return obj.Get('chart.tooltips.override')(obj, text, x, y, idx);
  42. }
  43. /**
  44. * Save the X/Y coords
  45. */
  46. var originalX = x;
  47. var originalY = y;
  48. /**
  49. * This facilitates the "id:xxx" format
  50. */
  51. text = RGraph.getTooltipTextFromDIV(text);
  52. /**
  53. * First clear any exising timers
  54. */
  55. var timers = RGraph.Registry.Get('chart.tooltip.timers');
  56. if (timers && timers.length) {
  57. for (i=0; i<timers.length; ++i) {
  58. clearTimeout(timers[i]);
  59. }
  60. }
  61. RGraph.Registry.Set('chart.tooltip.timers', []);
  62. /**
  63. * Hide the context menu if it's currently shown
  64. */
  65. if (obj.Get('chart.contextmenu')) {
  66. RGraph.HideContext();
  67. }
  68. var effect = obj.Get('chart.tooltips.effect').toLowerCase();
  69. /**
  70. * Show a tool tip
  71. */
  72. var tooltipObj = document.createElement('DIV');
  73. tooltipObj.className = obj.Get('chart.tooltips.css.class');
  74. tooltipObj.style.display = 'none';
  75. tooltipObj.style.position = 'absolute';
  76. tooltipObj.style.left = 0;
  77. tooltipObj.style.top = 0;
  78. tooltipObj.style.backgroundColor = 'rgb(255,255,239)';
  79. tooltipObj.style.color = 'black';
  80. if (!document.all) tooltipObj.style.border = '';
  81. tooltipObj.style.visibility = 'visible';
  82. tooltipObj.style.paddingLeft = RGraph.tooltips.padding;
  83. tooltipObj.style.paddingRight = RGraph.tooltips.padding;
  84. tooltipObj.style.fontFamily = RGraph.tooltips.font_face;
  85. tooltipObj.style.fontSize = RGraph.tooltips.font_size;
  86. tooltipObj.style.zIndex = 3;
  87. // Only apply a border if there's content
  88. if (RGraph.trim(text).length > 0) {
  89. tooltipObj.style.border = '1px #bbb solid';
  90. }
  91. tooltipObj.style.borderRadius = '5px';
  92. tooltipObj.style.MozBorderRadius = '5px';
  93. tooltipObj.style.WebkitBorderRadius = '5px';
  94. tooltipObj.style.WebkitBoxShadow = 'rgba(96,96,96,0.5) 0 0 15px';
  95. tooltipObj.style.MozBoxShadow = 'rgba(96,96,96,0.5) 0 0 15px';
  96. tooltipObj.style.boxShadow = 'rgba(96,96,96,0.5) 0 0 15px';
  97. tooltipObj.style.filter = 'progid:DXImageTransform.Microsoft.Shadow(color=#666666,direction=135)';
  98. tooltipObj.style.opacity = 0;
  99. //tooltipObj.style.overflow = 'hidden';
  100. tooltipObj.innerHTML = text;
  101. tooltipObj.__text__ = text; // This is set because the innerHTML can change when it's set
  102. tooltipObj.__canvas__ = obj.canvas;
  103. tooltipObj.style.display = 'inline';
  104. tooltipObj.id = '__rgraph_tooltip_' + obj.canvas.id + '_' + obj.uid + '_'+ idx;
  105. tooltipObj.__event__ = obj.Get('chart.tooltips.event') || 'click';
  106. tooltipObj.__object__ = obj;
  107. if (typeof(idx) == 'number') {
  108. tooltipObj.__index__ = idx;
  109. origIdx = idx;
  110. }
  111. if (obj.type == 'line' || obj.type == 'radar') {
  112. for (var ds=0; ds<obj.data.length; ++ds) {
  113. if (idx >= obj.data[ds].length) {
  114. idx -= obj.data[ds].length;
  115. } else {
  116. break;
  117. }
  118. }
  119. tooltipObj.__dataset__ = ds;
  120. tooltipObj.__index2__ = idx;
  121. }
  122. document.body.appendChild(tooltipObj);
  123. var width = tooltipObj.offsetWidth;
  124. var height = tooltipObj.offsetHeight;
  125. //if ((y - height - 2) > 0) {
  126. // y = y - height - 2;
  127. //} else {
  128. // y = y + 2;
  129. //}
  130. /**
  131. * Set the width on the tooltip so it doesn't resize if the window is resized
  132. */
  133. tooltipObj.style.width = width + 'px';
  134. //tooltipObj.style.height = 0; // Initially set the tooltip height to nothing
  135. /**
  136. * If the mouse is towards the right of the browser window and the tooltip would go outside of the window,
  137. * move it left
  138. *
  139. if ( (x + width) > document.body.offsetWidth ) {
  140. x = x - width - 7;
  141. var placementLeft = true;
  142. if (obj.Get('chart.tooltips.effect') == 'none') {
  143. x = x - 3;
  144. }
  145. tooltipObj.style.left = x + 'px';
  146. tooltipObj.style.top = y + 'px';
  147. } else {
  148. x += 5;
  149. tooltipObj.style.left = x + 'px';
  150. tooltipObj.style.top = y + 'px';
  151. }*/
  152. tooltipObj.style.top = (y - height - 2) + 'px';
  153. /**
  154. * If the function exists call the object specific tooltip positioning function
  155. */
  156. if (typeof(obj.positionTooltip) == 'function') {
  157. if (tooltipObj.innerHTML.length > 0) {
  158. obj.positionTooltip(obj, x, y, tooltipObj, origIdx ? origIdx : idx);
  159. if (obj.Get('chart.tooltips.coords.page')) {
  160. tooltipObj.style.left = e.pageX - (width / 2) - 4.25 + 'px';
  161. tooltipObj.style.top = e.pageY - height - 7 + 'px';
  162. document.getElementById('__rgraph_tooltip_pointer__').style.left = (parseInt(tooltipObj.offsetWidth) / 2) - 8.5 + 'px';
  163. }
  164. }
  165. }
  166. if (effect == 'fade' || effect == 'expand' || effect == 'contract' || effect == 'snap') {
  167. setTimeout(function () {tooltipObj.style.opacity = 0.1;}, 25);
  168. setTimeout(function () {tooltipObj.style.opacity = 0.2;}, 50);
  169. setTimeout(function () {tooltipObj.style.opacity = 0.3;}, 75);
  170. setTimeout(function () {tooltipObj.style.opacity = 0.4;}, 100);
  171. setTimeout(function () {tooltipObj.style.opacity = 0.5;}, 125);
  172. setTimeout(function () {tooltipObj.style.opacity = 0.6;}, 150);
  173. setTimeout(function () {tooltipObj.style.opacity = 0.7;}, 175);
  174. setTimeout(function () {tooltipObj.style.opacity = 0.8;}, 200);
  175. setTimeout(function () {tooltipObj.style.opacity = 0.9;}, 225);
  176. if (effect == 'expand' || effect == 'contract' || effect == 'snap') {
  177. console.log('[RGRAPH] The snap, expand and contract tooltip effects are deprecated. Available effects now are fade and none');
  178. }
  179. }
  180. setTimeout("if (RGraph.Registry.Get('chart.tooltip')) { RGraph.Registry.Get('chart.tooltip').style.opacity = 1;}", effect == 'none' ? 50 : 250);
  181. /**
  182. * If the tooltip it self is clicked, cancel it
  183. */
  184. tooltipObj.onmousedown = function (e){e.stopPropagation();}
  185. tooltipObj.onmouseup = function (e){e.stopPropagation();}
  186. tooltipObj.onclick = function (e){if (e.button == 0) {e.stopPropagation();}}
  187. /**
  188. * Keep a reference to the tooltip in the registry
  189. */
  190. RGraph.Registry.Set('chart.tooltip', tooltipObj);
  191. /**
  192. * Fire the tooltip event
  193. */
  194. RGraph.FireCustomEvent(obj, 'ontooltip');
  195. }
  196. /**
  197. *
  198. */
  199. RGraph.getTooltipTextFromDIV = function (text)
  200. {
  201. // This regex is duplicated firher down on roughly line 888
  202. var result = /^id:(.*)/.exec(text);
  203. if (result && result[1] && document.getElementById(result[1])) {
  204. text = document.getElementById(result[1]).innerHTML;
  205. } else if (result && result[1]) {
  206. text = '';
  207. }
  208. return text;
  209. }
  210. /**
  211. *
  212. */
  213. RGraph.getTooltipWidth = function (text, obj)
  214. {
  215. var div = document.createElement('DIV');
  216. div.className = obj.Get('chart.tooltips.css.class');
  217. div.style.paddingLeft = RGraph.tooltips.padding;
  218. div.style.paddingRight = RGraph.tooltips.padding;
  219. div.style.fontFamily = RGraph.tooltips.font_face;
  220. div.style.fontSize = RGraph.tooltips.font_size;
  221. div.style.visibility = 'hidden';
  222. div.style.position = 'absolute';
  223. div.style.top = '300px';
  224. div.style.left = 0;
  225. div.style.display = 'inline';
  226. div.innerHTML = RGraph.getTooltipTextFromDIV(text);
  227. document.body.appendChild(div);
  228. return div.offsetWidth;
  229. }
  230. /**
  231. * Hides the currently shown tooltip
  232. */
  233. RGraph.HideTooltip = function ()
  234. {
  235. var tooltip = RGraph.Registry.Get('chart.tooltip');
  236. if (tooltip) {
  237. tooltip.parentNode.removeChild(tooltip);
  238. tooltip.style.display = 'none';
  239. tooltip.style.visibility = 'hidden';
  240. RGraph.Registry.Set('chart.tooltip', null);
  241. }
  242. }
  243. /**
  244. * This installs the window mousedown event listener. It clears any highlight that may
  245. * be present.
  246. *
  247. * @param object obj The chart object
  248. *
  249. RGraph.InstallWindowMousedownTooltipListener = function (obj)
  250. {
  251. if (RGraph.Registry.Get('__rgraph_event_listeners__')['window_mousedown']) {
  252. return;
  253. }
  254. // When the canvas is cleared, reset this flag so that the event listener is installed again
  255. RGraph.AddCustomEventListener(obj, 'onclear', function (obj) {RGraph.Registry.Get('__rgraph_event_listeners__')['window_mousedown'] = false;})
  256. // NOTE: Global on purpose
  257. rgraph_window_mousedown = function (e)
  258. {
  259. if (RGraph.Registry.Get('chart.tooltip')) {
  260. var obj = RGraph.Registry.Get('chart.tooltip').__object__;
  261. var canvas = obj.canvas;
  262. /**
  263. * Get rid of the tooltip and redraw all canvases on the page
  264. *
  265. RGraph.HideTooltip();
  266. /**
  267. * No need to clear if highlighting is disabled
  268. *
  269. * TODO Really, need to check ALL of the pertinent objects that
  270. * are drawing on the canvas using the ObjectRegistry -
  271. * ie RGraph.ObjectRegistry.getObjectsByCanvasID()
  272. *
  273. if (obj.Get('chart.tooltips.highlight')) {
  274. RGraph.RedrawCanvas(canvas);
  275. }
  276. }
  277. }
  278. window.addEventListener('mousedown', rgraph_window_mousedown, false);
  279. RGraph.AddEventListener('window_' + obj.id, 'mousedown', rgraph_window_mousedown);
  280. }
  281. */
  282. /**
  283. * This installs the canvas mouseup event listener. This is the function that
  284. * actually shows the appropriate (if any) tooltip.
  285. *
  286. * @param object obj The chart object
  287. *
  288. RGraph.InstallCanvasMouseupTooltipListener = function (obj)
  289. {
  290. if (RGraph.Registry.Get('__rgraph_event_listeners__')[obj.canvas.id + '_mouseup']) {
  291. return;
  292. }
  293. RGraph.Registry.Get('__rgraph_event_listeners__')[obj.canvas.id + '_mouseup'] = true;
  294. // When the canvas is cleared, reset this flag so that the event listener is installed again
  295. RGraph.AddCustomEventListener(obj, 'onclear', function (obj) {RGraph.Registry.Get('__rgraph_event_listeners__')[obj.canvas.id + '_mouseup'] = false});
  296. // Install the onclick event handler for the tooltips
  297. //
  298. // // NOTE: Global on purpose
  299. rgraph_canvas_mouseup_func = function (e)
  300. {
  301. var x = arguments[1] ? arguments[1] : e.pageX;
  302. var y = arguments[2] ? arguments[2] : e.pageY;
  303. var objects = RGraph.ObjectRegistry.getObjectsByCanvasID(e.target.id);
  304. // It's important to go backwards through the array so that the front charts
  305. // are checked first, then the charts at the back
  306. for (var i=(objects.length - 1); i>=0; --i) {
  307. var shape = objects[i].getShape(e);
  308. if (shape && shape['object'] && !RGraph.Registry.Get('chart.tooltip')) {
  309. /**
  310. * This allows the Scatter chart funky tooltips style
  311. *
  312. if (objects[i].type == 'scatter' && shape['dataset'] > 0) {
  313. for (var j=0; j<(objects[i].data.length - 1); ++j) {
  314. shape['index'] += objects[i].data[j].length;
  315. }
  316. }
  317. var text = RGraph.parseTooltipText(objects[i].Get('chart.tooltips'), shape['index']);
  318. if (text) {
  319. if (shape['object'].Get('chart.tooltips.hotspot.xonly')) {
  320. var canvasXY = RGraph.getCanvasXY(objects[i].canvas);
  321. x = canvasXY[0] + shape[1];
  322. y = canvasXY[1] + shape[2];
  323. }
  324. RGraph.Tooltip(objects[i], text, x, y, shape['index']);
  325. objects[i].Highlight(shape);
  326. e.stopPropagation();
  327. e.cancelBubble = true;
  328. return false;
  329. }
  330. }
  331. }
  332. }
  333. obj.canvas.addEventListener('mouseup', rgraph_canvas_mouseup_func, false);
  334. RGraph.AddEventListener(obj.id, 'mouseup', rgraph_canvas_mouseup_func);
  335. }
  336. */
  337. /**
  338. * This installs the canvas mousemove event listener. This is the function that
  339. * changes the mouse pointer if need be.
  340. *
  341. * @param object obj The chart object
  342. *
  343. RGraph.InstallCanvasMousemoveTooltipListener = function (obj)
  344. {
  345. if (RGraph.Registry.Get('__rgraph_event_listeners__')[obj.canvas.id + '_mousemove']) {
  346. return;
  347. }
  348. RGraph.Registry.Get('__rgraph_event_listeners__')[obj.canvas.id + '_mousemove'] = true;
  349. // When the canvas is cleared, reset this flag so that the event listener is installed again
  350. RGraph.AddCustomEventListener(obj, 'onclear', function (obj) {RGraph.Registry.Get('__rgraph_event_listeners__')[obj.canvas.id + '_mousemove'] = false})
  351. // Install the mousemove event handler for the tooltips
  352. //
  353. // NOTE: Global on purpose
  354. rgraph_canvas_mousemove_func = function (e)
  355. {
  356. var objects = RGraph.ObjectRegistry.getObjectsByCanvasID(e.target.id);
  357. for (var i=0; i<objects.length; ++i) {
  358. var shape = objects[i].getShape(e);
  359. if (shape && shape['object']) {
  360. /**
  361. * This allows the Scatter chart funky tooltips style
  362. *
  363. if (objects[i].type == 'scatter' && shape['dataset'] > 0) {
  364. for (var j=0; j<(objects[i].data.length - 1); ++j) {
  365. shape['index'] += objects[i].data[j].length;
  366. }
  367. }
  368. var text = RGraph.parseTooltipText(objects[i].Get('chart.tooltips'), shape['index']);
  369. if (text) {
  370. e.target.style.cursor = 'pointer';
  371. /**
  372. * This facilitates the event triggering the tooltips being mousemove
  373. *
  374. if ( typeof(objects[i].Get('chart.tooltips.event')) == 'string'
  375. && objects[i].Get('chart.tooltips.event') == 'onmousemove'
  376. && (!RGraph.Registry.Get('chart.tooltip') || shape['index'] != RGraph.Registry.Get('chart.tooltip').__index__ || shape['object'].uid != RGraph.Registry.Get('chart.tooltip').__object__.uid)
  377. ) {
  378. // Hide any current tooltip
  379. rgraph_window_mousedown(e);
  380. rgraph_canvas_mouseup_func(e);
  381. }
  382. }
  383. }
  384. }
  385. }
  386. obj.canvas.addEventListener('mousemove', rgraph_canvas_mousemove_func, false);
  387. RGraph.AddEventListener(obj.id, 'mousemove', rgraph_canvas_mousemove_func);
  388. }
  389. */
  390. /**
  391. * This function highlights a rectangle
  392. *
  393. * @param object obj The chart object
  394. * @param number shape The coordinates of the rect to highlight
  395. */
  396. RGraph.Highlight.Rect = function (obj, shape)
  397. {
  398. if (obj.Get('chart.tooltips.highlight')) {
  399. var canvas = obj.canvas;
  400. var context = obj.context;
  401. /**
  402. * Draw a rectangle on the canvas to highlight the appropriate area
  403. */
  404. context.beginPath();
  405. context.strokeStyle = obj.Get('chart.highlight.stroke');
  406. context.fillStyle = obj.Get('chart.highlight.fill');
  407. context.strokeRect(shape['x'],shape['y'],shape['width'],shape['height']);
  408. context.fillRect(shape['x'],shape['y'],shape['width'],shape['height']);
  409. context.stroke;
  410. context.fill();
  411. }
  412. }
  413. /**
  414. * This function highlights a point
  415. *
  416. * @param object obj The chart object
  417. * @param number shape The coordinates of the rect to highlight
  418. */
  419. RGraph.Highlight.Point = function (obj, shape)
  420. {
  421. if (obj.Get('chart.tooltips.highlight')) {
  422. var canvas = obj.canvas;
  423. var context = obj.context;
  424. /**
  425. * Draw a rectangle on the canvas to highlight the appropriate area
  426. */
  427. context.beginPath();
  428. context.strokeStyle = obj.Get('chart.highlight.stroke');
  429. context.fillStyle = obj.Get('chart.highlight.fill');
  430. var radius = obj.Get('chart.highlight.point.radius') || 2;
  431. context.arc(shape['x'],shape['y'],radius, 0, TWOPI, 0);
  432. context.stroke();
  433. context.fill();
  434. }
  435. }
  436. /**
  437. * This (as the name suggests preloads any images it can find in the tooltip text
  438. *
  439. * @param object obj The chart object
  440. */
  441. RGraph.PreLoadTooltipImages = function (obj)
  442. {
  443. var tooltips = obj.Get('chart.tooltips');
  444. if (RGraph.hasTooltips(obj)) {
  445. if (obj.type == 'rscatter') {
  446. tooltips = [];
  447. for (var i=0; i<obj.data.length; ++i) {
  448. tooltips.push(obj.data[3]);
  449. }
  450. }
  451. for (var i=0; i<tooltips.length; ++i) {
  452. // Add the text to an offscreen DIV tag
  453. var div = document.createElement('DIV');
  454. div.style.position = 'absolute';
  455. div.style.opacity = 0;
  456. div.style.top = '-100px';
  457. div.style.left = '-100px';
  458. div.innerHTML = tooltips[i];
  459. document.body.appendChild(div);
  460. // Now get the IMG tags and create them
  461. var img_tags = div.getElementsByTagName('IMG');
  462. // Create the image in an off-screen image tag
  463. for (var j=0; j<img_tags.length; ++j) {
  464. if (img_tags && img_tags[i]) {
  465. var img = document.createElement('IMG');
  466. img.style.position = 'absolute';
  467. img.style.opacity = 0;
  468. img.style.top = '-100px';
  469. img.style.left = '-100px';
  470. img.src = img_tags[i].src
  471. document.body.appendChild(img);
  472. setTimeout(function () {document.body.removeChild(img);}, 250);
  473. }
  474. }
  475. // Now remove the div
  476. document.body.removeChild(div);
  477. }
  478. }
  479. }
  480. /**
  481. * This is the tooltips canvas onmousemove listener
  482. */
  483. RGraph.Tooltips_mousemove = function (obj, e)
  484. {
  485. var shape = obj.getShape(e);
  486. var changeCursor_tooltips = false
  487. if ( shape
  488. && typeof(shape['index']) == 'number'
  489. && obj.Get('chart.tooltips')[shape['index']]
  490. ) {
  491. var text = RGraph.parseTooltipText(obj.Get('chart.tooltips'), shape['index']);
  492. if (text) {
  493. /**
  494. * Change the cursor
  495. */
  496. changeCursor_tooltips = true;
  497. if (obj.Get('chart.tooltips.event') == 'onmousemove') {
  498. // Show the tooltip if it's not the same as the one already visible
  499. if (
  500. !RGraph.Registry.Get('chart.tooltip')
  501. || RGraph.Registry.Get('chart.tooltip').__object__.uid != obj.uid
  502. || RGraph.Registry.Get('chart.tooltip').__index__ != shape['index']
  503. ) {
  504. RGraph.HideTooltip();
  505. RGraph.Clear(obj.canvas);
  506. RGraph.Redraw();
  507. RGraph.Tooltip(obj, text, e.pageX, e.pageY, shape['index']);
  508. obj.Highlight(shape);
  509. }
  510. }
  511. }
  512. /**
  513. * More highlighting
  514. */
  515. } else if (shape && typeof(shape['index']) == 'number') {
  516. var text = RGraph.parseTooltipText(obj.Get('chart.tooltips'), shape['index']);
  517. if (text) {
  518. changeCursor_tooltips = true
  519. }
  520. }
  521. return changeCursor_tooltips;
  522. }