Reputation: 4855
Does anyone know if it is possible to fire a javascript event when clicking on a point on a Chart.js graph?
If so, how?
UPDATE: This is my current chart initialization script, based on feedback:
function RenderBasicAnalyticsChart(targetSelector, usersCreated, usersAuthenticated, contentDownloaded)
{
var ctx = $(targetSelector);
var chartObject = new Chart(ctx, {
type: 'line',
data: {
datasets: [
{
type: 'line',
label: 'Users created',
borderColor: 'rgba(0,169,224,1.0)',
pointBackgroundColor: 'rgba(0,169,224,1.0)',
backgroundColor: 'rgba(0,169,224,0.4)',
data: usersCreated
},
{
type: 'line',
label: 'Users signed in',
borderColor: 'rgba(120,170,0,1.0)',
pointBackgroundColor: 'rgba(120,170,0,1.0)',
backgroundColor: 'rgba(120,170,0,0.4)',
data: usersAuthenticated
},
{
type: 'line',
label: 'Assets downloaded',
borderColor: 'rgba(255,106,19,1.0)',
pointBackgroundColor: 'rgba(255,106,19,1.0)',
backgroundColor: 'rgba(255,106,19,0.4)',
data: contentDownloaded
}
]
},
options: {
defaultFontFamily: 'Open Sans',
responsiveAnimationDuration: 100,
scales: {
xAxes: [{
type: 'time',
time: {
displayFormats: {
quarter: 'MMM YYYY'
}
}
}]
}
}
});
$(targetSelector).click(function (e) {
var activePoints = chartObject.getElementsAtEvent(event);
if (activePoints.length > 0) {
var clickedDatasetIndex = activePoints[0]._datasetIndex;
var clickedElementIndex = activePoints[0]._index;
var value = chartObject.data.datasets[clickedDatasetIndex].data[clickedElementIndex];
console.log(clickedDatasetIndex + ' - ' + value['x']);
}
});
}
The issue I am now having is that my clickedDatasetIndex is always coming back as 0, regardless of which line I clicked.
Upvotes: 4
Views: 4605
Reputation: 10705
Yes you sure can! Just use the .getDatasetAtEvent(e)
or .getElementsAtEvent(e)
prototype methods (depending on your needs). Here is more detail on what they do.
Looks for the element under the event point, then returns all elements at the same data index. This is used internally for 'label' mode highlighting.
Calling getElementsAtEvent(event) on your Chart instance passing an argument of an event, or jQuery event, will return the point elements that are at that the same position of that event.
Here is an example for how to get the point that was clicked when there are more than 1 datasets. Assuming my canvas has an id of canvas
and my chart instance is called myLine
.
document.getElementById("canvas").onclick = function(evt){
var activePoints = myLine.getElementAtEvent(event);
// make sure click was on an actual point
if (activePoints.length > 0) {
var clickedDatasetIndex = activePoints[0]._datasetIndex;
var clickedElementindex = activePoints[0]._index;
var label = myLine.data.labels[clickedElementindex];
var value = myLine.data.datasets[clickedDatasetIndex].data[clickedElementindex];
alert("Clicked: " + label + " - " + value);
}
};
You can also experiment with this codepen example.
Upvotes: 4