ECharts学习

ECharts 特性

ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖轻量级的矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表

丰富的可视化类型

ECharts 提供了常规的折线图、柱状图、散点图、饼图、K线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于关系数据可视化的关系图、treemap、旭日图,多维数据可视化的平行坐标,还有用于 BI 的漏斗图,仪表盘,并且支持图与图之间的混搭。

除了已经内置的包含了丰富功能的图表,ECharts 还提供了自定义系列,只需要传入一个renderItem函数,就可以从数据映射到任何你想要的图形,更棒的是这些都还能和已有的交互组件结合使用而不需要操心其它事情。还可以在下载界面下载包含所有图表的构建文件,如果只是需要其中一两个图表,又嫌包含所有图表的构建文件太大,也可以在在线构建中选择需要的图表类型后自定义构建

多种数据格式无需转换直接使用

ECharts 内置的 dataset 属性(4.0+)支持直接传入包括二维表,key-value 等多种格式的数据源,通过简单的设置 encode 属性就可以完成从数据到图形的映射,这种方式更符合可视化的直觉,省去了大部分场景下数据转换的步骤,而且多个组件能够共享一份数据而不用克隆。

为了配合大数据量的展现,ECharts 还支持输入 TypedArray 格式的数据,TypedArray 在大数据量的存储中可以占用更少的内存,对 GC 友好等特性也可以大幅度提升可视化应用的性能

千万数据的前端展现

通过增量渲染技术(4.0+),配合各种细致的优化,ECharts 能够展现千万级的数据量,并且在这个数据量级依然能够进行流畅的缩放平移等交互。几千万的地理坐标数据就算使用二进制存储也要占上百 MB 的空间。因此 ECharts 同时提供了对流加载(4.0+)的支持,你可以使用 WebSocket 或者对数据分块后加载,加载多少渲染多少!不需要漫长地等待所有数据加载完再进行绘制

移动端优化

ECharts 针对移动端交互做了细致的优化,例如移动端小屏上适于用手指在坐标系中进行缩放、平移。 PC 端也可以用鼠标在图中进行缩放(用鼠标滚轮)、平移等。细粒度的模块化和打包机制可以让 ECharts 在移动端也拥有很小的体积,可选的 SVG 渲染模块让移动端的内存占用不再捉襟见肘

多渲染方案,跨平台使用

ECharts 支持以 Canvas、SVG(4.0+)、VML 的形式渲染图表。VML 可以兼容低版本 IE,SVG 使得移动端不再为内存担忧,Canvas 可以轻松应对大数据量和特效的展现。不同的渲染方式提供了更多选择,使得 ECharts 在各种场景下都有更好的表现。除了 PC 和移动端的浏览器,ECharts 还能在 node 上配合 node-canvas 进行高效的服务端渲染(SSR)。从 4.0 开始我们还和微信小程序的团队合作,提供了 ECharts 对小程序的适配!

社区热心的贡献者也为我们提供了丰富的其它语言扩展,比如 Python 的pyecharts,R 语言的 recharts, Julia 的 ECharts.jl 等等。我们希望平台和语言都不会成为大家使用 ECharts 实现可视化的限制

深度的交互式数据探索

交互是从数据中发掘信息的重要手段。“总览为先,缩放过滤按需查看细节”是数据可视化交互的基本需求。

ECharts 一直在交互的路上前进,我们提供了 图例、视觉映射、数据区域缩放、tooltip、数据刷选等开箱即用的交互组件,可以对数据进行多维度数据筛取、视图缩放、展示细节等交互操作

多维数据的支持以及丰富的视觉编码手段

ECharts 3 开始加强了对多维数据的支持。除了加入了平行坐标等常见的多维数据可视化工具外,对于传统的散点图等,传入的数据也可以是多个维度的。配合视觉映射组件 visualMap 提供的丰富的视觉编码,能够将不同维度的数据映射到颜色,大小,透明度,明暗度等不同的视觉通道

动态数据

ECharts 由数据驱动,数据的改变驱动图表展现的改变。因此动态数据的实现也变得异常简单,只需要获取数据,填入数据,ECharts 会找到两组数据之间的差异然后通过合适的动画去表现数据的变化。配合 timeline 组件能够在更高的时间维度上去表现数据的信息

绚丽的特效

ECharts 针对线数据,点数据等地理数据的可视化提供了吸引眼球的特效

通过 GL 实现更多更强大绚丽的三维可视化

想要在 VR,大屏场景里实现三维的可视化效果?我们提供了基于 WebGL 的 ECharts GL,你可以跟使用 ECharts 普通组件一样轻松的使用 ECharts GL 绘制出三维的地球,建筑群,人口分布的柱状图,在这基础之上我们还提供了不同层级的画面配置项,几行配置就能得到艺术化的画面

无障碍访问(4.0+)

当我们说到“可视化”的时候,我们往往很自然地将它与“看得⻅”联系在一起,但其实这是片面的。W3C制定了无障碍富互联网应用规范集(WAI-ARIA,the Accessible Rich Internet Applications Suite),致力于使得网⻚内容和网⻚应 用能够被更多残障人士访问。

ECharts 4.0遵从这一规范,支持自动根据图表配置项智能生成描述,使得盲人可以在朗读设备的帮助下了解图表内容,让图表可以被更多人群访问

ECharts 教程

5 分钟上手 ECharts

获取 ECharts

可以通过以下几种方式获取 ECharts

1.从官网下载界面选择你需要的版本下载,根据开发者功能和体积上的需求,我们提供了不同打包的下载,如果你在体积上没有要求,可以直接下载完整版本。开发环境建议下载源代码版本,包含了常见的错误提示和警告。

2.在ECharts的GitHub上下载最新的release版本,解压出来的文件夹里的dist目录里可以找到最新版本的echarts库。

3.通过npm获取 echarts,npm install echarts --save

4.cdn 引入,你可以在 cdnjs,npmcdn 或者国内的 bootcdn 上找到 ECharts 的最新版本

引入 ECharts

ECharts 3 开始不再强制使用 AMD 的方式按需引入,代码里也不再内置 AMD 加载器。因此引入方式简单了很多,只需要像普通的 JavaScript 库一样用 script 标签引入

<script src="echarts.min.js"></script>

绘制一个简单的图表

在绘图前我们需要为 ECharts 准备一个具备高宽的 DOM 容器

<div id="main" style="width: 600px;height:400px;"></div>

然后就可以通过 echarts.init 方法初始化一个 echarts 实例并通过 setOption 方法生成一个简单的柱状图,下面是完整代码

<div id="main" style="width: 600px;height:400px;"></div> <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<script type="text/javascript">        
    var myChart = echarts.init(document.getElementById('main')); // 基于准备好的dom,初始化echarts实例        
    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>

自定义构建 ECharts

一般来说,可以直接从echarts下载页中获取构建好的echarts,也可以从GitHub中的echarts/dist文件夹中获取构建好的echarts,这都可以直接在浏览器端项目中使用。这些构建好的echarts提供了下面这几种定制:

1.完全版:echarts/dist/echarts.js,体积最大,包含所有的图表和组件

2.常用版:echarts/dist/echarts.common.js,体积适中,包含常见的图表和组件

3.精简版:echarts/dist/echarts.simple.js,体积较小,仅包含最常用的图表和组件

如果对文件体积有更严苛的要求,可以自己构建 echarts,能够仅仅包括自己所需要的图表和组件。自定义构建有几种方式:

1.在线自定义构建:比较方便

2.使用 echarts/build/build.js 脚本自定义构建:比在线构建更灵活一点,并且支持多语言

3.直接使用构建工具(如 rollup、webpack、browserify)自己构建:也是一种选择

下面我们举些小例子,介绍后两种方式

准备工作:创建自己的工程和安装 echarts

使用命令行,创建自己的工程:

mkdir myProject
cd myProject

在 myProject 目录下使用命令行,初始化工程的 npm 环境并安装 echarts(这里前提是您已经安装了 npm):

npm init
npm install echarts --save

通过 npm 安装的 echarts 会出现在 myProject/node_modules 目录下,从而可以直接在项目代码中得到 echarts,例如:

1.使用 ES Module:

import * as echarts from 'echarts';

2.使用 CommonJS:

var echarts = require('echarts')

下面仅以使用 ES Module 的方式来举例

使用 echarts 提供的构建脚本自定义构建

在这个例子中,我们要创建一个饼图,并且想自定义构建一个只含有饼图的 echarts 文件,从而能使 echarts 文件的大小比较小一些。echarts 已经提供了构建脚本 echarts/build/build.js,基于 Node.js 运行。我们可以在 myProject 目录下使用命令行,看到它的使用方式:

node node_modules/echarts/build/build.js --help

其中我们在这个例子里会用到的参数有:

-i:代码入口文件,可以是绝对路径或者基于当前命令行路径的相对路径

-o:生成的 bundle 文件,可以是绝对路径或者基于当前命令行路径的相对路径

--min:是否压缩文件(默认不压缩),并且去多余的打印错误信息的代码,形成生产环境可用的文件

--lang :是否使用其他语言版本,默认是中文。例如:--lang en 表示使用英文,--lang my/langXX.js 表示构建时使用 /my/langXX.js 替代 echarts/lib/lang.js 文件

--sourcemap:是否输出 source map,以便于调试

--format:输出的格式,可选 'umb'(默认)、'amd'、'iife'、'cjs'、'es'

既然我们想自定义构建一个只含有饼图的 echarts 文件,我们需要创建一个入口文件,可以命名为 myProject/echarts.custom.js,文件里会引用所需要的 echarts 模块:

export * from 'echarts/src/echarts'; // 引入 echarts 主模块
import 'echarts/src/chart/pie'; // 引入饼图
// 在这个场景下,可以引用 `echarts/src` 或者 `echarts/lib` 下的文件(但是不可混用)

然后我们可以在 myProject 目录下使用命令行,这样开始构建:

node node_modules/echarts/build/build.js --min -i echarts.custom.js -o lib/echarts.custom.min.js

这样,myProject/lib/echarts.custom.min.js 就生成了。我们可以创建html页面来使用它:

<div id="main" style="width: 600px;height:400px;"></div>
<script>
    // 绘制图表。
    echarts.init(document.getElementById('main')).setOption({
        series: {
            type: 'pie',
            data: [ {name: 'A', value: 1212}, {name: 'B', value: 2323}, {name: 'C', value: 1919} ]
        }
    });
</script>

允许被引用的模块

在自定义构建中,允许被引用的模块,全声明在 myProject/node_module/echarts/echarts.all.js 和 myProject/node_module/echarts/src/export.js 中。echarts 和 zrender 源代码中的其他模块,都是 echarts 的内部模块,不应该去引用。因为在后续 echarts 版本升级中,内部模块的接口和功能可能变化,甚至模块本身也可能被移除

引用 echarts/lib/ 还是 echarts/src/

1.项目中如果直接引用 echarts 里的一些模块并自行构建,应该使用 echarts/lib/ 路径,而不可使用 echarts/src/

