How to make round segment divider in donut chart in chart.js

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

我试着做 看起来像 svg ,而不使用 svg 。 bcz in angular,我没有找到任何甜甜圈图,看起来像, 我确实找到了一张图表,但那是在 jquery 中,我不能使用 jquery。我怎样才能制作这个多级甜甜圈图的分段分隔线的圆边 我在 angular 中使用 chart.js 4。

这是例子。

 var config: any= {
      type: 'doughnut',
      data: {
        
          datasets: [{
            label: 'Dataset 1',
              data: [
                
                {
                  value: 50,                 
              },
              {
                  value: 50,                 
              }
                  
              ],
                  backgroundColor: [
                  "#ff3333",
                  "#660000",                
              ],
                  hoverBackgroundColor: [
                "#ff3333",
                "#660000",
              ],
              hoverBackground: NONE_TYPE,
              borderColor:NONE_TYPE,
              hoverBorderColor:NONE_TYPE,
              borderWidth: 0,
              datalabels : {
                display: false
               }
             
          }, {
            label: 'Dataset 2',
              data: [
                {
                  value: 70,                  
              },
              {
                  value: 30,
              }
              ],
                  backgroundColor: [
                  "#00ff00",
                  "#003300",
               ],
                hoverBackgroundColor: [
                "#00ff00",
                "#003300",
             ],
              
               borderColor:NONE_TYPE,
               hoverBorderColor:NONE_TYPE,
               borderWidth: 0,
               datalabels : {
                display: false
               }
               
          }, {
            label: 'Dataset 3', 
              data: [
                {
                 value:40,                    
              },
              {
                value:60,                  
              }
              
               ],
               labels: [
                'green',
                'yellow',
              ] ,
               backgroundColor: [
                  "#1991EB",
                  "#001f4d",
               ],
               hoverBackgroundColor: [
                "#1991EB",
                  "#001a4d",
              ],
              
               borderColor:NONE_TYPE,
               hoverBorderColor:NONE_TYPE,
               borderWidth: 0,
               datalabels : {
                display: false
               },
               
               
          }], 
        
          
      },
      options: {
          responsive: true,
          legend: {
            display: false
          },           
                
        
      }
  };
javascript angularjs chart.js
1个回答
0
投票

是的,圆环图或饼图中圆弧的圆角端由 borderRadius 选项覆盖。

如果我们选择圆角的半径为 10px,我们可以将其写为

    datasets: [{
        //..... data and other dataset options
        borderRadius: [
            {outerStart: 0, outerEnd: 15, innerStart: 0, innerEnd: 15},
            0
        ]
    }]

零的第二个值是作为背景的第二个值。

这是您的数据片段

const data = {
    datasets: [{
        label: 'Dataset 1',
        data: [50, 50],
        backgroundColor: [
            "#ff3333",
            "#660000",
        ],
        borderRadius: [
            {outerStart: 0, outerEnd: 15, innerStart: 0, innerEnd: 15},
            0
        ],
        borderWidth: 0
    },
    {
        label: 'Dataset 2',
        data: [70, 30],
        backgroundColor: [
            "#00ff00",
            "#003300",
        ],
        borderRadius: [
            {outerStart: 0, outerEnd: 20, innerStart: 0, innerEnd: 20},
            0
        ],
        borderWidth: 0
    },
    {
        label: 'Dataset 3',
        data: [40, 60],
        backgroundColor: [
            "#1991EB",
            "#001a4d",
        ],
        borderRadius: [
            {outerStart: 0, outerEnd: 20, innerStart: 0, innerEnd: 20},
            0
        ],
        borderWidth: 0,
    }]
};

const chart = new Chart(document.querySelector("#myChart"), {
    type: 'doughnut',
    data,
    options: {
        cutout: 30,
        responsive: true,
        radius: "80%"
    }
});
<div style="max-height:350px">
<canvas id="myChart" style="background-color: #000"></canvas>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.3.0/chart.umd.js"
        integrity="sha512-CMF3tQtjOoOJoOKlsS7/2loJlkyctwzSoDK/S40iAB+MqWSaf50uObGQSk5Ny/gfRhRCjNLvoxuCvdnERU4WGg=="
        crossorigin="anonymous" referrerpolicy="no-referrer"></script>

