Chart.js 2.0 doughnut tooltip percentages

后端 未结 3 1338
星月不相逢
星月不相逢 2021-01-30 03:57

I have worked with chart.js 1.0 and had my doughnut chart tooltips displaying percentages based on data divided by dataset, but I\'m unable to replicate this with chart 2.0.

相关标签:
3条回答
  • 2021-01-30 04:26

    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>

    0 讨论(0)
  • 2021-01-30 04:30

    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];
          }
        }
      },
    
    0 讨论(0)
  • 2021-01-30 04:39

    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:

    0 讨论(0)
提交回复
热议问题