<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
canvas {
border: 1px dashed pink;
display: block;
margin: 100px auto;
}
</style>
</head>
<body>
<canvas width="600px" height="400px"></canvas>
<script>
var myCanvas=document.querySelector('canvas');
var ctx=myCanvas.getContext('2d');
//构造函数
var PieChart=function(ctx){
// 获取画布和上下文
this.ctx = ctx||document.querySelector('canvas').getContext('2d');
// 获取画布的宽高
this.w=this.ctx.canvas.width;
this.h=this.ctx.canvas.height;
//圆心点
this.x0=this.w/2+60;
this.y0=this.h/2;
//半径
this.radius=150;
//超出饼状图的线
this.outline=20;
//矩形说明距离画布左边和上边的的宽度
this.space=20;
//矩形说明的宽度
this.rectW=30;
//矩形说明的高度
this.rectH=16;
};
//初始化
PieChart.prototype.init=function(data){
//调用函数画饼状图
this.drawPie(data);
};
//画饼状图
PieChart.prototype.drawPie=function(data){
// 转化弧度,包含三个属性的数字
var angleList=this.transformAngle(data);
//画饼状图
var startAngle=0;
var that=this;
angleList.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);
//为弧度添加随机颜色
var color=that.ctx.fillStyle=that.getRandomColor();
//不要忘记填充。。。。
that.ctx.fill();
that.addTitle(startAngle,item.angle,color,item.title);
that.addRect(i,item.title);
//这次结束弧度是下次弧度的开始
startAngle=endAngle;
})
};
//添加标题
PieChart.prototype.addTitle=function(startAngle,angle,color,title){
//从圆心拉一条线出来
var slash=this.radius+this.outline;
//找出斜线和饼状图的焦点
var slashX=this.x0+Math.cos(startAngle+angle/2)*slash;
var slashY=this.y0+Math.sin(startAngle+angle/2)*slash;
//将点连成线
this.ctx.beginPath();
this.ctx.moveTo(this.x0,this.y0);
this.ctx.lineTo(slashX,slashY);
this.ctx.strokeStyle=color;
//改变文字的大小
this.ctx.font='14px';
//画文字下面的一条线
var textLength=this.ctx.measureText(title).width;
// 如果伸出去的横坐标在圆心的右边,就加,如果在左边,就减
if(slashX>this.x0){
var textX=slashX+textLength;
var textY=slashY;
this.ctx.lineTo(textX,textY);
this.ctx.textAlign='left';
}else{
var textX=slashX-textLength;
var textY=slashY;
this.ctx.lineTo(textX,textY);
this.ctx.textAlign='right';
}
this.ctx.stroke();
this.ctx.textBaseline='bottom';
this.ctx.fillText(title,slashX,slashY);
};
//添加左边说明
PieChart.prototype.addRect=function(index,title){
this.ctx.fillRect(this.space,this.space+index*(this.space+this.rectH),this.rectW,this.rectH);
//重新开启一个路径
this.ctx.beginPath();
this.ctx.textAlign='left';
this.ctx.textBaseline='top';
this.ctx.fillText(title,this.space+this.rectW+10,this.space+index*(this.space+this.rectH));
};
//将数据转换成弧度
PieChart.prototype.transformAngle=function(data){
//计算总人数
var sum=0;
data.forEach(function(item,i){
sum+=item.num;
});
//按比例分弧度
data.forEach(function(item,i){
var angle=item.num/sum*Math.PI*2;
//将弧度添加到数组中,作为他的属性
item.angle=angle;
});
return data;
};
//添加随机颜色
PieChart.prototype.getRandomColor=function(){
var r=Math.floor(Math.random()*256);
var g=Math.floor(Math.random()*256);
var b=Math.floor(Math.random()*256);
return 'rgb('+r+','+g+','+b+')';
};
var data=[
{
title:'15-20岁之间',
num:6
},
{
title:'20-25岁之间',
num:30
},
{
title:'25-30岁之间',
num:10
},
{
title:'30岁以上',
num:8
}
];
var pieObj=new PieChart(ctx);
pieObj.init(data);
</script>
</body>
</html>
网友评论