Norbert Norbert - 2 months ago 19
Javascript Question

Truncating canvas labels in ChartJS while keeping the full label value in the tooltips

I have some bar charts that have really long labels and they affect the size of the charts.

Example: http://jsfiddle.net/norbiu/aqa8w19d/4/

I'm trying to truncate the labels that show up under the chart while keeping the label that shows up in the tooltips when hovering over a bar. The problem is that the tooltips and the canvas labels both get their values from the

labels
array in the data structure. Truncating the value will show the shortened version in both locations.

sales: ko.observable({
labels: ['A really really long label', 'Another long labe', 'A third label that is long', 'Q4', 'Q5', 'Q6'],
datasets: [{
label: 'Helados',
fillColor: '#152491',
data: [70, 32, 6, 23, 63, 43]
}]
}),


The documentation has nothing on this. Any ideas?

Answer

So the way i went about this was to add a new option called labelLength which, if passed a number greater than 0, will trim the labels on the x axis to that length.

It happens in the scale class of the chart and will only apply to the axis label and not the tool tip.

If you wanted you could extract the relevant bits and just override the scale class and also the build scale function in the bar chart to include the new option.

In the scale class here is what was added

 Chart.Scale = Chart.Element.extend({
        initialize: function() {
            //truncate the labels if option is grater than 0
            this.xLabels = this.labelLength > 0 ? this.xLabels.map(this.truncateLabel, this) : this.xLabels;
            this.fit();
        },
        truncateLabel: function(label) {
            return label.substring(0, this.labelLength);
        },

        addXLabel: function(label) {
            //also added here for when adding single items of data to a graph
            this.xLabels.push(this.labelLength > 0 ? this.truncateLabel(label) : label);
            this.valuesCount++;
            this.fit();
        },

}

then in the bar buildscale function you would need to pass the option to the scale.

Or i have included this in my fork of chart js (https://github.com/leighquince/Chart.js) to use just pass the option labelLength with your desired labels length, example below

var randomScalingFactor = function() {
  return Math.round(Math.random() * 100)
};

var barChartData = {
  labels: ["January a really long label", "February a really long label", "March a really long label", "April a really long label", "May a really long label", "June a really long label", "July a really long label"],
  datasets: [{
    fillColor: "rgba(220,220,220,0.5)",
    strokeColor: "rgba(220,220,220,0.8)",
    highlightFill: "rgba(220,220,220,0.75)",
    highlightStroke: "rgba(220,220,220,1)",
    data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
  }, {
    fillColor: "rgba(151,187,205,0.5)",
    strokeColor: "rgba(151,187,205,0.8)",
    highlightFill: "rgba(151,187,205,0.75)",
    highlightStroke: "rgba(151,187,205,1)",
    data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
  }, {
    fillColor: "rgba(15,18,20,0.5)",
    strokeColor: "rgba(15,18,20,0.8)",
    highlightFill: "rgba(15,18,20,0.75)",
    highlightStroke: "rgba(15,18,20,1)",
    data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
  }]

}
window.onload = function() {
  var ctx = document.getElementById("canvas").getContext("2d");
  window.myBar = new Chart(ctx).Bar(barChartData, {
    labelLength: 10,
  });
}
<script src="http://www.quincewebdesign.com/cdn/Chart.js"></script>
<div style="width: 50%">
  <canvas id="canvas" height="450" width="600"></canvas>
</div>