i have tried to make my donut chart look like svg , without using svg . bcz in angular, i did'nt find any donut chart , that look like this chart , i did find one chart , but that was in jquery and i cant use jquery. how can i make round edges of segment divider of this multilevel donut chart i'm using chart.js 4 in angular .

下面是一个例子.

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

推荐答案

是的,圆环图或饼图中圆弧的圆角末端包含在borderRadius选项中.

如果我们 Select 圆角末端的半径为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>

这其中有几个问题:

  • 背景并不完美,圆角下面是帆布背景,不是第二种 colored颜色
  • 第二项应用作背景,它还会在悬停时生成工具提示,需要禁用该提示
  • 圆角末端的半径必须是预设的,并且画布的大小调整可能会达到不适当的值(尽管可以实现更新).

为了涵盖这些情况,我实现了一个自定义DoughnutController,请参阅名为doughnut_round_endsdocs,它使用两个数据集选项扩展了标准doughnut:

  • roundEnd,每个值的布尔值(绘制时会自动考虑圆弧的当前大小来计算半径)
  • overallBackgroundColor-条纹的非活动背景 colored颜色 -允许仅使用一个值并将其设置为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.

Javascript相关问答推荐

JS、C++和C#给出不同的Base 64 Guid编码结果

使用json文件字符串来enum显示类型字符串无法按照计算的enum成员值的要求分配给类型号

使用JavaScript在ionic Web应用程序中更新.pane和.view的背景 colored颜色

GrapeJS -如何保存和加载自定义页面

在Angular中将样式应用于innerHTML

PrivateRoute不是路由组件错误

自定义高图中的x轴标签序列

构造HTML表单以使用表单数据创建对象数组

在执行异步导入之前判断模块是否已导入()

如何在ASP.NET中使用Google Charts API JavaScript将条形图标签显示为绝对值而不是负值

使用原型判断对象是否为类的实例

在运行时使用Next JS App Router在服务器组件中运行自定义函数

如何在不影响隐式类型的情况下将类型分配给对象?

从逗号和破折号分隔的给定字符串中查找所有有效的星期几

expo 联系人:如果联系人的状态被拒绝,则请求访问联系人的权限

ngOnChanges仅在第二次调用时才触发

在Java脚本中录制视频后看不到曲目

如何向内部有文本输入字段的HTML表添加行?

Refine.dev从不同的表取多条记录

使用python,我如何判断一个html复选框是否被隐藏,以及它是否被S选中?