有一些解决方案,可以使用图例onClick来打开/关闭点击图表上所有其他数据集的可见性,但是我需要一种在多个图表上同步此切换的方法,只要它们具有相同的标签/图例。例如,我有6个图表显示有关同一数据的不同信息。但是,并非所有图表都具有所有数据集。一个可能有5个数据集,另一个可能有3个,依此类推。而且它们也可能不会以相同的顺序出现。
目标是能够单击一个图表上的图例项目,并在所有图表上切换该项目。
由于找不到现有解决方案,因此我将其发布。
答案 0 :(得分:1)
为此,我将所有图表放在全局变量中并遍历它们,以legendItem.text
而不是legendItem.datasetindex
来匹配数据集,因为标签可能存在或可能不存在,甚至不在在其他图表上的相同索引位置。
这是我创建/替换多个图表的方法:https://stackoverflow.com/a/51882403/1181367
这是 legend onClick 切换解决方案:
var config = {
type: type,
data: {
labels: labels,
datasets: datasets
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
}
}]
},
legend: {
position: 'right',
onClick: function (e, legendItem) {
var text = legendItem.text;
Object.keys(charts).forEach(function (id) {
// loop through the charts
var ci = charts[id].chart
var cindex = (function () {
var match = null;
ci.legend.legendItems.forEach(function (item) {
if (item.text == text) {
// get index for legend.text that matches clicked legend.text
match = item.datasetIndex;
}
});
return match;
})();
if (cindex !== null) {
// if there's a match
var alreadyHidden = (ci.getDatasetMeta(cindex).hidden === null) ? false : ci.getDatasetMeta(cindex).hidden;
ci.data.datasets.forEach(function (e, i) {
var meta = ci.getDatasetMeta(i);
if (i !== cindex) {
if (!alreadyHidden) {
meta.hidden = meta.hidden === null ? !meta.hidden : null;
} else if (meta.hidden === null) {
meta.hidden = true;
}
} else if (i === cindex) {
meta.hidden = null;
}
});
ci.update();
}
});
}
}
}
};
答案 1 :(得分:0)
在这里使用克里斯的答案https://stackoverflow.com/a/51920456/671140之后,我创建了一个简化的解决方案。
var config = {
type: type,
data: {
labels: labels,
datasets: datasets
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
}
}]
},
legend: {
position: 'right',
onClick: function (e, legendItem) {
var text = legendItem.text;
Object.keys(charts).forEach(function (id) {
// loop through the charts
var ci = charts[id].chart
ci.legend.legendItems.forEach(function (item) {
if (item.text == text) {
ci.options.legend.onClick.call(chart.legend, null, item);
ci.update();
}
});
});
}
}
}
};
使用该解决方案的好处是,它将调用已添加到任何图表图例的任何自定义onClick()处理程序。
答案 2 :(得分:0)
如果任何人正在寻找一种将饼图图例与折线图图例同步的方法,请尝试执行此操作(如果图表的类型相同,它也应该可以正常工作):
onClick: function(e, legendItem) {
// Save name of clicked label, for later comparison
var legendName = legendItem.text;
// Iterate through global charts array
Object.keys(myCharts).forEach(function(id) {
// Assign shorthand variable to address chart easier
var chrt = myCharts[id];
// Determine chart type
var chartType = chrt.config.type;
// Iterate through each legend in the chart
chrt.legend.legendItems.forEach(function(item) {
// If legend name matches clicked label
if (item.text == legendName) {
if (chartType == 'pie') { // If pie chart
if (chrt.getDatasetMeta(0).data[item.index].hidden === true) chrt.getDatasetMeta(0).data[item.index].hidden = false;
else if (chrt.getDatasetMeta(0).data[item.index].hidden === false) chrt.getDatasetMeta(0).data[item.index].hidden = true;
} else if (chartType == 'line') { // If line chart
if (chrt.getDatasetMeta(item.datasetIndex).hidden === true) chrt.getDatasetMeta(item.datasetIndex).hidden = null;
else if (chrt.getDatasetMeta(item.datasetIndex).hidden === null) chrt.getDatasetMeta(item.datasetIndex).hidden = true;
}
// Trigger chart update
chrt.update();
}
});
});
将此onClick函数放置在选项的图例部分中,就像您在其他答案中看到的一样。
我的折线图是日常趋势,而饼图比较了整个范围内的总计。 图表的标签必须具有相同的名称才能正常工作。
与其他解决方案一样,您必须将两个图表都存储在一个全局变量中,例如:
window.myCharts['pieChart1']
window.myCharts['lineChart1']
由于隐藏数据集并在整个数据集中获取它们的索引因图表类型而异,因此此功能将检查图表类型并采取相应的措施。 还要注意,对于饼图,“隐藏”设置为true或false,但是对于折线图,它为true或null(感谢chart.js)。 我确定您可以将其扩展为其他图表类型,但是我只为设置“线形”和“饼形”图表而烦恼。