效果图如下:

html:

<canvas id="myCanvas" width="500" height="500"></canvas>

js:

 toCanvas(arr) {
let canvas = document.getElementById('myCanvas');//获取canvas
let ctx = canvas.getContext('2d');//通过getContext获取画图的环境
let cont = 0; //总数
let start = 0; //起始弧度
let x = 250,
y = 250; //圆点坐标
let startCoordinate = {
start: 200,
end: 100
}; //绘制起点坐标
arr.forEach((item) => {
cont += item.number;
}); //获取number之和
arr.forEach((item) => {
ctx.beginPath(); //初始化路径
let prop = item.number / cont; //计算比例
let radian = prop * (Math.PI * 2); //计算弧度
ctx.arc(x, y, 100, start, start + radian, false);//根据比例和弧度画圆
ctx.lineTo(x, y); //连接圆心画线
ctx.fillStyle = item.color; //设置圆弧颜色
ctx.fill(); //填充样式
let x1 = x + Math.cos(radian / 2 + start) * 100;//获取圆弧中间点X坐标
let y1 = y + Math.sin(radian / 2 + start) * 100;//获取圆弧中间点y坐标
ctx.moveTo(x1, y1);//画笔移动到圆弧中点
ctx.lineTo(x1 + 30 * Math.cos(radian / 2 + start), y1 + 30 * Math.sin(radian / 2 + start));//在圆弧中点和圆心的连线上画30单位长度的线
let proNumber = null;
if (Math.cos(radian / 2 + start) > 0) {
proNumber = 1
} else {
proNumber = -1
}//判断起点半径与当前圆弧线所成角的余弦值是为负数/正数
ctx.lineTo(x1 + 30 * Math.cos(radian / 2 + start) + proNumber * 30, y1 + 30 * Math.sin(radian / 2 + start));//在之前线的基础上画一条30单位长度的水平线
ctx.fillText(item.name, x1 + 30 * Math.cos(radian / 2 + start) + proNumber * 20, y1 + 30 * Math.sin(radian / 2 + start) - 5, 30);//在线上填充字体,设置字体的坐标,最大长度
ctx.strokeStyle = item.color;//设置线条和字体的颜色
ctx.font = "bold 10px consolas";//设置字体的样式
start += radian;//每次圆弧渲染完成将弧度累加作为下个圆弧的初始弧度
ctx.stroke();//渲染线条
})
let small = new Path2D(ctx);//创建新的一个路径
small.arc(x, y, 60, 0, Math.PI * 2, false);//画圆
ctx.fillStyle = "#fff";//设置圆的颜色
ctx.fill(small);//填充small
},
 let arrs = [{
name: '1号',
color: '#CD853F',
number: 500
},
{
name: '2号',
color: '#FFA500',
number: 500
},
{
name: '3号',
color: '#FF4500',
number: 200
},
{
name: '4号',
color: '#8B0000',
number: 300
},
{
name: '5号',
color: '#DAA520',
number: 50
},
]
this.toCanvas(arrs);

  有些不满意的是文字没有和底下的线条保持一致的margin,也找了很多方法依然没有成功。有大神看到了麻烦指点一下。万分感谢。

最新文章

  1. GIT文档
  2. Linux 挂载管理(mount)
  3. class Solution(object): def fizzBuzz(self, n): a = [] i = 1 while(i &lt;= n): if(i%15 == 0): a.append(&quot;FizzBuzz&quot;) elifleetcode day_01
  4. dhtmlx相关
  5. ubuntu 14.04 下找不到命令,路径出错
  6. finished with non-zero exit 添加v7包报错的问题
  7. windows ubuntu双系统启动
  8. hadoop错误Could not obtain block blk_XXX_YYY from any node:java.io.IOException:No live nodes contain current block
  9. new关键字在虚方法的动态调用中的阻断作用
  10. 用C++设计一个不能被继承的类(用私有构造函数+友元函数)
  11. (转)log4j(三)——如何控制不同级别的日志信息的输出?
  12. PG数据库——视图
  13. Codeforces 1140F Extending Set of Points 线段树 + 按秩合并并查集 (看题解)
  14. spring boot中的jave注解学习
  15. Exception 06 : org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session :
  16. Zookeeper常用操作命令 ls,ls2,get和stat
  17. Android被忽略的tools
  18. nginx重启命令方法(linux,centos,ubuntu)总结
  19. GitHub搭建博客过程
  20. Windows上安装Jekyll

热门文章

  1. NSURLProtocol
  2. React Core Features
  3. maven 查看依赖树结构命令mvn dependency:tree
  4. POJ3259-Wormholes-( spfa || Bellman_Ford )
  5. Game of Cards Gym - 101128G (SG函数)
  6. ent 基本使用八 索引
  7. Python3 连接各类数据库
  8. BZOJ 1801: [Ahoi2009]中国象棋
  9. [Zjoi2006]三色二叉树(bzoj1864)(洛谷2585)题解
  10. 如何高效的阅读uni-app框架?(建议收藏)