直接new PieChart(data)就能创建一个饼图对象
data数据类似如下:
var data = [
{
title: '15-20岁',
num: 6
},
{
title: '20-25岁',
num: 30
},
{
title: '25-30岁',
num: 10
},
{
title: '30以上',
num: 8
}
];
var PieChart=function(data,offsetX=0,offsetY=0,radius=150,outLine=20,space=20,rectW=30,rectH=16,ctx){
this.ctx=ctx||document.querySelector('canvas').getContext('2d');
this.radius=radius;
this.offsetX=offsetX;
this.offsetY=offsetY;
this.outLine=outLine;
this.space=space;
this.rectH=rectH;
this.rectW=rectW;
this.x0=this.ctx.canvas.width/2+this.offsetX;
this.y0=this.ctx.canvas.height/2+this.offsetY;
}
PieChart.prototype.init=function(data){
// 1. 画饼 把数据转化成弧度
// 2. 画指向线并描述
// 3. 画矩形+描述
this.drawPie(data);
}
PieChart.prototype.drawPie=function(data){
this.transAngle(data);
var startAngle=0;
var that=this;
data.forEach(function(item,i){
var endAngle=startAngle+item.angle;
that.ctx.beginPath();
that.ctx.moveTo(that.x0,that.y0);
that.ctx.arc(that.x0,that.y0,that.radius,startAngle,endAngle);
that.ctx.closePath();
var color=that.ctx.fillStyle=that.getRandomColor();
that.ctx.fill();
// 画线并描述
that.drawLine(startAngle,item.angle,color,item.title);
// 画矩形+描述
that.drawRect(i,item.title)
startAngle+=item.angle;
})
}
PieChart.prototype.transAngle=function(data){
var total=0;
data.forEach(function(item,i){
total+=item.num;
})
data.forEach(function(item,i){
item.angle=(item.num/total)*2*Math.PI
})
return data;
}
PieChart.prototype.getRandomColor=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+")";
}
PieChart.prototype.drawLine=function(startAngle,angle,color,title){
var edge = this.radius + this.outLine;
/*x轴方向的直角边*/
var edgeX = Math.cos(startAngle + angle / 2) * edge;
/*y轴方向的直角边*/
var edgeY = Math.sin(startAngle + angle / 2) * edge;
/*计算出去的点坐标*/
var outX = this.x0 + edgeX;
var outY = this.y0 + edgeY;
this.ctx.beginPath();
this.ctx.moveTo(this.x0, this.y0);
this.ctx.lineTo(outX, outY);
this.ctx.strokeStyle = color;
/*画文字和下划线*/
/*线的方向怎么判断 伸出去的点在X0的左边 线的方向就是左边*/
/*线的方向怎么判断 伸出去的点在X0的右边 线的方向就是右边*/
/*结束的点坐标 和文字大小*/
this.ctx.font = '14px Microsoft YaHei';
var textWidth = this.ctx.measureText(title).width ;
if(outX > this.x0){
/*右*/
this.ctx.lineTo(outX + textWidth,outY);
this.ctx.textAlign = 'left';
}else{
/*左*/
this.ctx.lineTo(outX - textWidth,outY);
this.ctx.textAlign = 'right';
}
this.ctx.stroke();
this.ctx.textBaseline = 'bottom';
this.ctx.fillText(title,outX,outY);
}
PieChart.prototype.drawRect=function(index,title){
this.ctx.fillRect(this.space,this.space + index * (this.rectH + 10),this.rectW,this.rectH);
/*绘制文字*/
this.ctx.beginPath();
this.ctx.textAlign = 'left';
this.ctx.textBaseline = 'top';
this.ctx.font = '12px Microsoft YaHei';
this.ctx.fillText(title,this.space + this.rectW + 10 , this.space + index * (this.rectH + 10));
}