I’m using Chart.js for some charts and I’ve run into a bit of an issue. I’ve got these neat comparisons set up, but I need the unselected ones to not show up on the printout. Any ideas on how to do that?
For example, in this chart, I selected the CDI variation:
my chart
On the print, it looks like this. I’d like the labels (the choices for the charts) to disappear and only have the selected one show up.
my print
Here’s my chart config. I tried to put everything together to make it clearer. Sorry if it’s a bit of a noodle code (js isn’t my main language), so I only know the basics.
Please let me know if you need anything more than the config to understand the chart.
const config_{{ unique_id }} = {
type: '{{ chart_type|default("line") }}',
data: data_{{ unique_id }},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
display: true,
title: {
display: true,
text: '{{ x_axis_title|default("Data") }}',
font: {
size: 14,
family: 'Times New Roman',
weight: 'bold'
},
color: 'black',
className: 'chart-axis'
},
ticks: {
color: 'black',
font: {
family: 'Times New Roman',
weight: 'bold'
},
className: 'chart-axis'
}
},
y: {
display: true,
title: {
display: true,
text: '{{ y_axis_title|default("Valor") }}',
font: {
size: 14,
family: 'Times New Roman',
weight: 'bold'
},
color: 'black',
className: 'chart-axis'
},
ticks: {
color: 'black',
font: {
family: 'Times New Roman',
weight: 'bold'
},
className: 'chart-axis'
}
}
},
plugins: {
title: {
display: true,
text: '{{ chart_title|default("Meu Gráfico") }}',
font: {
size: 18,
family: 'Times New Roman',
weight: 'bold'
},
color: 'black',
className: 'chart-title'
},
legend: {
display: true,
labels: {
usePointStyle: true,
color: 'black',
font: {
family: 'Times New Roman',
weight: 'bold'
},
className: 'chart-label',
generateLabels: function(chart) {
const original = Chart.defaults.plugins.legend.labels.generateLabels;
const labelsOriginal = original.call(this, chart);
labelsOriginal.forEach(label => {
const index = label.datasetIndex;
if (visibleDatasets_{{ unique_id }}.includes(index)) {
label.fillStyle = 'green';
} else {
label.fillStyle = 'gray';
}
});
return labelsOriginal;
}
},
onClick: function(e, legendItem, legend) {
const index = legendItem.datasetIndex;
const ci = legend.chart;
const isVisible = ci.isDatasetVisible(index);
ci.setDatasetVisibility(index, !isVisible);
ci.update();
if (isVisible) {
visibleDatasets_{{ unique_id }} = visibleDatasets_{{ unique_id }}.filter(idx => idx !== index);
} else {
visibleDatasets_{{ unique_id }}.push(index);
}
legend.legendItems[index].fillStyle = isVisible ? 'gray' : 'green';
ci.legend.update();
}
}
}
},
plugins: [{
id: 'removeStrikethrough',
afterUpdate: function(chart) {
const originalFillText = chart.ctx.fillText;
chart.ctx.fillText = function(text, x, y, maxWidth) {
originalFillText.apply(this, arguments);
this.fillStyle = "rgba(0,0,0,0)";
};
}
}, {
id: 'dataLabels',
afterDatasetsDraw: function(chart) {
const ctx = chart.ctx;
chart.data.datasets.forEach((dataset, i) => {
const meta = chart.getDatasetMeta(i);
if (!chart.isDatasetVisible(i)) return;
meta.data.forEach((element, index) => {
ctx.fillStyle = 'black';
const fontSize = 12;
const fontStyle = 'normal';
const fontFamily = 'Times New Roman';
ctx.font = Chart.helpers.fontString(fontSize, fontStyle, fontFamily);
const dataString = dataset.data[index].toFixed(2).toString();
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
const padding = 5;
const position = element.tooltipPosition();
ctx.fillText(dataString, position.x, position.y - (fontSize / 2) - padding);
});
});
}
}]
};
I tried using display: none, and I also tried assig a class to each label and then hiding them via JS, but nei worked.
LegsNotHand is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.