我有一个带有单个数据集的图表。这是条形图。我想将一些条形为黄色,将某些条形为红色。我可以使用数据集上的函数执行此操作。问题在于,图例仅显示整个数据集的一项。它变成黄色。我需要在图例中为红色项添加另一个项。
我尝试添加第二个数据集,但随后显示为两个条形图。我还没有尝试过堆积条形图。
如何为图例添加另一个元素?
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>
这是codepen上的一面镜子:https://codepen.io/dagostinelli/pen/BaKWpJR
答案 0 :(得分:0)
这是使用legendCallback
的幼稚方法。
如果需要多个图例项,则开箱即用,将需要多个数据集。通常,每个数据集都有自己的标签。
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>