Javascript Chart.js 中饼图上的单击事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26257268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 22:38:07  来源:igfitidea点击:

Click events on Pie Charts in Chart.js

javascriptjquerychartschart.js

提问by Newtt

I've got a question regard Chart.js.

我有一个关于 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?

我使用提供的文档绘制了多个饼图。我想知道是否单击其中一个图表的某个切片,我可以根据该切片的值进行 ajax 调用吗?

For example, if this is my data

例如,如果这是我的 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 Redlabelled slice and call a url of the following form: example.com?label=red&value=300? If yes, how do I go about this?

我是否可以单击Red标记的切片并调用以下形式的网址: example.com?label=red&value=300?如果是,我该怎么做?

回答by Tobías

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

更新:正如@Soham Shetty 评论的那样,getSegmentsAtEvent(event)只适用于 1.x 和 2.xgetElementsAtEvent应该使用。

.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.
};

.getElementsAtEvent(e)

查找事件点下的元素,然后返回同一数据索引处的所有元素。这在内部用于“标签”模式突出显示。

调用getElementsAtEvent(event)传递事件参数或 jQuery 事件的 Chart 实例将返回与该事件相同位置的点元素。

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/

示例:https: //jsfiddle.net/u1szh96g/208/



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

原始答案(适用于 Chart.js 1.x 版本):

You can achieve this using getSegmentsAtEvent(event)

您可以使用 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.

调用getSegmentsAtEvent(event)传递事件参数或 jQuery 事件的 Chart 实例将返回与该事件相同位置的段元素。

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>

回答by alessandrob

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:

使用 Chart.JS 版本2.1.3,比这个更旧的答案不再有效。使用 getSegmentsAtEvent(event) 方法将在控制台上输出此消息:

getSegmentsAtEvent is not a function

getSegmentsAtEvent 不是函数

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.

所以我认为它必须被删除。老实说,我没有阅读任何变更日志。要解决这个问题,只需使用getElementsAtEvent(event)方法,因为它可以在 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.

希望能帮助到你。

回答by Tom Glover

Chart.js 2.0 has made this even easier.

Chart.js 2.0 使这变得更加容易。

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.

它在整个图表上触发,但如果您单击饼图,该饼图的模型包括可用于获取值的索引。

回答by Lakshmi RM

Working fine chartJs sector onclick

工作精细 chartJs 部门 onclick

ChartJS : pie Chart - Add options "onclick"

ChartJS:饼图 - 添加选项“onclick”

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

回答by Sachin Raghav

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>

回答by Anwar

If using a Donught Chart, and you want to prevent user to trigger your event on click inside the empty space around your chart circles, you can use the following alternative :

如果使用甜甜圈图表,并且您希望防止用户在图表圆圈周围的空白区域内点击触发您的事件,您可以使用以下替代方法:

var myDoughnutChart = new Chart(ctx).Doughnut(data);

document.getElementById("myChart").onclick = function(evt){
    var activePoints = myDoughnutChart.getSegmentsAtEvent(evt);

    /* this is where we check if event has keys which means is not empty space */       
    if(Object.keys(activePoints).length > 0)
    {
        var label = activePoints[0]["label"];
        var value = activePoints[0]["value"];
        var url = "http://example.com/?label=" + label + "&value=" + value
        /* process your url ... */
    }
};

回答by Carlo Bos

To successfully track click events and on what graph element the user clicked, I did the following in my .js file I set up the following variables:

为了成功跟踪点击事件以及用户点击的图形元素,我在我的 .js 文件中执行了以下操作,我设置了以下变量:

vm.chartOptions = {
    onClick: function(event, array) {
        let element = this.getElementAtEvent(event);
        if (element.length > 0) {
            var series= element[0]._model.datasetLabel;
            var label = element[0]._model.label;
            var value = this.data.datasets[element[0]._datasetIndex].data[element[0]._index];
        }
    }
};
vm.graphSeries = ["Series 1", "Serries 2"];
vm.chartLabels = ["07:00", "08:00", "09:00", "10:00"];
vm.chartData = [ [ 20, 30, 25, 15 ], [ 5, 10, 100, 20 ] ];

Then in my .html file I setup the graph as follows:

然后在我的 .html 文件中,我按如下方式设置图表:

<canvas id="releaseByHourBar" 
    class="chart chart-bar"
    chart-data="vm.graphData"
    chart-labels="vm.graphLabels" 
    chart-series="vm.graphSeries"
    chart-options="vm.chartOptions">
</canvas>

回答by Steve The Sultan

If you are using TypeScript, the code is a little funky because there is no type inference, but this works to get the index of the data that has been supplied to the chart: // events public chartClicked(e:any):void { //console.log(e);

如果您使用的是 TypeScript,则代码有点古怪,因为没有类型推断,但这可以获取已提供给图表的数据的索引: // events public chartClicked(e:any):void { //console.log(e);

    try {
        console.log('DS ' + e.active['0']._datasetIndex);
        console.log('ID ' +  e.active['0']._index);
        console.log('Label: ' + this.doughnutChartLabels[e.active['0']._index]);
        console.log('Value: ' + this.doughnutChartData[e.active['0']._index]);


    } catch (error) {
        console.log("Error In LoadTopGraph", error);
    }

    try {
        console.log(e[0].active);
    } catch (error) {
        //console.log("Error In LoadTopGraph", error);
    }



}

回答by PradipPatel1411

  var ctx = document.getElementById('pie-chart').getContext('2d');
 var myPieChart = new Chart(ctx, {
                // The type of chart we want to create
                type: 'pie',

            });

             //define click event
  $("#pie-chart").click(
            function (evt) {
                var activePoints = myPieChart.getElementsAtEvent(evt);
                var labeltag = activePoints[0]._view.label;

                      });

回答by jared maldonado

Within options place your onclick and call the function you need as an example the ajax you need, I'll leave the example so that every click on a point tells you the value and you can use it in your new function.

在选项中放置您的 onclick 并调用您需要的函数作为您需要的 ajax 示例,我将保留该示例,以便每次点击一个点都会告诉您该值,您可以在新函数中使用它。

    options: {
        plugins: {
            // Change options for ALL labels of THIS CHART
            datalabels: {
                color: 'white',
                //backgroundColor:'#ffce00',
                align: 'start'
            }
        },
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero:true,
                    fontColor: "white"
                },gridLines: {
                        color: 'rgba(255,255,255,0.1)',
                        display: true
                    }
            }],
            xAxes: [{
                ticks: {
                    fontColor: "white"
                },gridLines: {                        
                        display: false
                    }
            }]
        },
        legend: {
        display: false

    },
    //onClick: abre     
        onClick:function(e){ 
    var activePoints = myChart.getElementsAtEvent(e); 
    var selectedIndex = activePoints[0]._index; 
    alert(this.data.datasets[0].data[selectedIndex]); 


} 
    }