CedricParkerLewis
CedricParkerLewis

Reputation: 403

Chart.js and long labels

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!

Upvotes: 39

Views: 59309

Answers (9)

Prakash
Prakash

Reputation: 73

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;
}

Upvotes: 0

Chocksmith
Chocksmith

Reputation: 1208

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

Upvotes: 1

Fermin Arellano
Fermin Arellano

Reputation: 633

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))

Upvotes: 32

Sebastian
Sebastian

Reputation: 1533

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;
}

Upvotes: 0

Gecko
Gecko

Reputation: 1344

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;
        },
      }, ...
    }, ...
}

Upvotes: 0

Arivan Bastos
Arivan Bastos

Reputation: 1996

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",...],
   ...
}

Upvotes: 65

Charitha Goonewardena
Charitha Goonewardena

Reputation: 4714

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;
          }              
        }
      }
    }
  ]
}

Upvotes: 11

John Kacz
John Kacz

Reputation: 414

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.

Upvotes: 0

David Blurton
David Blurton

Reputation: 150

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

Upvotes: 2

Related Questions