我有一张来自chart.js的雷达图表。目前,它加载了所有可行的数据,并且支持图例通过单击图例标签来表现,该标签可以切换与图例相关联的数据。我希望能够点击图例标签,然后切换所有其他关闭并可能引入“全部”选项?这是否适用于chart.js?
以下是我的图表现在的样子:
var chartata = {
labels: [
"Strategic Development and Ownership",
"Driving change through others",
"Exec Disposition",
"Commercial Acumen",
"Develops High Performance Teams",
"Innovation and risk taking",
"Global Leadership",
"Industry Leader"
]};
var ctx = $("#allRadarData");
var config = {
type: 'radar',
data: chartata,
animationEasing: 'linear',
options: {
legend: {
fontSize: 10,
display: true,
itemWidth: 150,
position: 'bottom',
fullWidth: true,
labels: {
fontColor: 'rgb(0,0,0)',
boxWidth: 10,
padding: 20
},
},
tooltips: {
enabled: true
},
scale: {
ticks: {
fontSize: 15,
beginAtZero: true,
stepSize: 1,
max: 5
}
}
},
},
LineGraph = new Chart(ctx, config);
var colorArray = [
["#f44336", false],
["#E91E63", false],
["#9C27B0", false],
["#673AB7", false],
['#3F51B5', false],
["#607D8B", false]
];
for (var i in data) {
tmpscore=[];
tmpscore.push(data[i].score1);
tmpscore.push(data[i].score2);
tmpscore.push(data[i].score3);
tmpscore.push(data[i].score4);
tmpscore.push(data[i].score5);
tmpscore.push(data[i].score6);
tmpscore.push(data[i].score7);
tmpscore.push(data[i].score8);
var color, done = false;
while (!done) {
var test = colorArray[parseInt(Math.random() * 10)];
if (!test[1]) {
color = test[0];
colorArray[colorArray.indexOf(test)][1] = true;
done = !done;
}
}
newDataset = {
label: data[i].firstName+' '+data[i].lastName,
borderColor: color,
backgroundColor: "rgba(0,0,0,0)",
data: tmpscore,
};
config.data.datasets.push(newDataset);
}
LineGraph.update();
},
});
});
答案 0 :(得分:12)
要反转图例标签点击的行为方式,您可以使用图例onClick
选项来实现新的点击逻辑。下面是一个示例,它将为您提供所需的行为。请注意,在此实现中,如果您单击已隐藏的标签,它将取消隐藏它,并隐藏所有其他标签。
function(e, legendItem) {
var index = legendItem.datasetIndex;
var ci = this.chart;
var alreadyHidden = (ci.getDatasetMeta(index).hidden === null) ? false : ci.getDatasetMeta(index).hidden;
ci.data.datasets.forEach(function(e, i) {
var meta = ci.getDatasetMeta(i);
if (i !== index) {
if (!alreadyHidden) {
meta.hidden = meta.hidden === null ? !meta.hidden : null;
} else if (meta.hidden === null) {
meta.hidden = true;
}
} else if (i === index) {
meta.hidden = null;
}
});
ci.update();
};
这也是working example。
但是,如果您想要一个更复杂的逻辑,当至少有一个其他标签当前可见时,该逻辑将取消隐藏当前隐藏的标签,那么您可以使用以下实现。
function(e, legendItem) {
var index = legendItem.datasetIndex;
var ci = this.chart;
var alreadyHidden = (ci.getDatasetMeta(index).hidden === null) ? false : ci.getDatasetMeta(index).hidden;
var anyOthersAlreadyHidden = false;
var allOthersHidden = true;
// figure out the current state of the labels
ci.data.datasets.forEach(function(e, i) {
var meta = ci.getDatasetMeta(i);
if (i !== index) {
if (meta.hidden) {
anyOthersAlreadyHidden = true;
} else {
allOthersHidden = false;
}
}
});
// if the label we clicked is already hidden
// then we now want to unhide (with any others already unhidden)
if (alreadyHidden) {
ci.getDatasetMeta(index).hidden = null;
} else {
// otherwise, lets figure out how to toggle visibility based upon the current state
ci.data.datasets.forEach(function(e, i) {
var meta = ci.getDatasetMeta(i);
if (i !== index) {
// handles logic when we click on visible hidden label and there is currently at least
// one other label that is visible and at least one other label already hidden
// (we want to keep those already hidden still hidden)
if (anyOthersAlreadyHidden && !allOthersHidden) {
meta.hidden = true;
} else {
// toggle visibility
meta.hidden = meta.hidden === null ? !meta.hidden : null;
}
} else {
meta.hidden = null;
}
});
}
ci.update();
}
以下是此替代实施的working example。
要在特定代码中使用此功能,只需使用onClick
属性将其放入图表的图例配置中。
var config = {
type: 'radar',
data: chartata,
animationEasing: 'linear',
options: {
legend: {
fontSize: 10,
display: true,
itemWidth: 150,
position: 'bottom',
fullWidth: true,
labels: {
fontColor: 'rgb(0,0,0)',
boxWidth: 10,
padding: 20
},
onClick: function(e, legendItem) {
var index = legendItem.datasetIndex;
var ci = this.chart;
var alreadyHidden = (ci.getDatasetMeta(index).hidden === null) ? false : ci.getDatasetMeta(index).hidden;
ci.data.datasets.forEach(function(e, i) {
var meta = ci.getDatasetMeta(i);
if (i !== index) {
if (!alreadyHidden) {
meta.hidden = meta.hidden === null ? !meta.hidden : null;
} else if (meta.hidden === null) {
meta.hidden = true;
}
} else if (i === index) {
meta.hidden = null;
}
});
ci.update();
},
},
tooltips: {
enabled: true
},
scale: {
ticks: {
fontSize: 15,
beginAtZero: true,
stepSize: 1,
max: 5
}
}
},
},
目前尚不清楚你想要什么样的行为'所有'选项,但可能能够使用legend.labels.generateLabels
选项来欺骗Chart.js添加一个' all' label(你必须修改上面的onClick
逻辑来处理这个想法。
但是,我认为更好的解决方案是在chart.js画布之外实现自己的链接或按钮,以显示/隐藏所有数据集。查看Chart.js radar sample page,了解它们如何将按钮与图表操作绑定在一起。
答案 1 :(得分:2)
请为饼图尝试此代码以获取单个数据集,以切换chart.js饼图的行为。
onClick:function(e, legendItem){
var index = legendItem.index;
var ci = this.chart;
var meta = ci.getDatasetMeta(0);
var CurrentalreadyHidden = (meta.data[index].hidden==null) ? false : (meta.data[index].hidden);
var allShown=true;
$.each(meta.data,function(ind0,val0){
if(meta.data[ind0].hidden){
allShown=false;
return false;
}else{
allShown=true;
}
});
if(allShown){
$.each(meta.data,function(ind,val){
if(meta.data[ind]._index===index){
meta.data[ind].hidden=false;
}else{
meta.data[ind].hidden=true;
}
});
}else{
if(CurrentalreadyHidden){
$.each(meta.data,function(ind,val){
if(meta.data[ind]._index===index){
meta.data[ind].hidden=false;
}else{
meta.data[ind].hidden=true;
}
});
}else{
$.each(meta.data,function(ind,val){
meta.data[ind].hidden=false;
});
}
}
ci.update();
}