不,我有一个折线图,上面有几条线。这些线在某些点相交。我还使用 Chartjs-plugin-datalabels 来标记图形上的点。
问题是:如果我在一个地方有来自不同行的几个点,它们的标签也会显示在一个地方,这很糟糕。我怎样才能让它们看起来漂亮且可读?
您可以在第二张图表中看到该问题(带有“2 (...)”的点):
在文档中没有找到任何内容,而且我是 JS 新手。所以,我希望能得到你们的帮助:)
好吧,在没有看到你的代码的情况下,我必须推断出它会是什么样子以及我将如何解决它。
我愿意:
formatter
功能来设置交叉点的标签这里有一个演示,我将如何做到这一点:
代码中有一些注释标记了重要部分。
const data = {
labels: ['1', '2', '3', '4', '5'],
datasets: [{
label: 'DS1',
data: [{x:1, y: 1, v:'d1'}, {x:2, y: 2, v:'d1'}, {x:3, y: 4, v:'d1'}, {x:4, y: 3, v:'d1'}],
}, {
label: 'DS2',
data: [
{x:1, y: 1, v:'d2'}, {x:2, y: 2, v:'d3'}, {x:3, y: 2, v:'d2'}, {x:4, y: 2, v:'d2'}],
}, {
label: 'DS3',
data: [{x:1, y: 1, v:'d3'}, {x:2, y: 2, v:'d3'}, {x:3, y: 5, v:'d3'}, {x:4, y: 5, v:'d3'}],
}],
};
// Helper to get all values into on array
let flatDatalist = data.datasets.map( entry => entry.data).flat();
// find all overlapping points
let overlappingEntries = flatDatalist.filter( (entry, index )=>{
return flatDatalist.some((entryInner, indexInner) => index != indexInner && entry.x == entryInner.x && entry.y == entryInner.y)
})
// create an Array with new formated label for overlapping labels
let labelsForOverlappingEntries = overlappingEntries.reduce((prev, curr) => {
let key = `${curr.x}__${curr.y}`;
if(!prev[key]){
prev[key] = `${data.labels[curr.x]}:${curr.v}`;
} else {
prev[key] = `${prev[key]}\n${data.labels[curr.x]}:${curr.v}`;
}
return prev;
}, {});
const config = {
type: 'line',
data: data,
plugins:[ChartDataLabels],
options: {
scales: {
y: {
min: 0,
max: 6,
}
},
maintainAspectRatio: false,
plugins: {
datalabels: {
align: 'end',
anchor: 'end',
offset: -1,
formatter: function(v, ctx){
// get a multiline label when needed
let key = `${v.x}__${v.y}`;
if(labelsForOverlappingEntries[key]){
return labelsForOverlappingEntries[key];
}
return ctx.chart.data.labels[ctx.dataIndex] + ': '+ v.v;
},
}
}
}
};
new Chart(
document.getElementById('chart'),
config
);
<script src="//cdn.jsdelivr.net/npm/chart.js"></script>
<script src="
https://cdn.jsdelivr.net/npm/[email protected]/dist/chartjs-plugin-datalabels.min.js
"></script>
<div class="chart" style="height:184px; width:350px;">
<canvas id="chart" ></canvas>
</div>
免责声明我不确定这是否是最好的方法,而且它可能有点过度设计。尽管如此,它还是有效的,我希望你能使用它,或者至少它有助于找到你的方法。