Chart.js: [FEATURE] Disabled legend by datasets

Created on 14 Sep 2017  路  6Comments  路  Source: chartjs/Chart.js

Current Behavior

I'm looking for a feature, I did not found how is it possible to not display all legends of a datasets, i develop a code, when a user click on a certain legend of a dataset, the datasets item + 1 is hidden. but i don't want the user to click on the datasets + 1. See next pictures.
image
I don't want to display legend 1 , 2 , 3 it correspond to the 3 straigth lines on the chart.
Here's the code to hide n+1 line

options: {
                        legend: {
                            onHover: function (e) {
                                e.target.style.cursor = 'pointer';
                            },
                            onClick: function (e, legendItem) {
                                var index = legendItem.datasetIndex;
                                var ci = this.chart;
                                var meta = ci.getDatasetMeta(index);

                                if (index != 1 && index != 3 && index != 5) {
                                    var meta1 = ci.getDatasetMeta(index + 1);
                                    meta1.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
                                }
                                // See controller.isDatasetVisible comment
                                meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
                                // We hid a dataset ... rerender the chart
                                ci.update();
                            }
                        },
}

Now I just don't want to display legend item 1 - 3 -5

Possible Solution

Question :
Is this already possible and i did not find how to do it ?

If it's not possible already, Is it possible to add an option on the datasets structure like "displayLegend : true/false" like that :

datasets: [{
                            label: 'Indicateur de r茅gularit茅',
                            data: dataIndicRegu,
                            backgroundColor: window.chartColors.purple,
                            borderColor: window.chartColors.purple,
                            borderWidth: 2,
                            fill: false,
                            lineTension: 0,
                            displayLegend: true,
                        },
                        {
                            label: 'R茅gularit茅 total',
                            data: dataGlobalRegu,
                            backgroundColor: window.chartColors.purple,
                            borderColor: window.chartColors.purple,
                            borderWidth: 2,
                            borderDash: [4,6],
                            pointRadius : 0,
                            fill: false,
                            lineTension: 0,
                            displayLegend:false
                        },

Thank you

support

Most helpful comment

Thanks for help , finally done, if that can help see code below
```
legend: {
labels: {
generateLabels: function (chart) {
var goodDataset = chart.data.datasets.filter(function (dataset, index) {
return index % 2 != 0 ? [] : dataset;
});
return goodDataset.map(function (dataset, i) {
if (i % 2 == 0)
return {
text: dataset.label,
fillStyle: dataset.backgroundColor,
hidden: !chart.isDatasetVisible(i),
lineCap: dataset.borderCapStyle,
lineDash: dataset.borderDash,
lineDashOffset: dataset.borderDashOffset,
lineJoin: dataset.borderJoinStyle,
lineWidth: dataset.borderWidth,
strokeStyle: dataset.borderColor,
pointStyle: dataset.pointStyle,
// Below is extra data used for toggling the datasets
datasetIndex: i
};
else
return {
text: "",
datasetIndex: i,
fillStyle: "white",
strokeStyle: "white",
pointStyle: 'default',
}
}, this);
},
},
onHover: function (e, chart) {
if (chart.datasetIndex % 2 == 0)
e.target.style.cursor = 'pointer';
},
onClick: function (e, legendItem) {
var index = legendItem.datasetIndex;
var ci = this.chart;
var meta = ci.getDatasetMeta(index);
if (index == 0 || index == 2 || index == 4) {
var meta1 = ci.getDatasetMeta(index + 1);
meta1.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;

                                // See controller.isDatasetVisible comment
                                meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
                                // We hid a dataset ... rerender the chart
                                ci.update();
                            }
                        }
                    },

```
For this result :
image

All 6 comments

@Oowaay this is possible by overriding the generateLabels option in the legend labels configuration. https://github.com/chartjs/Chart.js/blob/master/src/plugins/plugin.legend.js#L44

You would need to only return items for certain datasets.

Thanks for help , finally done, if that can help see code below
```
legend: {
labels: {
generateLabels: function (chart) {
var goodDataset = chart.data.datasets.filter(function (dataset, index) {
return index % 2 != 0 ? [] : dataset;
});
return goodDataset.map(function (dataset, i) {
if (i % 2 == 0)
return {
text: dataset.label,
fillStyle: dataset.backgroundColor,
hidden: !chart.isDatasetVisible(i),
lineCap: dataset.borderCapStyle,
lineDash: dataset.borderDash,
lineDashOffset: dataset.borderDashOffset,
lineJoin: dataset.borderJoinStyle,
lineWidth: dataset.borderWidth,
strokeStyle: dataset.borderColor,
pointStyle: dataset.pointStyle,
// Below is extra data used for toggling the datasets
datasetIndex: i
};
else
return {
text: "",
datasetIndex: i,
fillStyle: "white",
strokeStyle: "white",
pointStyle: 'default',
}
}, this);
},
},
onHover: function (e, chart) {
if (chart.datasetIndex % 2 == 0)
e.target.style.cursor = 'pointer';
},
onClick: function (e, legendItem) {
var index = legendItem.datasetIndex;
var ci = this.chart;
var meta = ci.getDatasetMeta(index);
if (index == 0 || index == 2 || index == 4) {
var meta1 = ci.getDatasetMeta(index + 1);
meta1.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;

                                // See controller.isDatasetVisible comment
                                meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
                                // We hid a dataset ... rerender the chart
                                ci.update();
                            }
                        }
                    },

```
For this result :
image

Looks great @Oowaay

Closing as resolved

I wouldnt say its resolved - setting legend box style to 'white' or even 'transparent' does not make it dissapear. In this example it may look alright, but generally those legend boxes are still taking space. If someone (e.g. me) wants to display different types of charts next to each other, this creates inconsistent look.

Adding display: boolean = true property to datasets would be a perfect solution.

Is there any currently achievable solution that makes chosen legend labels truly dissapear?

@patryk-wlaz Actually it works. Certainly, I have no idea why the dataset array is being filtered and after, when returning the array of objects (legends) it's asking again for: i % 2 == 0, it supposes to be already filtered.

If you don't want that unnecessary blank space, just return the filtered legends:

return goodDataset.map(function (dataset, i) {
    return {
        text: dataset.label,
        fillStyle: dataset.backgroundColor,
        hidden: !chart.isDatasetVisible(i),
        lineCap: dataset.borderCapStyle,
        lineDash: dataset.borderDash,
        lineDashOffset: dataset.borderDashOffset,
        lineJoin: dataset.borderJoinStyle,
        lineWidth: dataset.borderWidth,
        strokeStyle: dataset.borderColor,
        pointStyle: dataset.pointStyle,
        // Below is extra data used for toggling the datasets
        datasetIndex: i
    }
});

Don't do this:

return {
    text: "",
    datasetIndex: i,
    fillStyle: "white",
    strokeStyle: "white",
    pointStyle: 'default',
}

This causes the unnecessary blank space
However the dataset is already filtered, that's the point!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

joebirkin picture joebirkin  路  3Comments

benmccann picture benmccann  路  3Comments

JAIOMP picture JAIOMP  路  3Comments

Woogles picture Woogles  路  3Comments

nickgoodliff picture nickgoodliff  路  3Comments