(function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(["chartist"], function (Chartist) { return (root.returnExportsGlobal = factory(Chartist)); }); } else if (typeof exports === 'object') { // Node. Does not work with strict CommonJS, but // only CommonJS-like enviroments that support module.exports, // like Node. module.exports = factory(require("chartist")); } else { root['Chartist.plugins.tooltips'] = factory(Chartist); } }(this, function (Chartist) { /** * Chartist.js plugin to display a data label on top of the points in a line chart. * */ /* global Chartist */ (function (window, document, Chartist) { 'use strict'; var defaultOptions = { currency: undefined, currencyFormatCallback: undefined, tooltipOffset: { x: 0, y: -20 }, anchorToPoint: false, appendToBody: false, class: undefined, pointClass: 'ct-point' }; Chartist.plugins = Chartist.plugins || {}; Chartist.plugins.tooltip = function (options) { options = Chartist.extend({}, defaultOptions, options); return function tooltip(chart) { var tooltipSelector = options.pointClass; if (chart instanceof Chartist.Bar) { tooltipSelector = 'ct-bar'; } else if (chart instanceof Chartist.Pie) { // Added support for donut graph if (chart.options.donut) { tooltipSelector = 'ct-slice-donut'; } else { tooltipSelector = 'ct-slice-pie'; } } var $chart = chart.container; var $toolTip = $chart.querySelector('.chartist-tooltip'); if (!$toolTip) { $toolTip = document.createElement('div'); $toolTip.className = (!options.class) ? 'chartist-tooltip' : 'chartist-tooltip ' + options.class; if (!options.appendToBody) { $chart.appendChild($toolTip); } else { document.body.appendChild($toolTip); } } var height = $toolTip.offsetHeight; var width = $toolTip.offsetWidth; hide($toolTip); function on(event, selector, callback) { $chart.addEventListener(event, function (e) { if (!selector || hasClass(e.target, selector)) callback(e); }); } on('mouseover', tooltipSelector, function (event) { var $point = event.target; var tooltipText = ''; var isPieChart = (chart instanceof Chartist.Pie) ? $point : $point.parentNode; var seriesName = (isPieChart) ? $point.parentNode.getAttribute('ct:meta') || $point.parentNode.getAttribute('ct:series-name') : ''; var meta = $point.getAttribute('ct:meta') || seriesName || ''; var hasMeta = !!meta; var value = $point.getAttribute('ct:value'); if (options.transformTooltipTextFnc && typeof options.transformTooltipTextFnc === 'function') { value = options.transformTooltipTextFnc(value); } if (options.tooltipFnc && typeof options.tooltipFnc === 'function') { tooltipText = options.tooltipFnc(meta, value); } else { if (options.metaIsHTML) { var txt = document.createElement('textarea'); txt.innerHTML = meta; meta = txt.value; } meta = '' + meta + ''; if (hasMeta) { tooltipText += meta + '
'; } else { // For Pie Charts also take the labels into account // Could add support for more charts here as well! if (chart instanceof Chartist.Pie) { var label = next($point, 'ct-label'); if (label) { tooltipText += text(label) + '
'; } } } if (value) { if (options.currency) { if (options.currencyFormatCallback != undefined) { value = options.currencyFormatCallback(value, options); } else { value = options.currency + value.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, '$1,'); } } value = '' + value + ''; tooltipText += value; } } if(tooltipText) { $toolTip.innerHTML = tooltipText; setPosition(event); show($toolTip); // Remember height and width to avoid wrong position in IE height = $toolTip.offsetHeight; width = $toolTip.offsetWidth; } }); on('mouseout', tooltipSelector, function () { hide($toolTip); }); on('mousemove', null, function (event) { if (false === options.anchorToPoint) setPosition(event); }); function setPosition(event) { height = height || $toolTip.offsetHeight; width = width || $toolTip.offsetWidth; var offsetX = - width / 2 + options.tooltipOffset.x var offsetY = - height + options.tooltipOffset.y; var anchorX, anchorY; if (!options.appendToBody) { var box = $chart.getBoundingClientRect(); var left = event.pageX - box.left - window.pageXOffset ; var top = event.pageY - box.top - window.pageYOffset ; if (true === options.anchorToPoint && event.target.x2 && event.target.y2) { anchorX = parseInt(event.target.x2.baseVal.value); anchorY = parseInt(event.target.y2.baseVal.value); } $toolTip.style.top = (anchorY || top) + offsetY + 'px'; $toolTip.style.left = (anchorX || left) + offsetX + 'px'; } else { $toolTip.style.top = event.pageY + offsetY + 'px'; $toolTip.style.left = event.pageX + offsetX + 'px'; } } } }; function show(element) { if(!hasClass(element, 'tooltip-show')) { element.className = element.className + ' tooltip-show'; } } function hide(element) { var regex = new RegExp('tooltip-show' + '\\s*', 'gi'); element.className = element.className.replace(regex, '').trim(); } function hasClass(element, className) { return (' ' + element.getAttribute('class') + ' ').indexOf(' ' + className + ' ') > -1; } function next(element, className) { do { element = element.nextSibling; } while (element && !hasClass(element, className)); return element; } function text(element) { return element.innerText || element.textContent; } } (window, document, Chartist)); return Chartist.plugins.tooltips; }));