【问题标题】:Chart.js 2.0 doughnut tooltip percentagesChart.js 2.0 甜甜圈工具提示百分比
【发布时间】:2016-05-16 15:01:08
【问题描述】:

我使用过 chart.js 1.0,并且我的圆环图工具提示显示基于数据除以数据集的百分比,但我无法使用 chart 2.0 复制这一点。

我搜索了高低,但没有找到可行的解决方案。我知道它会受到选择,但我所尝试的一切都使馅饼功能失调。

<html>

<head>
    <title>Doughnut Chart</title>
    <script src="../dist/Chart.bundle.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <style>
    canvas {
        -moz-user-select: none;
        -webkit-user-select: none;
        -ms-user-select: none;
    }
    </style>
</head>

<body>
    <div id="canvas-holder" style="width:75%">
        <canvas id="chart-area" />
    </div>
    <script>
    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
            }

        }
    };

    window.onload = function() {
        var ctx = document.getElementById("chart-area").getContext("2d");
        window.myDoughnut = new Chart(ctx, config);{

        }
    };


    </script>
</body>

</html>

【问题讨论】:

    标签: javascript chart.js chart.js2


    【解决方案1】:

    更新:下面的答案显示了基于总数据的百分比,但@William Surya Permana 有一个很好的答案,它根据显示的数据更新https://stackoverflow.com/a/49717859/2737978


    options 中你可以传入一个tooltips 对象(更多内容可以在chartjs docs 阅读)

    为了得到你想要的结果,tooltips 的字段是带有label 字段的callbacks 对象。 label 将是一个函数,它接收您悬停的工具提示项和构成图表的数据。只需从这个函数返回一个字符串,你想进入工具提示。

    下面是一个例子

    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 + "%";
        }
      }
    } 
    

    以及您提供的数据的完整示例

    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>

    【讨论】:

    • 我们可以在图例文本中动态显示百分比吗?
    • 如果每个答案都像这样......干得好,伙计
    • 当你隐藏/刮标签时这不起作用。有没有办法根据未划伤的标签计算百分比?
    • parseInt the previousValue 和 currentValue 用于保证。
    • 谢谢!我扩展了您的示例以包含带有 return data.labels[tooltipItem.datasetIndex] + ": " + percentage + "%" 的项目文本
    【解决方案2】:

    对于那些想要根据图表上当前显示的内容(而不是基于总数据)显示动态百分比的人,您可以尝试以下代码:

     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];
          }
        }
      },
    

    【讨论】:

    • 我更喜欢这个,因为 1. 我还需要工具提示标题 2. percentage 拼写正确
    • 谢谢,这比公认的答案更好(尽管由于优点输入它非常好:))
    • 脱帽
    • 对于我们这些通过带有 Rails(或任何其他 API 包装器)的 ChartKick 使用 Chart.js 的人,您不能将 functions 设置为上面的那些选项(因为它们会只是呈现为字符串,而不是可调用函数)。但是,您可以在页面加载后简单地访问客户端的图表,并通过访问Chartkick.charts['&lt;your_chart_id&gt;'].getChartObject().tooltip._options.callbacks 覆盖那里的标签和标题功能。 labeltitle 是可以从那里设置的子属性。
    • 简单易行
    【解决方案3】:

    在 3.5 中它将是:

    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 + '%)';
            }
          }
        }
      }
    }
    

    但更好的动态版本:

    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 + '%)';
            }
          }
        }
      }
    }
    

    【讨论】:

    • 这个答案对我有用(Chart.js v3.7.0)。非常感谢@unbreak
    • 也为我工作,非常感谢。
    【解决方案4】:

    我遇到了这个问题,因为我需要在堆积条形图上显示百分比。我需要的百分比是每个堆叠的列。我通过像这样修改 Willian Surya 的答案来实现这一点:

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

    这是最终结果:

    【讨论】:

    • 是不是Y轴的数据也有“%”?
    【解决方案5】:

    3.x及更高版本的用法发生了变化,所以我会附上一个方法。

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

    【讨论】:

      【解决方案6】:

      只需使用这个:

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

      【讨论】:

        猜你喜欢
        • 2014-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多