score:115

Accepted answer

update: the below answer shows a percentage based on total data but @william surya permana has an excellent answer that updates based on the shown data https://stackoverflow.com/a/49717859/2737978


in options you can pass in a tooltips object (more can be read at the chartjs docs)

a field of tooltips, to get the result you want, is a callbacks object with a label field. label will be a function that takes in the tooltip item which you have hovered over and the data which makes up your graph. just return a string, that you want to go in the tooltip, from this function.

here is an example of what this can look like

tooltips: {
  callbacks: {
    label: function(tooltipitem, data) {
      //get the concerned dataset
      var dataset = data.datasets[tooltipitem.datasetindex];
      //calculate the total of this data set
      var total = dataset.data.reduce(function(previousvalue, currentvalue, currentindex, array) {
        return previousvalue + currentvalue;
      });
      //get the current items value
      var currentvalue = dataset.data[tooltipitem.index];
      //calculate the precentage based on the total and current item, also this does a rough rounding to give a whole number
      var percentage = math.floor(((currentvalue/total) * 100)+0.5);

      return percentage + "%";
    }
  }
} 

and a full example with the data you provided

fiddle

var randomscalingfactor = function() {
  return math.round(math.random() * 100);
};
var randomcolorfactor = function() {
  return math.round(math.random() * 255);
};
var randomcolor = function(opacity) {
  return 'rgba(' + randomcolorfactor() + ',' + randomcolorfactor() + ',' + randomcolorfactor() + ',' + (opacity || '.3') + ')';
};

var config = {
  type: 'doughnut',
  data: {
    datasets: [{
      data: [
        486.5,
        501.5,
        139.3,
        162,
        263.7,
      ],
      backgroundcolor: [
        "#f7464a",
        "#46bfbd",
        "#fdb45c",
        "#949fb1",
        "#4d5360",
      ],
      label: 'expenditures'
    }],
    labels: [
      "hospitals: $486.5 billion",
      "physicians & professional services: $501.5 billion",
      "long term care: $139.3 billion",
      "prescription drugs: $162 billion",
      "other expenditures: $263.7 billion"
    ]
  },
  options: {
    responsive: true,
    legend: {
      position: 'bottom',
    },
    title: {
      display: false,
      text: 'chart.js doughnut chart'
    },
    animation: {
      animatescale: true,
      animaterotate: true
    },
    tooltips: {
      callbacks: {
        label: function(tooltipitem, data) {
        	var dataset = data.datasets[tooltipitem.datasetindex];
          var total = dataset.data.reduce(function(previousvalue, currentvalue, currentindex, array) {
            return previousvalue + currentvalue;
          });
          var currentvalue = dataset.data[tooltipitem.index];
          var percentage = math.floor(((currentvalue/total) * 100)+0.5);         
          return percentage + "%";
        }
      }
    }
  }
};


var ctx = document.getelementbyid("chart-area").getcontext("2d");
window.mydoughnut = new chart(ctx, config); {

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/chart.js/2.1.3/chart.bundle.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="canvas-holder" style="width:75%">
  <canvas id="chart-area" />
</div>

score:0

the usage has changed in 3.x and higher versions, so i will attach a method for this.

const data: chartdata = {
    labels: ["red", "blue", "yellow", "green", "purple", "orange"],
    datasets: [
        {
            data: excercisedata,
            backgroundcolor: [
                "rgba(255, 99, 132, 0.5)",
                "rgba(54, 162, 235, 0.5)",
                "rgba(255, 206, 86, 0.5)",
                "rgba(75, 192, 192, 0.5)",
                "rgba(153, 102, 255, 0.5)",
                "rgba(255, 159, 64, 0.5)"
            ]
        }
    ]
};
...

     callbacks: {
                    label: tooltipitem => {
                        let total = 0;
                        data.datasets[0].data.foreach(num => {
                            total += num as number;
                        });
                        const currentvalue = data.datasets[0].data[tooltipitem.dataindex] as number;

                        const percentage = ((currentvalue * 100) / total).tofixed(1) + "%";

                        return `${currentvalue}(${percentage})`;
                    },
                    title: tooltipitems => {
                        return tooltipitems[0].label;
                    }
                }

score:1

i came across this question because i needed to show percentage on stacked bar charts. the percentage i needed was per stacked columns. i accomplished this by modifying willian surya's answer like this:

tooltips: {
  callbacks: {
    label: function(tooltipitem, data) {
      var index = tooltipitem.index;
      var currentvalue = data.datasets[tooltipitem.datasetindex].data[index];
      var total = 0;
      data.datasets.foreach(function(el){
        total = total + el.data[index];
      });
      var percentage = parsefloat((currentvalue/total*100).tofixed(1));
      return currentvalue + ' (' + percentage + '%)';
    },
    title: function(tooltipitem, data) {
      return data.datasets[tooltipitem[0].datasetindex].label;
    }
  }
}

this is the final result:

chartjs percentage for stacked bar charts

score:1

simply use this:

const options = {
    responsive: true,
    plugins: {
        tooltip: {
            callbacks: {
                label: (item) => '%' + (item.formattedvalue) + ' | ' + item.label
            }
        }
    },
};

score:5

in 3.5 it will be:

options: {
  plugins: {
    tooltip: {
      callbacks: {
        label: function(context){
          var data = context.dataset.data,
              label = context.label,
              currentvalue = context.raw,
              total = 0;

          for( var i = 0; i < data.length; i++ ){
            total += data[i];
          }
          var percentage = parsefloat((currentvalue/total*100).tofixed(1));

          return label + ": " +currentvalue + ' (' + percentage + '%)';
        }
      }
    }
  }
}

but better, dynamic version:

options: {
  plugins: {
    tooltip: {
      callbacks: {
        label: function(context){
          var label = context.label,
              currentvalue = context.raw,
              total = context.chart._metasets[context.datasetindex].total;

          var percentage = parsefloat((currentvalue/total*100).tofixed(1));

          return label + ": " +currentvalue + ' (' + percentage + '%)';
        }
      }
    }
  }
}

score:70

for those who want to display dynamic percentages based on what currently displayed on the chart (not based on total data), you can try this code:

 tooltips: {
    callbacks: {
      label: function(tooltipitem, data) {
        var dataset = data.datasets[tooltipitem.datasetindex];
        var meta = dataset._meta[object.keys(dataset._meta)[0]];
        var total = meta.total;
        var currentvalue = dataset.data[tooltipitem.index];
        var percentage = parsefloat((currentvalue/total*100).tofixed(1));
        return currentvalue + ' (' + percentage + '%)';
      },
      title: function(tooltipitem, data) {
        return data.labels[tooltipitem[0].index];
      }
    }
  },

Related Query

More Query from same tag