<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>用canvas画饼状图</title>
</head>
<style>
canvas{
border: 1px solid #ccc;
}
</style>
<body>
<canvas width="600" height='400'></canvas>
</body>
<script>
var Pie=function(ctx){
this.ctx=ctx||document.querySelector('canvas').getContext('2d');
// 半径
this.r=50;
// 圆心坐标
this.x0=this.ctx.canvas.width/2+60;
this.y0=this.ctx.canvas.height/2;
// 指向线的长度
this.outLine=20;
// 小矩形离x y轴的距离 矩形的长宽
this.space=20;
this.rectH=10;
this.rectW=20;
}
// 随机生成颜色
Pie.prototype.randomColor=function(){
var r=Math.floor(Math.random()*266);
var g=Math.floor(Math.random()*266);
var b=Math.floor(Math.random()*266);
return "rgb("+r+","+g+","+b+")";
}
// 角度转换
Pie.prototype.transAngle=function(data){
var totalNum=0;
data.forEach(function(item,i){
totalNum+=item.num;
});
data.forEach(function(item,i){
item.angle=(item.num/totalNum)*2*Math.PI;
})
}
// 初始化
Pie.prototype.init=function(data){
this.drawPie(data);
}
//画饼
Pie.prototype.drawPie=function(data){
var startAngle=0;
var endAngle=0;
var that=this;
that.transAngle(data);
data.forEach(function(item,i){
endAngle=startAngle+item.angle;
that.ctx.beginPath();
that.ctx.moveTo(that.x0,that.y0);
that.ctx.arc(that.x0,that.y0,that.r,startAngle,endAngle);
that.ctx.closePath();
that.ctx.stroke();
var color=that.ctx.fillStyle=that.randomColor();
that.ctx.fill();
// 画射线
that.drawLine(item.angle,startAngle,color,item.desc);
that.drawRect(color,item.desc,i);
startAngle=endAngle;
})
}
Pie.prototype.drawLine=function(angle,startAngle,color,text){
var outX=this.x0+Math.cos(startAngle+angle/2)*(this.r+this.outLine);
var outY=this.y0+Math.sin(startAngle+angle/2)*(this.r+this.outLine);
this.ctx.moveTo(this.x0,this.y0);
this.ctx.lineTo(outX,outY);
this.ctx.strokeStyle=color;
this.ctx.stroke();
var textWidth=this.ctx.measureText(text).width;
this.ctx.font="14px Microsoft YaHei";
if(outX<this.x0){
this.ctx.lineTo(outX-textWidth,outY);
this.ctx.textAlign='right';
}else{
this.ctx.lineTo(outX+textWidth,outY);
this.ctx.textAlign='left';
}
this.ctx.stroke();
this.ctx.textBaseLine='bottom';
this.ctx.fillText(text,outX,outY);
}
Pie.prototype.drawRect=function(color,text,i){
var rectX=this.space;
var rectY=this.space*i+this.rectH*(i+2);
this.ctx.beginPath();
this.ctx.rect(rectX,rectY,this.rectW,this.rectH);
this.ctx.fillStyle=color;
this.ctx.fill();
this.ctx.beginPath();
this.ctx.textAlign='left';
this.ctx.font='12px Microsoft YaHei';
this.ctx.textBaseLine='top';
this.ctx.fillText(text,rectX+30,rectY+10)
}
var data=[{'num':20,'desc':'小学生'},{'num':40,'desc':'中学生'}];
var pie=new Pie();
pie.init(data);
</script>
</html>