is there a way to get the nearest point when clicked anywhere on canvas? Maybe somehow harvest the core 'nearest' method? Thanks
I think you will find getElementsAtXAxis
very helpful.
Basically, getElementsAtXAxis
has a very similar behaviour to getElementsAtEvent
although when the click event doesn't intersect a point of the chart, it will return the nearest ChartElement.
The only downside is that it will return all the ChartElement on the nearest x-axis index.
So, if you use multiple datasets, this might not be the best choice for you.
Code example:
canvas.onclick = function(e) {
const elts = chart.getElementsAtXAxis(simulatedEvent);
if (elts && elts.length) {
// Do something with elts[0]
}
};
If anyone is looking for the related piece of code, it's in core.controller.js
:
getElementAtEvent: function(e) {
return Interaction.modes.nearest(this, e, {intersect: true});
},
getElementsAtEvent: function(e) {
return Interaction.modes.index(this, e, {intersect: true});
},
getElementsAtXAxis: function(e) {
return Interaction.modes.index(this, e, {intersect: false});
},
I believe you are looking for
.getElementAtEvent
and .getElementsAtEvent
(https://www.chartjs.org/docs/latest/developers/api.html#getelementsatevente)
What you can do - is set up a clickHandler
function that will grab the event from onClick
and use it to return the chart element under it.
Here is an example from the official docs:
function clickHandler(evt) {
var firstPoint = myChart.getElementAtEvent(evt)[0];
if (firstPoint) {
var label = myChart.data.labels[firstPoint._index];
var value = myChart.data.datasets[firstPoint._datasetIndex].data[firstPoint._index];
}
}
After, just add it to your chart canvas (again, from the official docs):
canvas.onclick = clickHandler;
.getElementAtEvent
and .getElementsAtEvent
only return elements at the position where you clicked. When I click just randomly on the canvas, it returns an empty array. I would need to get the nearest element wherever I click, hence the mentioned 'nearest' method in the core link . This question has been already asked numerous times before with (for me) incorrect answers and no followups, such as: link –
Electrostriction I achieved this in a graph with two datasets with the following:
const userPricingEl = document.getElementById("userPricingChart");
const userPricingChart = new Chart();
userPricingEl.onclick = function (evt) {
let nearestPoints = userPricingChart.getElementsAtEventForMode(evt, "nearest", {
intersect: false
});
if (nearestPoints) {
let nearestPoint = nearestPoints[0];
let label = userPricingChart.data.datasets[nearestPoint._datasetIndex].label;
let value = userPricingChart.data.datasets[nearestPoint._datasetIndex].data[nearestPoint._index];
console.log(label, value);
}
}
Where "userPricingChart" is a fully fleshed out new Chart()
object, which I omitted for brevity.
The key feature here is the getElementsAtEventForMode()
function, documented here (albeit arguably badly).
Hope this helps.
© 2022 - 2024 — McMap. All rights reserved.