Created
September 25, 2016 20:09
-
-
Save alistairtweedie/e5ec160d3f2e1c7aeda5cd6b1c47cef6 to your computer and use it in GitHub Desktop.
Custom chartist tooltip plugin - modified from original
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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 (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 = '<span class="chartist-tooltip-value">' + value + ' </span>'; | |
tooltipText += 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 = '<span class="chartist-tooltip-meta">' + meta + '</span>'; | |
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(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; | |
})); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment