canvas实现饼状图
2024-08-31 16:30:55
效果图如下:
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,也找了很多方法依然没有成功。有大神看到了麻烦指点一下。万分感谢。
最新文章
- GIT文档
- Linux 挂载管理(mount)
- class Solution(object): def fizzBuzz(self, n): a = [] i = 1 while(i <;= n): if(i%15 == 0): a.append(";FizzBuzz";) elifleetcode day_01
- dhtmlx相关
- ubuntu 14.04 下找不到命令,路径出错
- finished with non-zero exit 添加v7包报错的问题
- windows ubuntu双系统启动
- hadoop错误Could not obtain block blk_XXX_YYY from any node:java.io.IOException:No live nodes contain current block
- new关键字在虚方法的动态调用中的阻断作用
- 用C++设计一个不能被继承的类(用私有构造函数+友元函数)
- (转)log4j(三)——如何控制不同级别的日志信息的输出?
- PG数据库——视图
- Codeforces 1140F Extending Set of Points 线段树 + 按秩合并并查集 (看题解)
- spring boot中的jave注解学习
- Exception 06 : org.hibernate.NonUniqueObjectException: A different object with the same identifier value was already associated with the session :
- Zookeeper常用操作命令 ls,ls2,get和stat
- Android被忽略的tools
- nginx重启命令方法(linux,centos,ubuntu)总结
- GitHub搭建博客过程
- Windows上安装Jekyll
热门文章
- NSURLProtocol
- React Core Features
- maven 查看依赖树结构命令mvn dependency:tree
- POJ3259-Wormholes-( spfa || Bellman_Ford )
- Game of Cards Gym - 101128G (SG函数)
- ent 基本使用八 索引
- Python3 连接各类数据库
- BZOJ 1801: [Ahoi2009]中国象棋
- [Zjoi2006]三色二叉树(bzoj1864)(洛谷2585)题解
- 如何高效的阅读uni-app框架?(建议收藏)