/***** * A no-frills tooltip implementation. *****/ (function() { var nvtooltip = window.nv.tooltip = {}; nvtooltip.show = function(pos, content, gravity, dist, parentContainer, classes) { var container = document.createElement('div'); container.className = 'nvtooltip ' + (classes ? classes : 'xy-tooltip'); gravity = gravity || 's'; dist = dist || 20; var body = parentContainer ? parentContainer : document.getElementsByTagName('body')[0]; container.innerHTML = content; container.style.left = 0; container.style.top = 0; container.style.opacity = 0; body.appendChild(container); var height = parseInt(container.offsetHeight), width = parseInt(container.offsetWidth), windowWidth = nv.utils.windowSize().width, windowHeight = nv.utils.windowSize().height, scrollTop = window.scrollY, scrollLeft = window.scrollX, left, top; windowHeight = window.innerWidth >= document.body.scrollWidth ? windowHeight : windowHeight - 16; windowWidth = window.innerHeight >= document.body.scrollHeight ? windowWidth : windowWidth - 16; var tooltipTop = function ( Elem ) { var offsetTop = top; do { if( !isNaN( Elem.offsetTop ) ) { offsetTop += (Elem.offsetTop); } } while( Elem = Elem.offsetParent ); return offsetTop; } var tooltipLeft = function ( Elem ) { var offsetLeft = left; do { if( !isNaN( Elem.offsetLeft ) ) { offsetLeft += (Elem.offsetLeft); } } while( Elem = Elem.offsetParent ); return offsetLeft; } switch (gravity) { case 'e': left = pos[0] - width - dist; top = pos[1] - (height / 2); var tLeft = tooltipLeft(container); var tTop = tooltipTop(container); if (tLeft < scrollLeft) left = pos[0] + dist > scrollLeft ? pos[0] + dist : scrollLeft - tLeft + left; if (tTop < scrollTop) top = scrollTop - tTop + top; if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height; break; case 'w': left = pos[0] + dist; top = pos[1] - (height / 2); if (tLeft + width > windowWidth) left = pos[0] - width - dist; if (tTop < scrollTop) top = scrollTop + 5; if (tTop + height > scrollTop + windowHeight) top = scrollTop - height - 5; break; case 'n': left = pos[0] - (width / 2) - 5; top = pos[1] + dist; var tLeft = tooltipLeft(container); var tTop = tooltipTop(container); if (tLeft < scrollLeft) left = scrollLeft + 5; if (tLeft + width > windowWidth) left = left - width/2 + 5; if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height; break; case 's': left = pos[0] - (width / 2); top = pos[1] - height - dist; var tLeft = tooltipLeft(container); var tTop = tooltipTop(container); if (tLeft < scrollLeft) left = scrollLeft + 5; if (tLeft + width > windowWidth) left = left - width/2 + 5; if (scrollTop > tTop) top = scrollTop; break; } container.style.left = left+'px'; container.style.top = top+'px'; container.style.opacity = 1; container.style.position = 'absolute'; //fix scroll bar issue container.style.pointerEvents = 'none'; //fix scroll bar issue return container; }; nvtooltip.cleanup = function() { // Find the tooltips, mark them for removal by this class (so others cleanups won't find it) var tooltips = document.getElementsByClassName('nvtooltip'); var purging = []; while(tooltips.length) { purging.push(tooltips[0]); tooltips[0].style.transitionDelay = '0 !important'; tooltips[0].style.opacity = 0; tooltips[0].className = 'nvtooltip-pending-removal'; } setTimeout(function() { while (purging.length) { var removeMe = purging.pop(); removeMe.parentNode.removeChild(removeMe); } }, 500); }; })();