写在最前
本次分享一下在canvas中将绘制出来的折线段的棱角“磨平”,也就是通过贝塞尔曲线穿过各个描点来代替原有的折线图。
为什么要平滑拟合折线段
先来看下Echarts下折线图的渲染效果:
一开始我没注意到其实这个折线段是曲线穿过去的,只认为是单纯的描点绘图,所以起初我实现的“简(丑)易(陋)”版本是这样的:

不要关注样式,重点就是实现之后才发现看起来人家Echarts的实现描点非常的圆滑,也由此引发了之后的探讨。怎么有规律的画平滑曲线?
效果图
先来看下最终模仿的实现:
因为我也不知道Echarts内部怎么实现的(逃
看起来已经非常圆润了,和我们最初的设想十分接近了。再看下曲线是否穿过了描点:
好的!结果很明显现在来重新看下我们的实现方式。
实现过程
绘制折线图
贝塞尔曲线平滑拟合
模拟数据
var data = [Math.random() * 300];
for (var i = 1; i < 50; i++) { //按照echarts
data.push(Math.round((Math.random() - 0.5) * 20 + data[i - 1]));
}
option = {
canvas:{
id: 'canvas'
},
series: {
name: '模拟数据',
itemStyle: {
color: 'rgb(255, 70, 131)'
},
areaStyle: {
color: 'rgb(255, 158, 68)'
},
data: data
}
};绘制折线图
首先初始化一个构造函数来放置需要用到的数据:
function LinearGradient(option) {
this.canvas = document.getElementById(option.canvas.id)
this.ctx = this.canvas.getContext('2d')
this.width = this.canvas.width
this.height = this.canvas.height
this.tooltip = option.tooltip
this.title = option.text
this.series = option.series //存放模拟数据
}绘制折线图:
LinearGradient.prototype.draw1 = function() { //折线参考线
...
//要考虑到canvas中的原点是左上角,
//所以下面要做一些换算,
//diff为x,y轴被数据最大值和最小值的取值范围所平分的等份。









