How to create a doughnut with sum in the middle using JavaScript

Let's assume you want to create a doughnut figure with the sum in the middle. The figure will accumulate the data as the users click on each doughnut piece. At first, let's define the HTML:

html
<div class = "Graph">
  <h2>Elements</h2>
  <canvas id = "Elements"></canvas>
  <div class = "Sum">
    <div id = "Total"></div>
    <div id = "Percentage"></div>
  </div>
</div>

Declare the doughnut chart using Chart.js:

javascript
var elementsCanvas = document.getElementById("Elements")

var elementsData = {
    labels: ["State 1", "State 2", "State 3", "State 4", "State 5", "State 6"],
    datasets: [{
      data: [159, 64, 93, 98, 186, 347],
      backgroundColor: [
          "rgb(204, 204, 204)", 
          "rgb(199, 184, 207)", 
          "rgb(255, 161, 110)", 
          "rgb(214, 97, 56)", 
          "rgb(153, 34, 47)", 
          "rgb(49, 128, 173)"
      ]
    }]
}

var options = {
    responsive: true,
    plugins: {
        legend: {
          display: true,
          position: 'bottom',
          reverse: true
        }
    }
}

var pieChart = new Chart(elementsCanvas, {
    type: 'doughnut',
    data: elementsData,
    options: options
})

Use the onClick handler to activate or deactivate the pieces of the pie and display the sum in the middle:

javascript
var activated = {}

var options = {
    onClick: (evt, item, context) => {

        var total = document.getElementById('Total')
        var percentage = document.getElementById('Percentage')

        if(item.length){

            var number = total.innerHTML
            var sum = 0

            elementsData.datasets[0].data.forEach(elem => sum += elem)

            if(!activated[item[0].index]){

              number = +number + item[0].element.$context.parsed
              activated[item[0].index] = true
              item[0].element.outerRadius += 10

            }
            else{

              number = +number - item[0].element.$context.parsed
              activated[item[0].index] = false
              item[0].element.outerRadius -= 10

            }

            total.innerHTML = number === 0 ? '' : number
            percentage.innerHTML = number === 0 ? '' : `${(100 * number/sum).toFixed(1)}%`      

        }
        else{

            pieChart.update()
            total.innerHTML = ''
            percentage.innerHTML = ''
            activated = {} 

        }
    }
}

See the full example at CodePen.

Hi, I'm Erik, an engineer from Barcelona. If you like the post or have any comments, say hi.