如何在 Chart.js 画布、Angular 12 中垂直旋转圆环图切片中的标签文本?

问题描述 投票:0回答:3

我正在尝试在此圆环图中沿内圆方向垂直旋转标签文本。到目前为止,一点运气都没有。谁能建议如何实现? 我正在使用 chartjs-plugin-labels 在切片中显示标签。

我想实现这样的文字方向

angular chart.js donut-chart
3个回答
4
投票

使用chartjs-plugin-datalabels可以这样实现:

options: {
  plugins: {
    datalabels: {
      anchor: "center", //start, center, end
      rotation: function(ctx) {
        const valuesBefore = ctx.dataset.data.slice(0, ctx.dataIndex).reduce((a, b) => a + b, 0);
        const sum = ctx.dataset.data.reduce((a, b) => a + b, 0);
        const rotation = ((valuesBefore + ctx.dataset.data[ctx.dataIndex] /2) /sum *360);
        return rotation < 180 ? rotation-90 : rotation+90;
      },
      formatter: function (value, context) {
          return context.chart.data.labels[context.dataIndex];
      },
    },
  },
}

Resulting piechart


0
投票

我还创建了一个与您的问题相关的视频我看到您也在 youtube 上发送了一条消息。能够找到这篇 Stackoverflow 帖子,因为你的消息不知何故从 Youtube 上消失了。请参阅有关旋转计算的解释,因为它在 youtube 上非常棘手:https://youtu.be/M251H8RLr3Q

请记住,旋转选项是可编写脚本的,因此您可以用它创建一个函数来计算它。

你很接近,但你需要使用数据标签插件中的旋转选项。

这里有一些重要的项目: 角度的起点是90度,从那里开始你可以通过知道切片的百分比来计算。您需要从 360 度角度计算它。最好是观看视频以了解更深入的解释。

var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
    type: 'doughnut',
    data: {
        labels: ['Big Commerce', 'CRM', 'ZOHO'],
        datasets: [{
            label: 'My First Dataset',
            data: [300, 50, 100], 
            //  == 360 450 (300 / 450) 66 == 120 + 90 // 120 / 3 = 40 / 2 = 20
            // 100 = 80 = 40
            backgroundColor: [
              'rgb(255, 99, 132)',
              'rgb(54, 162, 235)',
              'rgb(255, 205, 86)'
            ],
          datalabels: { 
            rotation: [210, 350, 50]
          }
        },
        {
          label: 'My Second Dataset',
          data: [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
          backgroundColor: [
            'rgb(255, 99, 132)',
            'rgb(255, 99, 132)',
            'rgb(255, 99, 132)',
            'rgb(255, 99, 132)',
            'rgb(255, 99, 132)',
            'rgb(255, 99, 132)',
            'rgb(255, 99, 132)',
            'rgb(255, 99, 132)',
            'rgb(54, 162, 235)',
            'rgb(54, 162, 235)',
            'rgb(255, 205, 86)',
            'rgb(255, 205, 86)'
          ],
          datalabels: {
            // 30 = 360 = 8.33% 
            // 90 = 25% 
            
            // 90 = base
            // 30 / 2 = 15
            // 90 + 15 = 105
            // 90 + 30 + 30
            // 90 + 30 + 15 = 
            rotation: [105, 135, 165, 195, 225, 255, 285, 315, 345, 15, 45, 75]
          }
        }, 
        {
          label: 'My Third Dataset',
          data: [10, 50, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],
          backgroundColor: [
            'rgb(255, 99, 132)',
            'rgb(54, 162, 235)',
            'rgb(255, 205, 86)'
          ],
        }]
      },
    plugins: [ChartDataLabels],
    options: {}
});

0
投票

此外,旋转图表并保持标签旋转,您可以使用 tomludd 发布的解决方案并旋转饼图:

let resultValue = 101;
let randomDegree = Math.floor(Math.random() * (355 - 0 + 1) + 0);
let rotationInterval = window.setInterval(() => {
  
  myChart.options.rotation = myChart.options.rotation + resultValue;
  myChart.options.plugins.datalabels.rotation = function(ctx) {
    const valuesBefore = ctx.dataset.data.slice(0, ctx.dataIndex).reduce((a, b) => a + b, 0);
    const sum = ctx.dataset.data.reduce((a, b) => a + b, 0);
    const rotation = myChart.options.rotation + ((valuesBefore + ctx.dataset.data[ctx.dataIndex] /2) /sum *360);
    return rotation-90;
  };
  
  myChart.update();
  
  if (myChart.options.rotation >= 360) {
    count += 1;
    resultValue -= 5;
    myChart.options.rotation = 0;
  } else if (count > 15 && myChart.options.rotation == randomDegree) {
    clearInterval(rotationInterval);
    count = 0;
    resultValue = 101;
  }
}, 25); // timing

你可以在你想要的事件上触发它(点击按钮或任何你想要的)

© www.soinside.com 2019 - 2024. All rights reserved.