I have a scenario where I want to toggle series based on checkbox selection. I have added the checkbox to the legend using labelFormatting in legend option like:
var otherOptions = {
legend: {
container: legend,
labelFormatter: function (label, series) {
var cb = '<input type="checkbox" name="' + label + '" checked="checked" id="id' + label + '"> ' + label;
return cb;
}
},
};
And I have added the click event for the legend so that I can manipulate the series based on checked items. It all works fine except when I uncheck a label in legend, on re-draw it removes that series line from the legend as well. So for ex., below is the before and after image:
Before
After
Notice that in after image "USA" checkbox is missing. Is there any way I can still show the unchecked "USA" checkbox in legend?
I looked at the suggestion here: flot graph, use legend to turn on/off series
But the only problem is that I don't want to have legend AND checkbox legend separate. The question on the given link was answered 1+ year ago so I thought I am gonna take a chance and ask the question again in case someone knows a way to do this.
Please let me know.
Thanks!
I have a scenario where I want to toggle series based on checkbox selection. I have added the checkbox to the legend using labelFormatting in legend option like:
var otherOptions = {
legend: {
container: legend,
labelFormatter: function (label, series) {
var cb = '<input type="checkbox" name="' + label + '" checked="checked" id="id' + label + '"> ' + label;
return cb;
}
},
};
And I have added the click event for the legend so that I can manipulate the series based on checked items. It all works fine except when I uncheck a label in legend, on re-draw it removes that series line from the legend as well. So for ex., below is the before and after image:
Before
After
Notice that in after image "USA" checkbox is missing. Is there any way I can still show the unchecked "USA" checkbox in legend?
I looked at the suggestion here: flot graph, use legend to turn on/off series
But the only problem is that I don't want to have legend AND checkbox legend separate. The question on the given link was answered 1+ year ago so I thought I am gonna take a chance and ask the question again in case someone knows a way to do this.
Please let me know.
Thanks!
Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Apr 5, 2012 at 0:40 test123test123 14.2k10 gold badges30 silver badges34 bronze badges 03 Answers
Reset to default 6Instead of removing the series all together if the checkbox is unchecked, add it with empty data.
Something like this:
function plotByChoice(doAll)
{
$('#legend .legendCB').each(
function(){
if (this.checked)
{
data.push(datasets[someLabel]);
}
else
{
data.push({label: someLabel, data: []})
}
}
);
// plot call etc...
}
Working fiddle is here.
For anyone looking for a clean solution AND for Chart.js v3 :
This is unfortunately not possible for Chart.js v3 as legends are generated with text (no HTML can be appended to the legend itself, unfortunately).
We have to use generateLabels
function to render the legend labels.
I suggest using the pointStyle
option to render an image (checkbox, actually), instead of a rectangle by default, so we can rerender automatically everytime the user checks or not the legend (it's dynamic, ofc, and we don't have to do something plicated programmatically).
So, first, generate the 2 images, corresponding to the checkboxes (I'm using FontAwesome icons that I've generated in PNG from SVG files) :
let checkboxYes = new Image(14, 14);
checkboxYes.src = '/static/img/check_yes.png';
let checkboxNo = new Image(14, 14);
checkboxNo.src = '/static/img/check_no.png';
Then, we can use it in the Chart.js options:
legend: {
labels: {
usePointStyle: true,
generateLabels: function(chart) {
labels = Chart.defaults.plugins.legend.labels.generateLabels(chart);
for (var key in labels) {
labels[key].pointStyle = labels[key].hidden ? checkboxNo : checkboxYes
}
return labels;
}
}
},
Explanations
- I'm setting
usePointStyle
to true so that I can customize the point style later Chart.defaults.plugins.legend.labels.generateLabels(chart)
kind of pre generate the labels for me (and store it into labels), so it's like a function override!- Then for each label, I'm changing its
pointStyle
to the checkbox image depending on thehidden
parameter (if the user checked the box) - Finally, return the labels
It's perhaps not the best solution, but works amazingly well for me:
Click here to see the animated result in GIF :)
i did it in the same manner but when i click on legends all of the legends get disappear , even i updated the onclick function as well it is not working for me
labels: { usePointStyle: true,
// eslint-disable-next-line object-shorthand
generateLabels: (chart) => {
let labels = Chart.defaults.plugins.legend.labels.generateLabels(chart);
labels = labels.map((label) => ({
...label,
pointStyle: label.hidden ? checkboxNo : checkboxYes,
font: {
size: 14,
family: 'Montserrat',
weight: 600,
},
color: label.hidden ? '#999' : '#323C46',
margin: {
top: 5,
bottom: 5,
left: 10,
right: 10,
},
// Handle click event to toggle visibility of the clicked legend item
onClick: (e, legendItem, legend) => {
console.log(legendItem)
const index = legendItem.datasetIndex;
const meta = chart.getDatasetMeta(index);
meta.hidden = meta.hidden === null ? !chart.data.datasets[index].hidden : null;
chart.update();
},
}));
return labels;
},
},
and i am not able apply any style as well.