Chartjs-ChartJS: Change the positions of the tooltips

5đź‘Ť

Currently the center of your label text is at the position where you want to show the label. If you change it to the start of your label or end of your label for labels on the right and left of your chart, you’ll have much better layout.

You could also align your labels closer to the sector end point instead of the outermost edge of the scale.

Here’s how you do it

1. Override your scale

So that the chart does not take up the full canvas. I’ve hardcoded these values for a sample dataset, you could just as easily use the input data to get suitable values

scaleOverride: true,
scaleStartValue: 0,
scaleStepWidth: 40,
scaleSteps: 10,

2. Draw your Labels

The best place would be the end of your animation.

onAnimationComplete: function () {
    this.segments.forEach(function (segment) {

Figure out the outer edge of each sector – this is not that difficult. We just use the same function that the tooltip position uses

var outerEdge = Chart.Arc.prototype.tooltipPosition.apply({
    x: this.chart.width / 2,
    y: this.chart.height / 2,
    startAngle: segment.startAngle,
    endAngle: segment.endAngle,
    outerRadius: segment.outerRadius * 2 + 10,
    innerRadius: 0
})

outerRadius decides how far away from the center you want your labels to appear. The x 2 is because the tooltip normally appears in the middle of the sector. The + 10 is padding so that the label does not stick too close to end of the sector

If you want the labels to all appear on the outer edge of the scale use outerRadius = self.scale.drawingArea * 2 (with self set to the Chartjs chart object)

3. Set the text alignment

This is based on whether you are on the right or left side of the graph (or the top or bottom).

For this, first normalize the angle (so that it is within 0 to 2 * PI)

var normalizedAngle = (segment.startAngle + segment.endAngle) / 2;
while (normalizedAngle > 2 * Math.PI) {
    normalizedAngle -= (2 * Math.PI)
}

Then simply set the text position depending on the range of the angle (0 radians is on the right side middle and the radians increase anticlockwise).

if (normalizedAngle < (Math.PI * 0.4) || (normalizedAngle > Math.PI * 1.5))
    ctx.textAlign = "start";
else if (normalizedAngle > (Math.PI * 0.4) && (normalizedAngle < Math.PI * 0.6)) {
    outerEdge.y += 5;
    ctx.textAlign = "center";
}
else if (normalizedAngle > (Math.PI * 1.4) && (normalizedAngle < Math.PI * 1.6)) {
    outerEdge.y -5;
    ctx.textAlign = "center";
}
else
    ctx.textAlign = "end";

The “center” makes labels that appear near the top and bottom of the graph have the middle of their text align to the sector edge. The +5 and -5 are padding so that they don’t stick too close.

ctx.fillText(segment.label, outerEdge.x, outerEdge.y);

Fiddle – http://jsfiddle.net/nyjodx4v/


And here’s how it looks

enter image description here

Leave a comment