Search code examples
javascripthtmlcanvascharts

Chart JS text centre in doughnut chart


I have a circle with text within my doughnut chart js, how can i centre the text, seems to be different position depending on screens.

  Chart.pluginService.register({
  beforeDraw: function(chart) {
      
    var width = chart.chart.width,
      height = chart.chart.height,
      ctx = chart.chart.ctx;
     
    ctx.restore();

ctx.beginPath();
var fontSize = (height / 114).toFixed(2);
ctx.font = fontSize + "em sans-serif";
ctx.arc(width/2,height/2,55,0,2*Math.PI);
ctx.fillStyle = '#006072';
ctx.fill();
ctx.lineWidth = 1;
ctx.fillStyle = 'white';
ctx.strokeStyle = '#CBE1EF';
ctx.stroke();
ctx.fillText(text, textX, textY);
ctx.save();

     

    var text ="$" +  Math.round( round_number / Math.pow(10,zeroCount) ) + "M +",
      textX = Math.round((width - ctx.measureText(text).width) / 2),
      textY = height / 1.9;

    ctx.fillText(text, textX, textY);
    ctx.save();
  }
});

Solution

  • To center text within your doughnut chart in Chart.js, dynamically calculate the text position based on the canvas dimensions.

    • The text should drawn after defining textX and textY, ensuring correct placement.
    • The ctx.restore() and ctx.save() calls should be placed correctly to manage the context state.

    Here is the updated code:

    Chart.pluginService.register({
    
      
    beforeDraw: function(chart) {
      var width = chart.chart.width,
          height = chart.chart.height,
          ctx = chart.chart.ctx;
      
      ctx.restore();
    
      // Set font size dynamically based on chart height
      var fontSize = (height / 114).toFixed(2);
      ctx.font = fontSize + "em sans-serif";
      
      // Draw the circle
      ctx.beginPath();
      ctx.arc(width / 2, height / 2, 55, 0, 2 * Math.PI);
      ctx.fillStyle = '#006072';
      ctx.fill();
      ctx.lineWidth = 1;
      ctx.strokeStyle = '#CBE1EF';
      ctx.stroke();
    
      // Prepare the text
      var text = "$" + Math.round(round_number / Math.pow(10, zeroCount)) + "M +";
    
      // Measure text width to center it horizontally
      var textWidth = ctx.measureText(text).width;
    
      // Calculate the text's x and y coordinates
      var textX = (width - textWidth) / 2;
      var textY = (height / 2)
      
      // For exact verticle centring consider adjusting factor if necessary
      // var textY = (height / 2) + (fontSize * some_factor)
    
      // Set text color and fill text
      ctx.fillStyle = 'white';
      ctx.fillText(text, textX, textY);
      ctx.save();
    }
    });