Here is a example for(https://cdn.jsdelivr.net/npm/chart.js):
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: xLabels,
datasets: [generateDataset('starter')]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true,
title: {
display: true,
text: 'Pricing per Million Events',
color: '#374053',
font: {
weight: 'bold',
size: 14
},
padding: {
bottom: 20
}
},
border: {
display: true,
color: '#374053',
width: 2,
},
grid: {
color: function(context) {
var tickValue = context.tick.value;
var tickLabels = context.chart.scales.y.ticks.map(tick => tick.value);
if (tickLabels.length > 0 && tickValue === tickLabels[tickLabels.length - 1]) {
return 'transparent';
}
return '#ccc';
}
},
ticks: {
callback: function(value, index, values) {
if (index === values.length - 1) {
return '';
}
return value;
}
}
},
x: {
title: {
display: true,
text: 'Events',
color: '#374053',
font: {
weight: 'bold',
size: 14
},
padding: {
top: 20
}
},
border: {
display: true,
color: '#374053',
width: 2,
},
ticks: {
autoSkip: false,
maxTicksLimit: xLabels.length/25,
callback: function(index) {
var label = xLabels[index];
if (filteredXLabels.includes(label)) {
return label;
}
return '';
}
}
}
},
plugins: {
legend: {
display: false,
},
tooltip: {
enabled: false,
mode: 'index',
intersect: false,
external: function(context) {
var tooltipModel = context.tooltip;
var tooltipEl = document.getElementById('chartjs-tooltip');
if (!tooltipEl) {
tooltipEl = document.createElement('div');
tooltipEl.id = 'chartjs-tooltip';
tooltipEl.innerHTML = '<table></table>';
document.body.appendChild(tooltipEl);
}
if (tooltipModel.opacity === 0) {
tooltipEl.style.opacity = 0;
return;
}
tooltipEl.classList.remove('above', 'below', 'no-transform');
if (tooltipModel.yAlign) {
tooltipEl.classList.add(tooltipModel.yAlign);
} else {
tooltipEl.classList.add('no-transform');
}
if (tooltipModel.body) {
var titleLines = tooltipModel.title || [];
var bodyLines = tooltipModel.dataPoints.map(function(dataPoint) {
// Extract only the y-axis value
return dataPoint.raw;
});
var innerHtml = '<thead>';
innerHtml += '<tr class="tooltip-title"><td>$' + titleLines[0] + ' events </td></tr>';
innerHtml += '</thead><tbody>';
// Get the x-axis value from the tooltip model
var xAxisValue = tooltipModel.dataPoints[0].label;
var events = parseInt(xAxisValue, 10); // Parse the number of events
var costPerMillion = calculateCostPerMillion(events);
// Add a new row for cost per million
innerHtml += '<tr class="tooltip-total-cost"><td> <span class="total-cost">$' + bodyLines[0] + '</span> per month</td></tr>';
innerHtml += '<tr class="tooltip-cpm"><td>$' + costPerMillion + ' per Million Events</td></tr>';
innerHtml += '</tbody>';
var tableRoot = tooltipEl.querySelector('table');
tableRoot.innerHTML = innerHtml;
}
var position = context.chart.canvas.getBoundingClientRect();
tooltipEl.style.opacity = 1;
tooltipEl.style.position = 'absolute';
// Adjust the positioning logic here:
tooltipEl.style.left = position.left + window.pageXOffset + tooltipModel.caretX + 'px';
tooltipEl.style.top = position.top + window.pageYOffset + tooltipModel.caretY + 'px';
// Offset to ensure the top-left corner touches the line
tooltipEl.style.transform = 'translate(0%, 0%)';
tooltipEl.style.fontFamily = tooltipModel.options.bodyFont.family;
tooltipEl.style.fontSize = tooltipModel.options.bodyFont.size + 'px';
tooltipEl.style.fontStyle = tooltipModel.options.bodyFont.style;
tooltipEl.style.padding = tooltipModel.padding + 'px ' + tooltipModel.padding + 'px';
tooltipEl.style.pointerEvents = 'none';
}
}
}
}
});