我刚刚开始使用Chart.js,我很快就感到非常沮丧。我的堆积条形图有效,但我无法点击“事件”。
我发现了一个来自Chart.js的comment on GitHub by nnnick
,声明使用getBarsAtEvent
函数,即使在Chart.js documentation中根本找不到这个函数(继续,搜索它)。文档确实提到了getElementsAtEvent
参考的chart
函数,但仅适用于折线图。
我在canvas元素上设置了一个事件监听器(正确的方式):
canv.addEventListener('click', handleClick, false);
...但在我的handleClick
函数中,chart.getBarsAtEvent
未定义!
现在,在Chart.js文档中,有一个关于为条形图注册click事件的不同方法的声明。这与2年前nnnick
对GitHub的评论大不相同。
在Global Chart Defaults中,您可以为图表设置onClick
函数。我在我的图表配置中添加了一个onClick
函数,它没有做任何事......
那么,我如何获得点击回调以适用于我的条形图?!
任何帮助将不胜感激。谢谢!
P.S。:我没有使用GitHub的主版本。我试过,但它一直在尖叫,require is undefined
和我还没准备好包括CommonJS,以便我可以使用这个图表库。我宁愿写自己的dang图表。相反,我下载并使用Standard Build版本,我直接从documentation page顶部的链接下载。
示例:以下是我正在使用的配置示例:
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
}
};
通过查看Chart.js source code,我设法找到了我的问题的答案。
Chart.js,Standard Build的第3727行提供的是方法.getElementAtEvent
。此方法返回单击的“图表元素”。这里有足够的数据来确定在点击的数据集的深入视图中显示哪些数据。
在chart.getElementAtEvent
返回的数组的第一个索引上是一个值_datasetIndex
。此值显示单击的数据集的索引。
我相信,点击的特定栏由_index
值注明。在我的问题的例子中,_index
将指向One
中的chart_config.data.labels
。
我的handleClick
功能现在看起来像这样:
function handleClick(evt)
{
var activeElement = chart.getElementAtEvent(evt);
..其中chart
是chart.js在执行时创建的图表的引用:
chart = new Chart(canv, chart_config);
因此,点击选择的特定数据集可以在以下位置找到:
chart_config.data.datasets[activeElement[0]._datasetIndex].data[activeElement[0]._index];
你有它。我现在有一个数据点,我可以构建一个查询来显示被点击的栏的数据。
嗨这是选项下的点击事件,它从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);
}
我在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)
}
}
}
做得好!这似乎返回了被绘制的数据值,在许多情况下可能会出现不止一次,因此不清楚点击的内容。
这将返回被单击的栏的实际数据标签。在深入研究类别时,我发现这更有用。
chart_config.data.labels[activeElement[0]._index]
我能够以另一种方式完成这项工作。可能不受支持,但有时候,我发现标签和值都不足以为我提供必要的信息来填充钻取。
所以我所做的是为数据添加一组自定义属性:
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],
...等等
然后,当我需要将钻取键推入另一个ajax调用时,我能够得到它:
var theDrillThroughKey = theChart.config.data.datakeys[activePoints[0]._index];
所以我真的不确定将自定义元素添加到图表的数据中是否合适,但到目前为止它在Chrome,IE和Firefox中都有用。我需要能够将更多信息输入到钻孔中,而不是我真正希望显示的信息。
完整的例子:https://wa.rrdsb.com/chartExamples
思考?
假设您使用如下方法声明了图表:
window.myBar = new Chart({chart_name}, {
type: xxx,
data: xxx,
events: ["click"],
options: {
...
}
});
声明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") { ... }
}