简体   繁体   中英

How to add an extra legend item in chart.js?

I have a chart with a single dataset. It's a bar chart. Some of the bars I want colored yellow and some red. I can do this using a function on the dataset. The problem is that the legend only shows one item for the entire dataset. And it comes up yellow. I need to add another item in the legend for the red items.

I tried to add a second dataset, but then that displays as two bars next to one another. I have not yet tried a stacking bar chart.

How can I add another element to the legend?

 var data = [ { Name: 'John' , FeesPaid: 100 , MemberType: 'NonMember' }, { Name: 'Mary' , FeesPaid: 87 , MemberType: 'Member' }, { Name: 'Charles' , FeesPaid: 108 , MemberType: 'Member' }, { Name: 'Fern' , FeesPaid: 91 , MemberType: 'Member' }, { Name: 'Robert' , FeesPaid: 100 , MemberType: 'NonMember' }, { Name: 'Andrea' , FeesPaid: 114 , MemberType: 'Member' }, ] var labels = data.map((item, idx) => { return item.Name; }); var values = data.map((item, idx) => { return item.FeesPaid; }); var getColor = function(record) { var r = data[record.dataIndex]; if (r.MemberType == "NonMember") { return '#f5be0b'; } else { return 'rgb(255, 99, 132)'; } } var ctx = document.getElementById('canvas').getContext('2d'); var chart = new Chart(ctx, { type: 'bar', data: { labels: labels, datasets: [{ label: 'Non-Member', backgroundColor: getColor, borderColor: getColor, data: values }] } });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script> <canvas id="canvas"></canvas>

Here is a mirror on codepen: https://codepen.io/dagostinelli/pen/BaKWpJR

Here is a naïve approach using legendCallback .

If you want multiple legend items, out of the box, you will need multiple datasets. Typically, each dataset gets its own label.

 const ctx = document.getElementById('canvas').getContext('2d'); const data = [ { Name: 'John' , FeesPaid: 100 , MemberType: 'NonMember' }, { Name: 'Mary' , FeesPaid: 87 , MemberType: 'Member' }, { Name: 'Charles' , FeesPaid: 108 , MemberType: 'Member' }, { Name: 'Fern' , FeesPaid: 91 , MemberType: 'Member' }, { Name: 'Robert' , FeesPaid: 100 , MemberType: 'NonMember' }, { Name: 'Andrea' , FeesPaid: 114 , MemberType: 'Member' }, ] const fields = [ { label: 'Member' , color: 'rgb(255, 99, 132)' , active: true }, { label: 'NonMember' , color: '#f5be0b' , active: true } ]; const Colors = fields.reduce((obj, field) => ({ ...obj, [field.label]: field.color }), {}); const labels = data.map(item => item.Name); const values = data.map(item => item.FeesPaid); const getColor = record => { const r = data.find(d => d.Name === record.chart.data.labels[record.dataIndex]); return r ? Colors[r.MemberType] : Colors.NonMember; }; const customLegendRenderer = (chart) => { return ` <ul class="custom-legend ${chart.id}-legend"> ${fields.map(field => ` <li data-field="${field.label}" data-active="${field.active}"> <span style="background-color:${field.color}"></span> ${field.label} </li> `).join('')} </ul> `; }; const chart = new Chart(ctx, { type: 'bar', data: { labels: labels, datasets: [{ backgroundColor: getColor, borderColor: getColor, data: values }] }, options: { legend: false, legendCallback: customLegendRenderer } }); const handleClick = (e) => { const labels = chart.data.labels; const dataset = chart.data.datasets[0]; const item = e.target.closest('li'); if (item === null) return; const selected = fields.find(field => field.label === item.dataset.field); selected.active = !selected.active; const activeFields = fields.filter(field => field.active).map(field => field.label); while (dataset.data.length && labels.length) { dataset.data.pop(); labels.pop(); } const filteredData = data.filter(record => activeFields.includes(record.MemberType)); filteredData.forEach(item => { dataset.data.push(item.FeesPaid); labels.push(item.Name); }); chart.update(); customLegend.innerHTML = chart.generateLegend(); }; const customLegend = document.querySelector('#chartjs-legend'); customLegend.innerHTML = chart.generateLegend(); customLegend.addEventListener('click', handleClick);
 .custom-legend { display: flex; flex-direction: row; justify-content: space-evenly; list-style-type: none; } .custom-legend li[data-active="false"] { color: #777; text-decoration: line-through; } .custom-legend li span { display: inline-block; width: 1em; height: 1em; cursor: pointer; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script> <canvas id="canvas"></canvas> <div id="chartjs-legend" class="noselect"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM