canvas的矩形,圆弧,扇形,文本基本用法+ 绘制病状图
<!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 #eee;
}
</style>
</head>
<body>
<!-- 准备画布,要在canvas元素本身上设置大小 -->
<canvas width="600" height="400">
</canvas>
<script>
// 获取元素
var mycanvas = document.querySelector('canvas')
// 获取上下文,绘制工具箱
var ctx =mycanvas.getContext('2d');
//绘制矩形,不是独立路径
// ctx.rect(100,100,200,100);
// ctx.fillStyle ='green';
// ctx.stroke();
// ctx.fill();
//绘制矩形,有自己的独立路径
// ctx.strokeRect(100,100,200,100);
// ctx.fillRect(100,100,200,100); //起点(100,100),宽度,高度
// //清除矩形的内容
// ctx.clearRect(0,0,150,150)
//绘制一个渐变的矩形
//要素:方向,起始颜色,结束颜色
//x0y0 x1y1
// var linearGradient = ctx.createLinearGradient(100,100,500,100);//创建线形渐变方案
// linearGradient.addColorStop(0,'pink');//添加颜色
// linearGradient.addColorStop(0.5,'red');//添加颜色
// linearGradient.addColorStop(1,'blue');//添加颜色
// ctx.fillStyle =linearGradient;
// ctx.fillRect(100,300,400,100);
//绘制1/4圆弧
//确定圆心 坐标x,y
//确定圆半径 r
//确定起始绘制的位置和结束绘制的位置,确定弧的长度和位置startAngle endAngle
//取得绘制的方向 dirction 默认是顺时
//在中心位置画一个半径为150px的圆弧右下角
var w = ctx.canvas.width;
var h = ctx.canvas.height;
// ctx.arc(x,y,r,sAngle,eAngle,counterclockwise)//x:圆的中心x坐标,y:圆的中心y的坐标,r:圆的半径
//sAngle:起始角,以弧度计。(弧的圆形的三点钟位置是 0 度)eAngle:结束角,以弧度计
//counterclockwise:可选。规定应该逆时针还是顺时针绘图。False = 顺时针,true = 逆时针。
// ctx.arc(w/2,h/2,150,0,Math.PI/2,);
// ctx.stroke();
//绘制扇形,画一个半径150px的圆弧右上角
//把起点放在圆心位置
// ctx.beginPath();
// ctx.moveTo(w/2,h/2);
// ctx.arc(w/2,h/2,150,0,-Math.PI/2,true);
// ctx.fillStyle ='red';
// ctx.fill();
// //闭合路径
// ctx.stroke();
//绘制n等分的随机颜色的圆
//分成几等分
var num = 10;
//一份多少弧度
var ongle = Math.PI*2/10;
var x0 = w/2;
var y0 = h/2;
var 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 startAngle = 0
for(var i=0;i<num;i++){
var startAngle = i*ongle;
var endAngle = (i+1)*ongle;
ctx.beginPath();
ctx.moveTo(x0,y0);
ctx.arc(x0,y0,150,startAngle,endAngle);
ctx.fillStyle =getRandomColor();
ctx.fill();
}
</script>
</body>
</html>
- 绘制饼状图
<!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 #aaa;
margin: 0 auto;
}
</style>
</head>
<body>
<canvas width='800' height='400'>
</canvas>
<script>
// 获取元素
var mycanvas = document.querySelector('canvas')
// 获取上下文,绘制工具箱
var ctx =mycanvas.getContext('2d');
// 根据数据绘制饼图
//绘制标题 ,从扇形的弧的中点深处一条线,在横线的上面写上文字标题
//在画布的左上角绘制说明,一个和扇形一样颜色的矩形,旁边是文字说明
var PieChart = function(){
// 绘制工具
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.rectW = 30;
this.rectH = 16;
this.space = 20;
}
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.map((item,i) =>{
//当前的结束弧度等于下一次的起始弧度
var endAngle = startAngle + item.angle;
ctx.beginPath();
ctx.moveTo(that.x0,that.y0);
ctx.arc(that.x0,that.y0,that.radius,startAngle,endAngle);
var color = ctx.fillStyle = that.getRandomColor();
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){
//确定伸出去的线,通过圆心和伸出去的点,确定这个线
//确定伸出去的点,需要确定伸出去线的长度
//固定伸出去线的长度
//计算这个点的坐标
//需要根据角度(当前扇形的其实弧度+对应弧度的一般)和斜边的长度(半径+伸出去的长度)
// outX = x0 + cos(angle)+ (r+outline)
// outY = x0 + sin(angle)+ (r+outline)
//斜边
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.textAlign = 'right'; //文字对齐
this.ctx.font = '14px Microsoft YaHei'
var textWidth = this.ctx.measureText(title).width;
console.log(textWidth)
console.log(outX+textWidth)
console.log(outY)
console.log(outX>this.x0)
if(outX>this.x0){
//右
this.ctx.lineTo(outX+textWidth,outY);
this.ctx.textAlign = 'left';
}else{
//左边
this.ctx.lineTo(outX-textWidth,outY);
this.ctx.textBaseline = 'bottom';
}
this.ctx.stroke();
this.ctx.fillText(title,outX,outY);
};//画标题
PieChart.prototype.drawDesc = function(index,title){
//矩形的大小
//距离上和左边的间距
//矩形之间的间距
this.ctx.fillRect(this.space,this.space+index*(this.rectH+this.space),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.rectH+this.space))
};//画说明
PieChart.prototype.transformAngle = function(data){
//返回的数据内包含弧度
var total =0;
data.map((item,i)=>{
total += item.num;
});
//计算弧度,追加到当前的对象内容,将它也放在data数组里
data.map((item,i) =>{
var angle = item.num/total* Math.PI*2; //计算弧度方法
item.angle = angle;
})
return data
};//转换弧度方法
PieChart.prototype.getRandomColor = function(data){
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:30
},
{
title:'20-25岁',
num:6
},
{
title:'25-30岁',
num:10
},
{
title:'30-35岁',
num:35
},
];
var pieChart = new PieChart();
pieChart.init(data);
</script>
</body>
</html>