我正在处理图表.js,想为标签实现全选和全选选项。我试图找出它,但无法得到任何这样的东西。
如果可以实现任何此类功能,请帮助我。
如果您需要显示/隐藏选择/取消选择所有标签的图表,下面是一个示例:
var barChartData = {
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32],
datasets: [{
label: 'One',
backgroundColor: 'rgba(206, 0, 23, 1)',
data: [0, 1, 3, 0, 2, 0, 0, 2, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 2, 1, 0, 1, 2, 1, 1, 0, 0, 0, 2, 2, 0, 3]
}, {
label: 'Two',
backgroundColor: 'rgba(206, 0, 23, 0.75)',
data: [0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1]
}, {
label: 'Three',
backgroundColor: 'rgba(206, 0, 23, 0.5)',
data: [0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 2, 0, 0, 0, 1, 0, 0, 0, 0, 1]
}]
};
var ctx = document.getElementById('canvas').getContext('2d');
var chartInstance = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
title: {
display: false,
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true
}]
}
}
});
$("#toggle").click(function() {
chartInstance.data.datasets.forEach(function(ds) {
ds.hidden = !ds.hidden;
});
chartInstance.update();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<button id="toggle">show/hide all</button>
<canvas id="canvas" height="500" width="800"></canvas>
杰斯菲德尔:https://jsfiddle.net/beaver71/00q06vjp/
学分:见 https://github.com/chartjs/Chart.js/issues/3009
更新:对于饼图使用"元",请参阅:https://jsfiddle.net/beaver71/u0y0919b/
正确答案的结果是:
chart.data.datasets.forEach((obj, index) => {
let meta = this.eval_chart.getDatasetMeta(index);
meta.hidden = !meta.hidden || null;
});
chart.update();
如文档中所述: https://www.chartjs.org/docs/latest/configuration/legend.html#custom-on-click-actions
V3 答案
您可以将自定义generateLabels
函数与自定义onClick
一起使用,以将其作为额外的图例项获取,如下所示:
const defaultLegendClickHandler = Chart.defaults.plugins.legend.onClick;
const pieDoughnutLegendClickHandler = Chart.controllers.doughnut.overrides.plugins.legend.onClick;
const options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderColor: 'pink'
},
{
label: '# of Points',
data: [7, 11, 5, 8, 3, 7],
borderColor: 'orange'
}
]
},
options: {
plugins: {
legend: {
onClick: (evt, legendItem, legend) => {
const type = legend.chart.config.type;
let allLegendItemsState = [];
if (legendItem.text === 'hide all datasets' || legendItem.text === 'show all datasets') {
if (typeof legend.hideAll === 'undefined') {
legend.hideAll = false;
}
legend.chart.data.datasets.forEach((dataset, i) => {
legend.chart.setDatasetVisibility(i, legend.hideAll)
});
legend.hideAll = !legend.hideAll;
legend.chart.update();
return;
}
if (type === 'pie' || type === 'doughnut') {
pieDoughnutLegendClickHandler(evt, legendItem, legend)
} else {
defaultLegendClickHandler(evt, legendItem, legend);
}
allLegendItemsState = legend.chart.data.datasets.map((e, i) => (legend.chart.getDatasetMeta(i).hidden));
if (allLegendItemsState.every(el => !el)) {
legend.hideAll = false;
legend.chart.update();
} else if (allLegendItemsState.every(el => el)) {
legend.hideAll = true;
legend.chart.update();
}
},
labels: {
generateLabels: (chart) => {
const datasets = chart.data.datasets;
const {
labels: {
usePointStyle,
pointStyle,
textAlign,
color
}
} = chart.legend.options;
const legendItems = chart._getSortedDatasetMetas().map((meta) => {
const style = meta.controller.getStyle(usePointStyle ? 0 : undefined);
return {
text: datasets[meta.index].label,
fillStyle: style.backgroundColor,
fontColor: color,
hidden: !meta.visible,
lineCap: style.borderCapStyle,
lineDash: style.borderDash,
lineDashOffset: style.borderDashOffset,
lineJoin: style.borderJoinStyle,
strokeStyle: style.borderColor,
pointStyle: pointStyle || style.pointStyle,
rotation: style.rotation,
textAlign: textAlign || style.textAlign,
datasetIndex: meta.index
};
});
legendItems.push({
text: (!chart.legend.hideAll || typeof chart.legend.hideAll === 'undefined') ? 'hide all datasets' : 'show all datasets',
fontColor: color,
fillStyle: 'turquoise', // Box color
strokeStyle: 'turquoise', // LineCollor around box
});
return legendItems;
}
}
}
}
}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.6.0/chart.js"></script>
</body>
对于 ChartJS 2.9.3,这是按照 David 在注释中的要求工作的:
const chart = ...
chart.data.datasets.forEach(dataset => {
Object.keys(dataset._meta).forEach(key => {
const current = !dataset._meta[key].hidden
dataset._meta[key].hidden = current || null
})
})
chart.update()
使用按钮切换所有内容,同时在图表图例中很好地使用单个切换。
对于 v4 和 TypeScript,或者如果你想确保你不会因为 meta 可以未定义而出现异常,我使用了下面的代码。我想确保它始终将所有切换为处于相同状态(全部选择/取消选择(,因此隐藏变量位于函数范围之外。
我的回答受到@ivom回答的启发。
let hidden = false
function toggleAllDatasets() {
if (!chart) {
return
}
hidden = !hidden
chart.data.datasets.forEach((obj, index) => {
let meta = chart?.getDatasetMeta(index)
if (!meta) {
return
}
meta!.hidden = hidden
});
chart.update()
}