Click events on Pie Charts in Chart.js

191,038

Solution 1

Update: As @Soham Shetty comments, getSegmentsAtEvent(event) only works for 1.x and for 2.x getElementsAtEvent should be used.

.getElementsAtEvent(e)

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.

canvas.onclick = function(evt){
    var activePoints = myLineChart.getElementsAtEvent(evt);
    // => activePoints is an array of points on the canvas that are at the same position as the click event.
};

Example: https://jsfiddle.net/u1szh96g/208/


Original answer (valid for Chart.js 1.x version):

You can achieve this using getSegmentsAtEvent(event)

Calling getSegmentsAtEvent(event) on your Chart instance passing an argument of an event, or jQuery event, will return the segment elements that are at that the same position of that event.

From: Prototype Methods

So you can do:

$("#myChart").click( 
    function(evt){
        var activePoints = myNewChart.getSegmentsAtEvent(evt);           
        /* do something */
    }
);  

Here is a full working example:

<html>
    <head>
        <script type="text/javascript" src="http://code.jquery.com/jquery-2.0.2.js"></script>
        <script type="text/javascript" src="Chart.js"></script>
        <script type="text/javascript">
            var data = [
                {
                    value: 300,
                    color:"#F7464A",
                    highlight: "#FF5A5E",
                    label: "Red"
                },
                {
                    value: 50,
                    color: "#46BFBD",
                    highlight: "#5AD3D1",
                    label: "Green"
                },
                {
                    value: 100,
                    color: "#FDB45C",
                    highlight: "#FFC870",
                    label: "Yellow"
                }
            ];

            $(document).ready( 
                function () {
                    var ctx = document.getElementById("myChart").getContext("2d");
                    var myNewChart = new Chart(ctx).Pie(data);

                    $("#myChart").click( 
                        function(evt){
                            var activePoints = myNewChart.getSegmentsAtEvent(evt);
                            var url = "http://example.com/?label=" + activePoints[0].label + "&value=" + activePoints[0].value;
                            alert(url);
                        }
                    );                  
                }
            );
        </script>
    </head>
    <body>
        <canvas id="myChart" width="400" height="400"></canvas>
    </body>
</html>

Solution 2

Using Chart.JS version 2.1.3, answers older than this one aren't valid anymore. Using getSegmentsAtEvent(event) method will output on console this message:

getSegmentsAtEvent is not a function

So i think it must be removed. I didn't read any changelog to be honest. To resolve that, just use getElementsAtEvent(event) method, as it can be found on the Docs.

Below it can be found the script to obtain effectively clicked slice label and value. Note that also retrieving label and value is slightly different.

var ctx = document.getElementById("chart-area").getContext("2d");
var chart = new Chart(ctx, config);

document.getElementById("chart-area").onclick = function(evt)
{   
    var activePoints = chart.getElementsAtEvent(evt);

    if(activePoints.length > 0)
    {
      //get the internal index of slice in pie chart
      var clickedElementindex = activePoints[0]["_index"];

      //get specific label by index 
      var label = chart.data.labels[clickedElementindex];

      //get value by index      
      var value = chart.data.datasets[0].data[clickedElementindex];

      /* other stuff that requires slice's label and value */
   }
}

Hope it helps.

Solution 3

Chart.js 2.0 has made this even easier.

You can find it under common chart configuration in the documentation. Should work on more then pie graphs.

options:{
    onClick: graphClickEvent
}

function graphClickEvent(event, array){
    if(array[0]){
        foo.bar; 
    }
}

It triggers on the entire chart, but if you click on a pie the model of that pie including index which can be used to get the value.

Solution 4

Working fine chartJs sector onclick

ChartJS : pie Chart - Add options "onclick"

              options: {
                    legend: {
                        display: false
                    },
                    'onClick' : function (evt, item) {
                        console.log ('legend onClick', evt);
                        console.log('legd item', item);
                    }
                }

Solution 5

