Javascript Chart.js:条形图点击事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37122484/
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
Chart.js: Bar Chart Click Events
提问by WebWanderer
I've just started working with Chart.js, and I am getting very frustrated very quickly. I have my stacked bar chart working, but I can't get the click "events" to work.
我刚刚开始使用 Chart.js,很快就感到非常沮丧。我的堆积条形图可以工作,但我无法让点击“事件”起作用。
I have found a comment on GitHub by nnnick
from Chart.js stating to use the function getBarsAtEvent
, even though this function cannot be found in the Chart.js documentationat all (go ahead, do a search for it). The documentation does mention the getElementsAtEvent
function of the chart
reference, but that is for Line Charts only.
我在 GitHub 上找到了nnnick
来自 Chart.js的评论,说明要使用该函数getBarsAtEvent
,即使在Chart.js 文档中根本找不到该函数(继续,搜索它)。文档确实提到了参考的getElementsAtEvent
功能chart
,但这仅适用于折线图。
I set an event listener (the right way) on my canvas element:
我在画布元素上设置了一个事件侦听器(以正确的方式):
canv.addEventListener('click', handleClick, false);
...yet in my handleClick
function, chart.getBarsAtEvent
is undefined!
...然而在我的handleClick
函数中,chart.getBarsAtEvent
是未定义的!
Now, in the Chart.js document, there is a statement about a different way to register the click event for the bar chart. It is much different than nnnick
's comment on GitHub from 2 years ago.
现在,在 Chart.js 文档中,有一条关于为条形图注册点击事件的不同方式的声明。这nnnick
与 2 年前在 GitHub 上的评论大不相同。
In the Global Chart Defaultsyou can set an onClick
function for your chart. I added an onClick
function to my chart configuration, and it did nothing...
在全局图表默认值中,您可以onClick
为您的图表设置一个函数。我onClick
在图表配置中添加了一个函数,但它什么也没做...
So, how the heck do I get the on-click-callback to work for my bar chart?!
那么,我到底如何让点击回调为我的条形图工作?!
Any help would be greatly appreciated. Thanks!
任何帮助将不胜感激。谢谢!
P.S.:I am not using the master build from GitHub. I tried, but it kept screaming that require is undefined
and I was not ready to include CommonJS just so that I could use this chart library. I would rather write my own dang charts. Instead, I downloaded and am using the Standard Buildversion that I downloaded straight from the link at the top of the documentation page.
PS:我没有使用 GitHub 的主版本。我尝试过,但它一直在尖叫,require is undefined
我还没有准备好包含 CommonJS 以便我可以使用这个图表库。我宁愿写我自己的 dang 图表。相反,我下载并使用了直接从文档页面顶部的链接下载的标准构建版本。
EXAMPLE:Here is an example of the configuration I am using:
示例:这是我正在使用的配置示例:
var chart_config = {
type: 'bar',
data: {
labels: ['One', 'Two', 'Three'],
datasets: [
{
label: 'Dataset 1',
backgroundColor: '#848484',
data: [4, 2, 6]
},
{
label: 'Dataset 2',
backgroundColor: '#848484',
data: [1, 6, 3]
},
{
label: 'Dataset 3',
backgroundColor: '#848484',
data: [7, 5, 2]
}
]
},
options: {
title: {
display: false,
text: 'Stacked Bars'
},
tooltips: {
mode: 'label'
},
responsive: true,
maintainAspectRatio: false,
scales: {
xAxes: [
{
stacked: true
}
],
yAxes: [
{
stacked: true
}
]
},
onClick: handleClick
}
};
回答by WebWanderer
I managed to find the answer to my question by looking through the Chart.js source code.
我通过查看Chart.js 源代码设法找到了我的问题的答案。
Provided at line 3727 of Chart.js, Standard Build, is the method .getElementAtEvent
. This method returns me the "chart element" that was clicked on. There is sufficent data here to determine what data to show in a drill-down view of the dataset clicked on.
在 Chart.js, Standard Build 的第 3727 行提供的是方法.getElementAtEvent
。此方法返回我点击的“图表元素”。这里有足够的数据来确定要在单击的数据集的钻取视图中显示哪些数据。
On the first index of the array returned by chart.getElementAtEvent
is a value _datasetIndex
. This value shows the index of the dataset that was clicked on.
返回的数组的第一个索引chart.getElementAtEvent
是一个值_datasetIndex
。该值显示被点击的数据集的索引。
The specific bar that was clicked on, I believe, is noted by the value _index
. In my example in my question, _index
would point to One
in chart_config.data.labels
.
我相信,被点击的特定栏是由值记录的_index
。在我的问题中的示例中,_index
将指向One
in chart_config.data.labels
。
My handleClick
function now looks like this:
我的handleClick
函数现在看起来像这样:
function handleClick(evt)
{
var activeElement = chart.getElementAtEvent(evt);
..where chart
is the reference of the chart created by chart.js when doing:
..wherechart
是 chart.js 创建的图表的引用:
chart = new Chart(canv, chart_config);
The specific set of data that was selected by the click can therefore be found as:
因此,可以通过单击选择的特定数据集如下所示:
chart_config.data.datasets[activeElement[0]._datasetIndex].data[activeElement[0]._index];
And there you have it. I now have a datapoint that I can build a query from to display the data of the bar that was clicked on.
你有它。我现在有一个数据点,我可以从中构建查询以显示被点击的栏的数据。
回答by Vaimeo
Hi this is the click event under options which is getting values from x and y-axis
嗨,这是从 x 和 y 轴获取值的选项下的点击事件
onClick: function(c,i) {
e = i[0];
console.log(e._index)
var x_value = this.data.labels[e._index];
var y_value = this.data.datasets[0].data[e._index];
console.log(x_value);
console.log(y_value);
}
回答by Asif Karim Bherani
I found this solution at https://github.com/valor-software/ng2-charts/issues/489
我在https://github.com/valor-software/ng2-charts/issues/489找到了这个解决方案
public chartClicked(e: any): void {
if (e.active.length > 0) {
const chart = e.active[0]._chart;
const activePoints = chart.getElementAtEvent(e.event);
if ( activePoints.length > 0) {
// get the internal index of slice in pie chart
const clickedElementIndex = activePoints[0]._index;
const label = chart.data.labels[clickedElementIndex];
// get value by index
const value = chart.data.datasets[0].data[clickedElementIndex];
console.log(clickedElementIndex, label, value)
}
}
}
回答by Matt R O'Connor
Well done! This seems to return the data value being charted though, which in many cases might be possible to appear more than once, thus making it unclear what was clicked on.
做得好!这似乎返回了绘制的数据值,在许多情况下可能会出现不止一次,因此不清楚点击了什么。
This will return the actual data label of the bar being clicked on. I found this more useful when drilling down into a category.
这将返回被点击的栏的实际数据标签。当深入到一个类别时,我发现这更有用。
chart_config.data.labels[activeElement[0]._index]
回答by sergio0983
I had the same problem with multiple datasets, and used this workaround:
我在处理多个数据集时遇到了同样的问题,并使用了以下解决方法:
var clickOnChart = function(dataIndex){
...
}
var lastHoveredIndex = null;
var chart_options = {
...
tooltips: {
...
callbacks: {
label: function(tooltipItem, chart) {
var index = tooltipItem.datasetIndex;
var value = chart.datasets[index].data[0];
var label = chart.datasets[index].label;
lastHoveredIndex = index;
return value + "";
}
}
},
onClick:function(e, items){
if ( items.length == 0 ) return; //Clicked outside any bar.
clickOnChart(lastHoveredIndex);
}
}
回答by Abdullah Shahid
You can use onClick like this.
您可以像这样使用 onClick。
var worstCells3GBoxChart = new Chart(ctx, {
type: 'bar',
data: {
labels: lbls,
datasets: [{
label: 'Worst Cells by 3G',
data: datas,
backgroundColor: getColorsUptoArray('bg', datas.length),
borderColor: getColorsUptoArray('br', datas.length),
borderWidth: 1
}]
},
options: {
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
onClick: function (e) {
debugger;
var activePointLabel = this.getElementsAtEvent(e)[0]._model.label;
alert(activePointLabel);
}
}
});
回答by Chris Denby
I was able to make this work in another way. Might not be supported, but sometimes, I find that neither the label nor the value is adequate to get me the necessary information to populate a drill-through.
我能够以另一种方式完成这项工作。可能不受支持,但有时,我发现标签和值都不足以为我提供填充钻取所需的信息。
So what I did was add a custom set of attributes to the data:
所以我所做的是向数据添加一组自定义属性:
var ctx = document.getElementById("cnvMyChart").getContext("2d");
if(theChart != null) {theChart.destroy();}
theChart = new Chart(ctx, {
type: typ,
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datakeys: ["thefirstone","thesecondone","thethirdone","thefourthone","thefifthone","thesixthone"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
...etc
...等等
Then when I need to push the drillthrough key into another ajax call, I was able to get it with this:
然后,当我需要将钻取键推入另一个 ajax 调用时,我可以通过以下方式获得它:
var theDrillThroughKey = theChart.config.data.datakeys[activePoints[0]._index];
So I'm really not sure that it's appropriate to be adding custom elements into the data for the Chart, but it's working so far in Chrome, IE and Firefox. I needed to be able to put more information into the drillthrough than I really wanted displayed.
所以我真的不确定将自定义元素添加到图表的数据中是否合适,但到目前为止它在 Chrome、IE 和 Firefox 中工作。我需要能够在钻取中放入比我真正想要显示的更多的信息。
Example of the full thing: https://wa.rrdsb.com/chartExamples
完整示例:https: //wa.rrdsb.com/chartExamples
Thoughts?
想法?
回答by Marquistador
Let's say that you declared a chart using a method like so:
假设您使用如下方法声明了一个图表:
window.myBar = new Chart({chart_name}, {
type: xxx,
data: xxx,
events: ["click"],
options: {
...
}
});
A good way of declaring onclick events would involve listening for the canvas click, like so:
声明 onclick 事件的一个好方法是侦听画布点击,如下所示:
({chart_name}.canvas).onclick = function(evt) {
var activePoints = myBar.getElementsAtEvent(evt);
// let's say you wanted to perform different actions based on label selected
if (activePoints[0]._model.label == "label you are looking for") { ... }
}