I’m trying to change the color of other slices when hovering one of them, but is a little buggy sometimes and I’m trying to understand why.
As shown in the example, there is a flickering when hovering from one slice to another and the colors don’t change right away, and also when leaving the slice the colors should reset, but it doesn’t work sometimes.
const colors = ["red", "green", "blue"];
const colorsRGBA = ["rgba(255,0,0,.25)", "rgba(0,255,0,.25)", "rgba(0,0,255,.25)"];
new Chart(document.getElementById("doughnut"), {
type: "doughnut",
data: {
labels: ["A", "B", "C"],
datasets: [
{
data: [1, 2, 3],
backgroundColor: ["red", "green", "blue"],
hoverBackgroundColor: ["red", "green", "blue"]
}
]
},
options: {
plugins: {
tooltip: {
enabled: false
},
legend: {
display: false
}
},
onHover(event, elements, chart) {
if (event.type === "mousemove") {
if (elements.length) {
chart.getDatasetMeta(0).data.forEach((data, index) => {
if (index !== elements[0].index) {
data.options.backgroundColor = colorsRGBA[index];
}
});
} else {
chart.getDatasetMeta(0).data.forEach((data, index) => {
data.options.backgroundColor = colors[index];
});
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.min.js"></script>
<div style="height: 350px">
<canvas id="doughnut"></canvas>
</div>
2
Answers
I think your code is very good, but you need to add some simple code to achieve your goal.
This is my suggestion.
I hope this code snippet helps you.
The problem is that your explicit setting of colors is "competing against" the default chart.js process by which the colors are set when the cursor enters and leaves elements.
The only issue I can see, is that when the cursor is moved in one short fast shift from one element to another, the element that was left will be restored its color from the
dataset
(non-transparent), but that is done in an animation that will happen after your code hasset the semitransparent color, so you end up with two elements with full color.
The solution is to disable the
colors
animations
;that can be done in the chart configuration at
options
:You may want to also set at the canvas level a
mouseOut
event handler for the case the cursor ismoved fast outside the canvas or the browser tab is changed through the keyboard while the cursor is
on an element.
Code snippet with these changes:
This fiddle contains mostly the same code except for the
animations, where the opposite way is taken, setting the duration to 5 seconds so one
can see the effect that I described.
Please let me know if there are still undesired effects that I couldn’t detect.