chartjs / chartjs/Chart.js

When defining an External implementation for Tooltip, chart.canvas.offsetLeft doesn't work when chart in a table

Open
#11,830 2 comments 0 reactions 0 assignees View on GitHub
type: bug
Dominant language
JavaScript
Stars
67.7k
Forks
11.9k
Avg merge
7h 39m
Merged PRs (30d)
5

Description

### Expected behavior

No matter where a chart is positioned, correct coordinates should be available for the tooltip implementation (with respect to the viewport?).

### Current behavior

chart.canvas.offsetLeft and chart.canvas.offsetTop etc... have values representing the relative positioning of the chart within the table element.

### Reproducible sample

https://www.chartjs.org/dist/master/chart.umd.js

### Optional extra steps/info to reproduce

```html


```

```css
.myChartDiv {
max-width: 600px;
max-height: 400px;
}

.chartTooltip {
position: absolute;
background-color: #345;
font-size:80%;
box-shadow: 3px 3px 4px 0px #aaa;
opacity: 1;
border-radius: 5px 5px 5px 5px;
pointer-events: none;
transform: translate(-50%, 0);
transition: all .1s ease;
z-index: 9999;
color: #CCC;
}
```

```js
function getOrCreateTooltip(chart)
{
let tooltipEl = document.getElementById('chartjs-tooltip');
if (!tooltipEl)
{
tooltipEl = document.createElement('div');
tooltipEl.id = 'chartjs-tooltip';
tooltipEl.className="chartTooltip";
chart.canvas.parentNode.appendChild(tooltipEl);
}
return tooltipEl;
};

function tooltipExternal(context)
{
// Tooltip Element
const {chart, tooltip} = context;
const tooltipEl = getOrCreateTooltip(chart);

// Hide if no tooltip
if (tooltip.opacity === 0)
return tooltipEl.style.opacity = 0;

// table
tooltipEl.innerHTML = '

Hello!

';

// console.log("chart.canvas.getBoundingClientRect(): ", chart.canvas.getBoundingClientRect());
// console.log("chart.canvas.offsetst: ", [chart.canvas.offsetLeft, chart.canvas.offsetTop]);
// console.log("tooltip.carets: ", [tooltip.caretX, tooltip.caretY]);
// console.log("window.scrolls: ", [window.scrollX, window.scrollY]);
const positionX = chart.canvas.offsetLeft;
const positionY = chart.canvas.offsetTop;

// Display, position, and set styles for font
tooltipEl.style.opacity = 1;
tooltipEl.style.left = (positionX + tooltip.caretX) + 'px';
tooltipEl.style.top = (positionY + tooltip.caretY) + 'px';
};

var ctx = document.getElementById("chart1");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3, 5, 10, 8]
}]
},
options: {
plugins: {
tooltip: {
enabled: false
,borderColor: '#CCC'
,external: tooltipExternal
}
}
}
});

var ctx = document.getElementById("chart2");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3, 5, 10, 8]
}]
},
options: {
plugins: {
tooltip: {
enabled: false
,borderColor: '#CCC'
,external: tooltipExternal
}
}
}
});
```

### Possible solution

_No response_

### Context

We are trying to use ChartJS in an environment where lots of HTML tables are used. We can figure out some work arounds, but painful. In general though, for tooltips, we should be able to get viewport-relative coordinates.

### chart.js version

v4.2.1

### Browser name and version

Firefox and Chrome (latest) on Windows 11

### Link to your project

_No response_

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.