[Chartjs]-Truncating canvas labels in ChartJS while keeping the full label value in the tooltips

41πŸ‘

βœ…

In Chart JS V2 you can truncate labels passing the options object.
Also you can customize the tooltips.

options:{
    scales: {
        xAxes: [{
            ticks: {
                callback: function(value) {
                    return value.substr(0, 10);//truncate
                },
            }
        }],
        yAxes: [{}]
    },
    tooltips: {
        enabled: true,
        mode: 'label',
        callbacks: {
            title: function(tooltipItems, data) {
                var idx = tooltipItems[0].index;
                return 'Title:' + data.labels[idx];//do something with title
            },
            label: function(tooltipItems, data) {
                //var idx = tooltipItems.index;
                //return data.labels[idx] + ' €';
                return tooltipItems.xLabel + ' €';
            }
        }
    },
}

1πŸ‘

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>

0πŸ‘

Just some additional info (can’t comment, but thought this would be helpful) I added a small bit of code to the answer above to get β€œβ€¦β€ to show if labels are truncated.

truncateLabel: function(label) {
    var xSubstring = label.substring(0, this.labelLength);
    if(xSubstring.length < this.labelLength) {
        return xSubstring;  
    } else {
        // Check if a word is cut off
        if ( ' ' != label.charAt( (this.labelLength-1) ) && ' ' != label.charAt( this.labelLength ) ) {
            // If so, cut the label off at the last space instead of mid-word
            var last_space_pos = label.lastIndexOf(" ", this.labelLength);
            last_space_pos = (0 > last_space_pos)? this.labelLength: last_space_pos;
            xSubstring = label.substring(0, last_space_pos);
        }
        return xSubstring+"...";
    }
},

0πŸ‘

This can be achieved without modifying the plugin code with customTooltips:function(tooltip) option documented here.
A sample code is also provided here to modifying tooltips for line graph. Using that snippet its fairly easy to achieve the desired behavior.
– Create a div for custom tooltip.
– Truncate the labels for x-axis but keep the mapping to original text in an array.
– In customTooltip function, populate tooltip div with original text by using tooltip.text as key in mapping array.

Leave a comment