I use Chart.js to display a Radar Chart. My problem is that some labels are very long : the chart can't be display or it appears very small.
So, is there a way to break lines or to assign a max-width to the labels?
Thank you for your help!
I use Chart.js to display a Radar Chart. My problem is that some labels are very long : the chart can't be display or it appears very small.
So, is there a way to break lines or to assign a max-width to the labels?
Thank you for your help!
For Chart.js 2.0+ you can use an array as label:
Quoting the DOCs:
"Usage: If a label is an array as opposed to a string i.e. [["June","2015"], "July"] then each element is treated as a seperate line."
var data = {
labels: [["My", "long", "long", "long", "label"], "another label",...],
...
}
With ChartJS 2.1.6 and using @ArivanBastos answer
Just pass your long label to the following function, it will return your label in an array form, each element respecting your assigned maxWidth.
/**
* Takes a string phrase and breaks it into separate phrases
* no bigger than 'maxwidth', breaks are made at complete words.
*/
function formatLabel(str, maxwidth){
var sections = [];
var words = str.split(" ");
var temp = "";
words.forEach(function(item, index){
if(temp.length > 0)
{
var concat = temp + ' ' + item;
if(concat.length > maxwidth){
sections.push(temp);
temp = "";
}
else{
if(index == (words.length-1)) {
sections.push(concat);
return;
}
else {
temp = concat;
return;
}
}
}
if(index == (words.length-1)) {
sections.push(item);
return;
}
if(item.length < maxwidth) {
temp = item;
}
else {
sections.push(item);
}
});
return sections;
}
console.log(formatLabel("This string is a bit on the longer side, and contains the long word Supercalifragilisticexpialidocious for good measure.", 10))
To wrap the xAxes label, put the following code into optoins. (this will split from white space and wrap into multiple lines)
scales: {
xAxes: [
{
ticks: {
callback: function(label) {
if (/\s/.test(label)) {
return label.split(" ");
}else{
return label;
}
}
}
}
]
}
You can write a javascript function to customize the label:
// Interpolated JS string - can access value
scaleLabel: "<%=value%>",
See http://www.chartjs.org/docs/#getting-started-global-chart-configuration
Unfortunately there is no solution for this until now (April 5th 2016). There are multiple issues on Chart.js to deal with this:
This is a workaround: Remove x-axis label/text in chart.js
It seems you might be actually be talking about data labels and not the scale labels. In this case you'd want to use the pointLabelFontSize
option. See below example:
var ctx = $("#myChart").get(0).getContext("2d");
var data = {
labels: ["Eating", "Sleeping", "Coding"],
datasets: [
{
label: "First",
strokeColor: "#f00",
pointColor: "#f00",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "#ccc",
data: [45, 59, 90]
},
{
label: "Second",
strokeColor: "#00f",
pointColor: "#00f",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "#ccc",
data: [68, 48, 40]
}
]
};
// This is the important part
var options = {
pointLabelFontSize : 20
};
var myRadarChart = new Chart(ctx).Radar(data, options);
Finally you may want to play with the dimensions of your < canvas > element as I've found sometimes giving the Radar chart more height helps the auto scaling of everything.
I found the best way to manipulate the labels on the radar chart was by using the pointlabels configuration from Chartjs.
let skillChartOptions = {
scale: {
pointLabels: {
callback: (label: any) => {
return label.length > 5 ? label.substr(0, 5) + '...' : label;
},
}, ...
}, ...
}
I'd like to further extend on Fermin's answer with a slightly more readable version. As previously pointed out, it's possible to give Chart.js an array of strings to make it wrap the text. To make this array of strings from a longer string, I propose this function:
function chunkString(str, maxWidth){
const sections = [];
const words = str.split(" ");
let builder = "";
for (const word of words) {
if(word.length > maxWidth) {
sections.push(builder.trim())
builder = ""
sections.push(word.trim())
continue
}
let temp = `${builder} ${word}`
if(temp.length > maxWidth) {
sections.push(builder.trim())
builder = word
continue
}
builder = temp
}
sections.push(builder.trim())
return sections;
}
const str = "This string is a bit on the longer side, and contains the long word Supercalifragilisticexpialidocious for good measure."
console.log(str)
console.log(chunkString(str, 10))
.as-console-wrapper {
max-height: 100vh!important;
}
For most of the recent versions of chart.js, the labels can be mentioned as array of arrays. That's your labels can be:
labels = [['a', 'label1'],['the', 'lable2'],label3] '$'
You can use following function which is fast and compatible across all versions for converting your labels array into array of array in case the labels contain multiple words:
function splitLongLabels(labels){
//labels = ["ABC PQR", "XYZ"];
var i = 0, len = labels.length;
var splitlabels = labels;
while (i < len) {
var words = labels[i].trim().split(' ');
if(words.length>1){
for(var j=0; j<words.length; j++){
}
splitlabels[i] = words;
}
i++
}
return splitlabels;
}