您的位置:首页 > 其它

构造函数绘制canvas饼状图

2019-06-18 21:30 141 查看
<!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>
<style>
canvas{
border: 1px solid #ccc;
display: block;
margin: 50px auto;
}
</style>
</head>
<body>
<canvas width="600" height="600"></canvas>

<script>

// 构造函数
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;
this.y0 = this.h / 2;

// 半径
this.radius = 150;

// 文本伸出去的线
this.outline = 40;

// 说明矩形的大小
this.rectw = 30;
this.recth = 16;
this.space = 20;
}
// 入口函数
pieChart.prototype.init = function (data) { //提取数据
this.drawpie(data);
};

// 行为函数
pieChart.prototype.drawpie= function (data) {//获取数据 画圆

var that = this;
// 1,初始化数据
var anglelist = this.transformAngle(data);

// 2,绘制饼图

// 生命记录上一个的结束位置||起始位置
var startAngle = 0;
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.getRandoColor();
that.ctx.fill();

// 调用绘制文本行为函数
that.drawTitle(startAngle,item.angle,color,item.title);

// 绘制说明
that.drawDesc(i,item.title);

// 获取当前的结束角度
startAngle = endAngle;
});

};

pieChart.prototype.drawTitle= function (startAngle,angle,color,title) {//文本

// c点
var edge = this.radius + this.outline;
// x轴方向的直角边
var edgex = Math.cos(startAngle + angle / 2) * edge;
// 轴方向的直角边
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;
this.ctx.stroke();

// 伸出去的

// 判断伸出去的点在xod的左边 线的方向就是左边
// 判断伸出去的点在xod的右边 线的方向就是右边

this.ctx.font = '14px Fira Code';

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.drawDesc = 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 = '14px Fira Code';
// 绘制文字
this.ctx.fillText(title,this.space + this.rectw + 10,this.space + index * (this.recth + 10))

};

//计算弧度
pieChart.prototype.transformAngle = function (data) {
// 获取数组的numd的数据
var total = 0;
data.forEach(function (item,i) {
total += item.num;
});

// 计算每一个数据的弧度
data.forEach(function (item,i) {
var angle = item.num / total * Math.PI * 2;

// 把弧度追加到data中
item.angle = angle;
});
return data;
};

//随机颜色
pieChart.prototype.getRandoColor = 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 pieChart = new pieChart();
pieChart.init(data);
</script>
</body>
</html>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: