eat-sleep-code
eat-sleep-code

Reputation: 4855

Chart.js is it possible to fire javascript when clicking on point on the graph?

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

Answers (1)

jordanwillis
jordanwillis

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

Related Questions