用原生js手写 canvas饼状图

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Toomeout/article/details/86073336

一、canvas是什么?

    百度的定义:Canvas 通过 JavaScript 来绘制 2D图形。Canvas 是逐像素进行渲染的。开发者可以通过javascript脚本实现任意绘图。百度上的定义基本描述的什么是canvas,然而要补充的一点是,canvas现在只能支持2d渲染,它最早是由苹果在webkit的浏览器使用到canvas,由于实用性,逐渐被各个浏览器所支持,二、canvas本身就只能用js语言来编写,jquery是不支持的。

二、绘制饼状图

    1、原生js实现饼状图(效果图) 

2、原生代码(可以在任何电脑直接运行)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>饼状图</title>
	</head>
	<style>
		canvas{
			margin-left:300px;
			margin-top: 50px;
			border: 1px solid gray;
		}
	</style>
	<body>
		<div>
			<canvas width="650" height="400"></canvas>
		</div>
	</body>
	<script>
		window.onload = function(){
			function PieChart(ctx,radius){
			this.ctx = ctx||document.querySelector("canvas").getContext("2d");
			this.width = this.ctx.canvas.width;
			this.height = this.ctx.canvas.height;
			this.x0 = this.width/2+100;
			this.y0 = this.height/2;
			this.radius = radius;
			this.outLong = radius/8;
			this.dicX = 50;
			this.dicY = 50;
			this.dicWidth = 40;
			this.dicHeight = 14;
			this.spanY = 25;
			};
			PieChart.prototype.init = function(data){
				this.drawPie(data);
			};
			PieChart.prototype.drawPie = function(data){
				//转化后带有弧度的数据
				var that = this;
				var angleList = this.transformAngle(data);
				var startAngle = 0;
				angleList.forEach(function(item,index){
					var color = that.randomColor();
					that.ctx.beginPath();
					that.ctx.arc(that.x0,that.y0,that.radius,startAngle,startAngle+item.angle);
					that.ctx.lineTo(that.x0,that.y0);
					that.ctx.fillStyle = color
					that.ctx.fill();
					//调用drawTitle函数
					that.drawTitle(startAngle,item.angle,color,item.title);
					startAngle+=item.angle;
				});
			};
			PieChart.prototype.drawTitle = function(startAngle,angle,color,title){
				var out = this.outLong+this.radius;
				var du = startAngle+angle/2;
				//伸出外面的坐标原点
				var outX = this.x0+out*Math.cos(du);
				var outY = this.y0+out*Math.sin(du);
				this.ctx.beginPath();
				this.ctx.moveTo(this.x0,this.y0);
				this.ctx.lineTo(outX,outY);
				this.ctx.strokeStyle = color;
				//设置标题
				this.ctx.font = '14px Microsoft Yahei';
				var textWidth = this.ctx.measureText(title).width;
				this.ctx.textBaseline = "bottom";
				if(outX>this.x0){
					this.ctx.textAlign = "left";
					this.ctx.lineTo(outX+textWidth,outY);
				}else{
					this.ctx.textAlign = "right";
					this.ctx.lineTo(outX-textWidth,outY);
				}
				this.ctx.stroke();
				this.ctx.fillText(title,outX,outY);
				//画描述
				this.drawDic(title);
			};
			PieChart.prototype.drawDic = function(title){
				this.ctx.fillRect(this.dicX,this.dicY,this.dicWidth,this.dicHeight);
				this.ctx.font = '12px Microsoft Yahei';
				this.ctx.textAlign = "left";
				this.ctx.textBaseline = "middle";
				this.ctx.fillText(title,this.dicX+this.dicWidth+10,this.dicY+this.dicHeight/2);
				this.dicY +=this.spanY;	
			};
			PieChart.prototype.transformAngle = function(data){
				var total = 0;
				data.forEach(function(item,index){
					total+=item.per;
				});
				data.forEach(function(item,index){
					item.angle = item.per/total*2*Math.PI;
				});
				return data;
			};
			PieChart.prototype.randomColor = function(){
				//随机生成rgb三元色
				var r = Math.floor(Math.random()*255+1);
				var g = Math.floor(Math.random()*255+1);
				var b = Math.floor(Math.random()*255+1);
				return 'rgb('+r+','+g+','+b+')';
			};
			var data = [
				{
					title:'10-15岁',
					per:10
				},
				{
					title:'16-20岁',
					per:8
				},
				{
					title:'21-30岁',
					per:20
				},
				{
					title:'31-45岁',
					per:10
				},
				{
					title:'46-60岁',
					per:15
				}
			];
			var ctx = document.querySelector("canvas").getContext("2d");
			var pieChart = new PieChart(ctx,150);
			pieChart.init(data);
		};
	</script>
