I have a question about filtering/subsetting my dataset. Im creating a custom legend function by leveraging isDatasetVisible and setDatasetVisibility but I was wondering if its possible for my function to also subset the x-axis?
Here's the function now, but it works just like the default legend behavior
function updateLegend(click, output) {
const element = click.target.parentNode;
element.classList.toggle('fade');
output.update();
}
function generateLegend(output, container) {
if (document.querySelectorAll('.customLegend').length === 0) {
const chartBox = document.querySelector(container);
const div = document.createElement('DIV');
div.setAttribute('class', 'customLegend');
const ul = document.createElement('UL');
output.legend.legendItems.forEach((dataset, index) => {
const text = dataset.text;
const stroke = dataset.strokeStyle;
const fill = dataset.fillStyle;
const fontColor = '#666';
const dat = dataset.data;
const li = document.createElement('LI');
const spanBox = document.createElement('SPAN');
spanBox.style.borderColor = stroke;
if (fill == 'rgba(0,0,0,0.1)') {
spanBox.setAttribute('class', 'legend-annotation');
} else {
spanBox.setAttribute('class', 'legend-content');
spanBox.style.backgroundColor = fill;
}
const p = document.createElement('P');
const textNode = document.createTextNode(text);
li.onclick = (click) => {
const isHidden = !output.isDatasetVisible(index);
output.setDatasetVisibility(index, isHidden);
updateLegend(click, output);
};
ul.appendChild(li);
li.appendChild(spanBox);
li.appendChild(p);
p.appendChild(textNode);
});
chartBox.prepend(div);
div.appendChild(ul);
}
}
const customLegend = {
id: 'customLegend',
afterDraw(chart, args, options) {
generateLegend(chart, '.chart-container');
},
};
I created an example below where on click of Dataset 2 I not only want the bars to be removed as they are now but for [A, B, C] to take up the entire x-axis space since [D,E,F] no longer have visible data..... would this require creating my own data subset and triggering a redraw? Any advice would be super helpful!!
var data = {
datasets: [{
label: "Dataset #1",
backgroundColor: 'red',
data: [
{x: "A", y: 65},
{x: "B", y: 59},
{x: "C", y: 20}
],
}, {
label: "Dataset #2",
backgroundColor: 'blue',
data: [
{x: "D", y: 12},
{x: "E", y: 11},
{x: "F", y: 10}
],
}]
};
var option = {
plugins: {
legend: {
display: false,
}
}
};
function updateLegend(click, output) {
const element = click.target.parentNode;
element.classList.toggle('fade');
output.update();
}
function generateLegend(output, container) {
if (document.querySelectorAll('.customLegend').length === 0) {
const chartBox = document.querySelector(container);
const div = document.createElement('DIV');
div.setAttribute('class', 'customLegend');
const ul = document.createElement('UL');
output.legend.legendItems.forEach((dataset, index) => {
const text = dataset.text;
const stroke = dataset.strokeStyle;
const fill = dataset.fillStyle;
const fontColor = '#666';
const dat = dataset.data;
const li = document.createElement('LI');
const spanBox = document.createElement('SPAN');
spanBox.style.borderColor = stroke;
if (fill == 'rgba(0,0,0,0.1)') {
spanBox.setAttribute('class', 'legend-annotation');
} else {
spanBox.setAttribute('class', 'legend-content');
spanBox.style.backgroundColor = fill;
}
const p = document.createElement('P');
const textNode = document.createTextNode(text);
li.onclick = (click) => {
const isHidden = !output.isDatasetVisible(index);
output.setDatasetVisibility(index, isHidden);
updateLegend(click, output);
};
ul.appendChild(li);
li.appendChild(spanBox);
li.appendChild(p);
p.appendChild(textNode);
});
chartBox.prepend(div);
div.appendChild(ul);
}
}
const customLegend = {
id: 'customLegend',
afterDraw(chart, args, options) {
generateLegend(chart, '.chart-container');
},
};
new Chart('chart_0', {
// this is the string the constructor was registered at, ie Chart.controllers.MyType
type: 'bar',
data: data,
options: option,
plugins: [customLegend],
});
.chart-container {
position: relative;
max-width: 800px;
margin: auto;
}
.chartBox {
width: 80%;
}
.customLegend ul {
display: flex;
flex-direction: row;
margin: 0 auto;
list-style: none;
justify-content: center;
}
.customLegend ul li {
margin: 15px;
display: flex;
align-items: center;
cursor: pointer;
flex-direction: row;
line-height: 22px;
}
.customLegend p {
font-family: 'Helvetica';
font-size: 12px;
color: #666;
}
.customLegend ul li.fade p {
color: rgba(102, 102, 102, 0.5);
}
li.fade span {
opacity: 0.3;
}
.customLegend ul li span {
display: inline-block;
margin-right: 15px;
}
.legend-content {
height: 10px;
width: 10px;
}
.legend-annotation {
border-top-style: dotted;
height: 0px;
width: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<div class="chart-container">
<canvas id="chart_0"></canvas>
</div>