这有几个问题:

  • 背景不完美,圆头下面是画布背景,不是第二种颜色
  • 第二个应该作为背景的项目也在悬停时产生工具提示,需要禁用它
  • 圆角的半径必须预先设置,并且画布的大小可能会变得不合适(尽管可以实施更新)。

为了涵盖这些案例,我实现了一个自定义

DoughnutController
,请参阅docs,称为
doughnut_round_ends
,它扩展了标准
doughnut
具有两个数据集选项:

  • roundEnd
    ,每个值的布尔值(半径是根据绘制时弧的当前大小自动计算的)
  • overallBackgroundColor
    - 条纹的非活动背景颜色 - 这将允许仅使用一个值结合设置
    circumference

const _drawArcElement = Chart.ArcElement.prototype.draw;
class DoughnutWithRoundEnds extends Chart.DoughnutController{
    static id = "doughnut_round_ends";

    updateElements(arcs, start, count, mode) {
        super.updateElements(arcs, start, count, mode);
        const overallBackgroundColor = this.getDataset().overallBackgroundColor;
        let roundEnd = this.getDataset().roundEnd || [];
        if(!Array.isArray(roundEnd)){
            roundEnd = [roundEnd];
        }
        if(overallBackgroundColor && roundEnd.length > 0){
            arcs.forEach((arc, i) => {
                arc.options.roundEnd = {};
                let borderRadius = 0;
                if(roundEnd[i]){
                    const R = Math.ceil((arc.outerRadius - arc.innerRadius)/2);
                    borderRadius = {outerStart: 0, outerEnd: R, innerStart: 0, innerEnd: R};
                }
                if(i === 0){
                    arc.draw = function(ctx){
                        const backgroundColor = this.options.backgroundColor,
                            startAngle = this.startAngle,
                            endAngle = this.endAngle;
                        this.options.backgroundColor = overallBackgroundColor;
                        this.options.borderRadius = 0;
                        this.startAngle = 0;
                        this.endAngle = 2*Math.PI;
                        _drawArcElement.call(this, ctx);
                        this.options.backgroundColor = backgroundColor;
                        this.startAngle = startAngle;
                        this.endAngle = endAngle;
                        this.options.borderRadius = borderRadius;
                        _drawArcElement.call(this, ctx);
                    }
                }
                else{
                    this.options.borderRadius = borderRadius;
                }
            });
        }
    }
}

Chart.register(DoughnutWithRoundEnds);

const data = {
    datasets: [{
        label: 'Dataset 1',
        data: [50],
        circumference: [360*50/100],
        backgroundColor: [
            "#ff3333"
        ],
        roundEnd: [
            true
        ],
        overallBackgroundColor: "#660000",
        borderWidth: 0
    },
    {
        label: 'Dataset 2',
        data: [70],
        circumference: [70/100*360],
        backgroundColor: [
            "#00ff00"
        ],
        roundEnd: [
            true
        ],
        overallBackgroundColor: "#003300",
        borderWidth: 0
    },
    {
        label: 'Dataset 3',
        data: [40],
        circumference: [40/100*360],
        backgroundColor: [
            "#1991EB",
        ],
        roundEnd: [
            true
        ],
        overallBackgroundColor: "#001a4d",
        borderWidth: 0
    }]
};

const chart = new Chart(document.querySelector("#myChart"), {
    type: 'doughnut_round_ends',
    data,
    options: {
        cutout: 30,
        responsive: true,
        radius: "80%"
    }
});
<div style="max-height:350px">
<canvas id="myChart" style="background-color: #000"></canvas>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.3.0/chart.umd.js"
        integrity="sha512-CMF3tQtjOoOJoOKlsS7/2loJlkyctwzSoDK/S40iAB+MqWSaf50uObGQSk5Ny/gfRhRCjNLvoxuCvdnERU4WGg=="
        crossorigin="anonymous" referrerpolicy="no-referrer"></script>

此版本也适用于两个(或更多)值,如第一种情况,如果第二个值相关且不只是用于背景:jsFiddle.

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