一、Echarts是如何画图的
在ECharts 5没有出现之前,ECharts官方的首页还不是现在的简约风格。打开后映入眼帘的是一个很有科技感的视频,作为一个前端小白来讲,哇,前端还能这么秀?相信很多人都会有这样的想法,因为没有深入了解过大前端的小白们大都无法将数组、对象和眼前这个直观的图表联系起来。但是如果仔细研究后会发现,ECharts的原理其实也没有那么难。
整个ECharts库都是以canvas为基础的!canvas是一个可以在页面上固定的画图区域建立坐标系,然后通过JavaScript脚本在坐标系中绘制圆、盒、文字等。比如下面这段代码:
<canvas id="canvasArea" width="300" height="300"></canvas>
canvas {
border: 1px solid black;
}
function draw(){
var canvas = document.getElementById('canvasArea');
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect (10, 10, 55, 50);
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
ctx.fillRect (30, 30, 55, 50);
}
draw();
这是一段简单的canvas代码,用来生成两个矩形,在浏览器中显示的结果如下:
上图中黑色边框圈起来的区域便是画图区域。利用坐标和宽窄,canvas便会自动帮助我们生成我们想要图案。
理解清楚这一步以后,就可以理解ECharts究竟做了什么了:Echarts拿到数据后,通过一系列的计算,算出canvas绘制图案时所需要的数据(坐标、高度、宽度等);最终通过canvas,绘制出各色图表。
Created with Raphaël 2.2.0 原始数据 ECharts中的算法计算canvas绘制图表时需要的数据 canvas通过数据绘制图表 最终显示在浏览器中的图表
二、组件化——让开发者定制图表的解决方案
为了能满足用户的需求,ECharts对个色图表的组成也做了研究,并将其称之为组件。ECharts中的组件包括xAxis(直角坐标系 X 轴)、yAxis(直角坐标系 Y 轴)、grid(直角坐标系底板)、angleAxis(极坐标系角度轴)、radiusAxis(极坐标系半径轴)、polar(极坐标系底板)、geo(地理坐标系)、dataZoom(数据区缩放组件)、visualMap(视觉映射组件)、tooltip(提示框组件)、toolbox(工具栏组件)、series(系列)等等等等,几乎是满足了所有图表的需求。
为了更直观的展示这些组件是如何完善图表的,官方教程中给出了这样的一张图:
可以看到ECharts对整个图表中的各个部分都做了拆分,组件化为使用者提供了更多的选择,让ECharts在高度封装的前提下,又能满足开发者们的自定义需要。
三、ECharts如何了解你的想法
当然,ECharts有了非常好的解决方案,但也需要一种简洁的方法来了解开发者的想法,降低学习成本是一个优秀框架的前提,过高的学习成本会阻碍一个优秀框架的进步。万幸的是ECharts解决了这个问题。
仔细研究上面canvas确定绘图区域的方法,会发现canvas是结合DOM来选定绘图区域来最终确定坐标系的,这样做的好处的,可以通过CSS来控制最终图表的位置,绘图区域的调整和修改最终也不会影响到绘图的结果。ECharts在选取绘制区域上也使用了这一种方法:
<body>
<!-- 为 ECharts 准备一个具备大小(宽高)的 DOM -->
<div id="main" style="width: 600px;height:400px;"></div>
</body>
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
上面中通过dom确定了接下来的绘图区域。无论后续绘图区域的位置及宽高如何变化,ECharts都会基于该元素绘制图表。
确定在哪绘图后,ECharts需要了解开发者需要怎样的图表,基于组件化的设计,ECharts规定了开发者需要通过一个简单的option对象,来配置图表中的各个组件,例如官方文档中的简单例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ECharts</title>
<!-- 引入 echarts.js -->
<script src="echarts.min.js"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 指定图表的配置项和数据
var option = {
title: {
text: 'ECharts 入门示例'
},
tooltip: {},
legend: {
data:['销量']
},
xAxis: {
data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
},
yAxis: {},
series: [{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</body>
</html>
可以看出option对象中的属性最终都以组件的方式展示在了图表中:title属性被展示为图表的标题,legend属性被渲染成为图表的图例,xAxis属性被渲染成X轴,series属性被渲染成了柱状图(series是ECharts中的一个基础概念,它指一组数值以及他们映射成的图,后面的文章中会有介绍)。
四、ECharts真正的魅力
理解完上面的内容,会发现ECharts的语法真的非常简单,熟练运用后,制作图表或许比一点一点的调整CSS更容易,但这只是一个开始。
在我看来,ECharts真正的魅力在于除了绘图,它会帮你完成很多看似无关紧要的细节,比如动画效果:
除了这种初次加载时的动画,还包括一些数据加载中的动画效果,你会惊讶的发现这些效果不仅仅作用在核心图上,整个图表的组件都会跟随动画进行变动:
这些用心的小细节会让页面的使用者更加舒心。当然ECharts除了这些还有很多惊艳的地方,小到组件上的一些小细节,大到绘制3D图表等,也难怪它的运用范围如此广泛。
五、不安于现状的ECharts
ECharts本身已经十分优秀了,项目覆盖率也非常的广,但是ECharts 5又一次创造了变革。抛开数据层面的进步不说,使用svg渲染代替canvas渲染就已经让人十分乘醉。
先对比一下在浏览器中放大250%后两种渲染方式的区别,先看canvas下渲染的:
发现了什么?放大250%后,图表已经已经完全虚化。再看看svg下渲染的结果:
看出差距了吗?svg完全解决了虚化的问题,真的是强迫症工程师的福音。
我们再看看两种渲染结果在最终的html文档中的表现,先看canvas的:
看出来了吗?canvas最终在html里面只有一个标签,即容器标签,所有的操作都是在JavaScript脚本中进行的,再看看svg的:
svg渲染后,图中的每一个元素都会以标签的形式展现在最终的html文档中,这样做的好处就是给哪些大佬们提供了自我发挥的空间,虽然我暂时没有尝试,但是,svg可能的确会使ECharts变得更加灵活。
参考和应用
https://echarts.apache.org/zh/index.html (Apache ECharts官网)
https://www.runoob.com/w3cnote/html5-canvas-intro.html (《学习 HTML5 Canvas 这一篇文章就够了》(菜鸟教程))