I was facing the same issues since several days, Today i have found the solution. I have shown the complete file which is ready to execute.

<html>
<head><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js">
</script>
</head>
<body>
<canvas id="myChart" width="200" height="200"></canvas>
<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
    datasets: [{
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        backgroundColor: [
            'rgba(255, 99, 132, 0.2)',
            'rgba(54, 162, 235, 0.2)',
            'rgba(255, 206, 86, 0.2)',
            'rgba(75, 192, 192, 0.2)',
            'rgba(153, 102, 255, 0.2)',
            'rgba(255, 159, 64, 0.2)'
        ],
        borderColor: [
            'rgba(255,99,132,1)',
            'rgba(54, 162, 235, 1)',
            'rgba(255, 206, 86, 1)',
            'rgba(75, 192, 192, 1)',
            'rgba(153, 102, 255, 1)',
            'rgba(255, 159, 64, 1)'
        ],
        borderWidth: 1
    }]
},
options: {
    scales: {
        yAxes: [{
            ticks: {
                beginAtZero:true
            }
        }]
    },
onClick:function(e){
    var activePoints = myChart.getElementsAtEvent(e);
    var selectedIndex = activePoints[0]._index;
    alert(this.data.datasets[0].data[selectedIndex]);


}
}
});
</script>
</body>
</html>
Share:
191,038

Related videos on Youtube

Newtt
Author by

Newtt

JavaScript, Django Dev.

Updated on January 24, 2021

Comments

  • Newtt
    Newtt over 3 years

    I've got a question regard Chart.js.

    I've drawn multiple piecharts using the documentation provided. I was wondering if on click of a certain slice of one of the charts, I can make an ajax call depending on the value of that slice?

    For example, if this is my data

    var data = [
        {
            value: 300,
            color:"#F7464A",
            highlight: "#FF5A5E",
            label: "Red"
        },
        {
            value: 50,
            color: "#46BFBD",
            highlight: "#5AD3D1",
            label: "Green"
        },
        {
            value: 100,
            color: "#FDB45C",
            highlight: "#FFC870",
            label: "Yellow"
        }
    ], 
    

    is it possible for me to click on the Red labelled slice and call a url of the following form: example.com?label=red&value=300? If yes, how do I go about this?

  • techie_28
    techie_28 almost 8 years
    I have created a donut chart which shows a text value in the center hole.Is it possible to track the click of that text?
  • HartleySan
    HartleySan over 7 years
    I should also note that if you want to get the dataset index for things like stacked bar charts, etc., you'll have to use chart.getDatasetAtEvent(evt) in addition to chart.getElementsAtEvent(evt) above to get the info.
  • Admin
    Admin about 7 years
    It works for 1.x version. For greater than 2.x, you need to use getElementsAtEvent method.
  • Tobías
    Tobías about 7 years
    @SohamShetty, Thanks for your feedback, I've updated the answer based on your comment.
  • Matt Saunders
    Matt Saunders almost 7 years
    Thankyou for this answer. I noticed if you click on the chart (not a segment), you get an error in the console: Uncaught TypeError: Cannot read property '_chart' of undefined at HTMLCanvasElement.canvas.onclick
  • Tobías
    Tobías almost 7 years
    @MattSaunders You are right, a check like if (activePoints[0]) is missing to ensure there is some element. Thanks for pointing this out. I've updated the example.
  • Ron Daulagupu
    Ron Daulagupu almost 6 years
    thanks, your answer worked. Short and precise. Should have been the accepted answer.
  • Tom John
    Tom John over 5 years
    This is a handy answer as the documentation for chart.js mentions the event but does not currently give an example implementation: chartjs.org/docs/latest/general/interactions/events.html.
  • Emily
    Emily about 5 years
    That fiddle helps me solve my problem. Can you make it more obvious though by making it on top or something? Thanks
  • Asish
    Asish about 3 years
    I am getting this error getElementsAtEvent is not a function