Javascript ChartJS:数据标签:在饼图中显示百分比值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/52044013/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ChartJS: datalabels: show percentage value in Pie piece
提问by theKing
I have a piechart with four labels:
我有一个带有四个标签的饼图:
var data = [{
    data: [50, 55, 60, 33],
    labels: ["India", "China", "US", "Canada"],
    backgroundColor: [
        "#4b77a9",
        "#5f255f",
        "#d21243",
        "#B27200"
    ],
    borderColor: "#fff"
}];
Using chartjs-plugin-datalabelsplugin I wanted to show percentage value in each Pie piece with below code:
使用chartjs-plugin-datalabels插件我想用下面的代码在每个 Pie 块中显示百分比值:
formatter: (value, ctx) => {
        let datasets = ctx.chart.data.datasets;
        if (datasets.indexOf(ctx.dataset) === datasets.length - 1) {
            let sum = 0;
            datasets.map(dataset => {
                sum += dataset.data[ctx.dataIndex];
            });
            let percentage = Math.round((value / sum) * 100) + '%';
            return percentage;
        } else {
            return percentage;
        }
    },
    color: '#fff',
}
I am getting 100% value for all the pie pieces, instead of respective percentages. Here is the JSFiddle (https://jsfiddle.net/kingBethal/a1Lvn4eb/7/)
我得到了所有馅饼的 100% 价值,而不是各自的百分比。这是 JSFiddle ( https://jsfiddle.net/kingBethal/a1Lvn4eb/7/)
回答by Hiteshdua1
Updated fiddle with 2 decimal precision.
更新了 2 位小数精度的小提琴。
You were not computing the sum, instead storing the current value in sum only for every value.
您没有计算总和,而是仅将当前值存储在每个值的总和中。
Here is the working fiddle : https://jsfiddle.net/a1Lvn4eb/55/
这是工作小提琴:https: //jsfiddle.net/a1Lvn4eb/55/
var data = [{
    data: [50, 55, 60, 33],
    labels: ["India", "China", "US", "Canada"],
    backgroundColor: [
        "#4b77a9",
        "#5f255f",
        "#d21243",
        "#B27200"
    ],
    borderColor: "#fff"
}];
var options = {
    tooltips: {
        enabled: false
    },
    plugins: {
        datalabels: {
            formatter: (value, ctx) => {
                let sum = 0;
                let dataArr = ctx.chart.data.datasets[0].data;
                dataArr.map(data => {
                    sum += data;
                });
                let percentage = (value*100 / sum).toFixed(2)+"%";
                return percentage;
            },
            color: '#fff',
        }
    }
};
var ctx = document.getElementById("pie-chart").getContext('2d');
var myChart = new Chart(ctx, {
    type: 'pie',
    data: {
        datasets: data
    },
    options: options
});
回答by mvasilevsky
The problem is how you're calculating sum. See below.
问题是你如何计算总和。见下文。
 var data = [{
   data: [50, 55, 60, 33],
   labels: ["India", "China", "US", "Canada"],
   backgroundColor: [
     "#4b77a9",
     "#5f255f",
     "#d21243",
     "#B27200"
   ],
   borderColor: "#fff"
 }];
 var options = {
   tooltips: {
     enabled: false
   },
   plugins: {
     datalabels: {
       formatter: (value, ctx) => {
         let datasets = ctx.chart.data.datasets;
         if (datasets.indexOf(ctx.dataset) === datasets.length - 1) {
           let sum = datasets[0].data.reduce((a, b) => a + b, 0);
           let percentage = Math.round((value / sum) * 100) + '%';
           return percentage;
         } else {
           return percentage;
         }
       },
       color: '#fff',
     }
   }
 };
 var ctx = document.getElementById("pie-chart").getContext('2d');
 var myChart = new Chart(ctx, {
   type: 'pie',
   data: {
     datasets: data
   },
   options: options
 });
回答by Luechen
You could use the tooltip with an Array reducer to perform the percentage calculation and display it.
您可以使用带有 Array reducer 的工具提示来执行百分比计算并显示它。
  tooltips: {
    callbacks: {
      label: function (tooltipItem, data) {
        try {
          let label = ' ' + data.labels[tooltipItem.index] || '';
          if (label) {
            label += ': ';
          }
          const sum = data.datasets[0].data.reduce((accumulator, curValue) => {
            return accumulator + curValue;
          });
          const value = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
          label += Number((value / sum) * 100).toFixed(2) + '%';
          return label;
        } catch (error) {
          console.log(error);
        }
      }
    }
  }
回答by Muhammad Ashhar Hasan
I like to add a little in accepted answer,
ctx.chart.data.datasets[0].dataalways gives you entire data even if you filter out some data by clicking on legend, means you will always get same percentage for a country even if you filter out some countries.
我喜欢在接受的答案中添加一点,ctx.chart.data.datasets[0].data即使您通过单击图例过滤掉一些数据,也
总是为您提供完整的数据,这意味着即使您过滤掉了一些国家,您也将始终获得相同的国家/地区百分比。
I have used context.dataset._meta[0].totalto get the filtered total.
我曾经context.dataset._meta[0].total得到过滤的总数。
Here is the working snippet:
这是工作片段:
var data = [{
  data: [50, 55, 60, 33],
  backgroundColor: [
    "#4b77a9",
    "#5f255f",
    "#d21243",
    "#B27200"
  ],
  borderColor: "#fff"
}];
var options = {
  tooltips: {
    enabled: true
  },
  plugins: {
    datalabels: {
      formatter: (value, ctx) => {
        let sum = ctx.dataset._meta[0].total;
        let percentage = (value * 100 / sum).toFixed(2) + "%";
        return percentage;
      },
      color: '#fff',
    }
  }
};
var ctx = document.getElementById("pie-chart").getContext('2d');
var myChart = new Chart(ctx, {
  type: 'pie',
  data: {
  labels: ['India', 'China', 'US', 'Canada'],
    datasets: data
  },
  options: options
});<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<canvas id="pie-chart"></canvas>