</html>

   3、要掌握的前提知识

    1、js高级原型的使用,构造类是创建,

    2、canvas路径问题,canvas矩形绘制,扇形绘制,

    3、数字三角函数的运用,

    4、js中面向对象思想。

    5、弧度的计算

三、代码总体分析

1、html代码

<canvas width="650" height="400"></canvas>

     对于canvas这个元素来说,与html的其他元素是由微笑区别的,当腰设置canvas画板的高度和宽度时只能对属性进行设置不能使用css样式来设置因为css样式只能改变canvas元素的大小,二canvas实际画板的大小是由width和height属性才能控制的,也就是说css设置的大小对canvas画板来说无效。默认大小是300*150。

2、构造函数

     使用构造函数的方式穿件饼状图对象,使用构造函数的原型添加方式

3、数据使用对象数组

    让饼状图按数据比例有规律的显示

var data = [
				{
					title:'10-15岁',
					per:10
				},
				{
					title:'16-20岁',
					per:8
				},
				{
					title:'21-30岁',
					per:20
				},
				{
					title:'31-45岁',
					per:10
				},
				{
					title:'46-60岁',
					per:15
				}
			];

3、使用的原型方法

    1、init()初始化函数创建对象后代用该方法

    2、drawPie()画饼状图核心方法

    3、drawTitle()画标题方法

    4、drawDic()画描述信息方法

    5、transformAngle()数据转换方法

    6、randomColor()随机颜色方法

4、调用

四、方法分析

1、init()方法分析

PieChart.prototype.init = function(data){
	this.drawPie(data);
};

该方法只负责饼状图初始化方法集合调用,具体方法有this.drawPie(data)实现

2、.transformAngle()方法

			PieChart.prototype.transformAngle = function(data){
				var total = 0;
				data.forEach(function(item,index){
					total+=item.per;
				});
				data.forEach(function(item,index){
					item.angle = item.per/total*2*Math.PI;
				});
				return data;
			};

在该方法里同构数据的forEach循环为数据中的每个对象添加计算弧度值一遍在drawPie()方法里进行三角函数计算

3、drawPie()方法

			PieChart.prototype.drawPie = function(data){
				//转化后带有弧度的数据
				var that = this;
				var angleList = this.transformAngle(data);
				var startAngle = 0;
				angleList.forEach(function(item,index){
					var color = that.randomColor();
					that.ctx.beginPath();
					that.ctx.arc(that.x0,that.y0,that.radius,startAngle,startAngle+item.angle);
					that.ctx.lineTo(that.x0,that.y0);
					that.ctx.fillStyle = color
					that.ctx.fill();
					//调用drawTitle函数
					that.drawTitle(startAngle,item.angle,color,item.title);
					startAngle+=item.angle;
				});
			};

在该方法里var angleList = this.transformAngle(data);调用数据转换方法,将有弧度的对象数组复制给angleList,另外在该方法里还调用了绘制标题的drawTitle()方法,

该方法内的核心代码

 that.ctx.arc(that.x0,that.y0,that.radius,startAngle,startAngle+item.angle);

 that.ctx.arc(that.x0,that.y0,that.radius,startAngle,startAngle+item.angle);参数一二表示绘制扇形的原点坐标,参数三表示原点半径,参数四五表示绘制扇形的开始位置和结束位置。

该方法的最终效果就是绘制出一个扇形

4、drawTitle()方法

PieChart.prototype.drawTitle = function(startAngle,angle,color,title){
				var out = this.outLong+this.radius;
				var du = startAngle+angle/2;
				//伸出外面的坐标原点
				var outX = this.x0+out*Math.cos(du);
				var outY = this.y0+out*Math.sin(du);
				this.ctx.beginPath();
				this.ctx.moveTo(this.x0,this.y0);
				this.ctx.lineTo(outX,outY);
				this.ctx.strokeStyle = color;
				//设置标题
				this.ctx.font = '14px Microsoft Yahei';
				var textWidth = this.ctx.measureText(title).width;
				this.ctx.textBaseline = "bottom";
				if(outX>this.x0){
					this.ctx.textAlign = "left";
					this.ctx.lineTo(outX+textWidth,outY);
				}else{
					this.ctx.textAlign = "right";
					this.ctx.lineTo(outX-textWidth,outY);
				}
				this.ctx.stroke();
				this.ctx.fillText(title,outX,outY);
				//画描述
				this.drawDic(title);
			};

解析

5、drawDic()方法

PieChart.prototype.drawDic = function(title){
	this.ctx.fillRect(this.dicX,this.dicY,this.dicWidth,this.dicHeight);
	this.ctx.font = '12px Microsoft Yahei';
	this.ctx.textAlign = "left";
	this.ctx.textBaseline = "middle";
	this.ctx.fillText(title,this.dicX+this.dicWidth+10,this.dicY+this.dicHeight/2);
	this.dicY +=this.spanY;	
};

 

展开阅读全文

没有更多推荐了,返回首页