0👍
You could leverage on onClick
option on legend, hiding the datasets of the same stack and change a bit the filter callback returning if the datasets with empty labels are visibile.
const legendClickHandler = Chart.defaults.plugins.legend.onClick;
const ctx = document.getElementById("myChart");
const myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['January', 'Fabruary', 'March', 'April', 'May', 'June', 'July'],
datasets: [{
label: 'user 1 online',
data: [50, 35, 45, 47, 0, 3, 27],
backgroundColor: [
'rgba(40, 139, 170, 1)'
],
borderColor: [
'rgb(40, 139, 170)'
],
stack: 'Stack 0',
borderWidth: 1
},
{
label: '',
data: [30, 20, 20, 67, 10, 25, 3],
backgroundColor: [
'rgb(196, 201, 201)'
],
borderColor: [
'rgb(196, 201, 201)'
],
stack: 'Stack 0',
borderWidth: 1
},
{
label: 'user 2 online',
data: [50, 35, 45, 47, 0, 3, 27],
backgroundColor: [
'rgba(107, 112, 176, 1)'
],
borderColor: [
'rgb(107, 112, 176)'
],
stack: 'Stack 1',
borderWidth: 1
},
{
label: '',
data: [30, 20, 20, 67, 10, 25, 3],
backgroundColor: [
'rgb(196, 201, 201)'
],
borderColor: [
'rgb(196, 201, 201)'
],
stack: 'Stack 1',
borderWidth: 1
},
{
label: 'user 3 online',
data: [50, 35, 45, 47, 0, 3, 27],
backgroundColor: [
'rgba(208, 98, 155, 1)'
],
borderColor: [
'rgb(208, 98, 155)'
],
stack: 'Stack 2',
borderWidth: 1
},
{
label: '',
data: [30, 20, 20, 67, 10, 25, 3],
backgroundColor: [
'rgb(196, 201, 201)'
],
borderColor: [
'rgb(196, 201, 201)'
],
stack: 'Stack 2',
borderWidth: 1
},
{
label: 'user 4 online',
data: [50, 35, 45, 47, 0, 3, 27],
backgroundColor: [
'rgba(144, 71, 158, 1)'
],
borderColor: [
'rgb(144, 71, 158)'
],
stack: 'Stack 3',
borderWidth: 1
},
{
label: '',
data: [30, 20, 20, 67, 10, 25, 3],
backgroundColor: [
'rgb(196, 201, 201)'
],
borderColor: [
'rgb(196, 201, 201)'
],
stack: 'Stack 3',
borderWidth: 1
},
{
label: 'user 5 online',
data: [0, 35, 45, 47, 0, 3, 27],
backgroundColor: [
'rgba(40, 139, 170, 1)'
],
borderColor: [
'rgb(40, 139, 170)'
],
stack: 'Stack 4',
borderWidth: 1
},
{
label: '',
data: [30, 20, 20, 67, 10, 25, 3],
backgroundColor: [
'rgb(196, 201, 201)'
],
borderColor: [
'rgb(196, 201, 201)'
],
stack: 'Stack 4',
borderWidth: 1
}]
},
options: {
plugins: {
drawTime: 'afterDraw',
title: {
display: true,
text: 'Stacked, agregated, multi column'
},
legend: {
labels: {
filter(item, data, chart){
const lbl = data.datasets[item.datasetIndex].label;
if (lbl === '') {
const chart = this._context.chart;
return chart.isDatasetVisible(item.datasetIndex);
}
return true;
}
},
onClick(e, item, legend) {
if (item.text !== '') {
const ci = legend.chart;
const stack = ci.data.datasets[item.datasetIndex].stack;
const dsStack = ci.data.datasets.filter((el) => el.stack === stack);
if (dsStack.length) {
dsStack.forEach(function(dsitem) {
const index = ci.data.datasets.indexOf(dsitem);
ci.setDatasetVisibility(index, !ci.isDatasetVisible(index));
});
ci.update();
return;
}
legendClickHandler(e, item, legend);
}
}
}
},
responsive: true,
scales: {
x: {
stacked: true
},
y: {
stacked: true
}
},
}
});
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
<html>
<body>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"/>
</div>
</body>
</html>
Source:stackexchange.com