1👍
✅
Well Without seeing your code I must deduce how it would look like and how I would solve it.
Well I would:
- Iterate over the data and look for crossing points
- Create a "Dictionary" for the crossing points with the desired label
- To create the labels for the crossing points I use an newline, but one could also use any other separator, like comma or so.
- use the
formatter
function from the plugin to set the labels for the crossing point’s
Here a demo, how I would do this:
There are some comments in the code that mark the essential parts.
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/chartjs-plugin-datalabels@2.2.0/dist/chartjs-plugin-datalabels.min.js
"></script>
<div class="chart" style="height:184px; width:350px;">
<canvas id="chart" ></canvas>
</div>
Disclaimer I’m not sure if this is the best way, and it is maybe abit over engineered. Nevertheless it works, I hope you can use this, or atleast it helps to find your way.
Source:stackexchange.com