前几天用到了图表库,其中百度的ECharts,感觉做得最好,看它默认用的是canvas,canvas图表在处理大数据方面比svg要好。那我也用canvas来实现一个图表库吧,感觉不会太难,先实现个简单的柱状图。
效果如下:

主要功能点包括:
-
文本的绘制
XY轴的绘制;
数据分组绘制;
数据动画的实现;
鼠标事件的处理。
使用方式
首先我们看一下使用方式,参考了部分ECharts的使用方式,先传入要显示图表的html标签,接着调用init,初始化的同时传入数据。
| var con=document.getElementById('container'); var chart=new Bar(con); chart.init({ title:'全年降雨量柱状图', xAxis:{// x轴 data:['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'] }, yAxis:{//y轴 name:'水量', formatter:'{value} ml' }, series:[//分组数据 { name:'东部降水量', data:[62,20,17,45,100,56,19,38,50,120,56,130] }, { name:'西部降水量', data:[52,10,17,25,60,39,19,48,70,30,56,8] }, { name:'南部降水量', data:[12,10,17,25,27,39,50,38,100,30,56,90] }, { color:'hsla(270,80%,60%,1)', name:'北部降水量', data:[12,30,17,25,7,39,49,38,60,30,56,10] } ] }); |
图表基类,我们后面还要写饼图,折线图,所以把公共的部分抽出来。注意canvas.style.width与canvas.width是不一样的,前者会拉伸图形,后者才是我们正常用的,不会拉伸图形。在这里这样写先扩大再缩小是为了解决canvas绘制文字时模糊的问题。
| class Chart{ constructor(container){ this.container=container; this.canvas=document.createElement('canvas'); this.ctx=this.canvas.getContext('2d'); this.W=1000*2; this.H=600*2; this.padding=120; this.paddingTop=50; this.title=''; this.legend=[]; this.series=[]; //通过缩小一倍,解决字体模糊问题 this.canvas.width=this.W; this.canvas.height=this.H; this.canvas.style.width = this.W/2 + 'px'; this.canvas.style.height = this.H/2 + 'px'; } } |
柱状图初始化,调用es6中的Object.assign(this,opt),这个相当于JQ中的extend方法,把属性复制到当前实例。同时还建了个tip属性,这是个html标签,后面显示数据信息用。接着绘制图形,然后绑定鼠标事件。









