有这么个折线图,如下所示
image.png
应该怎么去实现它呢,我在这个demo中分了两步,分别为画坐标轴和画折线图
1.画坐标图
坐标分为纵坐标和横坐标,我们先来定义一下坐标原点,默认情况下,坐标原点位于canvas的左上角,即(0,0)的位置,如果我们以这个点来画坐标,其实也可以,但是不太符合我们一般的逻辑思维,一般我们都是从左下角开始画,所以我们需要通过使用translate变换坐标的原点,如下
ctx.translate(40, 500)
把坐标原点移到了距左40px的地方,距顶500px的地方,然后我们再从这个点开始画,首先,画出纵坐标,此时只需要把画笔移到当前坐标的(0,0)位置,然后向上画一条竖线,再画一下左边的箭头,再画一下右边的箭头,即可,代码如下
// 画y轴
ctx.moveTo(0, 0)
ctx.lineTo(0, -yaxisLength)
// y轴左边箭头
ctx.moveTo(0, -yaxisLength)
ctx.lineTo(-arrowLength, -(yaxisLength - arrowLength))
// y轴右边箭头
ctx.moveTo(0, -yaxisLength)
ctx.lineTo(arrowLength, -(yaxisLength - arrowLength))
接下来画横坐标,原理和画纵坐标一样,直接上代码吧
// 画x轴
ctx.moveTo(0, 0)
ctx.lineTo(xaxisLength, 0)
// x轴上边箭头
ctx.moveTo(xaxisLength, 0)
ctx.lineTo(xaxisLength - arrowLength, -arrowLength)
// x轴下边箭头
ctx.moveTo(xaxisLength, 0)
ctx.lineTo(xaxisLength - arrowLength, arrowLength)
ctx.stroke()
这样就把坐标画好了,接下来我们画折线
2.画折线
首先,我们需要数据,定义了一个简单的数据结构
var data = [{
value: 120,
title: '第一季度'
},
{
value: 50,
title: '第二季度'
},
{
value: 100,
title: '第三季度'
},
{
value: 60,
title: '第四季度'
}
]
data.unshift({
value: 0,
title: ''
})
如果组件化了,用户肯定是传的有效数据,我在第一项加了个0的值,也仅仅是为了逻辑处理,此处不用在乎,接下来,肯定是要遍历这个数组,然后画出折线,这里简单的处理就是,每次画笔移到上一次点的位置,然后再画一条线到当前位置即可,还是上源码
ctx.font = '20px Arial'
for (var i = 1, len = data.length; i < len; i++) {
ctx.moveTo(interval * (i - 1), -data[i - 1].value)
ctx.lineTo(interval * i, -data[i].value)
var y = -data[i].value - 20
if (i != len - 1 && data[i].value < data[i + 1].value) {
y = -data[i].value + 20
}
ctx.fillText(`${data[i].title}(${data[i].value})`, interval * i - 20, y)
}
ctx.stroke()
这样就简单地实现了一个折线图,但是实际中肯定不止这么简单,肯定要炫,这里暂时就不展开了,可以关注我的github,代码会不定期更新
qa:假如要给线条加上颜色,应该怎么实现呢,就像下面这样
image.png
网友评论