How to add text at center of the chart js donut chart

Viewed 6630

I want to place the text my data values at the center of the chart js donut charts, I don't know how to do that, I checked the chart js official docs, but they didn't provide any information about this, how can I achieve this.

Here is my code:

HTML:

<canvas id="gx_150s_658Ed8745321" width="200" height="120"></canvas>

JS:

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



var gx_150s_658Ed8745321_ctx = document.getElementById('gx_150s_658Ed8745321').getContext('2d');
var gx_150s_658Ed8745321 = new Chart(gx_150s_658Ed8745321_ctx, {
    type: 'doughnut',
    data: {
        labels: ['Utilized', 'Balence'],
        datasets: [{
            label: 'Utilized',
            data: [95, 5],
            backgroundColor: [
                'rgb(0, 153, 0, 0.7)',

            ],
            borderColor: [
                'rgba(54, 162, 235, 2)',

            ],
            borderWidth: 1
        }]
    },
    options: {
        legend: {
            display: false
        },
        title: {
            display: true,
            text: ' Utilized  :  95 %'
        },
        animation: {
            animateScale: true,
            animateRotate: true
        },
    }
});

Expected output:

enter image description here

2 Answers

I'm using a simple plug-in:

config = {
    options: {
      //...
    }

    //...

    plugin: [{
            id: 'my-doughnut-text-plugin',
            afterDraw: function (chart, option) {
                let theCenterText = "50%" ;
                const canvasBounds = canvas.getBoundingClientRect();
                const fontSz = Math.floor( canvasBounds.height * 0.10 ) ;
                chart.ctx.textBaseline = 'middle';
                chart.ctx.textAlign = 'center';
                chart.ctx.font = fontSz+'px Arial';
                chart.ctx.fillText(theCenterText, canvasBounds.width/2, canvasBounds.height*0.70 )
            }
    }];

}

You still need to calculate what you wan't in the center text (variable theCenterText).

we can use the animation onComplete callback to know when the animation has finished.

then we can calculate the size and placement of the canvas,
and position a label in the center of the canvas.

      animation: {
          animateScale: true,
          animateRotate: true,
          onComplete: function() {
            var canvasBounds = canvas.getBoundingClientRect();
            dataLabel.innerHTML = ' Utilized  :  95 %';
            var dataLabelBounds = dataLabel.getBoundingClientRect();
            dataLabel.style.top = (canvasBounds.top + (canvasBounds.height / 2) - (dataLabelBounds.height / 2)) + 'px';
            dataLabel.style.left = (canvasBounds.left + (canvasBounds.width / 2) - (dataLabelBounds.width / 2)) + 'px';
          }
      },

see following working snippet...

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

  var canvas = document.getElementById('gx_150s_658Ed8745321');
  var dataLabel = document.getElementById('data-label');

  var gx_150s_658Ed8745321_ctx = canvas.getContext('2d');
  var gx_150s_658Ed8745321 = new Chart(gx_150s_658Ed8745321_ctx, {
      type: 'doughnut',
      data: {
          labels: ['Utilized', 'Balence'],
          datasets: [{
              label: 'Utilized',
              data: [95, 5],
              backgroundColor: [
                  'rgb(0, 153, 0, 0.7)',

              ],
              borderColor: [
                  'rgba(54, 162, 235, 2)',

              ],
              borderWidth: 1
          }]
      },
      options: {
          legend: {
              display: false
          },
          animation: {
              animateScale: true,
              animateRotate: true,
              onComplete: function() {
                var canvasBounds = canvas.getBoundingClientRect();
                dataLabel.innerHTML = ' Utilized  :  95 %';
                var dataLabelBounds = dataLabel.getBoundingClientRect();
                dataLabel.style.top = (canvasBounds.top + (canvasBounds.height / 2) - (dataLabelBounds.height / 2)) + 'px';
                dataLabel.style.left = (canvasBounds.left + (canvasBounds.width / 2) - (dataLabelBounds.width / 2)) + 'px';
              }
          },
      }
  });
});
#data-label {
  font-size: 20px;
  position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"></script>
<canvas id="gx_150s_658Ed8745321" width="200" height="120"></canvas>
<span id="data-label"></span>

Related