I'm developing a site that uses chart.js (www.chartjs.org).
I have to make a line chart that shows multiple series of data, that users can hide or show by clicking on the respective legend symbol (similar to this http://js.syncfusion.com/demos/web/#!/azure/chart/linechart).
Is there any way to do it with chartjs?
You can try this
Create store for hidden datasets
window.chartName = new Chart(...
window.chartName.store = new Array();
Then use this function to update chart, must be handled by click on legend item
function updateDataset(legendLi, chart, label) {
var store = chart.store;
var exists = false;
for (var i = 0; i < store.length; i++) {
if (store[i][0] === label) {
exists = true;
chart.datasets.push(store.splice(i, 1)[0][1]);
legendLi.fadeTo("slow", 1);
}
}
if (!exists) {
for (var i = 0; i < chart.datasets.length; i++) {
if (chart.datasets[i].label === label) {
chart.store.push([label, chart.datasets.splice(i, 1)[0]]);
legendLi.fadeTo("slow", 0.33);
}
}
}
chart.update();
}
Don't forget updated legend template in chart options
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li class=\"legend-item\" onclick=\"updateDataset($(this), window.chartName, '<%=datasets[i].label%>')\"><span style=\"background-color:<%=datasets[i].strokeColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
Shortly, i added this onclick handler for li component
<li class=\"legend-item\" onclick=\"updateDataset($(this), window.chartName , '<%=datasets[i].label%>')\"><
For example fiddle
This is now available in Charts.js
From the documentation http://www.chartjs.org/docs/#chart-configuration-legend-configuration
Legend Configuration
The legend configuration is passed into the options.legend namespace. The global options for the chart legend is defined in Chart.defaults.global.legend.
onClick function(event, legendItem) {} A callback that is called when a 'click' event is registered on top of a label item
onHover function(event, legendItem) {} A callback that is called when a 'mousemove' event is registered on top of a label item
An update to @benallansmith answer, the link to the documentation is now :
https://www.chartjs.org/docs/latest/configuration/legend.html
My version of the example code, to have datasets 2 and 3 hidden while clicking on legend for dataset 1 (datasets 2 and 3 have their legends hidden with the filter function):
public static readonly myChart: Chart.ChartConfiguration = {
type: 'line',
data: {
datasets: [
{
label: 'A',
borderColor: 'red',
fill: false,
lineTension: 0
},
{
label: 'B',
borderColor: 'blue',
fill: false,
lineTension: 0,
pointRadius: 0
},
{
borderColor: 'blue',
borderDash: [5, 10],
borderWidth: 1,
fill: false,
lineTension: 0,
pointRadius: 0
},
{
borderColor: 'blue',
borderDash: [5, 10],
borderWidth: 1,
fill: false,
lineTension: 0,
pointRadius: 0
}
]
},
options: {
legend: {
labels: {
filter: function(legendItem, chartData) {
if (legendItem.datasetIndex > 1) {
return false;
}
return true;
}
},
onClick: function(e, legendItem) {
const index = legendItem.datasetIndex;
if (index === 1) {
const ci = this.chart;
[
ci.getDatasetMeta(1),
ci.getDatasetMeta(2),
ci.getDatasetMeta(3)
].forEach(function(meta) {
meta.hidden = meta.hidden === null ? !ci.data.datasets[1].hidden : null;
});
ci.update();
} else {
// Do the original logic
Chart.defaults.global.legend.onClick.call(this, e, legendItem);
}
}
},
responsive: false,
animation: {
duration: 0
},
}
...
};
my version is v2.8.0 I find a work way, try it.
add
legend : {
}
into option
var donutOptions = {
maintainAspectRatio : false,
responsive : true,
animation: {
animateScale: true,
animateRotate: true
},
tooltips: {
intersect: false,
callbacks: {
label: function (tooltipItem, data) {
...
}
},
},
plugins: {
datalabels: {
...
},
},
},
legend : {
}
};
and use this
donutChart.chart.getDatasetMeta(0).data[index].hidden = true;
donutChart.update();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With