I'm using chartjs 2.8 and I've created some custom html tooltip for it, now i need to make that tooltip interactive ( aka - hoverable, clickable etc...)
The problem is that chartjs only shows the tooltip while I hover over the point of data i want to see in the tooltip, once i hover outside to get in the tooltip it disappears.
I've tried checking chartjs docs for some options solution for that but couldn't find anything helpful\working.
I've been thinking to play with my customTooltip function so it will only disappear once tooltipModel.opacity===0 and the mouse is out of the tooltip, but I'm having some difficulties here
this.tooltip = $('<div/>').addClass('chartjs-tooltip')[0];
document.body.appendChild(this.tooltip);
return new Chart($chart, {
type: 'line',
data: {
labels: labels,
datasets: datasets,
cubicInterpolationMode: 'monotone'
},
options: Object.assign({}, options, {
tooltips: {
// Disable the on-canvas tooltip
enabled: false,
custom: (tooltipModel) => {
// Hide if no tooltips
if (tooltipModel.opacity === 0) {
$(this.tooltip).empty().removeClass('visible');
return;
} else {
$(this.tooltip).addClass('visible');
}
// Set caret Position
this.tooltip.classList.remove('above', 'below', 'no-transform');
if (tooltipModel.yAlign) {
this.tooltip.classList.add(tooltipModel.yAlign);
} else {
this.tooltip.classList.add('no-transform');
}
function getBody(bodyItem) {
return bodyItem.lines;
}
// Set Text
if ( empty_datapoint ) {
if (tooltipModel.body) {
this.tooltip.innerHTML = '<table></table>';
let titleLines = tooltipModel.title || [];
let bodyLines = tooltipModel.body.map(getBody);
let innerHtml = '<thead>';
titleLines.forEach(function(title) {
innerHtml += '<tr><th>' + title + '</th></tr>';
});
innerHtml += '</thead><tbody>';
bodyLines.forEach(function(body, i) {
let colors = tooltipModel.labelColors[i];
let style = 'background:' + colors.backgroundColor + ';';
let span = '<span class="color-box" style="' + style + '"></span>';
innerHtml += '<tr><td>' + span + body + '</td></tr>';
});
innerHtml += '</tbody>';
let tableRoot = this.tooltip.querySelector('table');
tableRoot.innerHTML = innerHtml;
this.tooltip.addStyles({
backgroundColor: 'rgba(0,0,0,0.8)',
borderRadius: '6px',
color: '#fff',
fontFamily: tooltipModel._bodyFontFamily,
fontSize: tooltipModel.bodyFontSize + 'px',
fontStyle: tooltipModel._bodyFontStyle,
});
}
} else {
let $tooltip = this.customTooltip(tooltipModel.dataPoints);
$('.chartjs-tooltip').html($tooltip);
tooltipModel.caretX += -150;
}
// `this` will be the overall tooltip
let position = this.chart.$el.canvas.getBoundingClientRect();
// Display, position, and set styles for font
this.tooltip.addStyles({
position: 'absolute',
left: position.left + window.pageXOffset + tooltipModel.caretX + 'px',
top: position.top + window.pageYOffset + tooltipModel.caretY + 'px',
padding: tooltipModel.yPadding + 'px ' + tooltipModel.xPadding + 'px',
zIndex: 9999999999,
// pointerEvents: 'none'; // pretty sure we'll want pointer event in the future
});
}
}
}),
});
let tooltipEl = document.getElementById('chartjs-tooltip');
if (!tooltipEl) {
tooltipEl = document.createElement('div');
tooltipEl.id = 'chartjs-tooltip';
tooltipEl.innerHTML = `<table></table>`;
document.body.appendChild(tooltipEl);
tooltipEl.addEventListener('mouseleave', () => {
tooltipEl.style.opacity = 0;
});
tooltipEl.addEventListener('mouseenter', () => {
tooltipEl.style.opacity = 1;
});
You can also control tooltip visibility in afterEvent hook.
plugins: [
{
id: 'turnOffTooltipPlugin',
afterEvent(chart, args, pluginOptions) {
const { event } = args;
if (event.native.type === 'mouseout') {
let tooltipEl = document.getElementById('chartjs-tooltip');
if (tooltipEl) {
tooltipEl.style.opacity = 0;
}
}
}
]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With