原文地址:canvas图表(2) - 折线图
话说这天气一冷啊, 就患懒癌, 就不想码代码, 就想着在床上舒舒服服看视频. 那顺便就看blender视频, 学习下3D建模, 如果学会了建3D模型, 那我的webGL技术就大有用处啊,可以独立开发小游戏了, 当然是玩笑了。但首先还是把canvas图表系列先弄完吧, 今天就弄折线图。
效果请看:柱状图https://edwardzhong.github.io/sites/demo/dist/chartline.html
主要功能点包括:
3. 数据动画的实现;
4. 鼠标事件的处理。
大部分的技术在上一节的canvas图表(1) - 柱状图实现了, 所以这节内容其实是比较简单的。比较麻烦一点的就是折线图的动画了,所以重点就看一下这部分的代码。
使用方式使用方式,和柱状图基本是一样的,我们这里表示的是气温变化图。
line (con)[] [ [] [] } ] })
代码结构折线图对象大体和柱状图一致,只是部分方法经过重构。
(container)(opt)opt)......()(pos(index)()()()()
数据动画折线图动画实现的是路径绘制特效,懂canvas的基本都知道原理,就是用lineTo绘制路径,最后stroke出来。但这个折线图是分段的,所以要分情况处理,主要难点就是获取两个点之间的坐标。
仔细思考下,因为我们知道x轴总长度,所以可以让x依次递增,再求出x对应的y坐标即可。既然知道了两个点的坐标,还知道了x坐标,根据同角度等比例三角形原理,很容易求出y坐标。然后用requestAnimationFrame递归调用即可实现动画了,具体看如下代码。
ctxxdis.prev, xy((x....itemi<il;i++){ item(.....objj<jl;j++){ obj=item.data[j]; prev(j..(x..(xy(x..h) .(objj<jl;j++){ obj(x...)..restore(); x(run); }()) }
事件处理还有就是鼠标事件处理方面,鼠标滑过画面,判断要将该阶段的信息显示,同时实心填充点和画一条指示线,这里必须不断擦除画面,然后重绘,这样就实现了交互动画。具体看以下代码。
ctxcanvasxlxs.padding)/(xl-1), index.(e)(isLegend) (..........(ii*xs){ index.arritemj<l;j++){ item(...data[index].num}) ...)(e))(pos.canvas.getBoundingClientRect(), con=this.container.getBoundingClientRect(), htmltxt.forEach(obj=>{ txt..num):obj.num; html.txt) .(..(..(index)ctx...........itemi<il;i++){ item(.....objj<jl;j++){ obj(j.....(objj<jl;j++){ obj(index.......).........)..restore(); }
最后图表代码请看chart.js