折线图相关知识:
到这里我们可以构建一个折线图了,它由许多相连的线段组成,要想能够构建折线图需要掌握相关的上下文对象的方法:
beginPath():开始定义一条新的路径;
moveTo():开始定义一条新的子路径,该方法确定了线段的起点
lineTo():将上面定义的线段起点和指定的新的点连接起来;
fill():填充区域,此时只是填充,起点和终点并没有连接起来;
closePath():会把起点和终点连接起来;
stroke():开始绘制图形,当前路径下的所有子路经都会绘制出来;
strokeStyle:定义线段颜色,默认不写为黑色;
lineWidth:定义线段粗细,注意不带单位;
如果要接着绘制新的路径,记得调用beginPath()方法。
尝试写一个心电图:
<canvas id="cav" width="500" height="500"></canvas>
<script>
var cav=document.getElementById("cav")
var ctx=cav.getContext("2d")
function bj(){
//背景网格
for (let i = 0; i < 500; i+=15) {
ctx.moveTo(i,500)
ctx.lineTo(i,0)
}
for (let i = 0; i < 500; i+=15) {
ctx.moveTo(0,i)
ctx.lineTo(500,i)
}
ctx.stroke()
//x,y坐标
ctx.beginPath()
ctx.strokeStyle="brown"
ctx.lineWidth=5
ctx.moveTo(50,350)
ctx.lineTo(450,350)
ctx.stroke()
//x轴小箭头
ctx.beginPath()
ctx.lineWidth=4
ctx.moveTo(450,350)
ctx.lineTo(435,340)
ctx.moveTo(450,350)
ctx.lineTo(435,360)
ctx.stroke()
//y轴
ctx.beginPath()
ctx.lineWidth=5
ctx.moveTo(103,450)
ctx.lineTo(103,50)
ctx.stroke()
//小箭头
ctx.beginPath()
ctx.lineWidth=4
ctx.moveTo(103,50)
ctx.lineTo(93,65)
ctx.moveTo(103,50)
ctx.lineTo(113,65)
ctx.stroke()
}
var x=100
//假数据
var arr=[30,60,80,90,70,45,50,66,30,49,80,40,70,70,20,40,50,30,60,50,40,50,50]
setInterval(function(){
arr.push(Math.random()*(200-30)+30)
},1000)
setInterval(function(){
//清除画板
cav.width=cav.width
//每调用一次让起始坐标的x变小,达到移动的效果
x-=30/3.3
bj()
heart()
},300)
//心跳
function heart(){
ctx.beginPath()
ctx.lineWidth=5
ctx.strokeStyle="green"
for (let i = 0; i < arr.length; i++) {
ctx.lineTo(i*30+x,300-arr[i])
//i*30为每一个数据横坐标,+x为让起始点往右移
}
ctx.stroke()
}
</script>
矩形相关知识:
在学习构建线段以后我们已经能够构建矩形了,设计连续相连的四条线段就能完成一个矩形;
但是对于构建矩形,canvas提供了rect()方法和fillRect()方法可以直接绘制一个矩形。
语法:上下文对象点rect(x,y,width,height);x为左上角顶点的x轴坐标,y为左上角顶点的y轴坐标,width为矩形的宽度,height为矩形的高度;fillRect()方法内的四个参数也相同。区别在于fillRect()会自动矩形填充颜色,而rect()还需要上下文对象调用fill()。
补充:这里需要涉及到fillStyle属性改变填充颜色。
实际操作:
创建一个柱状图
<style>
#cav{
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="cav" width="500" height="400"></canvas>
<script>
var cav =document.querySelector("#cav")
var ctx= cav.getContext("2d")
ctx.moveTo(50,350)
ctx.lineTo(450,350)
ctx.stroke()
//假数据
arr=[500,600,800,700,560,710]
//设置最大高度
var maxh=300/Math.max(...arr)
for (let i = 0; i < arr.length; i++) {
ctx.beginPath()
ctx.rect(80+i*60,350-maxh*arr[i],50,maxh*arr[i])
ctx.fillStyle="purple"
ctx.fill()
}
</script>
运行效果:
曲线绘制的相关知识:
arc():在当前子路经添加一条弧线。
它有六个参数:
第一个参数代表圆心的x轴坐标;
第二个参数代表圆心的y轴坐标;
第三个参数代表圆的半径;
第四个参数代表起始角,以弧度计。(弧的圆形的三点钟位置是 0 度);
第五个参数代表结束角,以弧度计;
在实际应用中,我们得到的是角度,我们需要用角度乘以(π/180) 得到对应的弧度;
第六个参数 (可选)为布尔值,False = 顺时针,true = 逆时针,规定应该逆时针还是顺时针绘图。
注意:构建曲线时,默认开始的边是圆形的三点钟位置。
实际运用构建饼状图:
<canvas id="cav" width="800" height="800"></canvas>
<script>
var cav=document.querySelector("#cav")
var ctx=cav.getContext("2d")
//创建假数据
var jiashuju = [
{
name:"tour",
money:5000
},
{
name:"clothes",
money:3000
},
{
name:"eat",
money:10000
},
{
name:"live",
money:7000
},
{
name:"yue",
money:20000
}
]
jiashuju.total=0
for (let i = 0; i < jiashuju.length; i++) {
jiashuju.total+=jiashuju[i].money
}
// console.log( jiashuju.total);
var deg=Math.PI/180
var start=0
function bt(r=200,x=200,y=200){
for (let i = 0; i < jiashuju.length; i++) {
ctx.beginPath()//每循环一次要从新开始新的线段,否则后面会填充的颜色会覆盖掉前面
//创建三个随机数,随机每次填充的颜色
let r1=~~(Math.random()*255)
let g1=~~(Math.random()*255)
let b1=~~(Math.random()*255)
ctx.fillStyle=`rgb(${r1},${g1},${b1})`
ctx.arc(x,y,r,start*deg,(start+(jiashuju[i].money/jiashuju.total)*360)*deg)
//设置下次开始的角度
start+=(jiashuju[i].money/jiashuju.total)*360
//曲线的终点就是我们需要与圆心连接的点,所以不用再moveTo()设置起点
ctx.lineTo(x,y)//特性:会将上次结束的终点作为下一次的起点
ctx.fill()
ctx.stroke()
}
}
bt()
</script>
运行结果: