效果图:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<canvas id="drawing">您的浏览器不支持,赶紧换个吧</canvas>
<script src="my.js"></script>
<script>
// 构造函数
function Draw (ctx) {
this.ctx = ctx;
// 总人数
this.total = 0;
// 起始度数
this.start = 0;
// 结束度数
this.end = 0;
// 圆心坐标
this.x = this.ctx.canvas.width / 2;
this.y = this.ctx.canvas.height / 2;
// 圆半径
this.r = 100;
// 存储当前颜色
this.color;
// 线长
this.line = 150;
// 描述中矩形的间隔
this.space = 20;
};
// 初始化
Draw.prototype.init = function (arr) {
this.drawChat(arr);
}
// 画饼图
Draw.prototype.drawChat = function (arr) {
// 判断是否存在getContext
if (canvas.getContext) {
// 获取总人数
for (let i = 0, len = arr.length; i < len; i ++) {
this.total += arr[i].num;
}
// 设置圆心在画布中间
// 根据所占比例画圆弧(当前num/总数),
// 起始位置==>上一轮结束位置,
// 结束位置==>比例 * 2π + 上一轮起始位置
for (let i = 0, len = arr.length; i < len; i ++) {
// 获取当前title
var title = arr[i].title;
// 获取当前num
var num = arr[i].num;
this.ctx.beginPath();
this.ctx.moveTo(this.x, this.y);
this.start = this.end;
this.end = num / this.total * 2 * Math.PI + this.start;
this.ctx.arc(this.x, this.y, this.r, this.start, this.end,false);
this.ctx.closePath();
// 赋予随机颜色
this.color = this.ctx.fillStyle = randomColor();
this.ctx.fill();
this.writeTiltle(title, num);
this.describe(i, num);
}
}
}
// 写title
// 从圆心画一条线出去(刚好扇形中间),角度为(结束角度-起始角度)/ 2 + 起始角度
Draw.prototype.writeTiltle = function (title, num) {
// 获取角度
var reg = (this.end - this.start) / 2 + this.start;
// 计算点坐标
var titleX = this.line * Math.cos(reg) + this.x;
var titleY = this.line * Math.sin(reg) + this.y;
// 获取文字长度
var titleLength = this.ctx.measureText(title).width;
this.ctx.beginPath();
this.ctx.moveTo(this.x, this.y);
this.ctx.lineTo(titleX, titleY);
this.ctx.lineTo(titleX, titleY);
// 判断是在圆心左边还是右边
if (titleX > this.x) {
// 向右
this.ctx.lineTo(titleX + titleLength, titleY);
this.ctx.textAlign = "left";
}else {
// 向左
this.ctx.lineTo(titleX - titleLength, titleY);
this.ctx.textAlign = "right";
}
this.ctx.strokeStyle = this.color;
// 写字
this.ctx.textBaseline = "bottom";
this.ctx.font = "14px 宋体"
this.ctx.fillText(title, titleX, titleY);
this.ctx.stroke();
}
// 写描述(左上角)
Draw.prototype.describe = function (i, num) {
var numX = this.space;
var numY = i * this.space;
this.ctx.beginPath();
this.ctx.fillRect(numX, numY, 40, 15);
this.ctx.textAlign = "left";
this.ctx.textBaseline = "top";
this.ctx.fillText(num + "人", numX + 50, numY);
this.ctx.closePath();
}
// 随机颜色
function randomColor () {
var arr = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"];
var str = "#";
for(let i = 0; i < 6; i ++) {
str += arr[parseInt(Math.random()*16)];
}
return str;
}
// 模拟后台数据
var arr = [
{
title : "大于90分",
num : 4
},
{
title : "大于80小于90分",
num : 9
},
{
title : "大于70小于80分",
num : 12
},
{
title : "大于60小于70分",
num : 16
},
{
title : "小于60分",
num : 9
}
];
// 获取画布
var canvas = document.getElementById("drawing");
canvas.width = 500;
canvas.height = 500;
canvas.style.border = "1px solid red";
var ctx = canvas.getContext("2d");
var d = new Draw(ctx);
d.init(arr);
</script>
</body>
</html>