问题
I am using Chart.JS with the Chart.JS datalabel plugin. Is it possible to only show the data labels when the bar width is big enough for the text?
I have the following example:
https://jsfiddle.net/f5p3twcg/2/
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
plugins: [ChartDataLabels],
type: 'bar',
options: {
plugins: {
datalabels: {
color: '#000000',
display: true,
formatter: function(value, ctx) {
return value + "kWh";
}
}
}
},
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange", "Red1", "Blue1", "Yellow1", "Green1", "Purple1", "Orange1", "Red2", "Blue2", "Yellow2", "Green2", "Purple2", "Orange2", "Red3", "Blue3", "Yellow3", "Green3", "Purple3", "Orange3", "Red4", "Blue4", "Yellow4", "Green4", "Purple4", "Orange4"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3, 12, 19, 3, 5, 2, 3, 12, 19, 3, 5, 2, 3, 12, 19, 3, 5, 2, 3, 12, 19, 3, 5, 2, 3, 12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)',
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)',
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)',
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)',
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)',
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
]
}]
}
});
I know, this example doesn't make any sense, but you can see the issue.
If there is a lot of data, the data labels overflow the bar width like this:
Is there an option to tell Chart.JS to only show these labels when the text fits into the bar? (Otherwise just show the tooltips).
回答1:
If the graph isn't changing size dynamically you could obtain the width of a bar after creating the chart instance with
var width = myChart.getDatasetMeta(0).data[0]._model.width;
and rewrite your formatter to check if the text width does not exceed bar's width
formatter: function (value, ctx) {
function getTextWidth(text, font) {
// re-use canvas object for better performance
var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
var context = canvas.getContext("2d");
context.font = font;
var metrics = context.measureText(text);
return metrics.width;
}
return getTextWidth(value + "kWh") > width ? "" : value + "kWh";
}
Please take a note of the fact that i ignored the font in the example before so you would have to extract it manually if any changes were made.
You could perhaps even write a plugin that would write into the var width variable before the render
plugins: [
ChartDataLabels,
{
beforeRender: (myChart) => { width = myChart.getDatasetMeta(0).data[1]._model.width;}
}
],
回答2:
The solution from Krzysztof Krzeszewski works. However, I had to slightly adjust it and add some checks for 'undefined' in my case:
if (typeof chart !== 'undefined') {
let datasetData = chart.getDatasetMeta(0);
if (datasetData !== 'undefined') {
if (datasetData.data.length > 0) {
barWidth = chart.getDatasetMeta(0).data[0]._model.width;
}
}
}
来源:https://stackoverflow.com/questions/56256818/chart-js-how-can-i-only-display-data-labels-when-the-bar-width-is-big-enough-fo