Echarts学习
Posted xiaobu-wu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Echarts学习相关的知识,希望对你有一定的参考价值。
Echarts学习
简介 :ECharts,一个使用 javascript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。
引入 ECharts
ECharts 3 开始不再强制使用 AMD 的方式按需引入,代码里也不再内置 AMD 加载器。因此引入方式简单了很多,只需要像普通的 JavaScript 库一样用 script 标签引入。
<!DOCTYPE html> <html> <header> <meta charset="utf-8"> <!-- 引入 ECharts 文件 --> <script src="echarts.min.js"></script> </header> </html>
绘制一个简单的图表
在绘图前我们需要为 ECharts 准备一个具备高宽的 DOM 容器。
<body> <!-- 为 ECharts 准备一个具备大小(宽高)的 DOM --> <div id="main" style="width: 600px;height:400px;"></div> </body>
然后就可以通过 echarts.init 方法初始化一个 echarts 实例并通过 setOption 方法生成一个简单的柱状图,下面是完整代码。
<!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>
这样你的第一个图表就诞生了!
Webpack 是目前比较流行的模块打包工具,你可以在使用 webpack 的项目中轻松的引入和打包 ECharts,这里假设你已经对 webpack 具有一定的了解并且在自己的项目中使用。
npm 安装 ECharts
在 3.1.1
版本之前 ECharts 在 npm 上的 package 是非官方维护的,从 3.1.1
开始由官方 EFE 维护 npm 上 ECharts 和 zrender 的 package。
你可以使用如下命令通过 npm 安装 ECharts
npm install echarts --save
引入 ECharts
通过 npm 上安装的 ECharts 和 zrender 会放在node_modules
目录下。可以直接在项目代码中 require(‘echarts‘)
得到 ECharts。
var echarts = require(‘echarts‘); // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById(‘main‘)); // 绘制图表 myChart.setOption({ title: { text: ‘ECharts 入门示例‘ }, tooltip: {}, xAxis: { data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"] }, yAxis: {}, series: [{ name: ‘销量‘, type: ‘bar‘, data: [5, 20, 36, 10, 10, 20] }] });
按需引入 ECharts 图表和组件
默认使用 require(‘echarts‘)
得到的是已经加载了所有图表和组件的 ECharts 包,因此体积会比较大,如果在项目中对体积要求比较苛刻,也可以只按需引入需要的模块。
例如上面示例代码中只用到了柱状图,提示框和标题组件,因此在引入的时候也只需要引入这些模块,可以有效的将打包后的体积从 400 多 KB 减小到 170 多 KB。
// 引入 ECharts 主模块 var echarts = require(‘echarts/lib/echarts‘); // 引入柱状图 require(‘echarts/lib/chart/bar‘); // 引入提示框和标题组件 require(‘echarts/lib/component/tooltip‘); require(‘echarts/lib/component/title‘); // 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById(‘main‘)); // 绘制图表 myChart.setOption({ title: { text: ‘ECharts 入门示例‘ }, tooltip: {}, xAxis: { data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"] }, yAxis: {}, series: [{ name: ‘销量‘, type: ‘bar‘, data: [5, 20, 36, 10, 10, 20] }] });
对于另一个流行的模块打包工具 browserify 也是同样的用法,这里就不赘述了。
绘制南丁格尔图
饼图主要是通过扇形的弧度表现不同类目的数据在总和中的占比,它的数据格式比柱状图更简单,只有一维的数值,不需要给类目。因为不在直角坐标系上,所以也不需要xAxis
,yAxis
。
myChart.setOption({ series : [ { name: ‘访问来源‘, type: ‘pie‘, radius: ‘55%‘, data:[ {value:400, name:‘搜索引擎‘}, {value:335, name:‘直接访问‘}, {value:310, name:‘邮件营销‘}, {value:274, name:‘联盟广告‘}, {value:235, name:‘视频广告‘} ] } ] })
异步加载
入门示例中的数据是在初始化后setOption
中直接填入的,但是很多时候可能数据需要异步加载后再填入。ECharts
中实现异步数据的更新非常简单,在图表初始化后不管任何时候只要通过 jQuery 等工具异步获取数据后通过 setOption
填入数据和配置项就行。
var myChart = echarts.init(document.getElementById(‘main‘)); $.get(‘data.json‘).done(function (data) { myChart.setOption({ title: { text: ‘异步数据加载示例‘ }, tooltip: {}, legend: { data:[‘销量‘] }, xAxis: { data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"] }, yAxis: {}, series: [{ name: ‘销量‘, type: ‘bar‘, data: [5, 20, 36, 10, 10, 20] }] }); }); var myChart = echarts.init(document.getElementById(‘main‘)); // 显示标题,图例和空的坐标轴 myChart.setOption({ title: { text: ‘异步数据加载示例‘ }, tooltip: {}, legend: { data:[‘销量‘] }, xAxis: { data: [] }, yAxis: {}, series: [{ name: ‘销量‘, type: ‘bar‘, data: [] }] }); // 异步加载数据 $.get(‘data.json‘).done(function (data) { // 填入数据 myChart.setOption({ xAxis: { data: data.categories }, series: [{ // 根据名字对应到相应的系列 name: ‘销量‘, data: data.data }] }); });
ECharts 中在更新数据的时候需要通过name
属性对应到相应的系列,上面示例中如果name
不存在也可以根据系列的顺序正常更新,但是更多时候推荐更新数据的时候加上系列的name
数据。
loading 动画
如果数据加载时间较长,一个空的坐标轴放在画布上也会让用户觉得是不是产生 bug 了,因此需要一个 loading 的动画来提示用户数据正在加载。
ECharts 默认有提供了一个简单的加载动画。只需要调用 showLoading 方法显示。数据加载完成后再调用 hideLoading 方法隐藏加载动画。
myChart.showLoading(); $.get(‘data.json‘).done(function (data) { myChart.hideLoading(); myChart.setOption(...); });
ECharts 工作在用户指定高宽的 DOM 节点(容器)中。ECharts 的『组件』和『系列』都在这个 DOM 节点中,每个节点都可以由用户指定位置。图表库内部并不适宜实现 DOM 文档流布局,因此采用类似绝对布局的简单容易理解的布局方式。但是有时候容器尺寸极端时,这种方式并不能自动避免组件重叠的情况,尤其在移动端小屏的情况下。
另外,有时会出现一个图表需要同时在PC、移动端上展现的场景。这需要 ECharts 内部组件随着容器尺寸变化而变化的能力。
为了解决这个问题,ECharts 完善了组件的定位设置,并且实现了类似 CSS Media Query 的自适应能力。
ECharts组件的定位和布局
大部分『组件』和『系列』会遵循两种定位方式:
left/right/top/bottom/width/height 定位方式:
这六个量中,每个量都可以是『绝对值』或者『百分比』或者『位置描述』。
-
绝对值
单位是浏览器像素(px),用
number
形式书写(不写单位)。例如{left: 23, height: 400}
。 -
百分比
表示占 DOM 容器高宽的百分之多少,用
string
形式书写。例如{right: ‘30%‘, bottom: ‘40%‘}
。 -
位置描述
- 可以设置
left: ‘center‘
,表示水平居中。 - 可以设置
top: ‘middle‘
,表示垂直居中。
- 可以设置
这六个量的概念,和 CSS 中六个量的概念类似:
- left:距离 DOM 容器左边界的距离。
- right:距离 DOM 容器右边界的距离。
- top:距离 DOM 容器上边界的距离。
- bottom:距离 DOM 容器下边界的距离。
- width:宽度。
- height:高度。
在横向,left
、right
、width
三个量中,只需两个量有值即可,因为任两个量可以决定组件的位置和大小,例如 left
和right
或者 right
和 width
都可以决定组件的位置和大小。 纵向,top
、bottom
、height
三个量,和横向类同不赘述。
center
/ radius
定位方式:
-
center
是一个数组,表示
[x, y]
,其中,x
、y
可以是『绝对值』或者『百分比』,含义和前述相同。 -
radius
是一个数组,表示
[内半径, 外半径]
,其中,内外半径可以是『绝对值』或者『百分比』,含义和前述相同。在自适应容器大小时,百分比设置是很有用的。
横向(horizontal)和纵向(vertical)
ECharts的『外观狭长』型的组件(如 legend
、visualMap
、dataZoom
、timeline
等),大多提供了『横向布局』『纵向布局』的选择。例如,在细长的移动端屏幕上,可能适合使用『纵向布局』;在PC宽屏上,可能适合使用『横向布局』。
横纵向布局的设置,一般在『组件』或者『系列』的 orient
或者 layout
配置项上,设置为 ‘horizontal‘
或者‘vertical‘
。
于 ECharts2 的兼容:
ECharts2 中的 x/x2/y/y2
的命名方式仍被兼容,对应于 left/right/top/bottom
。但是建议写 left/right/top/bottom
。
位置描述中,为兼容 ECharts2,可以支持一些看起来略奇怪的设置:left: ‘right‘
、left: ‘left‘
、top: ‘bottom‘
、top: ‘top‘
。这些语句分别等效于:right: 0
、left: 0
、bottom: 0
、top: 0
,写成后者就不奇怪了。
Media Query
Media Query 提供了『随着容器尺寸改变而改变』的能力。
如下例子,可尝试拖动右下角的圆点,随着尺寸变化,legend 和 系列会自动改变布局位置和方式。
要在 option 中设置 Media Query 须遵循如下格式:
option = { baseOption: { // 这里是基本的『原子option』。 title: {...}, legend: {...}, series: [{...}, {...}, ...], ... }, media: [ // 这里定义了 media query 的逐条规则。 { query: {...}, // 这里写规则。 option: { // 这里写此规则满足下的option。 legend: {...}, ... } }, { query: {...}, // 第二个规则。 option: { // 第二个规则对应的option。 legend: {...}, ... } }, { // 这条里没有写规则,表示『默认』, option: { // 即所有规则都不满足时,采纳这个option。 legend: {...}, ... } } ] };
上面的例子中,baseOption
、以及 media
每个 option 都是『原子 option』,即普通的含有各组件、系列定义的 option。而由『原子option』组合成的整个 option,我们称为『复合 option』。baseOption
是必然被使用的,此外,满足了某个 query
条件时,对应的 option 会被使用 chart.mergeOption()
来 merge 进去。
query:
每个 query
类似于这样:
{ minWidth: 200, maxHeight: 300, minAspectRatio: 1.3 }
现在支持三个属性:width
、height
、aspectRatio
(长宽比)。每个属性都可以加上 min
或 max
前缀。比如,minWidth: 200
表示『大于等于200px宽度』。两个属性一起写表示『并且』,比如:{minWidth: 200, maxHeight: 300}
表示『大于等于200px宽度,并且小于等于300px高度』。
option:
media
中的 option 既然是『原子 option』,理论上可以写任何 option 的配置项。但是一般我们只写跟布局定位相关的,例如截取上面例子中的一部分 query option:
media: [ ..., { query: { maxAspectRatio: 1 // 当长宽比小于1时。 }, option: { legend: { // legend 放在底部中间。 right: ‘center‘, bottom: 0, orient: ‘horizontal‘ // legend 横向布局。 }, series: [ // 两个饼图左右布局。 { radius: [20, ‘50%‘], center: [‘50%‘, ‘30%‘] }, { radius: [30, ‘50%‘], center: [‘50%‘, ‘70%‘] } ] } }, { query: { maxWidth: 500 // 当容器宽度小于 500 时。 }, option: { legend: { right: 10, // legend 放置在右侧中间。 top: ‘15%‘, orient: ‘vertical‘ // 纵向布局。 }, series: [ // 两个饼图上下布局。 { radius: [20, ‘50%‘], center: [‘50%‘, ‘30%‘] }, { radius: [30, ‘50%‘], center: [‘50%‘, ‘75%‘] } ] } }, ... ]
多个 query 被满足时的优先级:
注意,可以有多个 query
同时被满足,会都被 mergeOption
,定义在后的后被 merge(即优先级更高)。
默认 query:
如果 media
中有某项不写 query
,则表示『默认值』,即所有规则都不满足时,采纳这个option。
容器大小实时变化时的注意事项:
在不少情况下,并不需要容器DOM节点任意随着拖拽变化大小,而是只是根据不同终端设置几个典型尺寸。
但是如果容器DOM节点需要能任意随着拖拽变化大小,那么目前使用时需要注意这件事:某个配置项,如果在某一个 query option
中出现,那么在其他 query option
中也必须出现,否则不能够回归到原来的状态。(left/right/top/bottom/width/height
不受这个限制。)
『复合 option』 中的 media
不支持 merge
也就是说,当第二(或三、四、五 ...)次 chart.setOption(rawOption)
时,如果 rawOption
是 复合option
(即包含 media
列表),那么新的 rawOption.media
列表不会和老的 media
列表进行 merge,而是简单替代。当然,rawOption.baseOption
仍然会正常和老的 option 进行merge。
其实,很少有场景需要使用『复合 option』来多次 setOption
,而我们推荐的做法是,使用 mediaQuery 时,第一次setOption使用『复合 option』,后面 setOption
时仅使用 『原子 option』,也就是仅仅用 setOption 来改变 baseOption
。
以上是关于Echarts学习的主要内容,如果未能解决你的问题,请参考以下文章
echarts学习总结:一个页面存在多个echarts图形,图形自适应窗口大小