javascript ChartJS:数据标签:在饼图中显示百分比值

vuv7lop3  于 2022-12-21  发布在  Java
关注(0)|答案(9)|浏览(461)

我有一张有四个标签的皮哈特:

var data = [{
    data: [50, 55, 60, 33],
    labels: ["India", "China", "US", "Canada"],
    backgroundColor: [
        "#4b77a9",
        "#5f255f",
        "#d21243",
        "#B27200"
    ],
    borderColor: "#fff"
}];

使用chartjs-plugin-datalabels插件,我想用下面的代码显示每个饼块的百分比值:

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',
}

我得到了所有饼图块的100%值,而不是各自的百分比。

7rtdyuoh

7rtdyuoh1#

更新了精度为2位小数的小提琴。
您没有计算总和,而是仅针对每个值将当前值存储在总和中。
这是一把实用的小提琴: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
});
rryofs0p

rryofs0p2#

我想在公认答案中添加一点,ctx.chart.data.datasets[0].data总是给你完整的数据,即使你通过点击图例过滤掉一些数据,这意味着你总是会得到一个国家相同的百分比,即使你过滤掉一些国家。
我已经使用context.dataset._meta[0].total来获得过滤后的总数。
下面是工作片段:

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/chartjs-plugin-datalabels@0.7.0"></script>
<canvas id="pie-chart"></canvas>
mwyxok5s

mwyxok5s3#

问题是你如何计算总和。见下文。
Fiddle

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
 });
tjjdgumg

tjjdgumg4#

这是针对chart.js〉= 3.x和chartjs-plugin-datalabels〉= 2.x的更新
chartjs-plugin-datalabels插件不再自动注册自身(docs)
你得手动操作

    • 为所有图表注册插件**
Chart.register(ChartDataLabels)
    • 或仅限于特定图表**
var chart = new Chart(ctx, {
  plugins: [ChartDataLabels],
  options: {
    // ...
  }
})
    • 下面是呈现饼图的代码**

一个二个一个一个

lawou6xi

lawou6xi5#

可以将工具提示与阵列缩减器一起使用,以执行百分比计算并显示百分比。

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);
        }
      }
    }
  }
68de4m5k

68de4m5k6#

我使用的是ChartJS v3.7.0和chartjs-plugin-datalabels v2.0.0,答案是:
https://stackoverflow.com/a/59403435/6830478
并不适合我,而我只是想保持最新的百分比,当隐藏元素。似乎ctx.dataset._meta是不可用了。我想出了一些丑陋的猴子补丁:

formatter: function(value, context) {
    var hiddens = context.chart._hiddenIndices;
    var total = 0;
    var datapoints = context.dataset.data;
    datapoints.forEach((val, i) => {
        if (hiddens[i] != undefined) {
            if (!hiddens[i]) {
                total += val;
            }
        } else {
            total += val;
        }
    });
    var percentage = (value / total * 100).toFixed(2) + '%';
    var out = context.chart.data.labels[context.dataIndex] + '\n' + percentage;
    return out;
}

希望这对任何人都有帮助。干杯。

oxiaedzo

oxiaedzo7#

如果使用nodejs:请按照以下步骤操作:

  1. npm安装图表插件数据标签
    1.从“chartjs-plugin-datalabels”导入图表数据标签;
    1.图表登记簿(...可登记项、图表数据标签);
    1.从注解上方复制代码...
    https://chartjs-plugin-datalabels.netlify.app/guide/#table-of-contents
r8xiu3jd

r8xiu3jd8#

正如一些人提到的,context.dataset._meta[0].total似乎已经在chart.js版本3和更高版本中被删除,不再起作用了。相反,我使用了context.chart.getDatasetMeta(0).total,它对我很有效--它在饼图中显示百分比值,当点击图例时,值会根据过滤后的总数更新。

options:{ 
        plugins:{         
          datalabels: {
            color: 'white',
            formatter: function(value, context) {                  
              return Math.round(value/context.chart.getDatasetMeta(0).total * 100) + "%" ;
            }
          }
        }
      }
ogsagwnx

ogsagwnx9#

显然,ChartDataLabels现在是从另一个包chartjs-plugin-datalabels导出的。我使用npm i chartjs-plugin-datalabels安装了这个包,然后修改了我的代码,如下所示。

import React from "react";
import ChartDataLabels from "chartjs-plugin-datalabels";
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from "chart.js";
import { Pie } from "react-chartjs-2";

ChartJS.register(ArcElement, Tooltip, Legend, ChartDataLabels);

export default function PieChart() {
  return (
    <>
      <Pie
        options={{
          responsive: true,
          maintainAspectRatio: false,
          plugins: {
            legend: { display: false },
            tooltip: false,
            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",
            },
          },
          onHover: function (e) {
            e.native.target.style.cursor = "pointer";
          },
          rotation: 270,
          events: ["click"],
          onClick: function (event, element) {
            console.log(element[0].index);
          },
        }}
        data={{
          labels: ["Above 60%", "Below 60%"],
          datasets: [
            {
              data: [20, 10],
              backgroundColor: ["#3A925D", "#FD7E14"],
              borderWidth: 0,
            },
          ],
        }}
      />
    </>
  );
}

结果

相关问题