2.当使用构建脚本 echarts/build/build.js 打包 bundle,那么两者可以选其一使用(不可混用),使用 echarts/src/** 可以获得稍微小一些的文件体积

原因是:目前,echarts/src/ 中是采用 ES Module 的源代码,echarts/lib/ 中是 echarts/src/ 编译成为 CommonJS 后的产物(编译成 CommonJS 是为了向后兼容一些不支持 ES Module 的老版本 NodeJS 和 webpack)。 因为历史上,各个 echarts 扩展、各个用户项目,一直是使用的包路径是 echarts/lib/,所以这个路径不应该改变,否则,可能导致混合使用 echarts/src/ 和 echarts/lib/ 得到两个不同的 echarts 名空间造成问题。而使用 echarts/build/build.js 打包 bundle 时没有涉及这个问题,echarts/src/** 中的 ES Module 便于静态分析从而得到稍微小些的文件体积

直接使用 rollup 自定义构建

与如何使用 echarts 提供的脚本 echarts/build/build.js 自定义构建并列的另一种选择是,我们直接使用构建工具(如 rollup、webpack、browserify)自定义构建,并且把 echarts 代码和项目代码在构建成一体。在一些项目中可能需要这么做。下面我们仅仅介绍如何使用 rollup 来构建。webpack 和 browserify 与此类同述

首先我们在 myProject 目录下使用 npm 安装 rollup:

npm install rollup --save-dev
npm install rollup-plugin-node-resolve --save-dev
npm install rollup-plugin-uglify --save-dev

接下来创建项目 JS 文件 myProject/line.js 来绘制图表,内容为:

import * as echarts from 'echarts/lib/echarts'; // 引入 echarts 主模块
import 'echarts/lib/chart/line'; // 引入折线图
import 'echarts/lib/component/tooltip'; // 引入提示框组件、标题组件、工具箱组件
import 'echarts/lib/component/title';
import 'echarts/lib/component/toolbox';
echarts.init(document.getElementById('main')).setOption({ // 基于准备好的dom,初始化 echarts 实例并绘制图表
    title: {text: 'Line Chart'},
    tooltip: {},
    toolbox: {
        feature: {
            dataView: {},
            saveAsImage: { pixelRatio: 2 },
            restore: {}
        }
    },
    xAxis: {},
    yAxis: {},
    series: [{ type: 'line', smooth: true, data: [[12, 5], [24, 20], [36, 36], [48, 10], [60, 10], [72, 20]] }]
});

对于不支持 ES Module 的浏览器而言,刚创建的 myProject/line.js 还不能直接被网页引用并在浏览器中运行,需要进行构建。使用 rollup 构建前,需要创建它的配置文件 myProject/rollup.config.js,内容如下:

import nodeResolve from 'rollup-plugin-node-resolve'; // 这个插件用于在 `node_module` 文件夹(即npm用于管理模块的文件夹)中寻找模块。比如,代码中有`import 'echarts/lib/chart/line';` 时,这个插件能够寻找到`node_module/echarts/lib/chart/line.js` 这个模块文件
import uglify from 'rollup-plugin-uglify'; // 用于压缩构建出的代码
// import ecLangPlugin from 'echarts/build/rollup-plugin-ec-lang'; // 用于多语言支持(如果不需要可忽略此 plugin)
export default {
    name: 'myProject',    
    input: './line.js', // 入口代码文件,就是刚才所创建的文件
    plugins: [
        nodeResolve(),
        // ecLangPlugin({lang: 'en'}),
        // 消除代码中的 __DEV__ 代码段,从而不在控制台打印错误提示信息。
        uglify()
    ],
    output: {        
        format: 'umd', // 以 UMD 格式输出,从而能在各种浏览器中加载使用      
        sourcemap: true, // 输出 source map 便于调试      
        file: 'lib/line.min.js' // 输出文件的路径
    }
};

然后在 myProject 目录下使用命令行,构建工程代码 myProject/line.js:

./node_modules/.bin/rollup -c

其中 -c 表示让 rollup 使用我们刚才创建的 myProject/rollup.config.js 文件作为配置文件

构建生成的 myProject/lib/line.min.js 文件包括了工程代码和 echarts 代码,并且仅仅包括我们所需要的图和组件,并且可以直接在浏览器中使用

<div id="main" style="width: 600px;height:400px;"></div>
<script src="lib/line.min.js"></script>

在浏览器里打开会得到和上面代码相同的结果

多语言支持

上面例子中能看到,工具箱组件(toolbox)的提示文字是中文。本质上,echarts 图表显示出来的文字,都可以通过 option 来定制,改成任意语言。但是如果想“默认就是某种语言”,则需要通过构建来实现。上面的例子中,可以在 echarts/build/build.js 的参数中指定语言:

node node_modules/echarts/build/build.js --min -i echarts.custom.js -o lib/echarts.custom.min.js --lang en

表示使用内置的英文。此外还可以是 --lang fi

node node_modules/echarts/build/build.js --min -i echarts.custom.js -o lib/echarts.custom.min.js --lang my/langXX.js

表示在构建时使用 myProject/my/langXX.js 文件来替换 myProject/node_modules/echarts/lib/lang.js 文件。这样可以在 myProject/my/langXX.js 文件中自定义语言。注意这种方式中,必须指定 -o 或者 --output。另外,上面的 rollup 插件 echarts/build/rollup-plugin-ec-lang 也可以传入同样的参数,实现同样的功能

在 webpack 中使用 ECharts

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');
var myChart = echarts.init(document.getElementById('main')); // 基于准备好的dom,初始化echarts实例
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

var echarts = require('echarts/lib/echarts'); // 引入 ECharts 主模块
require('echarts/lib/chart/bar'); // 引入柱状图
require('echarts/lib/component/tooltip'); // 引入提示框和标题组件
require('echarts/lib/component/title');

个性化图表的样式

ECharts 提供了丰富的自定义配置选项,并且能够从全局、系列、数据三个层级去设置数据图形的样式。下面我们来看如何使用 ECharts 实现南丁格尔图:

绘制南丁格尔图

这次要画的是饼图,饼图主要是通过扇形的弧度表现不同类目的数据在总和中的占比,它的数据格式比柱状图更简单,只有一维的数值,不需要给类目。因为不在直角坐标系上,所以也不需要xAxis,yAxis

myChart.setOption({
    series : [
        {
            name: '访问来源',
            type: 'pie',
            radius: '55%',
            data:[ {value:235, name:'视频广告'}, {value:274, name:'联盟广告'}, {value:310, name:'邮件营销'}, {value:335, name:'直接访问'}, {value:400, name:'搜索引擎'} ]
        }
    ]
})

上面代码就能画出一个简单的饼图;这里data属性值包含 name 和 value 属性的对象,ECharts 中的数据项都是既可以只设成数值,也可以设成一个包含有名称、该数据图形的样式配置、标签配置的对象。ECharts 中的饼图也支持通过设置 roseType 显示成南丁格尔图

roseType: 'angle'

南丁格尔图会通过半径表示数据的大小

阴影的配置

ECharts 中有一些通用的样式,诸如阴影、透明度、颜色、边框颜色、边框宽度等,这些样式一般都会在系列的 itemStyle 里设置。例如阴影的样式可以通过下面几个配置项设置:

itemStyle: {    
    shadowBlur: 200, // 阴影的大小    
    shadowOffsetX: 0, // 阴影水平方向上的偏移    
    shadowOffsetY: 0, // 阴影垂直方向上的偏移    
    shadowColor: 'rgba(0, 0, 0, 0.5)' // 阴影颜色
}

深色背景和浅色标签

现在我们需要把整个主题改成开始的示例中那样的深色主题,这就需要改背景色和文本颜色。背景色是全局的,所以直接在 option 下设置 backgroundColor

setOption({
    backgroundColor: '#2c343c'
})

文本的样式可以设置全局的 textStyle

setOption({
    textStyle: { color: 'rgba(255, 255, 255, 0.3)' }
})

也可以每个系列分别设置,每个系列的文本设置在 label.textStyle

label: {
    textStyle: { color: 'rgba(255, 255, 255, 0.3)' }
}

饼图的话还要将标签的视觉引导线的颜色设为浅色

labelLine: {
    lineStyle: { color: 'rgba(255, 255, 255, 0.3)' }
}

跟itemStyle一样,label和labelLine的样式也有emphasis状态

设置扇形的颜色

扇形的颜色也是在 itemStyle 中设置:

itemStyle: {    
    color: '#c23531', // 设置扇形的颜色
    shadowBlur: 200,
    shadowColor: 'rgba(0, 0, 0, 0.5)'
}

跟我们要实现的效果已经挺像了,除了每个扇形的颜色,效果中阴影下面的扇形颜色更深,有种光线被遮住的感觉,从而会出现层次感和空间感。ECharts 中每个扇形的颜色可以通过分别设置 data 下的数据项实现

data: [{
    value:400,
    name:'搜索引擎',
    itemStyle: { color: '#c23531' }
}, ...]

如果只有明暗度的变化,有种更快捷的方式是通过 visualMap 组件将数值的大小映射到明暗度

visualMap: {    
    show: false, // 不显示 visualMap 组件,只用于明暗度的映射    
    min: 80, // 映射的最小值为 80    
    max: 600, // 映射的最大值为 600
    inRange: {        
        colorLightness: [0, 1] // 明暗度的范围是 0 到 1
    }
}

ECharts 中的样式简介

这里主要是大略概述,用哪些方法可以设置样式,改变图形元素或者文字的颜色、明暗、大小等;之所以用“样式”这种可能不很符合数据可视化思维的词,是因为,比较通俗易懂;这里介绍的几种方式,功能范畴可能会有交叉(即同一种细节的效果可能可以用不同的方式实现),但是他们各有各的场景偏好

1.颜色主题(Theme)

2.调色盘

3.直接样式设置(itemStyle、lineStyle、areaStyle、label、...)

4.视觉映射(visualMap)

颜色主题(Theme)

最简单的更改全局样式的方式,是直接采用颜色主题(theme)。例如,在 示例集合 中,可以选择 “Theme”,直接看到采用主题的效果。ECharts4 开始,除了一贯的默认主题外,新内置了两套主题,分别为 'light' 和 'dark'。可以这么来使用它们:

var chart = echarts.init(dom, 'light');
或
var chart = echarts.init(dom, 'dark');

其他的主题,没有内置在 ECharts 中,需要自己加载;这些主题可以在主题编辑器里访问到,也可以使用这个主题编辑器自己编辑主题;下载下来的主题可以这样使用;如果主题保存为JSON文件,那么可以自行加载和注册,例如:

// 假设主题名称是 "vintage"
$.getJSON('xxx/xxx/vintage.json', function (themeJSON) {
    echarts.registerTheme('vintage', JSON.parse(themeJSON))
    var chart = echarts.init(dom, 'vintage');
});

如果保存为 UMD 格式的 JS 文件,那么支持了自注册,直接引入 JS 文件即可:

// HTML 引入 vintage.js 文件后(假设主题名称是 "vintage")
var chart = echarts.init(dom, 'vintage');
// ...

调色盘

调色盘可以在option中设置,它给定了一组颜色,图形、系列会自动从其中选择颜色;可以设置全局的调色盘,也可以设置系列自己专属的调色盘

option = {    
    color: ['#c23531','#2f4554', '#61a0a8', '#d48265', '#91c7ae','#749f83',  '#ca8622', '#bda29a','#6e7074', '#546570', '#c4ccd3'], // 全局调色盘
    series: [{
        type: 'bar',        
        color: ['#dd6b66','#759aa0','#e69d87','#8dc1a9','#ea7e53','#eedd78','#73a373','#73b9bc','#7289ab', '#91ca8c','#f49f42'], // 此系列自己的调色盘
        ...
    }, {
        type: 'pie',        
        color: ['#37A2DA', '#32C5E9', '#67E0E3', '#9FE6B8', '#FFDB5C','#ff9f7f', '#fb7293', '#E062AE', '#E690D1', '#e7bcf3', '#9d96f5', '#8378EA', '#96BFFF'], // 此系列自己的调色盘
        ...
    }]
}

直接的样式设置 itemStyle, lineStyle, areaStyle, label, ...

直接的样式设置是比较常用设置方式;纵观ECharts的option中,很多地方可以设置itemStyle、lineStyle、areaStyle、label等。这些的地方可以直接设置图形元素的颜色、线宽、点的大小、标签的文字、标签的样式等。一般来说,ECharts 的各个系列和组件,都遵从这些命名习惯,虽然不同图表和组件中,itemStyle、label 等可能出现在不同的地方

高亮的样式:emphasis

在鼠标悬浮到图形元素上时,一般会出现高亮的样式;默认情况下,高亮的样式是根据普通样式自动生成的。但是高亮的样式也可以自己定义,主要是通过emphasis属性来定制。emphsis中的结构,和普通样式的结构相同,例如:

option = {
    series: {
        type: 'scatter', //分散点       
        itemStyle: { // 普通样式            
            color: 'red' // 点的颜色
        },
        label: {
            show: true,            
            formatter: 'This is a normal label.' // 标签的文字
        },
        emphasis: { // 高亮样式
            itemStyle: {                
                color: 'blue' // 高亮时点的颜色
            },
            label: {
                show: true,
                formatter: 'This is a emphasis label.' // 高亮时标签的文字
            }
        }
    }
}

注意:在 ECharts4 以前,高亮和普通样式的写法,是这样的

option = {
    series: {
        type: 'scatter',
        itemStyle: { // 普通样式
            normal: {
                color: 'red' // 点的颜色
            },
            emphasis: { // 高亮样式                
                color: 'blue' // 高亮时点的颜色
            }
        },
        label: {
            normal: { // 普通样式
                show: true,
                formatter: 'This is a normal label.' // 标签的文字
            },            
            emphasis: { // 高亮样式
                show: true,
                formatter: 'This is a emphasis label.' // 高亮时标签的文字
            }
        }
    }
}

这种写法仍然被兼容,但是不推荐。事实上,多数情况下,使用者只会配置普通状态下的样式,而使用默认的高亮样式。所以在ECharts4中,支持不写normal的配置方法(即本文开头的那种写法),使得配置项更扁平简单

通过 visualMap 组件设定样式

visualMap 组件 能指定数据到颜色、图形尺寸的映射规则

异步数据加载和更新

异步加载

之前章节数据是在初始化后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由数据驱动,数据的改变驱动图表展现的改变,因此动态数据的实现也变得异常简单。所有数据的更新都通过setOption实现,你只需要定时获取数据,setOption填入数据,而不用考虑数据到底产生了那些变化,ECharts会找到两组数据之间的差异然后通过合适的动画去表现数据的变化;ECharts 3中移除了ECharts 2中的addData方法。如果只需要加入单个数据,可以先data.push(value)后setOption

使用 dataset 管理数据

ECharts 4开始支持了dataset组件用于单独的数据集声明,从而数据可以单独管理,被多个组件复用,并且可以基于数据指定数据到视觉的映射。这在不少场景下能带来使用上的方便。ECharts 4 以前,数据只能声明在各个“系列(series)”中,例如:

option: {
    xAxis: { type: 'category', data: ['Matcha Latte', 'Milk Tea', 'Cheese Cocoa', 'Walnut Brownie'] },
    yAxis: {}
    series: [
        { type: 'bar', name: '2015', data: [89.3, 92.1, 94.4, 85.4] },
        { type: 'bar', name: '2016', data: [95.8, 89.4, 91.2, 76.9] },
        { type: 'bar', name: '2017', data: [97.7, 83.1, 92.5, 78.1] }
    ]
}

这种方式的优点是,直观易理解,以及适于对一些特殊图表类型进行一定的数据类型定制;但缺点是,为匹配这种数据输入形式,常需要有数据处理的过程,把数据分割设置到各个系列(和类目轴)中;此外,不利于多个系列共享一份数据,也不利于基于原始数据进行图表类型、系列的映射安排。于是,ECharts 4提供了数据集(dataset)组件来单独声明数据,它带来了这些效果:

1.能够贴近这样的数据可视化常见思维方式:基于数据(dataset组件来提供数据),指定数据到视觉的映射(由encode属性来指定映射),形成图表

2.数据和其他配置可以被分离开来,使用者相对便于进行单独管理,也省去了一些数据处理的步骤

3.数据可以被多个系列或者组件复用,对于大数据,不必为每个系列创建一份

4.支持更多的数据的常用格式,例如二维数组、对象数组等,一定程度上避免使用者为了数据格式而进行转换

数据到图形的映射

本篇里,我们制作数据可视化图表的逻辑是这样的:基于数据,在配置项中指定如何映射到图形。概略而言,可以进行这些映射:

1.指定 dataset 的列(column)还是行(row)映射为图形系列(series)。这件事可以使用 series.seriesLayoutBy 属性来配置。默认是按照列(column)来映射。

2.指定维度映射的规则:如何从 dataset 的维度(一个“维度”的意思是一行/列)映射到坐标轴(如 X、Y 轴)、提示框(tooltip)、标签(label)、图形元素大小颜色等(visualMap)。这件事可以使用 series.encode 属性,以及 visualMap 组件(如果有需要映射颜色大小等视觉维度的话)来配置。上面的例子中,没有给出这种映射配置,那么 ECharts 就按最常见的理解进行默认映射:X 坐标轴声明为类目轴,默认情况下会自动对应到 dataset.source 中的第一列;三个柱图系列,一一对应到 dataset.source 中后面每一列

按行还是按列做映射

有了数据表之后,使用者可以灵活得配置:数据如何对应到轴和图形系列。用户可以使用 seriesLayoutBy 配置项,改变图表对于行列的理解。seriesLayoutBy 可取值:

1.'column': 默认值。系列被安放到 dataset 的列上面。

2.'row': 系列被安放到 dataset 的行上面。

维度(dimension)

介绍 encode 之前,首先要介绍“维度(dimension)”的概念。

常用图表所描述的数据大部分是“二维表”结构,我们使用二维数组来容纳二维表。现在,当我们把系列(series)对应到“列”的时候,那么每一列就称为一个“维度(dimension)”,而每一行称为数据项(item)。反之,如果我们把系列(series)对应到表行,那么每一行就是“维度(dimension)”,每一列就是数据项(item)。维度可以有单独的名字,便于在图表中显示;维度名(dimension name)可以定义在 dataset 的第一行(或者第一列),从第二行开始才是正式的数据。dataset.source 中第一行(列)到底包含不包含维度名,ECharts默认会自动探测。当然也可以设置 dataset.sourceHeader: true 显示声明第一行(列)就是维度,或者 dataset.sourceHeader: false 表明第一行(列)开始就直接是数据。维度的定义,也可以使用单独的dataset.dimensions或者series.dimensions来定义,这样可以同时指定维度名,和维度的类型(dimension type):

var option = {
    dataset: {
        dimensions: [
            {name: 'score'},            
            'amount', // 可以简写为 string,表示维度名            
            {name: 'product', type: 'ordinal'} // 可以在 type 中指定维度类型
        ],
        source: [...]
    },
    series: {
        type: 'line',        
        dimensions: [ // 在系列中设置的 dimensions 会更优先采纳
            null, // 可以设置为 null 表示不想设置维度名
            'amount',
            {name: 'product', type: 'ordinal'}
        ]
    },
    ...
};

大多数情况下,我们并不需要去设置维度类型,因为会自动判断;但是如果因为数据为空之类原因导致判断不足够准确时,可以手动设置维度类型。维度类型(dimension type)可以取这些值:

'number': 默认,表示普通数据

'ordinal': 对于类目、文本这些string类型的数据,如果需要能在数轴上使用,须是 'ordinal' 类型。ECharts 默认会自动判断这个类型。但是自动判断也是不可能很完备的,所以使用者也可以手动强制指定

'time': 表示时间数据。设置成 'time' 则能支持自动解析数据成时间戳(timestamp),比如该维度的数据是 '2017-05-10',会自动被解析。如果这个维度被用在时间数轴(axis.type 为 'time')上,那么会被自动设置为 'time' 类型

'float': 如果设置成 'float',在存储时候会使用 TypedArray,对性能优化有好处

'int': 如果设置成 'int',在存储时候会使用 TypedArray,对性能优化有好处

数据到图形的映射(encode)

了解了维度的概念后,我们就可以使用 encode 来做映射

encode 声明的基本结构如下,其中冒号左边是坐标系、标签等特定名称,如 'x', 'y', 'tooltip' 等,冒号右边是数据中的维度名(string 格式)或者维度的序号(number 格式,从0开始计数),可以指定一个或多个维度(使用数组)。通常情况下,下面各种信息不需要所有的都写,按需写即可。下面是 encode 支持的属性:

// 在任何坐标系和系列中,都支持:
encode: {    
    tooltip: ['product', 'score'] // 使用 “名为 product 的维度” 和 “名为 score 的维度” 的值在 tooltip 中显示    
    seriesName: [1, 3], // 使用 “维度 1” 和 “维度 3” 的维度名连起来作为系列名。(有时候名字比较长,这可以避免在 series.name 重复输入这些名字)    
    itemId: 2, // 表示使用 “维度2” 中的值作为 id。这在使用 setOption 动态更新数据时有用处,可以使新老数据用 id 对应起来,从而能够产生合适的数据更新动画    
    itemName: 3 // 指定数据项的名称使用 “维度3” 在饼图等图表中有用,可以使这个名字显示在图例(legend)中
}
// 直角坐标系(grid/cartesian)特有的属性:
encode: {    
    x: [1, 5, 'score'], // 把 “维度1”、“维度5”、“名为 score 的维度” 映射到 X 轴    
    y: 0 // 把“维度0”映射到 Y 轴
}
// 极坐标系(polar)特有的属性:
encode: { radius: 3, angle: 2 }
// 地理坐标系(geo)特有的属性:
encode: { lng: 3, lat: 2 }
// 对于一些没有坐标系的图表,例如饼图、漏斗图等,可以是:
encode: { value: 3 }

在图表中加入交互组件

除了图表外 ECharts 中,提供了很多交互组件。例如:图例组件 legend、标题组件 title、视觉映射组件 visualMap、数据区域缩放组件 dataZoom、时间线组件 timeline;下面以 数据区域缩放组件 dataZoom 为例,介绍如何加入这种组件

数据区域缩放组件(dataZoom)介绍

『概览数据整体,按需关注数据细节』是数据可视化的基本交互需求;dataZoom 组件能够在直角坐标系(grid)、极坐标系(polar)中实现这一功能:

1.dataZoom组件是对数轴(axis)进行『数据窗口缩放』『数据窗口平移』操作;可以通过 dataZoom.xAxisIndex 或 dataZoom.yAxisIndex 来指定 dataZoom 控制哪个或哪些数轴

2.dataZoom 组件可同时存在多个,起到共同控制的作用。控制同一个数轴的组件,会自动联动

3.dataZoom 的运行原理是通过『数据过滤』来达到『数据窗口缩放』的效果;数据过滤模式的设置不同,效果也不同

4.dataZoom 的数据窗口范围的设置,目前支持两种形式:百分比形式/绝对数值形式

dataZoom 组件现在支持几种子组件:

1.内置型数据区域缩放组件(dataZoomInside):内置于坐标系中

2.滑动条型数据区域缩放组件(dataZoomSlider):有单独的滑动条操作

3.框选型数据区域缩放组件(dataZoomSelect):全屏的选框进行数据区域缩放。入口和配置项均在 toolbox中

移动端自适应

ECharts工作在用户指定高宽的DOM节点(容器)中,ECharts的『组件』和『系列』都在这个DOM节点中,每个节点都可以由用户指定位置。图表库内部并不适宜实现DOM文档流布局,因此采用类似绝对布局的简单容易理解的布局方式;但是容器尺寸极端时,这种方式并不能自动避免组件重叠的情况,尤其在移动端小屏的情况下。另外,有时会出现一个图表需要同时在PC、移动端上展现的场景。这需要 ECharts 内部组件随着容器尺寸变化而变化的能力。为了解决这个问题,ECharts 完善了组件的定位设置,并且实现了类似 CSS Media Query 的自适应能力

ECharts组件的定位和布局

大部分『组件』和『系列』会遵循两种定位方式:

left/right/top/bottom/width/height 定位方式

这六个量中,每个量都可以是『绝对值』或者『百分比』或者『位置描述』

1.绝对值:单位是浏览器像素(px),用number形式书写(不写单位);例如 {left: 23, height: 400}

2.百分比:表示占DOM容器高宽的百分之多少,用string形式书写。例如 {right: '30%', bottom: '40%'}

3.位置描述:可以设置 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的每种图表本身就内置了这种映射过程,比如折线图把数据映射到『线』,柱状图把数据映射到『长度』。一些更复杂的图表,如 graph、事件河流图、treemap 也都会做出他们内置的映射;此外,ECharts还提供了visualMap组件 来提供通用的视觉映射。visualMap组件中可以使用的视觉元素有:

图形类别(symbol)、图形大小(symbolSize)

颜色(color)、透明度(opacity)、颜色透明度(colorAlpha)、

颜色明暗度(colorLightness)、颜色饱和度(colorSaturation)、色调(colorHue)

下面对 visualMap 组件的使用方式进行简要的介绍

数据和维度

ECharts中的数据,一般存放于 series.data 中。根据图表类型不同,数据的具体形式也可能有些许差异。比如可能是『线性表』、『树』、『图』等。但他们都有个共性:都是『数据项(dataItem)』的集合。每个数据项含有『数据值(value)』和其他信息(如果需要的话)。每个数据值,可以是单一的数值(一维)或者一个数组(多维)

例如,series.data 最常见的形式,是『线性表』,即一个普通数组:

series: {
    data: [
        {       // 这里每一个项就是数据项(dataItem)
            value: 2323, // 这是数据项的数据值(value)
            itemStyle: {...}
        },
        1212,   // 也可以直接是 dataItem 的 value,这更常见
        2323,   // 每个 value 都是『一维』的
        4343,
        3434
    ]
}
series: {
    data: [
        {                        // 这里每一个项就是数据项(dataItem)
            value: [3434, 129,  '圣马力诺'], // 这是数据项的数据值(value)
            itemStyle: {...}
        },
        [1212, 5454, '梵蒂冈'],   // 也可以直接是 dataItem 的 value,这更常见
        [2323, 3223, '瑙鲁'],     // 每个 value 都是『三维』的,每列是一个维度
        [4343, 23,   '图瓦卢']    // 假如是『气泡图』,常见第一维度映射到x轴,第二维度映射到y轴,第三维度映射到气泡半径(symbolSize)
    ]
}

在图表中,往往默认把 value 的前一两个维度进行映射,比如取第一个维度映射到x轴,取第二个维度映射到y轴。如果想要把更多的维度展现出来,可以借助 visualMap 。最常见的情况,气泡图(scatter) 使用半径展现了第三个维度

visualMap 组件

visualMap 组件定义了把数据的『哪个维度』映射到『什么视觉元素上』,现在提供如下两种类型的visualMap组件,通过 visualMap.type 来区分;其定义结构例如:

option = {
    visualMap: [ // 可以同时定义多个 visualMap 组件。
        { // 第一个 visualMap 组件
            type: 'continuous', // 定义为连续型 viusalMap
            ...
        },
        { // 第二个 visualMap 组件
            type: 'piecewise', // 定义为分段型 visualMap
            ...
        }
    ],
    ...
};

分段型视觉映射组件(visualMapPiecewise),有三种模式:

1.连续型数据平均分段: 依据 visualMap-piecewise.splitNumber 来自动平均分割成若干块

2.连续型数据自定义分段: 依据 visualMap-piecewise.pieces 来定义每块范围

3.离散数据(类别性数据): 类别定义在 visualMap-piecewise.categories 中

视觉映射方式的配置

既然是『数据』到『视觉元素』的映射,visualMap 中可以指定数据的『哪个维度』映射到哪些『视觉元素』

例一:

option = {
    visualMap: [
        {
            type: 'piecewise'
            min: 0,
            max: 5000,
            dimension: 3,       // series.data 的第四个维度(即 value[3])被映射
            seriesIndex: 4,     // 对第四个系列进行映射。
            inRange: {          // 选中范围中的视觉配置
                color: ['blue', '#121122', 'red'], // 定义了图形颜色映射的颜色列表,数据最小值映射到'blue'上,最大值映射到'red'上,其余自动线性计算
                symbolSize: [30, 100]               // 定义了图形尺寸的映射范围,数据最小值映射到30上,最大值映射到100上,其余自动线性计算
            },
            outOfRange: {       // 选中范围外的视觉配置
                symbolSize: [30, 100]
            }
        },
        ...
    ]
};

例二:

option = {
    visualMap: [
        {
            ...,
            inRange: {          // 选中范围中的视觉配置
                colorLightness: [0.2, 1], // 映射到明暗度上。也就是对本来的颜色进行明暗度处理。本来的颜色可能是从全局色板中选取的颜色,visualMap组件并不关心
                symbolSize: [30, 100]
            },
            ...
        },
        ...
    ]
};

ECharts 中的事件和行为

在 ECharts 的图表中用户的操作将会触发相应的事件;开发者可以监听这些事件,然后通过回调函数做相应的处理,比如跳转到一个地址,或者弹出对话框,或者做数据下钻等等。在 ECharts 3 中绑定事件跟 2 一样都是通过 on 方法,但是事件名称比 2 更加简单了。ECharts 3 中,事件名称对应 DOM 事件名称,均为小写的字符串,如下是一个绑定点击操作的示例

myChart.on('click', function (params) {    
    console.log(params.name); // 控制台打印数据的名称
});

在 ECharts 中事件分为两种类型,一种是用户鼠标操作点击,或者 hover 图表的图形时触发的事件,还有一种是用户在使用可以交互的组件后触发的行为事件,例如在切换图例开关时触发的 'legendselectchanged' 事件(这里需要注意切换图例开关是不会触发'legendselected'事件的),数据区域缩放时触发的 'datazoom' 事件等等

鼠标事件的处理

ECharts支持常规的鼠标事件类型,包括'click'、'dblclick'、'mousedown'、'mousemove'、'mouseup'、'mouseover'、'mouseout'、'globalout'、'contextmenu' 事件;所有的鼠标事件包含参数 params,这是一个包含点击图形的数据信息的对象,如下格式:

{    
    componentType: string, // 当前点击的图形元素所属的组件名称, 其值如 'series'、'markLine'、'markPoint'、'timeLine' 等    
    seriesType: string, // 系列类型。值可能为:'line'、'bar'、'pie' 等。当 componentType 为 'series' 时有意义
    seriesIndex: number, // 系列在传入的 option.series 中的 index。当 componentType 为 'series' 时有意义   
    seriesName: string, // 系列名称。当 componentType 为 'series' 时有意义   
    name: string,  // 数据名,类目名
    dataIndex: number, // 数据在传入的 data 数组中的 index   
    data: Object, // 传入的原始数据项
    dataType: string, // sankey、graph 等图表同时含有 nodeData 和 edgeData 两种 data, dataType 的值会是 'node' 或者 'edge',表示当前点击在 node 还是 edge 上;其他大部分图表中只有一种 data,dataType 无意义    
    value: number|Array // 传入的数据值
    color: string // 数据图形的颜色。当 componentType 为 'series' 时有意义
}

如何区分鼠标点击到了哪里:

myChart.on('click', function (params) {
    if (params.componentType === 'markPoint') { // 点击到了 markPoint 上        
        if (params.seriesIndex === 5) {}  // 点击到了 index 为 5 的 series 的 markPoint 上
    }else if (params.componentType === 'series') {
        if (params.seriesType === 'graph') {
            if (params.dataType === 'edge') {} // 点击到了 graph 的 edge(边)上            
            else {} // 点击到了 graph 的 node(节点)上  
        }
    }
});

使用 query 只对指定的组件的图形元素的触发回调:

chart.on(eventName, query, handler);

query 可为 string 或者 Object。如果为 string 表示组件类型。格式可以是 'mainType' 或者 'mainType.subType'。例如:

chart.on('click', 'series', function () {...});
chart.on('click', 'series.line', function () {...});
chart.on('click', 'dataZoom', function () {...});
chart.on('click', 'xAxis.category', function () {...});

如果为 Object,可以包含以下一个或多个属性,每个属性都是可选的:

{
    <mainType>Index: number // 组件 index
    <mainType>Name: string // 组件 name
    <mainType>Id: string // 组件 id
    dataIndex: number // 数据项 index
    name: string // 数据项 name
    dataType: string // 数据项 type,如关系图中的 'node', 'edge'
    element: string // 自定义系列中的 el 的 name
}

可以在回调函数中获得这个对象中的数据名、系列名称后在自己的数据仓库中索引得到其它的信息候更新图表,显示浮层等

myChart.on('click', function (parmas) {
    $.get('detail?q=' + params.name, function (detail) {
        myChart.setOption({
            series: [{
                name: 'pie',                
                data: [detail.data] // 通过饼图表现单个柱子中的数据分布
            }]
        });
    });
});

组件交互的行为事件

在 ECharts 中基本上所有的组件交互行为都会触发相应的事件,常用的事件和事件对应参数在 events 文档中有列出。下面是监听一个图例开关的示例:

myChart.on('legendselectchanged', function (params) { // 图例开关的行为只会触发 legendselectchanged 事件    
    var isSelected = params.selected[params.name]; // 获取点击图例的选中状态    
    console.log((isSelected ? '选中了' : '取消选中了') + '图例' + params.name); // 在控制台中打印    
    console.log(params.selected); // 打印所有图例的状态
});

代码触发 ECharts 中组件的行为

上面提到诸如'legendselectchanged'事件会由组件交互的行为触发,那除了用户的交互操作,有时候也会有需要在程序里调用方法触发图表的行为,诸如显示 tooltip,选中图例。在 ECharts 2.x 是通过 myChart.component.tooltip.showTip 这种形式调用相应的接口触发图表行为,入口很深,而且涉及到内部组件的组织。相对地,在 ECharts 3 里改为通过调用 myChart.dispatchAction({ type: '' }) 触发图表行为,统一管理了所有动作,也可以方便地根据需要去记录用户的行为路径。

旭日图

旭日图(Sunburst)由多层的环形图组成,在数据结构上,内圈是外圈的父节点。因此,它既能像饼图一样表现局部和整体的占比,又能像矩形树图一样表现层级关系

创建旭日图需要在 series 配置项中声明类型为 'sunburst' 的系列,并且以树形结构声明其 data

颜色等样式调整

默认情况下会使用全局调色盘 color 分配最内层的颜色,其余层则与其父元素同色。在旭日图中,扇形块的颜色有以下三种设置方式:

在 series.data.itemStyle 中设置每个扇形块的样式/在 series.levels.itemStyle 中设置每一层的样式/在 series.itemStyle 中设置整个旭日图的样式。

上述三者的优先级是从高到低的,也就是说,配置了 series.data.itemStyle 的扇形块将会覆盖 series.levels.itemStyle 和 series.itemStyle 的设置

按层配置样式

旭日图是一种有层次的结构,为了方便同一层样式的配置,我们提供了 levels 配置项。它是一个数组,其中的第 0 项表示数据下钻后返回上级的图形,其后的每一项分别表示从圆心向外层的层级

数据下钻

旭日图默认支持数据下钻,也就是说,当点击了扇形块之后,将以该扇形块的数据作为根节点,便于进一步了解该数据的细节;当数据下钻后,中间会出现一个用于返回上一层的图形,该图形的样式可以通过 levels[0] 配置;如果不需要数据下钻功能,可以通过将 nodeClick 设置为 false 关闭;或者将其设为 'link',并将 data.link 设为点击扇形块对应打开的链接

高亮相关扇形块

旭日图支持鼠标移动到某扇形块时,高亮相关数据块的操作,可以通过设置 highlightPolicy,包括以下几种高亮方式:

'descendant'(默认值):高亮鼠标移动所在扇形块与其后代元素

'ancestor':高亮鼠标所在扇形块与其祖先元素

'self':仅高亮鼠标所在扇形块

'none':不会淡化(downplay)其他元素

上面提到的“高亮”,对于鼠标所在的扇形块,会使用 emphasis 样式;对于其他相关扇形块,则会使用 highlight 样式。通过这种方式,可以很方便地实现突出显示相关数据的需求

自定义系列

自定义系列(custom series),是一种系列的类型。它把绘制图形元素这一步留给开发者去做,从而开发者能在坐标系中*绘制出自己需要的图表。echarts 为什么会要支持 自定义系列 呢?echarts 内置支持的图表类型是最常见的图表类型,但是图表类型是难于穷举的,有很多小众的需求 echarts 并不能内置的支持。那么就需要提供一种方式来让开发者自己扩展。另一方面,所提供的扩展方式要尽可能得简单,例如图形元素创建和释放、过渡动画、tooltip、数据区域缩放(dataZoom)、视觉映射(visualMap)等功能,尽量在 echarts 中内置得处理,使开发者不必纠结于这些细节。综上考虑形成了 自定义系列(custom series)

renderItem 方法

开发者自定义的图形元素渲染逻辑,是通过书写 renderItem 函数实现的

myChart.on('legendselectchanged', function (params) { // 图例开关的行为只会触发 legendselectchanged 事件    
    var isSelected = params.selected[params.name]; // 获取点击图例的选中状态    
    console.log((isSelected ? '选中了' : '取消选中了') + '图例' + params.name); // 在控制台中打印    
    console.log(params.selected); // 打印所有图例的状态
});

在渲染阶段,对于 series.data 中的每个数据项(为方便描述,这里称为 dataItem),会调用此 renderItem 函数。这个 renderItem 函数的职责,就是返回一个(或者一组)图形元素定义,图形元素定义中包括图形元素的类型、位置、尺寸、样式等。echarts 会根据这些 图形元素定义 来渲染出图形元素

var option = {
    ...,
    series: [{
        type: 'custom',
        renderItem: function (params, api) { // 对于data中的每个dataItem,都会调用这个renderItem函数(但是注意,并不一定是按照 data 的顺序调用);这里进行一些处理,例如,坐标转换;这里使用 api.value(0) 取出当前 dataItem 中第一个维度的数值            
            var categoryIndex = api.value(0);            
            var startPoint = api.coord([api.value(1), categoryIndex]); // 这里使用 api.coord(...) 将数值在当前坐标系中转换成为屏幕上的点的像素值
            var endPoint = api.coord([api.value(2), categoryIndex]);            
            var height = api.size([0, 1])[1] * 0.6; // 这里使用 api.size(...) 获得 Y 轴上数值范围为 1 的一段所对应的像素长度            
            var rectShape = echarts.graphic.clipRectByRect({ // shape 属性描述了这个矩形的像素位置和大小;其中特殊得用到了 echarts.graphic.clipRectByRect,意思是如果矩形超出了当前坐标系的包围盒,则剪裁这个矩形;如果矩形完全被剪掉,会返回 undefined
                // 矩形的位置和大小
                x: startPoint[0],
                y: startPoint[1] - height / 2,
                width: endPoint[0] - startPoint[0],
                height: height
            }, {
                // 当前坐标系的包围盒
                x: params.coordSys.x,
                y: params.coordSys.y,
                width: params.coordSys.width,
                height: params.coordSys.height
            });            
            return rectShape && { // 这里返回为这个 dataItem 构建的图形元素定义
                // 表示这个图形元素是矩形。还可以是 'circle', 'sector', 'polygon' 等等
                type: 'rect',
                shape: rectShape,                
                style: api.style() // 用 api.style(...) 得到默认的样式设置。这个样式设置包含了option 中 itemStyle 的配置和视觉映射得到的颜色
            };
        },
        data: [
            [12, 44, 55, 60], // 这是第一个 dataItem
            [53, 31, 21, 56], // 这是第二个 dataItem
            [71, 33, 10, 20], // 这是第三个 dataItem
            ...
        ]
    }]
}

renderItem 函数提供了两个参数:

1.params:包含了当前数据信息(如 seriesIndex、dataIndex 等等)和坐标系的信息(如坐标系包围盒的位置和尺寸)

2.api:是一些开发者可调用的方法集合(如 api.value()、api.coord())

renderItem 函数须返回根据此 dataItem 绘制出的图形元素的定义信息;一般来说,renderItem 函数的主要逻辑,是将 dataItem 里的值映射到坐标系上的图形元素。这一般需要用到 renderItem.arguments.api 中的两个函数:

1.api.value(...),意思是取出 dataItem 中的数值。例如 api.value(0) 表示取出当前 dataItem 中第一个维度的数值

2.api.coord(...),意思是进行坐标转换计算。例如 var point = api.coord([api.value(0), api.value(1)]) 表示 dataItem 中的数值转换成坐标系上的点

有时候还需要用到 api.size(...) 函数,表示得到坐标系上一段数值范围对应的长度;返回值中样式的设置可以使用 api.style(...) 函数,他能得到 series.itemStyle 中定义的样式信息,以及视觉映射的样式信息。也可以用这种方式覆盖这些样式信息:api.style({fill: 'green', stroke: 'yellow'});书写完 renderItem 方法后,自定义系列的 90% 工作就做完了。剩下的是一些精化工作

使坐标轴的范围自适应数据范围

在 直角坐标系(grid)、极坐标系(polar) 中都有坐标轴;坐标轴的刻度范围需要自适应当前显示出的数据的范围,否则绘制出的图形会超出去。所以,例如在直角坐标系(grid)中使用自定义系列的开发者,需要设定data中的哪些维度会对应到x轴上,哪些维度会对应到y轴上。这件事通过encode来设定

option = {
    series: [{
        type: 'custom',
        renderItem: function () { ... },
        encode: {            
            x: [1, 2], // data 中『维度1』和『维度2』对应到 X 轴            
            y: 0 // data 中『维度0』对应到 Y 轴
        },
        data: [ // 维度0  维度1  维度2  维度3            
            [   12,   44,   55,   60   ], // 这是第一个 dataItem
            [   53,   31,   21,   56   ], // 这是第二个 dataItem
            [   71,   33,   10,   20   ], // 这是第三个 dataItem
            ...
        ]
    }]
};

设定 tooltip

当然,使用 tooltip.formatter 可以任意定制 tooltip 中的内容。但是还有更简单的方法,通过encode 和 dimensions 来设定:

option = {
    series: [{
        encode: {                        
            tooltip: [2, 3] // 表示『维度2』和『维度3』要显示到 tooltip 中 (其他同上)
        },
    }]
};

超出坐标系范围的截取

与 dataZoom 结合使用的时候,常常使用会设置 dataZoom.filterMode 为 'weakFilter'。这个设置的意思是:当 dataItem 部分超出坐标系边界的时候,dataItem 不会整体被过滤掉。例如:

option = {
    dataZoom: {
        xAxisIndex: 0,
        filterMode: 'weakFilter'
    },
    series: [{ ... }] //(此处内容同上)
};

在这个例子中,『维度1』和『维度2』对应到 X 轴,dataZoom 组件控制 X 轴的缩放。假如在缩放的过程中,某个 dataItem 的『维度1』超出了 X 轴的范围,『维度2』还在 X 轴的范围中,那么只要设置 dataZoom.filterMode = 'weakFilter',这个 dataItem 就不会被过滤掉,从而还能够使用 renderItem 绘制图形(可以使用上面提到过的 echarts.graphic.clipRectByRect 把图形绘制成被坐标系剪裁过的样子)

关于 dataIndex

开发者如果使用到的话应注意,renderItem.arguments.params 中的 dataIndex 和 dataIndexInside 是有区别的:

1.dataIndex 指的 dataItem 在原始数据中的 index

2.dataIndexInside 指的是 dataItem 在当前数据窗口中的index。

renderItem.arguments.api 中使用的参数都是 dataIndexInside 而非 dataIndex,因为从 dataIndex 转换成 dataIndexInside 需要时间开销

事件监听

chart.setOption({
    // ...
    series: {
        type: 'custom',
        renderItem: function () {
            // ...
            return {
                type: 'group',
                children: [{
                    type: 'circle'
                    // ...
                }, {
                    type: 'circle',
                    name: 'aaa',                    
                    info: 12345, // 用户指定的信息,可以在 event handler 访问到
                    // ...
                }]
            };
        }
    }
});
chart.on('click', {element: 'aaa'}, function (params) { // 当 name 为 'aaa' 的图形元素被点击时,此回调被触发    
    console.log(params.info);
});

自定义矢量图形

自定义系列能支持使用 SVG PathData 定义矢量路径。从而可以使用矢量图工具中做出的图形

富文本标签

原先echarts中的文本标签,只能对整块统一进行样式设置,并且仅仅支持颜色和字体的设置,从而导致不易于制作表达能力更强的文字描述信息;echarts v3.7以后,支持了富文本标签,能够:

1.定制文本块整体的样式(如背景、边框、阴影等)、位置、旋转等

2.对文本块中个别片段定义样式(如颜色、字体、高宽、背景、阴影等)、对齐方式等

3.在文本中使用图片做小图标或者背景

4.特定组合以上的规则,可以做出简单表格、分割线等效果

开始下面的介绍之前,先说明下面会使用的两个名词的含义:

1.文本块(Text Block):文本标签块整体

2.文本片段(Text Fregment):文本标签块中的部分文本

文本样式相关的配置项

echarts 提供了丰富的文本标签配置项,包括:

1.字体基本样式设置:fontStyle、fontWeight、fontSize、fontFamily

2.文字颜色:color

3.文字描边:textBorderColor、textBorderWidth

4.文字阴影:textShadowColor、textShadowBlur、textShadowOffsetX、textShadowOffsetY

5.文本块或文本片段大小:lineHeight、width、height、padding

6.文本块或文本片段的对齐:align、verticalAlign

7.文本块或文本片段的边框、背景(颜色或图片):backgroundColor、borderColor、borderWidth、borderRadius

8.文本块或文本片段的阴影:shadowColor、shadowBlur、shadowOffsetX、shadowOffsetY

9.文本块的位置和旋转:position、distance、rotate

可以在各处的 rich 属性中定义文本片段样式。例如 series-bar.label.rich

label: {
    // 在文本中,可以对部分文本采用 rich 中定义样式;这里需要在文本中使用标记符号: `{styleName|text content text content}` 标记样式名;注意,换行仍是使用 '\n'。
    formatter: [
        '{a|这段文本采用样式a}',
        '{b|这段文本采用样式b}这段用默认样式{x|这段用样式x}'
    ].join('\n'),
    // 这里是文本块的样式设置:
    color: '#333', fontSize: 5, fontFamily: 'Arial', borderWidth: 3, backgroundColor: '#984455', padding: [3, 10, 10, 5], lineHeight: 20,    
    rich: { // rich 里是文本片段的样式设置
        a: { color: 'red', lineHeight: 10 },
        b: { backgroundColor: { image: 'xxx/xxx.jpg' }, height: 40 },
        x: { fontSize: 18, fontFamily: 'Microsoft YaHei', borderColor: '#449933', borderRadius: 4 },
        ...
    }
}

注意:如果不定义 rich,不能指定文字块的 width 和 height

文本、文本框、文本片段的基本样式和装饰

每个文本可以设置基本的字体样式:fontStyle、fontWeight、fontSize、fontFamily

可以设置文字的颜色 color 和边框的颜色 textBorderColor、textBorderWidth

文本框可以设置边框和背景的样式:borderColor、borderWidth、backgroundColor、padding

文本片段也可以设置边框和背景的样式:borderColor、borderWidth、backgroundColor、padding

标签的位置

对于折线图、柱状图、散点图等,均可以使用 label 来设置标签。标签的相对于图形元素的位置,一般使用 label.position、label.distance 来配置

注意:position 在不同的图中可取值有所不同。distance 并不是在每个图中都支持

标签的旋转

某些图中,为了能有足够长的空间来显示标签,需要对标签进行旋转;这种场景下,可以结合 align 和 verticalAlign 来调整标签位置

注意,逻辑是,先使用 align 和 verticalAlign 定位,再旋转

文本片段的排版和对齐

关于排版方式,每个文本片段,可以想象成 CSS 中的 inline-block,在文档流中按行放置;每个文本片段的内容盒尺寸(content box size),默认是根据文字大小决定的;但也可以设置 width、height 来强制指定。文本片段的边框盒尺寸(border box size),由上述本身尺寸,加上文本片段的padding来得到;只有 'n' 是换行符,能导致换行。一行内,会有多个文本片段,每行的实际高度由lineHeight最大的文本片段决定,文本片段的lineHeight可直接在rich中指定,也可以在rich的父层级中统一指定而采用到rich的所有项中,如果都不指定,则取文本片段的边框盒尺寸(border box size);在一行的 lineHeight 被决定后,一行内,文本片段的竖直位置,由文本片段的verticalAlign来指定(这里和 CSS 中的规则稍有不同):

'bottom':文本片段的盒的底边贴住行底/'top':文本片段的盒的顶边贴住行顶/'middle':居行中

文本块的宽度,可以直接由文本块的width指定,否则由最长的行决定;宽度决定后,在一行中进行文本片段的放置;文本片段的align决定了文本片段在行中的水平位置:

首先,从左向右连续紧靠放置 align 为 'left' 的文本片段盒

然后,从右向左连续紧靠放置 align 为 'right' 的文本片段盒

最后,剩余的没处理的文本片段盒,紧贴着,在中间剩余的区域中居中放置

关于文字在文本片段盒中的位置:

如果 align 为 'center',则文字在文本片段盒中是居中的

如果 align 为 'left',则文字在文本片段盒中是居左的

如果 align 为 'right',则文字在文本片段盒中是居右的

特殊效果:图标、分割线、标题块、简单表格

文本片段的 backgroundColor 可以指定为图片后,就可以在文本中使用图标了:

rich: {
    Sunny: {        
        backgroundColor: { // 这样设定 backgroundColor 就可以是图片了
            image: './data/asset/img/weather/sunny_128.png'
        },        
        height: 30 // 可以只指定图片的高度,从而图片的宽度根据图片的长宽比自动得到
    }
}

分割线实际是用 border 实现的:

rich: {
    hr: {
        borderColor: '#777',
        width: '100%', // 这里把width设置为'100%',表示分割线的长度充满文本块;注意,这里是文本块内容盒(content box)的100%,而不包含padding;虽然这和 CSS 相关的定义有所不同,但是在这类场景中更加方便
        borderWidth: 0.5,
        height: 0
    }
}

标题块是使用 backgroundColor 实现的

// 标题文字居左
formatter: '{titleBg|Left Title}',
rich: {
    titleBg: { backgroundColor: '#000', height: 30, borderRadius: [5, 5, 0, 0], padding: [0, 10, 0, 10], width: '100%', color: '#eee' }
}
// 标题文字居中; 这个实现有些 tricky,但是能够不引入更复杂的排版规则而实现这个效果
formatter: '{tc|Center Title}{titleBg|}',
rich: {
    titleBg: { align: 'right', backgroundColor: '#000', height: 30, borderRadius: [5, 5, 0, 0], padding: [0, 10, 0, 10], width: '100%', color: '#eee'
    }
}

简单表格的设定,其实就是给不同行上纵向对应的文本片段设定同样的宽度就可以了

服务端渲染

ECharts 可以在服务端进行渲染;服务端渲染可以使用流行的 headless 环境,例如 puppeteer、headless chrome、node-canvas、jsdom、PhantomJS 等

使用 Canvas 或者 SVG 渲染

浏览器端图表库大多会选择SVG或者Canvas进行渲染;对于绘制图表来说,这两种技术往往是可替换的,效果相近;但是在一些场景中,他们的表现和能力又有一定差异。于是,对它们的选择取舍,就成为了一个一直存在的不易有标准答案的话题。ECharts 从初始一直使用 Canvas 绘制图表(除了对 IE8- 使用 VML)。而 ECharts v4.0 发布了 SVG 渲染器,从而提供了一种新的选择。只须在初始化一个图表实例时,设置 renderer 参数 为 'canvas' 或 'svg' 即可指定渲染器,比较方便

SVG 和 Canvas 这两种使用方式差异很大的技术,能够做到同时被透明支持,主要归功于 ECharts 底层库 ZRender 的抽象和实现,形成可互换的 SVG 渲染器和 Canvas 渲染器

选择哪种渲染器

一般来说,Canvas 更适合绘制图形元素数量非常大(这一般是由数据量大导致)的图表(如热力图、地理坐标系或平行坐标系上的大规模线图或散点图等),也利于实现某些视觉 特效;但是,在不少场景中,SVG 具有重要的优势:它的内存占用更低(这对移动端尤其重要)、渲染性能略高、并且用户使用浏览器内置的缩放功能时不会模糊;例如,我们在一些硬件环境中分别使用 Canvas 渲染器和 SVG 渲染器绘制中等数据量的折、柱、饼,统计初始动画阶段的帧率,得到性能对比结果:SVG 渲染器相比 Canvas 渲染器在移动端的总体表现更好。当然,这个实验并非是全面的评测,在另一些数据量较大或者有图表交互动画的场景中,目前SVG渲染器的性能还比不过Canvas渲染器。但是同时有这两个选项,为开发者们根据自己的情况优化性能提供了更广阔的空间

选择哪种渲染器,我们可以根据软硬件环境、数据量、功能需求综合考虑。

1.在软硬件环境较好,数据量不大的场景下(例如 PC 端做商务报表),两种渲染器都可以适用,并不需要太多纠结

2.在环境较差,出现性能问题需要优化的场景下,可以通过试验来确定使用哪种渲染器。比如有这些经验:

(1)在须要创建很多 ECharts 实例且浏览器易崩溃的情况下(可能是因为 Canvas 数量多导致内存占用超出手机承受能力),可以使用 SVG 渲染器来进行改善。大略得说,如果图表运行在低端安卓机,或者我们在使用一些特定图表如 水球图 等,SVG 渲染器可能效果更好。

(2)数据量很大、较多交互时,可以选用 Canvas 渲染器

注:除了某些特殊的渲染可能依赖 Canvas:如炫光尾迹特效、带有混合效果的热力图等,绝大部分功能 SVG 都是支持的。此外,目前的 SVG 版中,富文本、材质功能尚未实现

如何使用渲染器

ECharts 默认使用 Canvas 渲染;如果想使用 SVG 渲染,ECharts 代码中须包括有 SVG 渲染器模块

1.ECharts 的 预构建文件 中,常用版 和 完整版 已经包含了 SVG 渲染器,可直接使用。而 精简版 没有包括

2.如果 在线自定义构建 ECharts,则需要勾上页面下方的 “SVG 渲染”

3.如果 线下自定义构建 ECharts,则须引入 SVG 渲染器模块,即:

import 'zrender/lib/svg/svg';

然后,我们就可以在代码中,初始化图表实例时,传入参数 选择渲染器类型:

// 使用 Canvas 渲染器(默认)
var chart = echarts.init(containerDom, null, {renderer: 'canvas'});
// 等价于:
var chart = echarts.init(containerDom);
// 使用 SVG 渲染器
var chart = echarts.init(containerDom, null, {renderer: 'svg'});

在图表中支持无障碍访问

W3C制定了无障碍富互联网应用规范集(WAI-ARIA,the Accessible Rich Internet Applications Suite),致力于使得网页内容和网页应用能够被更多残障人士访问。ECharts 4.0遵从这一规范,支持自动根据图表配置项智能生成描述,使得盲人可以在朗读设备的帮助下了解图表内容,让图表可以被更多人群访问。默认关闭,需要通过将 aria.show设置为true开启。开启后,会根据图表、数据、标题等情况,自动智能生成关于图表的描述,用户也可以通过配置项修改描述

对于配置项:

option = {
    aria: { show: true },
    title: { text: '某站点用户访问来源', x: 'center' },
    series: [{
        name: '访问来源',
        type: 'pie',
        data: [ { value: 335, name: '直接访问' }, { value: 310, name: '邮件营销' }, { value: 234, name: '联盟广告' }, { value: 135, name: '视频广告' }, { value: 1548, name: '搜索引擎' } ]
    }]
};

生成的图表 DOM 上,会有一个 aria-label 属性,在朗读设备的帮助下,盲人能够了解图表的内容

整体修改描述

对于有些图表,默认生成的数据点的描述并不足以表现整体的信息;比如散点图,默认生成的描述可以包含数据点的坐标值,但是知道几百几千个点的坐标并不能帮助我们有效地理解图表表达的信息;这时候,用户可以通过 aria.description 配置项指定图表的整体描述

定制模板描述

除了整体性修改描述外,我们还提供了生成描述的模板,可以方便地进行细粒度的修改;生成描述的基本流程为,如果 aria.show 设置为 true,则生成无障碍访问描述,否则不生成。如果定义了 aria.description,则将其作为图表的完整描述,否则根据模板拼接生成描述。我们提供了默认的生成描述的算法,仅当生成的描述不太合适时,才需要修改这些模板,甚至使用 aria.description 完全覆盖。

使用模板拼接时,先根据是否存在标题 title.text 决定使用 aria.general.withTitle 还是 aria.general.withoutTitle 作为整体性描述。其中,aria.general.withTitle 配置项包括模板变量 '{title}',将会被替换成图表标题。也就是说,如果 aria.general.withTitle 被设置为 '图表的标题是:{title}。',则如果包含标题 '价格分布图',这部分的描述为 '图表的标题是:价格分布图。'。

拼接完标题之后,会依次拼接系列的描述(aria.series),和每个系列的数据的描述(aria.data)。同样,每个模板都有可能包括模板变量,用以替换实际的值

使用 ECharts GL 实现基础的三维可视化

ECharts GL (后面统一简称 GL)为 ECharts 补充了丰富的三维可视化组件,这里我们会简单介绍如何基于 GL 实现一些常见的三维可视化作品。实际上如果你对 ECharts 有一定了解的话,也可以很快的上手 GL,GL 的配置项完全是按照 ECharts 的标准和上手难度来设计的

如何下载和引入 ECharts GL

为了不再增加已经很大了的 ECharts 完整版的体积,我们将 GL 作为扩展包的形式提供,和诸如水球图这样的扩展类似,如果要使用 GL 里的各种组件,只需要在引入echarts.min.js的基础上再引入一个echarts-gl.min.js。你可以从 官网 下载最新版的 GL,然后在页面中通过标签引入:

<script src="lib/echarts.min.js"></script>
<script src="lib/echarts-gl.min.js"></script>

如果你的项目使用 webpack 或者 rollup 来打包代码的话,也可以通过 npm 安装后引入

npm install echarts
npm install echarts-gl
// 通过 ES6 的 import 语法引入 ECharts 和 ECharts GL
import echarts from 'echarts';
import 'echarts-gl';

声明一个基础的三维笛卡尔坐标系

引入ECharts和ECharts GL后,我们先来声明一个基础的三维笛卡尔坐标系用于绘制三维的散点图,柱状图,曲面图等常见的统计图;在ECharts中我们有grid组件用于提供一个矩形的区域放置一个二维的笛卡尔坐标系,以及笛卡尔坐标系上的x轴(xAxis)和y轴(yAxis)。对于三维的笛卡尔坐标系,我们在GL中提供了grid3D 组件用于划分一块三维的笛卡尔空间,以及放置在这个grid3D上的xAxis3D,yAxis3D,zAxis3D

小提示:在 GL 中我们对除了 globe 之外所有的三维组件和系列都加了 3D 的后缀用以区分,例如三维的散点图就是 scatter3D,三维的地图就是 map3D 等

下面这段代码就声明了一个最简单的三维笛卡尔坐标系

var option = {    
    grid3D: {}, // 需要注意的是我们不能跟 grid 一样省略 grid3D    
    xAxis3D: {}, // 默认情况下, x, y, z 分别是从 0 到 1 的数值轴
    yAxis3D: {},
    zAxis3D: {}
}

跟二维的笛卡尔坐标系一样,每个轴都会有多种类型,默认是数值轴,如果需要是类目轴的话,简单的设置为 type: 'category'就行了

绘制三维的散点图

声明好笛卡尔坐标系后,我们先试试用一份程序生成的正态分布数据在这个三维的笛卡尔坐标系中画散点图。

下面这段是生成正态分布数据的代码,你可以先不用关心这段代码是怎么工作的,只需要知道它生成了一份三维的正态分布数据放在data数组中

function makeGaussian(amplitude, x0, y0, sigmaX, sigmaY) {
    return function (amplitude, x0, y0, sigmaX, sigmaY, x, y) {
        var exponent = -( ( Math.pow(x - x0, 2) / (2 * Math.pow(sigmaX, 2))) + ( Math.pow(y - y0, 2) / (2 * Math.pow(sigmaY, 2))) );
        return amplitude * Math.pow(Math.E, exponent);
    }.bind(null, amplitude, x0, y0, sigmaX, sigmaY);
}
var gaussian = makeGaussian(50, 0, 0, 20, 20); // 创建一个高斯分布函数
var data = [];
for (var i = 0; i < 1000; i++) { // x, y 随机分布    
    var x = Math.random() * 100 - 50;
    var y = Math.random() * 100 - 50;
    var z = gaussian(x, y);
    data.push([x, y, z]);
}

生成的正态分布的数据大概长这样:

[
  [46.74395071259907, -33.88391024738553, 0.7754030099768191],
  [-18.45302873809771, 16.88114775416834, 22.87772504105404],
  [2.9908128281121336, -0.027699444453467947, 49.44400635911886],
  ...
]

每一项都包含了x, y, z三个值,这三个值会分别被映射到笛卡尔坐标系的 x 轴,y 轴和 z 轴上。然后我们可以使用 GL 提供的 scatter3D 系列类型把这些数据画成三维空间中正态分布的点

option = {
    grid3D: {},
    xAxis3D: {},
    yAxis3D: {},
    zAxis3D: { max: 100 },
    series: [{ type: 'scatter3D', data: data }]
}

使用真实数据的三维散点图

接下来我们来看一个使用真实多维数据的三维散点图例子;格式化一下可以看到这份数据是很传统转成JSON后的表格格式;第一行是每一列数据的属性名,可以从这个属性名看出来每一列数据的含义,分别是人均收入,人均寿命,人口数量,国家和年份

[
    ["Income", "Life Expectancy", "Population", "Country", "Year"],
    [815, 34.05, 351014, "Australia", 1800],
    [1314, 39, 645526, "Canada", 1800],
    [985, 32, 321675013, "China", 1800],
    [864, 32.2, 345043, "Cuba", 1800],
    [1244, 36.5731262, 977662, "Finland", 1800],
    ...
]

在 ECharts 4 中我们可以使用 dataset 组件非常方便地引入这份数据

$.get('data/asset/data/life-expectancy-table.json', function (data) {
    myChart.setOption({
        grid3D: {},
        xAxis3D: {},
        yAxis3D: {},
        zAxis3D: {},
        dataset: { source: data },
        series: [{ type: 'scatter3D', symbolSize: 2.5 }]
    })
});

默认会把前三列,也就是收入(Income),人均寿命(Life Expectancy),人口(Population)分别放到x、y、z轴上;使用encode属性我们还可以将指定列的数据映射到指定的坐标轴上,从而省去很多繁琐的数据转换代码;例如我们将x轴换成是国家(Country),y轴换成年份(Year),z轴换成收入(Income),可以看到不同国家不同年份的人均收入分布

myChart.setOption({
    grid3D: {},
    xAxis3D: { type: 'category' }, // 因为 x 轴和 y 轴都是类目数据,所以需要设置 type: 'category' 保证正确显示数据
    yAxis3D: { type: 'category' },
    zAxis3D: {},
    dataset: { source: data },
    series: [{
        type: 'scatter3D', symbolSize: 2.5,
        encode: {  // 维度的名字默认就是表头的属性名               
            x: 'Country', y: 'Year', z: 'Income',
            tooltip: [0, 1, 2, 3, 4]
        }
    }]
});

利用 visualMap 组件对三维散点图进行视觉编码

刚才多维数据的例子中,我们还有几个维度(列)没能表达出来,利用 ECharts 内置的 visualMap 组件我们可以继续将第四个维度编码成颜色

myChart.setOption({
    grid3D: {
        viewControl: { projection: 'orthographic' } // 使用正交投影
    },
    xAxis3D: { type: 'category' }, // 因为 x 轴和 y 轴都是类目数据,所以需要设置 type: 'category' 保证正确显示数据
    yAxis3D: { type: 'log' },
    zAxis3D: {},
    visualMap: {
        calculable: true,
        max: 100,        
        dimension: 'Life Expectancy', // 维度的名字默认就是表头的属性名
        inRange: { color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026'] }
    },
    dataset: { source: data },
    series: [
        {
            type: 'scatter3D', symbolSize: 5,
            encode: { x: 'Country', y: 'Population', z: 'Income', tooltip: [0, 1, 2, 3, 4] } // 维度的名字默认就是表头的属性名
        }
    ]
})

这段代码中我们又在刚才的例子基础上加入了 visualMap 组件,将Life Expectancy这一列数据映射到了不同的颜色;除此之外我们还把原来默认的透视投影改成了正交投影。正交投影在某些场景中可以避免因为近大远小所造成的表达错误

当然,除了 visualMap 组件,还可以利用其它的 ECharts 内置组件并且充分利用这些组件的交互效果,比如 legend。也可以像 三维散点图和散点矩阵结合使用 这个例子一样实现二维和三维的系列混搭;在实现 GL 的时候我们尽可能地把 WebGL 和 Canvas 之间的差异屏蔽了到最小,从而让 GL 的使用可以更加方便自然

在笛卡尔坐标系上显示其它类型的三维图表

除了散点图,我们也可以通过GL在三维的笛卡尔坐标系上绘制其它类型的三维图表;比如刚才例子中将scatter3D类型改成bar3D就可以变成一个三维的柱状图;机器学习中会用到的三维曲面图surface,三维曲面图常用来表达平面上的数据走势,刚才的正态分布数据我们也可以像下面这样画成曲面图

var data = [];
// 曲面图要求给入的数据是网格形式按顺序分布
for (var y = -50; y <= 50; y++) {
    for (var x = -50; x <= 50; x++) {
        var z = gaussian(x, y); data.push([x, y, z]);
    }
}
option = {
    grid3D: {},
    xAxis3D: {},
    yAxis3D: {},
    zAxis3D: { max: 60 },
    series: [{ type: 'surface', data: data }]
}

在微信小程序中使用 ECharts

Echarts和微信小程序官方团队合作,提供了 ECharts 的微信小程序版本。开发者可以通过熟悉的 ECharts 配置方式,快速开发图表,满足各种可视化需求

下载

为了兼容小程序 Canvas,我们提供了一个小程序的组件,用这种方式可以方便地使用 ECharts

首先,下载 GitHub 上的 ecomfe/echarts-for-weixin 项目;其中,ec-canvas 是我们提供的组件,其他文件是如何使用该组件的示例;ec-canvas 目录下有一个 echarts.js,默认我们会在每次 echarts-for-weixin 项目发版的时候替换成最新版的 ECharts。如有必要,可以自行从 ECharts 项目中下载最新发布版,或者从官网自定义构建以减小文件大小

引入组件

在创建项目后,可以将下载的 ecomfe/echarts-for-weixin 项目完全替换新建的项目,然后将修改代码;或者仅拷贝 ec-canvas 目录到新建的项目下,然后做相应的调整。如果采用完全替换的方式,需要将 project.config.json 中的 appid 替换成在公众平台申请的项目id。pages 目录下的每个文件夹是一个页面,可以根据情况删除不需要的页面,并且在 app.json 中删除对应页面。如果仅拷贝 ec-canvas 目录,则可以参考 pages/bar 目录下的几个文件的写法。下面,我们具体地说明

创建图表

首先,在 pages/bar 目录下新建以下几个文件:index.js、 index.json、 index.wxml、 index.wxss。并且在 app.json 的 pages 中增加 'pages/bar/index'

index.json 配置如下:

{ "usingComponents": { "ec-canvas": "../../ec-canvas/ec-canvas" } }

这一配置的作用是,允许我们在 pages/bar/index.wxml 中使用 组件。注意路径的相对位置要写对,如果目录结构和本例相同,就应该像上面这样配置。

index.wxml 中,我们创建了一个 组件,内容如下:

<view class="container">
  <ec-canvas id="mychart-dom-bar" canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas>
</view>

其中 ec 是一个我们在 index.js 中定义的对象,它使得图表能够在页面加载后被初始化并设置。index.js 的结构如下:

function initChart(canvas, width, height) {
  const chart = echarts.init(canvas, null, { width: width, height: height });
  canvas.setChart(chart);
  var option = { ... };
  chart.setOption(option);
  return chart;
}
Page({
  data: {
    ec: { onInit: initChart }
  }
});

这对于所有 ECharts 图表都是通用的,用户只需要修改上面 option 的内容,即可改变图表

暂不支持的功能

ECharts 中的绝大部分功能都支持小程序版本,因此这里仅说明不支持的功能,以及存在的问题。

1.Tooltip

2.图片

3.多个 zlevel 分层

此外,目前还有一些 bug 尚未修复,部分需要小程序团队配合上线支持,但不影响基本的使用。已知的 bug 包括:

1.安卓平台:transform 的问题(会影响关系图边两端的标记位置、旭日图文字位置等)

2.iOS 平台:半透明略有变深的问题

3.iOS 平台:渐变色出现在定义区域之外的地方

API

echarts

全局 echarts 对象,在 script 标签引入 echarts.js 文件后获得,或者在 AMD 环境中通过 require('echarts') 获得;不能在单个容器上初始化多个 ECharts 实例

echarts.init

创建一个 ECharts 实例,返回 echartsInstance,不能在单个容器上初始化多个 ECharts 实例

参数

1.dom:实例容器,一般是一个具有高宽的div元素。

注:如果div是隐藏的,ECharts 可能会获取不到div的高宽导致初始化失败,这时候可以明确指定div的style.width和style.height,或者在div显示后手动调用 echartsInstance.resize 调整尺寸

ECharts 3 中支持直接使用canvas元素作为容器,这样绘制完图表可以直接将 canvas 作为图片应用到其它地方,例如在 WebGL 中作为贴图,这跟使用 echartsInstance.getDataURL 生成图片链接相比可以支持图表的实时刷新

2.theme

应用的主题。可以是一个主题的配置对象,也可以是使用已经通过 echarts.registerTheme 注册的主题名称

3.opts

附加参数。有下面几个可选项:

devicePixelRatio:设备像素比,默认取浏览器的值window.devicePixelRatio

renderer:渲染器,支持 'canvas' 或者 'svg'

width:可显式指定实例宽度,单位为像素。如果传入值为 null/undefined/'auto',则表示自动取 dom(实例容器)的宽度

height:可显式指定实例高度,单位为像素。如果传入值为 null/undefined/'auto',则表示自动取 dom(实例容器)的高度

echarts.connect

多个图表实例实现联动

参数

group:group的id,或者图表实例的数组

// 分别设置每个实例的 group id
chart1.group = 'group1';
chart2.group = 'group1';
echarts.connect('group1');
// 或者可以直接传入需要联动的实例数组
echarts.connect([chart1, chart2]);

echarts.disconnect

解除图表实例的联动,如果只需要移除单个实例,可以将通过将该图表实例 group 设为空

echarts.dispose

销毁实例,实例销毁后无法再被使用

echarts.getInstanceByDom

获取 dom 容器上的实例

echarts.registerMap

注册可用的地图,必须在包括 geo 组件或者 map 图表类型的时候才能使用

参数

1.mapName:地图名称,在geo组件或者map图表类型中设置的map对应的就是该值

2.geoJson:GeoJson格式的数据

3.specialAreas:可选;将地图中的部分区域缩放到合适的位置,可以使得整个地图的显示更加好看

echarts.registerMap('USA', usaJson, {  
  Alaska: { // 把阿拉斯加移到美国主大陆左下方      
      left: -131, // 左上角经度      
      top: 25, // 左上角纬度      
      width: 15 // 经度横跨的范围
  },  
  Hawaii: { left: -110, top: 28, width: 5 }, // 夏威夷  
  'Puerto Rico': { left: -76, top: 26, width: 2 } // 波多黎各
});

echarts.getMap

获取已注册的地图,返回的对象类型如下

{    
    geoJson: Object, // 地图的 geoJson 数据    
    specialAreas: Object // 地图的特殊区域,见 registerMap
}

echarts.registerTheme

注册主题,用于初始化实例的时候指定

echarts.graphic

图形相关帮助方法

echarts.graphic.clipPointsByRect

输入一组点,和一个矩形,返回被矩形截取过的点

(    
    points: Array.<Array.<number>>, // 要被截取的点列表,如 [[23, 44], [12, 15], ...]    
    rect: { // 用于截取点的矩形
        x: number, y: number, width: number, height: number
    }
) => Array.<Array.<number>> // 截取结果

echarts.graphic.clipRectByRect

输入两个矩形,返回第二个矩形截取第一个矩形的结果

(
    targetRect: { // 要被截取的矩形
        x: number, y: number, width: number, height: number
    },    
    rect: { // 用于截取点的矩形
        x: number, y: number, width: number, height: number
    }
) => { // 截取结果
    x: number, y: number, width: number, height: number
}

注意:如果矩形完全被截干净,会返回 undefined

echartsInstance

通过 echarts.init 创建的实例

echartsInstance.group

图表的分组,用于联动

echartsInstance.setOption

设置图表实例的配置项以及数据,万能接口,所有参数和数据的修改都可以通过 setOption 完成,ECharts 会合并新的参数和数据,然后刷新图表。如果开启动画的话,ECharts 找到两组数据之间的差异然后通过合适的动画去表现数据的变化

注: ECharts 2.x 中的通过 addData , setSeries 方法设置配置项的方式将不再支持,在 ECharts 3 中统一使用 setOption

参数

调用方式:

chart.setOption(option, notMerge, lazyUpdate);
或者
chart.setOption(option, {
    notMerge: ...,
    lazyUpdate: ...,
    silent: ...
});

1.option:图表的配置项和数据

2.notMerge:可选,是否不跟之前设置的 option 进行合并,默认为 false,即合并

3.lazyUpdate:可选,在设置完 option 后是否不立即更新图表,默认为 false,即立即更新

4.silent:可选,阻止调用 setOption 时抛出事件,默认为 false,即抛出事件

echartsInstance.getWidth

获取 ECharts 实例容器的宽度

echartsInstance.getHeight

获取 ECharts 实例容器的高度

echartsInstance.getDom

获取 ECharts 实例容器的 dom 节点

echartsInstance.getOption

获取当前实例中维护的 option 对象,返回的 option 对象中包含了用户多次 setOption 合并得到的配置项和数据,也记录了用户交互的状态,例如图例的开关,数据区域缩放选择的范围等等。所以从这份 option 可以恢复或者得到一个新的一模一样的实例

注意:返回的 option 每个组件的属性值都统一是一个数组,不管 setOption 传进来的时候是单个组件的对象还是多个组件的数组。如下形式:

{ title: [{...}], legend: [{...}], grid: [{...}] }

另外不推荐下面这种写法:

var option = myChart.getOption();
option.visualMap[0].inRange.color = ...;
myChart.setOption(option);

因为 getOption 获取的是已经合并过默认值了的,所以在修改了某些配置项后会导致原本是根据这些配置项值去设置的默认值失效;因此我们更推荐通过setOption去修改部分配置

myChart.setOption({
    visualMap: {
        inRange: { color: ... }
    }
})

echartsInstance.resize

改变图表尺寸,在容器大小发生改变时需要手动调用

参数

opts:可缺省。有下面几个可选项:

1.width:可显式指定实例宽度,单位为像素。如果传入值为 null/undefined/'auto',则表示自动取 dom(实例容器)的宽度

2.height:可显式指定实例高度,单位为像素。如果传入值为 null/undefined/'auto',则表示自动取 dom(实例容器)的高度

silent:是否禁止抛出事件。默认为 false

Tip: 有时图表会放在多个标签页里,那些初始隐藏的标签在初始化图表的时候因为获取不到容器的实际高宽,可能会绘制失败,因此在切换到该标签页时需要手动调用 resize 方法获取正确的高宽并且刷新画布,或者在 opts 中显示指定图表高宽。

echartsInstance.dispatchAction

触发图表行为,例如图例开关legendToggleSelect, 数据区域缩放dataZoom,显示提示框showTip等等,payload 参数可以通过batch属性同时触发多个行为

注:在 ECharts 2.x 是通过 myChart.component.tooltip.showTip 这种形式调用相应的接口触发图表行为,入口很深,而且涉及到内部组件的组织。因此在 ECharts 3 里统一改为 dispatchAction 的形式

myChart.dispatchAction({ type: 'dataZoom', start: 20, end: 30 });
myChart.dispatchAction({ // 可以通过 batch 参数批量分发多个 action
    type: 'dataZoom',
    batch: [{ // 第一个 dataZoom 组件        
        start: 20, end: 30
    }, { // 第二个 dataZoom 组件        
        dataZoomIndex: 1, start: 10, end: 20
    }]
})

echartsInstance.on

绑定事件处理函数;ECharts 中的事件有两种,一种是鼠标事件,在鼠标点击某个图形上会触发,还有一种是 调用 dispatchAction 后触发的事件。每个 action 都会有对应的事件;如果事件是外部 dispatchAction 后触发,并且 action 中有 batch 属性触发批量的行为,则相应的响应事件参数里也会把属性都放在 batch 属性中

参数

1.eventName:事件名称,全小写,例如'click','mousemove', 'legendselected'

注: ECharts 2.x 中会使用 config 对象中的 CLICK 等属性作为事件名称。在 ECharts 3 中统一使用跟 dom 事件一样的全小写字符串作为事件名

2.query:可选的过滤条件,能够只在指定的组件或元素上进行响应。可为 string 或 Object;如果为 string 表示组件类型,格式可以是 'mainType' 或者 'mainType.subType'。例如:

chart.on('click', 'series', function () {...});
chart.on('click', 'series.line', function () {...});
chart.on('click', 'dataZoom', function () {...});
chart.on('click', 'xAxis.category', function () {...});

如果为 Object,可以包含以下一个或多个属性,每个属性都是可选的:

{
    <mainType>Index: number // 组件 index
    <mainType>Name: string // 组件 name
    <mainType>Id: string // 组件 id
    dataIndex: number // 数据项 index
    name: string // 数据项 name
    dataType: string // 数据项 type,如关系图中的 'node', 'edge'
    element: string // 自定义系列中的 el 的 name
}

例如:

chart.setOption({
     // ...
     series: [{
         name: 'uuu'
         // ...
     }]
 });
 chart.on('mouseover', {seriesName: 'uuu'}, function () {
     // series name 为 'uuu' 的系列中的图形元素被 'mouseover' 时,此方法被回调
 });
 或
 chart.setOption({
      // ...
      series: [{
          // ...
      }, {
          // ...
          data: [
              {name: 'xx', value: 121},
              {name: 'yy', value: 33}
          ]
      }]
  });
  chart.on('mouseover', {seriesIndex: 1, name: 'xx'}, function () {
      // series index 1 的系列中的 name 为 'xx' 的元素被 'mouseover' 时,此方法被回调
  });
或
chart.setOption({
    // ...
    series: [{
        type: 'graph',
        nodes: [{name: 'a', value: 10}, {name: 'b', value: 20}],
        edges: [{source: 0, target: 1}]
    }]
});
chart.on('click', {dataType: 'node'}, function () {
    // 关系图的节点被点击时此方法被回调
});
chart.on('click', {dataType: 'edge'}, function () {
    // 关系图的边被点击时此方法被回调
});
或
chart.setOption({
      // ...
      series: {
          // ...
          type: 'custom',
          renderItem: function (params, api) {
              return {
                  type: 'group',
                  children: [{
                      type: 'circle',
                      name: 'my_el',
                      // ...
                  }, {
                      // ...
                  }]
              }
          },
          data: [[12, 33]]
      }
  })
  chart.on('mouseup', {element: 'my_el'}, function () {
      // name 为 'my_el' 的元素被 'mouseup' 时,此方法被回调
  });

3.handler:事件处理函数。格式为: (event: Object)

4.context:可选。回调函数内部的context,即this的指向

echartsInstance.off

解绑事件处理函数

参数

eventName:事件名称

handler:可选,可以传入需要解绑的处理函数,不传的话解绑所有该类型的事件函数

echartsInstance.convertToPixel

转换坐标系上的点到像素坐标值

(    
    finder: { // finder 用于指示『使用哪个坐标系进行转换』;通常地,可以使用 index 或者 id 或者 name 来定位
        seriesIndex?: number,
        seriesId?: string,
        seriesName?: string,
        geoIndex?: number,
        geoId?: string,
        geoName?: string,
        xAxisIndex?: number,
        xAxisId?: string,
        xAxisName?: string,
        yAxisIndex?: number,
        yAxisId?: string,
        yAxisName?: string,
        gridIndex?: number,
        gridId?: string
        gridName?: string
    },    
    value: Array|string // 要被转换的值    
) => Array|string // 转换的结果为像素坐标值,以 echarts 实例的 dom 节点的左上角为坐标 [0, 0] 点

例1:在地理坐标系(geo)上,把某个点的经纬度坐标转换成为像素坐标

// [128.3324, 89.5344] 表示 [经度,纬度],使用第一个 geo 坐标系进行转换:
chart.convertToPixel('geo', [128.3324, 89.5344]); // 参数 'geo' 等同于 {geoIndex: 0}
// 使用第二个 geo 坐标系进行转换:
chart.convertToPixel({geoIndex: 1}, [128.3324, 89.5344]);
// 使用 id 为 'bb' 的 geo 坐标系进行转换:
chart.convertToPixel({geoId: 'bb'}, [128.3324, 89.5344]);

例2:在直角坐标系(cartesian,grid)上,把某个点的坐标转换成为像素坐标

// [300, 900] 表示该点 x 轴上对应刻度值 300,y 轴上对应刻度值 900;一个 grid 可能含有多个 xAxis 和多个 yAxis,任何一对 xAxis-yAxis 形成一个 cartesian;使用第三个 xAxis 和 id 为 'y1' 的 yAxis 形成的 cartesian 进行转换:
chart.convertToPixel({xAxisIndex: 2, yAxisId: 'y1'}, [300, 900]);
// 使用 id 为 'g1' 的 grid 的第一个 cartesian 进行转换:
chart.convertToPixel({gridId: 'g1'}, [300, 900]);

例3:把某个坐标轴的点转换成像素坐标:

// id 为 'x0' 的 xAxis 的刻度 3000 位置所对应的横向像素位置:
chart.convertToPixel({xAxisId: 'x0'}, 3000); // 返回一个 number
// 第二个 yAxis 的刻度 600 位置所对应的纵向像素位置:
chart.convertToPixel({yAxisIndex: 1}, 600); // 返回一个 number

例4:把关系图(graph)的点转换成像素坐标:

// 因为每个 graph series 自己持有一个坐标系,所以我们直接在 finder 中指定 series:
chart.convertToPixel({seriesIndex: 0}, [2000, 3500]);
chart.convertToPixel({seriesId: 'k2'}, [100, 500]);

例5:在某个系列所在的坐标系(无论是 cartesian、geo、graph 等)中,转换某点成像素坐标:

// 使用第一个系列对应的坐标系:
chart.convertToPixel({seriesIndex: 0}, [128.3324, 89.5344]);
// 使用 id 为 'k2' 的系列所对应的坐标系:
chart.convertToPixel({seriesId: 'k2'}, [128.3324, 89.5344]);

echartsInstance.convertFromPixel

转换像素坐标值到逻辑坐标系上的点。是 convertToPixel 的逆运算

(    
    finder: { // finder 用于指示『使用哪个坐标系进行转换』;通常地,可以使用 index 或 id 或 name 来定位
        seriesIndex?: number,
        seriesId?: string,
        seriesName?: string,
        geoIndex?: number,
        geoId?: string,
        geoName?: string,
        xAxisIndex?: number,
        xAxisId?: string,
        xAxisName?: string,
        yAxisIndex?: number,
        yAxisId?: string,
        yAxisName?: string,
        gridIndex?: number,
        gridId?: string
        gridName?: string
    },    
    value: Array|string // 要被转换的值,为像素坐标值,以 echarts 实例的 dom 节点的左上角为坐标 [0, 0] 点    
) => Array|string // 转换的结果,为逻辑坐标值

echartsInstance.containPixel

判断给定的点是否在指定的坐标系或者系列上;目前支持在这些坐标系和系列上进行判断:grid, polar, geo, series-map, series-graph, series-pie

// 判断 [23, 44] 点是否在 geoIndex 为 0 的 geo 坐标系上
chart.containPixel('geo', [23, 44]); // 'geo' 等同于 {geoIndex: 0}
// 判断 [23, 44] 点是否在 gridId 为 'z' 的 grid 上
chart.containPixel({gridId: 'z'}, [23, 44]);
// 判断 [23, 44] 点是否在 index 为 1,4,5 的系列上
chart.containPixel({seriesIndex: [1, 4, 5]}, [23, 44]);
// 判断 [23, 44] 点是否在 index 为 1,4,5 的系列或者 gridName 为 'a' 的 grid 上
chart.containPixel({seriesIndex: [1, 4, 5], gridName: 'a'}, [23, 44]);

echartsInstance.showLoading

显示加载动画效果;可以在加载数据前手动调用该接口显示加载动画,在数据加载完成后调用 hideLoading 隐藏加载动画

参数

1.type:可选,加载动画类型,目前只有一种'default'

2.opts:可选,加载动画配置项,跟type有关,下面是默认配置项:

default: {
  text: 'loading',
  color: '#c23531',
  textColor: '#000',
  maskColor: 'rgba(255, 255, 255, 0.8)',
  zlevel: 0
}

echartsInstance.hideLoading

隐藏动画加载效果

echartsInstance.getDataURL

(opts: {    
    type?: string, // 导出的格式,可选 png, jpeg    
    pixelRatio?: number, // 导出的图片分辨率比例,默认为 1    
    backgroundColor?: string, // 导出的图片背景色,默认使用 option 里的 backgroundColor    
    excludeComponents?: Array.<string> // 忽略组件的列表,例如要忽略 toolbox 就是 ['toolbox']
}) => string

导出图表图片,返回一个 base64 的 URL,可以设置为Image的src

var img = new Image();
img.src = myChart.getDataURL({
    pixelRatio: 2,
    backgroundColor: '#fff'
});

echartsInstance.getConnectedDataURL

导出联动的图表图片,返回一个 base64 的 url,可以设置为Image的src。导出图片中每个图表的相对位置跟容器的相对位置有关

(opts: {    
    type?: string,// 导出的格式,可选 png, jpeg
    pixelRatio?: number,// 导出的图片分辨率比例,默认为 1
    backgroundColor?: string,// 导出的图片背景色,默认使用 option 里的 backgroundColor    
    excludeComponents?: Array.<string>// 忽略组件的列表,例如要忽略 toolbox 就是 ['toolbox']
}) => string

echartsInstance.appendData

此接口用于在大数据量(百万以上)的渲染场景,分片加载数据和增量渲染。在大数据量的场景下(例如地理数的打点),就算数据使用二进制格式,也会有几十或上百兆,在互联网环境下,往往需要分片加载。appendData 接口提供了分片加载后增量渲染的能力,渲染新加入的数据块时不会清除原有已经渲染的部分

(opts: {
    seriesIndex?: string,// 要增加数据的系列序号
    data?: Array|TypedArray,// 增加的数据
}) => string

注意:

1.现在不支持 系列(series) 使用 dataset 同时使用 appendData,只支持系列使用自己的 series.data 时使用 appendData

2.目前并非所有的图表都支持分片加载时的增量渲染。目前支持的图有:ECharts 基础版本的 散点图(scatter) 和 线图(lines)。ECharts GL 的 散点图(scatterGL)、线图(linesGL) 和 可视化建筑群(polygons3D)

echartsInstance.clear

清空当前实例,会移除实例中所有的组件和图表。清空后调用 getOption 方法返回一个{}空对象

echartsInstance.isDisposed

当前实例是否已经被释放

echartsInstance.dispose

销毁实例,销毁后实例无法再被使用

action

ECharts 中支持的图表行为,通过 dispatchAction 触发。

注: 代码中的 ?: 表示该属性是可选的。EVENT: 是 action 对应触发的事件

action.highlight

高亮指定的数据图形;通过seriesName或者seriesIndex指定系列,如果要再指定某个数据可以再指定dataIndex或者name

dispatchAction({
    type: 'highlight',    
    seriesIndex?: number|Array,// 可选,系列 index,可以是一个数组指定多个系列    
    seriesName?: string|Array,// 可选,系列名称,可以是一个数组指定多个系列    
    dataIndex?: number,// 可选,数据的 index    
    name?: string// 可选,数据的 名称
})

action.legend

图例组件相关的行为,必须引入图例组件后才能使用

action.legend.legendSelect

选中图例

dispatchAction({
    type: 'legendSelect',    
    name: string // 图例名称
})

action.legend.legendUnSelect

取消选中图例

dispatchAction({
    type: 'legendUnSelect',    
    name: string // 图例名称
})

action.legend.legendToggleSelect

切换图例的选中状态

dispatchAction({
    type: 'legendToggleSelect',    
    name: string // 图例名称
})

action.legend.legendScroll

控制图例的滚动。当 legend.type 为 'scroll' 时有效

dispatchAction({
    type: 'legendScroll',
    scrollDataIndex: number,
    legendId: string
})

action.tooltip

提示框组件相关的行为,必须引入提示框组件后才能使用

action.tooltip.showTip

显示提示框;有下面两种使用方式:

1 指定在相对容器的位置处显示提示框,如果指定的位置无法显示则无效

dispatchAction({
    type: 'showTip',    
    x: number, // 屏幕上的 x 坐标    
    y: number, // 屏幕上的 y 坐标    
    position: Array.<number>|string|Function // 本次显示 tooltip 的位置,只在本次 action 中生效, 缺省则使用 option 中定义的 tooltip 位置
})

2 指定数据图形,根据 tooltip 的配置项显示提示框。

dispatchAction({
    type: 'showTip',
    seriesIndex?: number, // 系列的 index,在 tooltip 的 trigger 为 axis 的时候可选
    dataIndex?: number, // 数据的 index,如果不指定也可以通过 name 属性根据名称指定数据
    name?: string, // 可选,数据名称,在有 dataIndex 的时候忽略
    position: Array.<number>|string|Function, // 本次显示 tooltip 的位置,只在本次 action 中生效,缺省则使用 option 中定义的 tooltip 位置
})

参数position同tooltip.position相同

action.tooltip.hideTip

隐藏提示框

dispatchAction({
    type: 'hideTip'
})

action.dataZoom

数据区域缩放组件相关的行为,必须引入数据区域缩放组件后才能使用

action.dataZoom.dataZoom

数据区域缩放

dispatchAction({
    type: 'dataZoom',    
    dataZoomIndex: number, // 可选,dataZoom 组件的 index,多个 dataZoom 组件时有用,默认为 0    
    start: number, // 开始位置的百分比,0 - 100    
    end: number, // 结束位置的百分比,0 - 100    
    startValue: number, // 开始位置的数值    
    endValue: number // 结束位置的数值
})

action.dataZoom.takeGlobalCursor

启动或关闭 toolbox 中 dataZoom 的刷选状态

myChart.dispatchAction({
    type: 'takeGlobalCursor',
    key: 'dataZoomSelect',    
    dataZoomSelectActive: true // 启动或关闭
});

action.visualMap

视觉映射组件相关的行为,必须引入视觉映射组件后才能使用

action.visualMap.selectDataRange

选取映射的数值范围

dispatchAction({
    type: 'selectDataRange',    
    visualMapIndex: number, // 可选,visualMap 组件的 index,多个 visualMap 组件时有用,默认为 0    
    selected: Object|Array // 连续型 visualMap 和 离散型 visualMap 不一样;连续型的是一个表示数值范围的数组;离散型的是一个对象,键值是类目或者分段的索引。值是 `true`, `false`
})

action.timeline

时间轴组件相关的行为,必须引入时间轴组件后才能使用

action.timeline.timelineChange

设置当前的时间点

dispatchAction({
    type: 'timelineChange',    
    currentIndex: number // 时间点的 index
})

action.timeline.timelinePlayChange

切换时间轴的播放状态

dispatchAction({
    type: 'timelinePlayChange',    
    playState: boolean // 播放状态,true 为自动播放
})

action.toolbox

工具栏组件相关的行为,必须引入工具栏组件后才能使用

action.toolbox.restore

重置 option

dispatchAction({
    type: 'restore'
})

action.pie

饼图相关的行为,必须引入饼图后才能使用

action.pie.pieSelect

选中指定的饼图扇形

dispatchAction({
    type: 'pieSelect',    
    seriesIndex?: number|Array, // 可选,系列 index,可以是一个数组指定多个系列    
    seriesName?: string|Array, // 可选,系列名称,可以是一个数组指定多个系列    
    dataIndex?: number, // 数据的 index,如果不指定也可以通过 name 属性根据名称指定数据    
    name?: string // 可选,数据名称,在有 dataIndex 的时候忽略
})

action.pie.pieUnSelect

取消选中指定的饼图扇形

dispatchAction({
    type: 'pieUnSelect',    
    seriesIndex?: number|Array, // 可选,系列 index,可以是一个数组指定多个系列    
    seriesName?: string|Array, // 可选,系列名称,可以是一个数组指定多个系列    
    dataIndex?: number, // 数据的 index,如果不指定也可以通过 name 属性根据名称指定数据    
    name?: string // 可选,数据名称,在有 dataIndex 的时候忽略
})

action.pie.pieToggleSelect

切换指定的饼图扇形选中状态

dispatchAction({
    type: 'pieToggleSelect',    
    seriesIndex?: number|Array, // 可选,系列 index,可以是一个数组指定多个系列    
    seriesName?: string|Array, // 可选,系列名称,可以是一个数组指定多个系列    
    dataIndex?: number, // 数据的 index,如果不指定也可以通过 name 属性根据名称指定数据    
    name?: string // 可选,数据名称,在有 dataIndex 的时候忽略
})

action.geo

地图组件相关的行为,必须引入地图组件后才能使用

action.geo.geoSelect

选中指定的地图区域

dispatchAction({
    type: 'geoSelect',    
    seriesIndex?: number|Array, // 可选,系列 index,可以是一个数组指定多个系列    
    seriesName?: string|Array, // 可选,系列名称,可以是一个数组指定多个系列    
    dataIndex?: number, // 数据的 index,如果不指定也可以通过 name 属性根据名称指定数据    
    name?: string // 可选,数据名称,在有 dataIndex 的时候忽略
})

action.geo.geoUnSelect

取消选中指定的地图区域

dispatchAction({
    type: 'geoUnSelect',    
    seriesIndex?: number|Array, // 可选,系列 index,可以是一个数组指定多个系列    
    seriesName?: string|Array, // 可选,系列名称,可以是一个数组指定多个系列    
    dataIndex?: number, // 数据的 index,如果不指定也可以通过 name 属性根据名称指定数据    
    name?: string // 可选,数据名称,在有 dataIndex 的时候忽略
})

action.geo.geoToggleSelect

切换指定的地图区域选中状态

dispatchAction({
    type: 'geoToggleSelect',    
    seriesIndex?: number|Array, // 可选,系列 index,可以是一个数组指定多个系列    
    seriesName?: string|Array, // 可选,系列名称,可以是一个数组指定多个系列    
    dataIndex?: number, // 数据的 index,如果不指定也可以通过 name 属性根据名称指定数据    
    name?: string // 可选,数据名称,在有 dataIndex 的时候忽略
})

action.map

地图图表相关的行为,必须引入地图图表后才能使用

action.map.mapSelect

选中指定的地图区域

dispatchAction({
    type: 'mapSelect',    
    seriesIndex?: number|Array, // 可选,系列 index,可以是一个数组指定多个系列    
    seriesName?: string|Array, // 可选,系列名称,可以是一个数组指定多个系列    
    dataIndex?: number, // 数据的 index,如果不指定也可以通过 name 属性根据名称指定数据    
    name?: string // 可选,数据名称,在有 dataIndex 的时候忽略
})

action.map.mapUnSelect

取消选中指定的地图区域

dispatchAction({
    type: 'mapUnSelect',    
    seriesIndex?: number|Array, // 可选,系列 index,可以是一个数组指定多个系列    
    seriesName?: string|Array, // 可选,系列名称,可以是一个数组指定多个系列    
    dataIndex?: number, // 数据的 index,如果不指定也可以通过 name 属性根据名称指定数据    
    name?: string // 可选,数据名称,在有 dataIndex 的时候忽略
})

action.map.mapToggleSelect

切换指定的地图区域选中状态

dispatchAction({
    type: 'mapToggleSelect',    
    seriesIndex?: number|Array, // 可选,系列 index,可以是一个数组指定多个系列    
    seriesName?: string|Array, // 可选,系列名称,可以是一个数组指定多个系列    
    dataIndex?: number, // 数据的 index,如果不指定也可以通过 name 属性根据名称指定数据    
    name?: string // 可选,数据名称,在有 dataIndex 的时候忽略
})

action.graph

关系图 相关的行为,必须引入 关系图 后才能使用

action.graph.focusNodeAdjacency

将指定的节点以及其所有邻接节点高亮

dispatchAction({
    type: 'focusNodeAdjacency',
    // 使用 seriesId 或 seriesIndex 或 seriesName 来定位 series
    seriesId: 'xxx',
    seriesIndex: 0,
    seriesName: 'nnn',
    // 使用 dataIndex 来定位节点
    dataIndex: 12
})

最后会抛出 focusNodeAdjacency 事件

action.graph.unfocusNodeAdjacency

将指定的节点以及其所有邻接节点高亮

dispatchAction({
    type: 'unfocusNodeAdjacency',
    // 使用 seriesId 或 seriesIndex 或 seriesName 来定位 series.
    seriesId: 'xxx',
    seriesIndex: 0,
    seriesName: 'nnn'
})

最后会抛出 unfocusNodeAdjacency 事件

action.brush

区域选择相关的行为

action.brush.brush

触发此 action 可设置或删除 chart 中的选框,例如:

myChart.dispatchAction({
    type: 'brush',
    areas: [ // areas 表示选框的集合,可以指定多个选框;如果 areas 为空,则删除所有选框;注意这并非增量接口而是全量接口,所以应包括所有的选框
        { // 选框一:指定此选框是“坐标系选框”,属于 index 为 0 的 geo 坐标系;也可以通过 xAxisIndex 或 yAxisIndex 来指定此选框属于直角坐标系;如果没有指定,则此选框属于“全局选框”,不属于任何坐标系;属于『坐标系选框』,可以随坐标系一起缩放平移。属于全局的选框不行
            geoIndex: 0,
            // xAxisIndex: 0,
            // yAxisIndex: 0,            
            brushType: 'polygon', // 指定选框的类型。可以为 'polygon', 'rect', 'lineX', 'lineY'
            range: [ // 如果是“全局选框”,则使用 range 来描述选框的范围(里面是像素坐标)
                ...
            ],            
            coordRange: [ // 如果是“坐标系选框”,则使用 coordRange 来指定选框的范围(里面是坐标系坐标)                
                [119.72,34.85],[119.68,34.85],[119.5,34.84],[119.19,34.77] // 这个例子中,因为指定了 geoIndex,所以 coordRange 里单位是经纬度
            ]
        },
        ... // 选框二、三、四、...
    ]
});

其中,areas 中的 range 和 coordRange 的格式,根据 brushType 不同而不同:

1.brushType 为 'rect' range 和 coordRange 的格式为:[[minX, maxX], [minY, maxY]]

2.brushType 为 'lineX' 或 'lineY' range 和 coordRange 的格式为:[min, maxX]

3.brushType 为 'polygon' range 和 coordRange 的格式为:[[point1X, point1X], [point2X, point2X], ...]

range 和 coordRange 的区别是:

1.当此选框为『全局选框』时,使用 range。

2.当此选框为『坐标系选框』时(即指定了 geoIndex 或 xAxisIndex 或 yAxisIndex 时),使用 coordRange。

3.range 的单位为 像素,coordRange 的单位为 坐标系单位,比如 geo 中,coordRange 单位为经纬度,直角坐标系中,coordRange 单位为对应轴的数据的单位

action.brush.takeGlobalCursor

刷选模式的开关。使用此 action 可将当前鼠标变为可刷选状态;事实上,点击 toolbox 中的 brush 按钮时,就是通过这个 action,将当前普通鼠标变为刷选器的

此 action 对应的事件为 globalCursorTaken

api.dispatchAction({
    type: 'takeGlobalCursor',    
    key: 'brush', // 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”
    brushOption: {        
        brushType: string, // 参见 brush 组件的 brushType。如果设置为 false 则关闭“可刷选状态”        
        brushMode: string // 参见 brush 组件的 brushMode。如果不设置,则取 brush 组件的 brushMode 设置
    }
});

events

在 ECharts 中主要通过 on 方法添加事件处理函数,该文档描述了所有 ECharts 的事件列表;ECharts 中的事件分为两种,一种是鼠标事件,在鼠标点击某个图形上会触发,还有一种是 调用 dispatchAction 后触发的事件

myChart.on('click', function (params) {
    console.log(params);
});
myChart.on('legendselectchanged', function (params) {
    console.log(params);
});
chart.on('click', 'series.line', function (params) {
    console.log(params);
});
chart.on('mouseover', {seriesIndex: 1, name: 'xx'}, function (params) {
    console.log(params);
});

events.鼠标事件

鼠标事件的事件参数是事件对象的数据的各个属性,对于图表的点击事件,基本参数如下,其它图表诸如饼图可能会有部分附加参数。例如饼图会有percent属性表示百分比,具体见各个图表类型的 label formatter 回调函数的 params

{    
    componentType: string, // 当前点击的图形元素所属的组件名称,其值如 'series'、'markLine'、'markPoint'、'timeLine' 等
    seriesType: string, // 系列类型。值可能为:'line'、'bar'、'pie' 等。当 componentType 为 'series' 时有意义
    seriesIndex: number, // 系列在传入的 option.series 中的 index。当 componentType 为 'series' 时有意义
    seriesName: string, // 系列名称。当 componentType 为 'series' 时有意义
    name: string, // 数据名,类目名
    dataIndex: number, // 数据在传入的 data 数组中的 index
    data: Object, // 传入的原始数据项
    dataType: string, // sankey、graph 等图表同时含有 nodeData 和 edgeData 两种 data,dataType 的值会是 'node' 或者 'edge',表示当前点击在 node 还是 edge 上;其他大部分图表中只有一种 data,dataType 无意义
    value: number|Array, // 传入的数据值
    color: string, // 数据图形的颜色。当 componentType 为 'series' 时有意义
    info: * // 用户自定义的数据。只在 graphic component 和自定义系列(custom series)中生效,如果节点定义上设置了如:{type: 'circle', info: {some: 123}}
}

鼠标事件包括 'click'、'dblclick'、'mousedown'、'mousemove'、'mouseup'、'mouseover'、'mouseout'、'globalout'、'contextmenu'。

events.legendselectchanged

ACTION: legendToggleSelect 切换图例选中状态后的事件;图例组件用户切换图例开关会触发该事件

{
    type: 'legendselectchanged',    
    name: string // 切换的图例名称    
    selected: Object // 所有图例的选中状态表
}

events.legendselected

ACTION: legendSelect 图例选中后的事件

{
    type: 'legendselected',    
    name: string // 切换的图例名称    
    selected: Object // 所有图例的选中状态表
}

注: ECharts 2.x 中用户开关图例对应的事件从 legendselected 改为 legendselectchanged

events.legendunselected

ACTION: legendUnSelect 图例取消选中后的事件

{
    type: 'legendunselected',    
    name: string // 切换的图例名称    
    selected: Object // 所有图例的选中状态表
}

events.legendscroll

ACTION: legendscroll 图例滚动事件

{
    type: 'legendscroll',
    scrollDataIndex: number
    legendId: string
}

events.datazoom

ACTION: dataZoom

数据区域缩放后的事件

{
    type: 'datazoom',    
    start: number // 缩放的开始位置的百分比,0 - 100    
    end: number // 缩放的结束位置的百分比,0 - 100    
    startValue?: number // 缩放的开始位置的数值,只有在工具栏缩放行为的事件中存在
    endValue?: number // 缩放的结束位置的数值,只有在工具栏缩放行为的事件中存在
}

events.datarangeselected

ACTION: selectDataRange 视觉映射组件中,range 值改变后触发的事件

{
    type: 'datarangeselected',    
    selected: Object|Array // 连续型 visualMap 和 离散型 visualMap 不一样;连续型的是一个表示数值范围的数组;离散型的是一个对象,键值是类目或者分段的索引。值是`true`或`false`
}

events.timelinechanged

ACTION: timelineChange 时间轴中的时间点改变后的事件

{
    type: 'timelinechanged',    
    currentIndex: number // 时间点的 index
}

events.timelineplaychanged

ACTION: timelinePlayChange 时间轴中播放状态的切换事件

{
    type: 'timelineplaychanged',    
    playState: boolean // 播放状态,true 为自动播放
}

events.restore

ACTION: restore 重置 option 事件

{ type: 'restore' }

events.dataviewchanged

工具栏中数据视图的修改事件

{ type: 'dataviewchanged' }

events.magictypechanged

工具栏中动态类型切换的切换事件

{
    type: 'magictypechanged',    
    currentType: string // 点击切换的当前类型,同 echarts 2.x 中的 type 属性
 }

events.geoselectchanged

ACTION: geoToggleSelect;geo中地图区域切换选中状态的事件,用户点击选中会触发该事件

{
    type: 'geoselectchanged',    
    seriesId: string // 系列 ID,可以在 option 中传入    
    name: name, // 数据名称    
    selected: Object // 所有数据的选中状态表
}

events.geoselected

ACTION: geoSelect;geo 中地图区域选中后的事件;使用dispatchAction可触发此事件,用户点击不会触发此事件(用户点击事件请使用 geoselectchanged)

{
    type: 'geoselected',    
    seriesId: string // 系列 ID,可以在 option 中传入    
    name: name, // 数据名称
    selected: Object // 所有数据的选中状态表
}

events.geounselected

ACTION: geoUnSelect;geo 中地图区域取消选中后的事件;使用dispatchAction可触发此事件,用户点击不会触发此事件(用户点击事件请使用 geoselectchanged)

{
    type: 'geounselected',
    seriesId: string // 系列 ID,可以在 option 中传入
    name: name, // 数据名称
    selected: Object // 所有数据的选中状态表
}

events.pieselectchanged

ACTION: pieToggleSelect;series-pie 中饼图扇形切换选中状态的事件;用户点击选中会触发该事件

{
    type: 'pieselectchanged',
    seriesId: string // 系列 ID,可以在 option 中传入
    name: name, // 数据名称
    selected: Object // 所有数据的选中状态表
}

注: 该事件同 ECharts 2 中的 pieSelected 事件相同

events.pieselected

ACTION: pieSelect;series-pie 中饼图扇形选中后的事件;使用dispatchAction可触发此事件,用户点击不会触发此事件(用户点击事件请使用 pieselectchanged)

{
    type: 'pieselected',
    seriesId: string // 系列 ID,可以在 option 中传入
    name: name, // 数据名称
    selected: Object // 所有数据的选中状态表
}

注: ECharts 2.x 中用户开关图例对应的事件从 pieselected 改为 pieselectchanged

events.pieunselected

ACTION: pieUnSelect;series-pie 中饼图扇形取消选中后的事件;使用dispatchAction可触发此事件,用户点击不会触发此事件(用户点击事件请使用 pieselectchanged)

{
    type: 'pieunselected',
    seriesId: string // 系列 ID,可以在 option 中传入
    name: name, // 数据名称
    selected: Object // 所有数据的选中状态表
}

events.mapselectchanged

ACTION: mapToggleSelect;series-map 中地图区域切换选中状态的事件;用户点击选中会触发该事件

{
    type: 'mapselectchanged',
    seriesId: string // 系列 ID,可以在 option 中传入
    name: name, // 数据名称
    selected: Object // 所有数据的选中状态表
}

注: 该事件同 ECharts 2 中的 mapSelected 事件相同

events.mapselected

ACTION: mapSelect;series-map 中地图区域选中后的事件;使用dispatchAction可触发此事件,用户点击不会触发此事件(用户点击事件请使用 mapselectchanged)

{
    type: 'mapselected',
    seriesId: string // 系列 ID,可以在 option 中传入
    name: name, // 数据名称
    selected: Object // 所有数据的选中状态表
}

注: ECharts 2.x 中用户开关图例对应的事件从 mapselected 改为 mapselectchanged

events.mapunselected

ACTION: mapUnSelect;series-map 中地图区域取消选中后的事件;使用dispatchAction可触发此事件,用户点击不会触发此事件(用户点击事件请使用 mapselectchanged)

{
    type: 'mapunselected',
    seriesId: string // 系列 ID,可以在 option 中传入
    name: name, // 数据名称
    selected: Object // 所有数据的选中状态表
}

events.axisareaselected

平行坐标轴 (Parallel)范围选取事件;当进行坐标轴范围选取时,可以用如下方式获取当前高亮的线所对应的 data indices (即 series 的 data 中的序号列表)

chart.on('axisareaselected', function () {
    var series0 = chart.getModel().getSeries()[0];
    var series1 = chart.getModel().getSeries()[1];
    var indices0 = series0.getRawIndicesByActiveState('active');
    var indices1 = series1.getRawIndicesByActiveState('active');
    console.log(indices0, indices1);
});

events.focusnodeadjacency

graph的邻接节点高亮事件

events.unfocusnodeadjacency

graph的邻接节点取消高亮事件

events.brush

选框添加事件。即发出 brush action 得到的事件

events.brushselected

对外通知当前选中了什么;这个事件在 setOption 时不会发出,在其他的 dispatchAction 时,或者用户在界面中创建、删除、修改选框时会发出

事件参数内容为:

{
    type: 'brushselected',
    batch: [
        {
            brushId: string, // brush 组件的 id,大多数情况只使用一个 brush 组件,所以不必理会
            brushIndex: number, // brush 组件的 index
            brushName: string, // brush 组件的 name
            areas: [ // 各个选框
                { // 第一个选框;则此处使用 range 或者 coordRange 记录了选框当前的形状,其值参见 brush action 中 range/coordRange 的解释;
                    range: Array.<number>, //如果此选框是“全局选框”(即并不属于哪个坐标系),则使用 range 单位是像素
                    coordRange: Array.<number>, // 如果此选框是“坐标系选框”,则使用 coordRange 和 coordRanges,单位为坐标系单位
                    coordRanges: Array.<Array.<number>>, // 其中,如果选框属于直角坐标系(grid)的某个轴(例如指定了 xAxisIndex: 0),且此轴对应于多个 cartesian(例如,对应两个 yAxis),那么这里 coordRanges是每个 cartesian 中的选框的范围值。而 coordRange 是 coordRanges[0]
                },
                ...
            ],
            selected: [ // 每个系列被选中的项;如果某个系列不支持 brush,但是还是会在这里出现对应的项;也就是说,selected 可以使用 seriesIndex 来直接找到对应的项
                { // series 0 被选中的项
                    seriesIndex: number,
                    dataIndex: [ 3, 6, 12, 23 ] // 用这些 dataIndex,可以去原始数据中找到真正的值
                },
                { // series 1 被选中的项
                    seriesIndex: number,
                    dataIndex: []
                },
                ...
            ]
        },
        ...
    ]
}

事件使用方式例如:

var dataBySeries = [
    [ 12, 23, 54, 6 ], // series 0 的数据
    [ 34, 34433, 2223, 21122, 1232, 34 ] // series 1 的数据
];
chart.setOption({
    ...,
    brush: {
        ...
    },
    series: [
        { // series 0
            data: dataBySeries[0]
        },
        { // series 1
            data: dataBySeries[1]
        }
    ]
});
chart.on('brushSelected', function (params) {
    var brushComponent = params.batch[0];
    var sum = 0; // 统计选中项的数据值的和
    for (var sIdx = 0; sIdx < brushComponent.selected.length; sIdx++) { // 对于每个 series:        
        var dataIndices = brushComponent.selected[sIdx].dataIndex;
        for (var i = 0; i < dataIndices.length; i++) {
            var dataIndex = dataIndices[i];
            sum += dataBySeries[sIdx][dataIndex];
        }
    }
    console.log(sum); // 用某种方式输出统计值。
});

如果想避免此事件频繁触发,可以使用 brush.throttleType

events.globalCursorTaken

参见 takeGlobalCursor

events.rendered

渲染结束事件。注意 rendered 事件并不代表渲染动画(参见 animation 相关配置)或者渐进渲染(参见 progressive 相关配置)停止,只代表本帧的渲染结束

var snapshotImage = new Image();
document.body.append(snapshotImage);
chart.on('rendered', function () {
    snapshotImage.src = chart.getDataURL();
});

events.finished

渲染完成事件。当渲染动画(参见 animation 相关配置)或者渐进渲染(参见 progressive 相关配置)停止时触发

var snapshotImage = new Image();
document.body.append(snapshotImage);
chart.on('finished', function () {
    snapshotImage.src = chart.getDataURL();
});
上一篇:HTML 5中的标记方法


下一篇:小程序框架wepy文档