ECharts教程(未完) ECharts 特性 —————————————————————————————————————————— 5 分钟上手 ECharts 自定义构建 ECharts 在 webpack 中使用 ECharts 个性化图表的样式 ECharts 中的样式简介 异步数据加载和更新 使用 dataset 管理数据 在图表中加入交互组件 移动端自适应————————————————————————搁置 数据的视觉映射———————————————————————搁置 ECharts 中的事件和行为 ——————————————————————————————————-未完待续 经验

  • 兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等)
  • 底层依赖轻量级的矢量图形库 ZRender

丰富的可视化类型

  • 常规的折线图、柱状图、散点图、饼图、K线图
  • 用于统计的盒形图
  • 用于地理数据可视化的地图、热力图、线图
  • 用于关系数据可视化的关系图、treemap、旭日图
  • 多维数据可视化的平行坐标
  • 用于 BI 的漏斗图,仪表盘
  • 并且支持图与图之间的混搭
  • 除了已经内置的包含了丰富功能的图表,ECharts 还提供了自定义系列,只需要传入一个renderItem函数,就可以从数据映射到任何你想要的图形,更棒的是这些都还能和已有的交互组件结合使用而不需要操心其它事情。

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

  • ECharts 内置的 dataset 属性(4.0+)支持直接传入包括二维表,key-value 等多种格式的数据源,通过简单的设置 encode 属性就可以完成从数据到图形的映射
    • ECharts 4 开始支持了 数据集(dataset)组件用于单独的数据集声明,从而数据可以单独管理,被多个组件复用,并且可以*指定数据到视觉的映射。
  • 为了配合大数据量的展现,ECharts 还支持输入 TypedArray 格式的数据
    • TypedArray 对象没有实际的对象和构造函数,是个一类对象的统称,描述一个底层的二进制数据缓存区的一个类似数组视图
    • TypedArray包括 Int8Array、Uint8Array、Uint8ClampedArray、Int16Array、Uint16Array、Int32Array、Uint32Array、Float32Array、Float64Array
    • TypedArray 在大数据量的存储中可以占用更少的内存
    • 对 GC(垃圾回收) 友好
    • 参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypedArray

千万数据的前端展现

  • 通过增量渲染技术(4.0+),配合各种细致的优化,ECharts 能够展现千万级的数据量
  • ECharts 同时提供了对流加载(4.0+)的支持,你可以使用 WebSocket 或者对数据分块后加载,加载多少渲染多少
    • WebSocket 全双功

移动端优化

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

多渲染方案,跨平台使用

  • 支持以 Canvas、SVG(4.0+)、VML 的形式渲染图表
    • VML 可以兼容低版本 IE:Vector Markup Language(VML)是一种XML语言用于绘制矢量图形(由微软提出,但被W3C拒绝成为标准矢量图形语言)
    • SVG 使得移动端不再为内存担忧
    • Canvas 可以轻松应对大数据量和特效的展现
  • ECharts 还能在 node 上配合 node-canvas 进行高效的服务端渲染(SSR)
  • 从 4.0 开始我们还和微信小程序的团队合作,提供了 ECharts 对小程序的适配
  • 除了JS的其他语言也支持使用

深度的交互式数据探索

  • 总览为先,缩放、过滤、按需查看细节是数据可视化交互的基本需求
  • 提供了图例、视觉映射、数据区域缩放、tooltip、数据刷选等开箱即用的交互组件 ?

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

  • 加入了平行坐标等常见的多维数据可视化工具
    • series-parallel:每一行是一个『数据项』,每一列属于一个『维度』。例子:https://echarts.baidu.com/option.html#parallelAxis
    • color(调色盘)提供的颜色会在legend(图例组件)及图标中应用
    • legend 图例组件展现了不同系列的标记(symbol),颜色和名字。可以通过点击图例控制哪些系列不显示。
    • parallelAxis[n].nameLocation 设置一列会影响所有列
    • grid(直角坐标系内绘图网格)单个 grid 内最多可以放置上下两个 X 轴,左右两个 Y 轴。可以在网格上绘制折线图,柱状图,散点图(气泡图)
  • 传统的散点图等,传入的数据也可以是多个维度的
    • series[i]-scatter(散点图)
  • 视觉映射组件 visualMap 提供的丰富的视觉编码,能够将不同维度的数据映射到颜色,大小,透明度,明暗度等不同的视觉通道 ?

动态数据

  • ECharts 由数据驱动,数据的改变驱动图表展现的改变(通过setOption更新数据)
  • 只需要获取数据,填入数据,ECharts 会找到两组数据之间的差异然后通过合适的动画去表现数据的变化
  • 配合 timeline 组件能够在更高的时间维度上去表现数据的信息
    • timeline 组件,提供了在多个 ECharts option 间进行切换、播放等操作的功能。

绚丽的特效

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

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

  • 在 VR,大屏场景里实现三维的可视化效果,提供了基于 WebGL 的 ECharts GL
  • 在这基础之上我们还提供了不同层级的画面配置项?

无障碍访问(4.0+)

  • W3C制定了无障碍富互联网应用规范集(WAI-ARIA,the Accessible Rich Internet Applications Suite)
  • ECharts 4.0遵从这一规范,支持自动根据图表配置项智能生成描述

——————————————————————————————————————————

5 分钟上手 ECharts

获取 ECharts

引入 ECharts

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

绘制一个简单的图表

  • 在绘图前我们需要为 ECharts 准备一个具备高宽的 DOM 容器,然后通过 echarts.init 方法初始化一个 echarts 实例并通过 setOption 方法生成一个简单的柱状图
<script src="echarts.min.js"></script>

<body>
    <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
    <div ></div>
    <script type="text/javascript">
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('main'));

        // 指定图表的配置项和数据
        var option = {
            title: { // 标题组件,包含主标题和副标题。
                text: 'ECharts 入门示例' // 主标题文本,支持使用 
 换行。
            },
            tooltip: {}, // 提示框组件。
            legend: { // 图例组件展现了不同系列的标记(symbol),颜色和名字。可以通过点击图例控制哪些系列不显示。图例会根据series的类别显示不同的系列标志
                data:['销量']
            },
            xAxis: {
                data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
            },
            yAxis: {},
            series: [{
                name: '销量',
                type: 'bar',
                data: [5, 20, 36, 10, 10, 20]
            }]
        };

        // 使用刚指定的配置项和数据显示图表。
        myChart.setOption(option);
    </script>
</body>

自定义构建 ECharts

  • 构建好的 echarts,可以直接在浏览器端项目中使用

    • 完全版:echarts/dist/echarts.js,体积最大,包含所有的图表和组件,所包含内容参见:echarts/echarts.all.js。
    • 常用版:echarts/dist/echarts.common.js,体积适中,包含常见的图表和组件,所包含内容参见:echarts/echarts.common.js。
    • 精简版:echarts/dist/echarts.simple.js,体积较小,仅包含最常用的图表和组件,所包含内容参见:echarts/echarts.simple.js
  • 如果对文件体积有更严苛的要求,可以自己构建 echarts,能够仅仅包括自己所需要的图表和组件。

    • 在线自定义构建:https://echarts.baidu.com/builder.html
    • 使用 echarts/build/build.js 脚本自定义构建:比在线构建更灵活一点,并且支持多语言。
    • 直接使用构建工具(如 rollup、webpack、browserify)自己构建

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

npm install echarts --save

import * as echarts from 'echarts';

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

  • 使用node_modules/echarts/build/build.js构建库,需要node环境。不深入
  • node_modules/echarts/build/build.js似乎基于rollup构建工具,需要安装 ?
npm install rollup --save-dev

// 这个插件用于在 `node_module` 文件夹(即 npm 用于管理模块的文件夹)中寻找模块。比如,代码中有`import 'echarts/lib/chart/line';` 时,这个插件能够寻找到`node_module/echarts/lib/chart/line.js` 这个模块文件。
npm install rollup-plugin-node-resolve --save-dev  
npm install rollup-plugin-uglify --save-dev // 用于压缩构建出的代码。

允许被引用的模块

  • 在自定义构建中,允许被引用的模块,全声明在 myProject/node_module/echarts/echarts.all.jsmyProject/node_module/echarts/src/export.js 中(这两个模块似乎声明了不同模块?)
    • myProject/node_module/echarts/echarts.all.js声明大部分为echarts/src下文件
    • myProject/node_module/echarts/src/export.js声明大部分为echarts/src/utilzrender下文件
  • 完整的内容
    • 公共
      • import * as echarts from 'echarts/lib/echarts'; 主模块
    • echarts.all.js中,
      • '/component/dataset';
      • '/chart/line'; 折线图,例子import 'echarts/lib/chart/line';
      • '/chart/bar';
      • '/chart/pie';
      • '/chart/scatter';
      • '/chart/radar';
      • '/chart/map';
      • '/chart/tree';
      • '/chart/treemap';
      • '/chart/graph';
      • '/chart/gauge';
      • '/chart/funnel';
      • '/chart/parallel';
      • '/chart/sankey';
      • '/chart/boxplot';
      • '/chart/candlestick';
      • '/chart/effectScatter';
      • '/chart/lines';
      • '/chart/heatmap';
      • '/chart/pictorialBar';
      • '/chart/themeRiver';
      • '/chart/sunburst';
      • '/chart/custom';
      • '/component/graphic';
      • '/component/grid';
      • '/component/legendScroll'; // 图例组件展现了不同系列的标记(symbol),颜色和名字。可以通过点击图例控制哪些系列不显示。
      • '/component/tooltip'; 提示框组件
      • '/component/axisPointer';
      • '/component/polar';
      • '/component/geo';
      • '/component/parallel';
      • '/component/singleAxis';
      • '/component/brush';
      • '/component/calendar';
      • '/component/title'; 标题组件
      • '/component/dataZoom';
      • '/component/visualMap';
      • '/component/markPoint';
      • '/component/markLine';
      • '/component/markArea';
      • '/component/timeline';
      • '/component/toolbox'; 工具箱组件,内置有导出图片,数据视图,动态类型切换,数据区域缩放,重置五个工具
      • 'zrender/src/vml/vml';
      • 'zrender/src/svg/svg';
    • export.js中
      • 'zrender/src/zrender';
      • 'zrender/src/core/matrix';
      • 'zrender/src/core/vector';
      • 'zrender/src/core/util';
      • 'zrender/src/tool/color';
      • './util/graphic';
      • './util/number';
      • './util/format';
      • import {throttle} from './util/throttle';
      • './helper';
      • './coord/geo/parseGeoJson';
  • echarts 和 zrender 源代码中的其他模块,都是 echarts 的内部模块,不应该去引用。因为在后续 echarts 版本升级中,内部模块的接口和功能可能变化,甚至模块本身也可能被移除。

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

  • 如果直接引用 echarts 里的一些模块并自行构建,应该使用 echarts/lib/** 路径,而不可使用 echarts/src/**
    • 因为历史上,各个 echarts 扩展、各个用户项目,一直是使用的包路径是 echarts/lib/**,所以这个路径不应该改变,否则,可能导致混合使用 echarts/src/**echarts/lib/** 得到两个不同的 echarts 名空间
  • 使用 echarts/src/** 可以获得稍微小一些的文件体积
  • echarts/src/** 中是采用 ES Module 的源代码
  • echarts/lib/** 中是 echarts/src/** 编译成为 CommonJS 后的产物(编译成 CommonJS 是为了向后兼容一些不支持 ES Module 的老版本 NodeJS 和 webpack)

直接使用 rollup 自定义构建

  • rollup 和 webpack 相似,是一种构建工具
// 引入 echarts 主模块。
import * as echarts from 'echarts/lib/echarts';
// 引入折线图。
import 'echarts/lib/chart/line';
// 引入提示框组件、标题组件、工具箱组件。
import 'echarts/lib/component/tooltip';
import 'echarts/lib/component/title';
import 'echarts/lib/component/toolbox';

// 基于准备好的dom,初始化 echarts 实例并绘制图表。
echarts.init(document.getElementById('main')).setOption({
    title: {text: 'Line Chart'},
    tooltip: {}, // 提示框
    toolbox: { // 工具栏。内置有导出图片,数据视图,动态类型切换,数据区域缩放,重置五个工具
        feature: {
            dataView: {}, // 数据视图工具,可以展现当前图表所用的数据
            saveAsImage: { // 保存为图片
                pixelRatio: 2 // 保存图片的分辨率比例,默认跟容器相同大小,如果需要保存更高分辨率的,可以设置为大于 1 的值,例如 2
            },
            restore: {} // 配置项还原。
        }
    },
    xAxis: {}, // 当横轴未传入或绑定类目数据data时,展现为横轴纵轴都为数值的坐标系。传入的维度数据,需要采用长度为2的数组表明X,Y坐标(似乎是line线图的特殊用法)
    yAxis: {},
    series: [{ // 每个series代表一个维度,每个维度表现为一个图例。柱状图比较特殊,会自动处理多个图例之间的关系
        type: 'line',
        // showSymbol:false, // symbol是值线型图例中代表每个数据的空心圆点(可以为其他样式)
        smooth: true, // 是否平滑曲线显示
        data: [[12, 5], [24, 20], [36, 36], [48, 10], [60, 10], [72, 20]]
    }]
});
  • 这样构建的代码如何包含多语言支持?以下为 rollup 的构建配置文件,仅仅只是为了保留ecLangPlugin的使用例子
// 这个插件用于在 `node_module` 文件夹(即 npm 用于管理模块的文件夹)中寻找模块。比如,代码中有
// `import 'echarts/lib/chart/line';` 时,这个插件能够寻找到
// `node_module/echarts/lib/chart/line.js` 这个模块文件。
import nodeResolve from 'rollup-plugin-node-resolve';
// 用于压缩构建出的代码。
import uglify from 'rollup-plugin-uglify';
// 用于多语言支持(如果不需要可忽略此 plugin)。
// import ecLangPlugin from 'echarts/build/rollup-plugin-ec-lang';

export default {
    name: 'myProject',
    // 入口代码文件,就是刚才所创建的文件。
    input: './line.js',
    plugins: [
        nodeResolve(),
        // ecLangPlugin({lang: 'en'}),
        // 消除代码中的 __DEV__ 代码段,从而不在控制台打印错误提示信息。
        uglify()
    ],
    output: {
        // 以 UMD 格式输出,从而能在各种浏览器中加载使用。
        format: 'umd',
        // 输出 source map 便于调试。
        sourcemap: true,
        // 输出文件的路径。
        file: 'lib/line.min.js'
    }
};

多语言支持

  • 本质上,echarts 图表显示出来的文字,都可以通过 option 来定制,改成任意语言
  • 如果想“默认就是某种语言”,则需要通过构建来实现。(需要在webpack中为导入的 echarts 文件添加特殊的处理插件,该插件会在打包时根据传入的参数调用lib下不同的lang文件)
  • 语言文件默认为node_modules/echarts/lib/lang.js

在 webpack 中使用 ECharts

npm 安装 ECharts

引入 ECharts

按需引入 ECharts 图表和组件

  • echarts/lib/chart 包含图表类型
  • echarts/lib/component 包含组件

个性化图表的样式

  • 能够从全局、系列、数据三个层级去设置数据图形的样式。
    • 系列指图标的样式,例如柱状图、扇形图就是2个系列
    • 数据(为data中的数据绑定独立的样式)

绘制南丁格尔图

  • Charts 中的数据项都是既可以只设成数值,也可以设成一个对象,包含有名称、该数据图形的样式配置、标签配置
  • ECharts 中的饼图也支持通过设置 roseType 显示成南丁格尔图
myChart.setOption({
    series : [
        {
            name: '访问来源',
            type: 'pie', // 饼图不需要直角坐标系,多个饼图不能自动合理布局,后者会覆盖前者
            radius: '55%', // 饼图的半径,限制饼图显示的大小
            data:[ // 查看‘绘制一个简单的图表’中的例子,该项是一个数组
                {value:235, name:'视频广告'},
                {value:274, name:'联盟广告'},
                {value:310, name:'邮件营销'},
                {value:335, name:'直接访问'},
                {value:400, name:'搜索引擎'}
            ],
            roseType: 'angle' // 是否展示成南丁格尔图,通过半径区分数据大小。
        }
    ]
})

阴影的配置

  • ECharts 中有一些通用的样式,诸如阴影、透明度、颜色、边框颜色、边框宽度等,这些样式一般都会在系列的 itemStyle 里设置。
  • 例如阴影的样式可以通过下面几个配置项设置:
itemStyle: {
    // 阴影的大小
    shadowBlur: 200,
    // 阴影水平方向上的偏移
    shadowOffsetX: 0,
    // 阴影垂直方向上的偏移
    shadowOffsetY: 0,
    // 阴影颜色
    shadowColor: 'rgba(0, 0, 0, 0.5)'
}
  • itemStyle的emphasis是鼠标 hover 时候的高亮样式。ECharts4的写法已经改变
itemStyle: {
    emphasis: {
        shadowBlur: 200,
        shadowColor: 'rgba(0, 0, 0, 0.5)'
    }
}

深色背景和浅色标签

  • 背景色是全局的,所以直接在 option 下设置 backgroundColor
setOption({
    backgroundColor: '#2c343c'
})
  • 文本的样式可以设置全局的 textStyle。
setOption({
    textStyle: {
        color: 'rgba(255, 255, 255, 0.3)'
    }
})
  • 也可以每个系列分别设置,每个系列的文本设置在 label.textStyle。(API没有这项,但如教程所写可以实现)
// 教程中例子
label: {
    textStyle: {
        color: 'rgba(255, 255, 255, 0.3)'
    }
}

// API中能实现相同效果的方法,两个都能实现该功能
series:[
    {
        label:{
            color: 'rgba(255, 255, 255, 0.3)'
        }
    }
]
  • 饼图的话还要将标签的视觉引导线的颜色设为浅色。
// 系列series中
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 下的数据项实现。
// 系列series中
data: [{
    value:400,
    name:'搜索引擎',
    itemStyle: {
        color: '#c23531'
    }
}, ...]
  • 只有明暗度的变化,所以有一种更快捷的方式是通过 visualMap 组件将数值的大小映射到明暗度。
visualMap: {
    // 不显示 visualMap 组件,只用于明暗度的映射
    show: false,
    // 映射的最小值为 80,明暗范围会依据最小到最大值进行平均分配,然后对应的data获得相应的明暗度
    min: 80,
    // 映射的最大值为 600
    max: 600,
    inRange: { // 数据在图形上映射的表现方式,包括图元的图形类别、图元的大小、图元的颜色、图元的颜色的透明度、图元以及其附属物(如文字标签)的透明度、 颜色的明暗度、 颜色的饱和度、颜色的色调
        // 明暗度的范围是 0 到 1
        colorLightness: [0, 1]
    }
}

ECharts 中的样式简介

  • 同一种细节的效果可能可以用不同的方式实现

颜色主题(Theme)

  • 最简单的更改全局样式的方式,是直接采用颜色主题(theme),新内置了两套主题,分别为 'light' 和 'dark'。
var chart = echarts.init(dom, 'light');

var chart = echarts.init(dom, 'dark');
  • 建立自定义主题https://echarts.baidu.com/theme-builder/
  • 没有内置在 ECharts 中的主题需要自行加载和注册
// 如果主题保存为 JSON 文件
echarts.registerTheme('vintage', JSON.parse(themeJSON)) // import一个json文件,返回一个对象
var chart = echarts.init(dom, 'vintage');

// 如果保存为 UMD 格式的 JS 文件,那么支持了自注册,直接引入 JS 文件即可
var chart = echarts.init(dom, 'vintage');

调色盘

  • 可以在 option 中设置。它给定了一组颜色, 图形、系列会自动从其中选择颜色。
  • 可以设置全局的调色盘,也可以设置系列自己专属的调色盘。(API中缺少这项配置,但可以如例子使用)
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.'
            }
        }
    }
}

通过 visualMap(视觉映射组件) 组件设定样式

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

异步数据加载和更新

异步加载

  • ECharts 中实现异步数据的更新非常简单,在图表初始化后不管任何时候只要通过 jQuery 等工具异步获取数据后通过 setOption 填入数据和配置项就行
  • 或者先设置完其它的样式,显示一个空的直角坐标轴,然后获取数据后填入数据。
var myChart = echarts.init(document.getElementById('main'));
// 显示标题,图例和空的坐标轴
myChart.setOption({
    title: {
        text: '异步数据加载示例'
    },
    tooltip: {},
    legend: { // 根据series[i].name中的值进行分类
        data:['销量']
    },
    xAxis: {
        data: []
    },
    yAxis: {},
    series: [{
        name: '销量',
        type: 'bar',
        data: []
    }]
});

// 异步加载数据
$.get('data.json').done(function (data) {
    // 填入数据
    myChart.setOption({ // setOption会自动合并传入的对象
        xAxis: {
            data: data.categories
        },
        series: [{
            // 根据名字对应到相应的系列
            name: '销量', // 如果
            data: data.data
        }]
    });
});
  • ECharts 中在更新数据的时候需要通过name属性对应到相应的系列,上面示例中如果name不存在也可以根据系列的顺序正常更新,但是更多时候推荐更新数据的时候加上系列的name数据。

loading 动画

  • ECharts 默认有提供了一个简单的加载动画。只需要调用 showLoading 方法显示。数据加载完成后再调用 hideLoading 方法隐藏加载动画。
myChart.showLoading();
$.get('data.json').done(function (data) {
    myChart.hideLoading();
    myChart.setOption(...);
});

数据的动态更新

  • 你只需要定时获取数据,setOption 填入数据,而不用考虑数据到底产生了那些变化,ECharts 会找到两组数据之间的差异然后通过合适的动画去表现数据的变化。

使用 dataset 管理数据

  • 数据可以单独管理,被多个组件复用,并且可以基于数据指定数据到视觉的映射。这在不少场景下能带来使用上的方便。
    • 能够贴近这样的数据可视化常见思维方式:基于数据(dataset 组件来提供数据),指定数据到视觉的映射(由 encode 属性来指定映射),形成图表。
    • 数据和其他配置可以被分离开来,使用者相对便于进行单独管理,也省去了一些数据处理的步骤。
    • 数据可以被多个系列或者组件复用,对于大数据,不必为每个系列创建一份。
    • 支持更多的数据的常用格式,例如二维数组、对象数组等,一定程度上避免使用者为了数据格式而进行转换。

入门例子

option = {
    legend: {}, // 图例组件不设置值的话是不会显示的
    tooltip: {},
    dataset: {
        // 提供一份数据。
        source: [
            // 第一行为维度,第一列为横轴
            ['product', '2015', '2016', '2017'], // 相对于name,用于图例组件、提示框组件。第一个值为横轴名,该行似乎没有意义 // X 坐标轴声明为类目轴,默认情况下会自动对应到 dataset.source 中的第一列;可以通过series.encode修改
            ['Matcha Latte', 43.3, 85.8, 93.7], // 三个柱图系列,一一对应到 dataset.source 中后面每一列。
            ['Milk Tea', 83.1, 73.4, 55.1],
            ['Cheese Cocoa', 86.4, 65.2, 82.5],
            ['Walnut Brownie', 72.4, 53.9, 39.1]
        ]
    },
    // 声明一个 X 轴,类目轴(category)。默认情况下,类目轴对应到 dataset 第一列。(不包括product)
    xAxis: {type: 'category'}, // 第一维度会被作为横轴
    // 声明一个 Y 轴,数值轴。
    yAxis: {},
    // 声明多个 bar 系列,默认情况下,每个系列会自动对应到 dataset 的每一列。
    series: [
        {type: 'bar'},
        {type: 'bar'},
        {type: 'bar'}
    ]
}
  • 也可以使用常见的对象数组的格式:
option = {
    legend: {},
    tooltip: {},
    dataset: {
        // 这里指定了维度名的顺序,从而可以利用默认的维度到坐标轴的映射。
        // 如果不指定 dimensions,也可以通过指定 series.encode 完成映射,参见后文。
        dimensions: ['product', '2015', '2016', '2017'], // 第一个值默认为横轴名的对应值,横轴根据xAxis、yAxis的type来决定,例子中xAxis为横轴
        source: [
            {product: 'Matcha Latte', '2015': 43.3, '2016': 85.8, '2017': 93.7},
            {product: 'Milk Tea', '2015': 83.1, '2016': 73.4, '2017': 55.1},
            {product: 'Cheese Cocoa', '2015': 86.4, '2016': 65.2, '2017': 82.5},
            {product: 'Walnut Brownie', '2015': 72.4, '2016': 53.9, '2017': 39.1}
        ]
    },
    xAxis: {type: 'category'},
    yAxis: {},
    series: [
        {type: 'bar'},
        {type: 'bar'},
        {type: 'bar'}
    ]
};

数据到图形的映射

  • 指定 dataset 的列(column)还是行(row)映射为图形系列(series)。这件事可以使用 series.seriesLayoutBy 属性来配置。默认是按照列(column)来映射。
      let option = {
          legend: {},
          tooltip: {},
          dataset: {
              source: [
                ['ccc','Matcha Latte','Milk Tea','Cheese Cocoa','Walnut Brownie'],  // 和上上个例子刚好相反,第一行是横轴。第一列为维度
                ['2015',43.3,83.1,86.4,72.4],
                ['2016',85.8,73.4,65.2,53.9],
                ['2017',93.7,55.1,82.5,39.1],
              ]
          },
          xAxis: {type: 'category'},
          yAxis: {},
          series: [
              {type: 'bar',seriesLayoutBy:'row'},
              {type: 'bar',seriesLayoutBy:'row'},
              {type: 'bar',seriesLayoutBy:'row'}
          ]
      }
  • 指定维度映射的规则:可以使用 series.encode 属性,以及 visualMap 组件(如果有需要映射颜色大小等视觉维度的话)来配置。
    • series.encode 设置在XY轴以及组件中映射哪些维度

按行还是按列做映射

option = {
    legend: {},
    tooltip: {},
    dataset: { // 一组数据映射到两个图例中,他们会共用legend图例组件
        source: [
            ['product', '2012', '2013', '2014', '2015'],
            ['Matcha Latte', 41.1, 30.4, 65.1, 53.3],
            ['Milk Tea', 86.5, 92.1, 85.7, 83.1],
            ['Cheese Cocoa', 24.1, 67.2, 79.5, 86.4]
        ]
    },
    xAxis: [
        {type: 'category', gridIndex: 0},
        {type: 'category', gridIndex: 1} // 和yAxis共同决定了有几个坐标系
    ],
    yAxis: [ // 当只有一个坐标系时传入对象,否则会报错
        {gridIndex: 0}, // y 轴所在的 grid 的索引,默认位于第一个 grid。
        {gridIndex: 1}
    ],
    grid: [ // 一个canvas中多个图例的方法
        {bottom: '55%'}, // 第一个图例的位置
        {top: '55%'} // 第2个
    ],
    series: [
        // 这几个系列会在第一个直角坐标系中,每个系列对应到 dataset 的每一行。
        {type: 'bar', seriesLayoutBy: 'row'}, // seriesLayoutBy: 'row'当前图表以dataset.source的第一行为横坐标
        {type: 'bar', seriesLayoutBy: 'row'},
        {type: 'bar', seriesLayoutBy: 'row'},
        // 这几个系列会在第二个直角坐标系中,每个系列对应到 dataset 的每一列。
        {type: 'bar', xAxisIndex: 1, yAxisIndex: 1}, // xAxisIndex 使用的 x 轴的 index,在单个图表实例中存在多个 x 轴的时候有用。
        {type: 'bar', xAxisIndex: 1, yAxisIndex: 1}, // yAxisIndex 使用的 y 轴的 index,在单个图表实例中存在多个 y轴的时候有用。
        {type: 'bar', xAxisIndex: 1, yAxisIndex: 1},
        {type: 'bar', xAxisIndex: 1, yAxisIndex: 1}
    ]
}

维度(dimension)

  • 常用图表所描述的数据大部分是“二维表”结构,上述的例子中,我们都使用二维数组来容纳二维表。现在,当我们把系列(series)对应到“列”的时候,那么每一列就称为一个“维度(dimension)”,而每一行称为数据项(item)

  • dataset.source 中第一行(列)到底包含不包含维度名,ECharts 默认会自动探测。上例中的‘product’(seriesLayoutBy为默认值时)

  • 可以设置 dataset.sourceHeader: true 显示声明第一行(列)就是维度,或者 dataset.sourceHeader: false 表明第一行(列)开始就直接是数据。

  • 维度的定义,也可以使用单独的 dataset.dimensions 或者 series.dimensions 来定义,这样可以同时指定维度名,和维度的类型(dimension type)

    • dataset中单独设置了dimensions后,dataset.source不一定要传入对象数组,也可以传入二维数组。能够自动一一对应,不再会自动从 dataset.source 的第一行/列中获取维度信息。
    • 传入的dataset.source依然可以包含维度,这时第一列会被自动忽略
    • 维度表现为图例的重叠绘制,如果是坐标系中的同一种类型的图例,会按照合理的方式分布。例如:柱状图会横轴中并列显示(可以设置重叠)
    • 需要为每个维度的数据指定图例类型
  • 大多数情况下,我们并不需要去设置维度类型,因为会自动判断。但是如果因为数据为空之类原因导致判断不足够准确时,可以手动设置维度类型。

    • 'number': 默认,表示普通数据。
    • 'ordinal': 对于类目、文本这些 string 类型的数据,如果需要能在数轴上使用,须是 'ordinal' 类型。ECharts 默认会自动判断这个类型。但是自动判断也是不可能很完备的,所以使用者也可以手动强制指定。
    • 'time': 表示时间数据。设置成 'time' 则能支持自动解析数据成时间戳(timestamp),比如该维度的数据是 '2017-05-10',会自动被解析。如果这个维度被用在时间数轴(axis.type 为 'time')上,那么会被自动设置为 'time' 类型。时间类型的支持参见 data。
    • 'float': 如果设置成 'float',在存储时候会使用 TypedArray,对性能优化有好处。
    • 'int': 如果设置成 'int',在存储时候会使用 TypedArray,对性能优化有好处。
      let option = {
        legend: {},
        tooltip: {},
        dataset: {
          source: [
            ['Matcha Latte', 41.1, 30.4, 65.1, 53.3],
            ['Milk Tea', 86.5, 92.1, 85.7, 83.1],
            ['Cheese Cocoa', 24.1, 67.2, 79.5, 86.4]
          ],
          dimensions: [
            'ccc',
            {name: '2012'},
            {name: '2013',type: 'float'},
            null,
            {name: 'product'}
          ]
        },
        xAxis: {
          type: 'category',
          // data:[] // 使用dataset映射数据后不能设置独立的横坐标,会导致数据无法正确绑定
        },
        yAxis: {},
        series: [
          {type: 'bar'},
          {type: 'bar'},
          {type: 'bar'},
          {type: 'bar'},
        ]
      }



      let option = {
        legend: {},
        tooltip: {},
        dataset: {
          source: [
            ['Matcha Latte', 41.1, 30.4, 65.1, 53.3],
            ['Milk Tea', 86.5, 92.1, 85.7, 83.1],
            ['Cheese Cocoa', 24.1, 67.2, 79.5, 86.4]
          ],
        },
        xAxis: {
          type: 'category',
          // data:[]
        },
        yAxis: {},
        series: [
          {
            type: 'bar',
            dimensions: [ // 在series[i].dimensions中所有系列的维度名需要保持一致顺序,并且每个系列都需要单独配置(似乎没有意义,不如直接配置dataset.dimensions更便捷)?
              'ccc',
              {name: '2012'},
              {name: '2013',type: 'float'},
              null,
              {name: '2014'}
            ]
          },
          {
            type: 'bar',
            dimensions: [
              'ccc',
              {name: '2012'},
              {name: '2013',type: 'float'},
              null,
              {name: '2014'}
            ]
          },
          {
            type: 'bar',
            dimensions: [
              'ccc',
              {name: '2012'},
              {name: '2013',type: 'float'},
              null,
              {name: '2014'}
            ]
          },
          {
            type: 'bar',
            dimensions: [
              'ccc',
              {name: '2012'},
              {name: '2013',type: 'float'},
              null,
              {name: '2014'}
            ]
          },
        ]
      }

数据到图形的映射(encode)

  • encode 声明的基本结构如下,其中冒号左边是坐标系、标签等特定名称,如 'x', 'y', 'tooltip' 等,冒号右边是数据中的维度名(string 格式)或者维度的序号(number 格式,从 0 开始计数),可以指定一个或多个维度(使用数组)。
var option = {
    dataset: {
        source: [
            ['score', 'amount', 'product'],
            [89.3, 58212, 'Matcha Latte'],
            [57.1, 78254, 'Milk Tea'],
            [74.4, 41032, 'Cheese Cocoa'],
            [50.1, 12755, 'Cheese Brownie'],
            [89.7, 20145, 'Matcha Cocoa'],
            [68.1, 79146, 'Tea'],
            [19.6, 91852, 'Orange Juice'],
            [10.6, 101852, 'Lemon Juice'],
            [32.7, 20112, 'Walnut Brownie']
        ]
    },
    xAxis: {},
    yAxis: {type: 'category'},
    series: [
        {
            type: 'bar',
            encode: {
                // 将 "amount" 列映射到 X 轴。
                x: 'amount',
                // 将 "product" 列映射到 Y 轴。
                y: 'product'
            }
        }
    ]
};
  • 下面是 encode 支持的属性(不同坐标轴不同)
// 在任何坐标系和系列中,都支持:
encode: {
    // 使用 “名为 product 的维度” 和 “名为 score 的维度” 的值在 tooltip 中显示
    tooltip: ['product', 'score']
    // 使用 “维度 1” 和 “维度 3” 的维度名连起来作为系列名。(有时候名字比较长,这可以避免在 series.name 重复输入这些名字)(维度是由0开始计起的,这里的3显示为空)
    seriesName: [1, 3],
    // 表示使用 “维度2” 中的值作为 id。这在使用 setOption 动态更新数据时有用处,可以使新老数据用 id 对应起来,从而能够产生合适的数据更新动画。
    itemId: 2,
    // 指定数据项的名称使用 “维度3” 在饼图等图表中有用,可以使这个名字显示在图例(legend)中。(饼图的标签名)
    itemName: 3
}

// 直角坐标系(grid/cartesian)特有的属性:
encode: {
    // 把 “维度1”、“维度5”、“名为 score 的维度” 映射到 X 轴:(似乎没有意义,设置多值只会显示维度序号靠后的值)
    x: [1, 5, 'score'],
    // 把“维度0”映射到 Y 轴。
    y: 0
}

// 单轴(singleAxis)特有的属性:(未详究)
encode: {
    single: 3
}

// 极坐标系(polar)特有的属性:(未详究)
encode: {
    radius: 3,
    angle: 2
}

// 地理坐标系(geo)特有的属性:(未详究)
encode: {
    lng: 3,
    lat: 2
}

// 对于一些没有坐标系的图表,例如饼图、漏斗图等,可以是:(设置x也是可行的)
encode: {
    value: 3
}
  • 用法示例
      let option = {
        tooltip: {}, // 默认只有横轴标题和对应值
        dataset: {
          source: [
            ['score', 'amount', 'product'],
            [89.3, 58.212, 'Matcha Latte'],
            [57.1, 78.254, 'Milk Tea'],
            [74.4, 41.032, 'Cheese Cocoa'],
            [50.1, 12.755, 'Cheese Brownie'],
            [89.7, 20.145, 'Matcha Cocoa'],
            [68.1, 79.146, 'Tea'],
            [19.6, 91.852, 'Orange Juice'],
            [10.6, 10.1852, 'Lemon Juice'],
            [32.7, 20.112, 'Walnut Brownie']
          ]
        },
        xAxis: {},
        yAxis: { type: 'category' },
        series: [
          {
            type: 'bar',
            encode: { // 1、传入数据,2、确定维度,3、确定X轴和Y轴类型,4、映射数据的轴上。(类目轴也是一样的,X轴为某个类时对应显示在X轴对应位置)
              tooltip: [0, 1], // 提示框内容,默认为横轴标题和对应值(类目坐标时,数值坐标则显示为空)。设置后横轴标题依然保留,下面对应各项出现列表
              seriesName: [1], // 系列名,位于横轴标题和数值上方,该series全部显示同一个
              // 将 "amount" 列映射到 X 轴。
              x: [1],
              // 将 "product" 列映射到 Y 轴。
              y: 2
            }
          },
          {
            type: 'bar',
            encode: {
              tooltip: [0, 1],
              seriesName: [0],
              // 将 "amount" 列映射到 X 轴。
              x: [0],
              // 将 "product" 列映射到 Y 轴。
              y: 2
            }
          }
        ]
      };

视觉通道(颜色、尺寸等)的映射

默认的映射

  • 指的一提的是,ECharts 针对最常见直角坐标系中的图表(折线图、柱状图、散点图、K线图等)、饼图、漏斗图,给出了简单的默认的映射,从而不需要配置 encode 也可以出现图表(一旦给出了 encode,那么就不会采用默认映射)。
  • 在坐标系中(如直角坐标系、极坐标系等)
    • 如果有类目轴(axis.type 为 'category'),则将第一列(行)映射到这个轴上,后续每一列(行)对应一个系列。
    • 如果没有类目轴,假如坐标系有两个轴(例如直角坐标系的 X Y 轴),则每两列对应一个系列,这两列分别映射到这两个轴上。
  • 如果没有坐标系(如饼图)
    • 取第一列(行)为名字,第二列(行)为数值(如果只有一列,则取第一列为数值)。只能自动判断一个维度

几个常见的映射设置方式

问:如何把第三行设置为 X 轴,第五行设置为 Y 轴?

      let option = {
        legend: {},
        tooltip: {},
        dataset: {
          source: [
            ['ccc', 'Matcha Latte', 'Milk Tea', 'Cheese Cocoa', 'Walnut Brownie'],  // 和上上个例子刚好相反,第一行是横轴。第一列为维度
            ['2015', 43.3, 83.1, 86.4, 72.4],
            ['2016', 85.8, 73.4, 65.2, 53.9],
            ['2017', 93.7, 55.1, 82.5, 39.1],
          ]
        },
        xAxis: { type: 'category' },
        yAxis: {},
        series: [
          { type: 'bar', seriesLayoutBy: 'row', encode: { x: 0, y: 1 } }, // seriesLayoutBy: 'row'可以认为按行绑定数据,默认按列
          { type: 'bar', seriesLayoutBy: 'row', encode: { x: 0, y: 2 } },
          { type: 'bar', seriesLayoutBy: 'row', encode: { x: 0, y: 3 } }
        ]
      }

问:如何把第二列设置为标签?

  • 答: 关于标签的显示 label.formatter,现在支持引用特定维度的值,例如:
series: {
    label: {
        // `'{@score}'` 表示 “名为 score” 的维度里的值。
        // `'{@[4]}'` 表示引用序号为 4 的维度里的值。
        formatter: 'aaa{@product}bbb{@score}ccc{@[4]}ddd' // 受seriesLayoutBy: 'row'影响
    }
}

数据的各种格式

  • 广为使用的数据表格软件(如 MS Excel、Numbers)或者关系数据数据库都是二维表。他们的数据可以导出成 JSON 格式,输入到 dataset.source 中,在不少情况下可以免去一些数据处理的步骤。
  • 除了二维数组以外,dataset 也支持例如下面 key-value 方式的数据格式,这类格式也非常常见。但是这类格式中,目前并不支持 seriesLayoutBy 参数。
    • seriesLayoutBy 用于设置维度取行还是列(见过往例子)
dataset: [{ // 这里使用数组,很特别,见下文
    // 按行的 key-value 形式(对象数组),这是个比较常见的格式。
    dimensions: ['product', 'count', 'score'],
    source: [
        {product: 'Matcha Latte', count: 823, score: 95.8}, // 需要配合dimensions定义维度名
        {product: 'Milk Tea', count: 235, score: 81.4},
        {product: 'Cheese Cocoa', count: 1042, score: 91.2},
        {product: 'Walnut Brownie', count: 988, score: 76.9}
    ]
}, {
    // 按列的 key-value 形式。
    dimensions: ['product', 'count', 'score'],
    source: {
        'product': ['Matcha Latte', 'Milk Tea', 'Cheese Cocoa', 'Walnut Brownie'],  // 需要配合dimensions定义维度名
        'count': [823, 235, 1042, 988],
        'score': [95.8, 81.4, 91.2, 76.9]
    }
}]

多个 dataset 和他们的引用

  • 可以同时定义多个 dataset。系列可以通过 series.datasetIndex 来指定引用哪个 dataset。
var option = {
    dataset: [{
        // 序号为 0 的 dataset。
        source: [...],
    }, {
        // 序号为 1 的 dataset。
        source: [...]
    }, {
        // 序号为 2 的 dataset。
        source: [...]
    }],
    series: [{
        // 使用序号为 2 的 dataset。
        datasetIndex: 2
    }, {
        // 使用序号为 1 的 dataset。
        datasetIndex: 1
    }]
}

ECharts 3 的数据设置方式(series.data)仍正常使用

  • ECharts 4 之前一直以来的数据声明方式仍然被正常支持,如果系列已经声明了 series.data, 那么就会使用 series.data 而非 dataset。
  • 一些特殊的非 table 格式的图表,如 treemap、graph、lines 等,现在仍不支持在 dataset 中设置,仍然需要使用 series.data。(lines和line是不同的,lines是用于带有起点和终点信息的线数据的绘制,主要用于地图上的航线,路线的可视化。)
  • 对于巨大数据量的渲染(如百万以上的数据量),需要使用 appendData 进行增量加载,这种情况不支持使用 dataset。

其他

  • 支持 dataset 的图表有: line、bar、pie、scatter、effectScatter、parallel、candlestick、map、funnel、custom。
    option = {
        legend: {},
        tooltip: {
            trigger: 'axis', // 提示框触发方式,坐标轴hover触发
            showContent: false, // 只用于触发updateAxisPointer事件,不显示
            //formatter(){ // 可以返回dom节点
            //    let html = '<br>这里可以把字符串转为dom节点<br>'
            //    return htm.
            //}
        },
        dataset: {
            source: [
                ['product', '2012', '2013', '2014', '2015', '2016', '2017'],
                ['Matcha Latte', 41.1, 30.4, 65.1, 53.3, 83.8, 98.7],
                ['Milk Tea', 86.5, 92.1, 85.7, 83.1, 73.4, 55.1],
                ['Cheese Cocoa', 24.1, 67.2, 79.5, 86.4, 65.2, 82.5],
                ['Walnut Brownie', 55.2, 67.1, 69.2, 72.4, 53.9, 39.1]
            ]
        },
        xAxis: {type: 'category'},
        yAxis: {gridIndex: 0},
        grid: {top: '55%'}, // 直角坐标系内绘图网格,单个 grid 内最多可以放置上下两个 X 轴,左右两个 Y 轴。可以在网格上绘制折线图,柱状图,散点图(气泡图)。pie饼图不受这个控制
        series: [
            {type: 'line', smooth: true, seriesLayoutBy: 'row'},
            {type: 'line', smooth: true, seriesLayoutBy: 'row'},
            {type: 'line', smooth: true, seriesLayoutBy: 'row'},
            {type: 'line', smooth: true, seriesLayoutBy: 'row'},
            {
                type: 'pie',
                id: 'pie', // 唯一标识便于事件修改数据
                radius: '30%',
                center: ['50%', '25%'],
                label: {
                    formatter: '{b}: {@2012} ({d}%)'
                },
                encode: {
                    itemName: 'product',
                    value: '2012',
                    tooltip: '2012'
                }
            }
        ]
    };

    myChart.on('updateAxisPointer', function (event) {
        var xAxisInfo = event.axesInfo[0]; // 返回触发updateAxisPointer的横轴项
        if (xAxisInfo) {
            var dimension = xAxisInfo.value + 1; // dataset.source比横轴项多了一列维度名称,所以需要+1
            myChart.setOption({
                series: {
                    id: 'pie',
                    label: {
                        formatter: '{b}: {@[' + dimension + ']} ({d}%)' // 传入的并非模板,而是静态文本,需要每次事件重新传递否则值不会被改变
                    },
                    encode: {
                        value: dimension,
                        // tooltip: dimension
                    }
                }
            });
        }
    });

    myChart.setOption(option);

在图表中加入交互组件

  • 图例组件 legend、标题组件 title、视觉映射组件 visualMap、数据区域缩放组件 dataZoom、时间线组件 timeline

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

  • dataZoom 组件是对 数轴(axis) 进行『数据窗口缩放』『数据窗口平移』操作。
    • 通过 dataZoom.xAxisIndex 或 dataZoom.yAxisIndex 来指定 dataZoom 控制哪个或哪些数轴。
  • dataZoom 组件可同时存在多个,起到共同控制的作用。控制同一个数轴的组件,会自动联动。
  • dataZoom 的运行原理是通过『数据过滤』
    • 数据过滤模式的设置不同,效果也不同,参见:dataZoom.filterMode。
  • dataZoom 的数据窗口范围的设置,目前支持两种形式:
    • 百分比形式:参见 dataZoom.start 和 dataZoom.end。
    • 绝对数值形式:参见 dataZoom.startValue 和 dataZoom.endValue。
  • dataZoom 组件现在支持几种子组件:
    • 内置型数据区域缩放组件(dataZoomInside):内置于坐标系中。
    • 滑动条型数据区域缩放组件(dataZoomSlider):有单独的滑动条操作
    • 框选型数据区域缩放组件(dataZoomSelect):全屏的选框进行数据区域缩放。入口和配置项均在 toolbox中。

在代码加入 dataZoom 组件

option = {
    xAxis: {
        type: 'value'
    },
    yAxis: {
        type: 'value',
        // formatter(data){ return data + 'px' } // 可以通过设置formatter时坐标保持数值型,但是显示的值是类目轴
    },
    dataZoom: [
        {   // 这个dataZoom组件,默认控制x轴。
            type: 'slider', // 这个 dataZoom 组件是 slider 型 dataZoom 组件
            start: 10,      // 左边在 10% 的位置。(初始位置,距离左边全长10%)
            end: 60         // 右边在 60% 的位置。(初始位置,距离左边全长60%)
            20        // 20px 在API中没有列出这项,height也一样
        }
    ],
    series: [
        {
            type: 'scatter', // 这是个『散点图』
            itemStyle: {
                opacity: 0.8
            },
            symbolSize: function (val) {
                return val[2] * 40;
            },
            data: [["14.616","7.241","0.896"],["3.958","5.701","0.955"],["2.768","8.971","0.669"],["9.051","9.710","0.171"],["14.046","4.182","0.536"],["12.295","1.429","0.962"],["4.417","8.167","0.113"],["0.492","4.771","0.785"],["7.632","2.605","0.645"],["14.242","5.042","0.368"]]
        }
    ]
}
  • 果想在坐标系内进行拖动,以及用滚轮(或移动触屏上的两指滑动)进行缩放,那么要再加上一个 inside 型的 dataZoom组件。
    • 初始化开始和结束位置由第一个组件参数决定
option = {
    ...,
    dataZoom: [
        {   // 这个dataZoom组件,默认控制x轴。
            type: 'slider', // 这个 dataZoom 组件是 slider 型 dataZoom 组件
            start: 10,      // 左边在 10% 的位置。
            end: 60         // 右边在 60% 的位置。
        },
        {   // 这个dataZoom组件,也控制x轴。
            type: 'inside', // 这个 dataZoom 组件是 inside 型 dataZoom 组件
            start: 10,      // 左边在 10% 的位置。
            end: 60         // 右边在 60% 的位置。
        }
    ],
    ...
}
  • 如果想 y 轴也能够缩放,那么在 y 轴上也加上 dataZoom 组件
option = {
    ...,
    dataZoom: [
        {
            type: 'slider',
            xAxisIndex: 0,
            start: 10,
            end: 60
        },
        {
            type: 'inside',
            xAxisIndex: 0,
            start: 10,
            end: 60
        },
        {
            type: 'slider',
            yAxisIndex: 0,
            start: 30,
            end: 80
        },
        {
            type: 'inside',
            yAxisIndex: 0,
            start: 30,
            end: 80
        }
    ],
    ...
}

移动端自适应————————————————————————搁置

数据的视觉映射———————————————————————搁置

ECharts 中的事件和行为

  • ECharts 3 中,事件名称对应 DOM 事件名称,均为小写的字符串,如下是一个绑定点击操作的示例。
myChart.on('click', function (params) {
    // 控制台打印数据的名称
    console.log(params.name);
});
  • 在 ECharts 中事件分为两种类型
    • 一种是用户鼠标操作点击,或者 hover 图表的图形时触发的事件
    • 还有一种是用户在使用可以交互的组件后触发的行为事件
      • 在切换图例开关时触发的 'legendselectchanged' 事件
      • 切换图例开关是不会触发'legendselected'事件的
      • 数据区域缩放时触发的 'datazoom' 事件

鼠标事件的处理

  • 所有的鼠标事件包含参数 params,这是一个包含点击图形的数据信息的对象,如下格式:
{
    // 当前点击的图形元素所属的组件名称,
    // 其值如 'series'、'markLine'(标识线,例如股票中的划线)、'markPoint'(提示标签,例如股票中的最高点和最低点标注)、'timeLine' 等。
    componentType: string,
    // 系列类型。值可能为:'line'、'bar'、'pie' 等。当 componentType 为 'series' 时有意义。
    seriesType: string,
    // 系列在传入的 option.series 中的 index。当 componentType 为 'series' 时有意义。(没传的话根据series数组序列来)
    seriesIndex: number,
    // 系列名称。当 componentType 为 'series' 时有意义。(传入的series[i].name值)
    seriesName: string,
    // 数据名,类目名(横轴名)
    name: string,
    // 数据在传入的 data 数组中的 index
    dataIndex: number,
    // 传入的原始数据项
    data: Object,
    // sankey、graph 等图表同时含有 nodeData 和 edgeData 两种 data,
    // dataType 的值会是 'node' 或者 'edge',表示当前点击在 node 还是 edge 上。
    // 其他大部分图表中只有一种 data,dataType 无意义。
    dataType: string,
    // 传入的数据值
    value: number|Array
    // 数据图形的颜色。当 componentType 为 'series' 时有意义。
    color: string
}
  • 使用 query 只对指定的组件的图形元素的触发回调:可为 string 或者 Object
  • 如果为 string 表示组件类型。格式可以是 'mainType' 或者 'mainType.subType'。
chart.on('click', 'series', function () {...}); // 指定图例才触发(图例包括了'markPoint'提示标签)
chart.on('click', 'series.line', function () {...}); // 只有line这种特定图例才触发
chart.on('click', 'dataZoom', function () {...});
chart.on('click', 'xAxis.category', function () {...}); // 只有类目类X轴才触发
  • 如果为 Object,可以包含以下一个或多个属性,每个属性都是可选的:
{
    <mainType>seriesIndex: number // 组件 index
    <mainType>seriesName: string // 组件 name
    <mainType>Id: string // 组件 id
    dataIndex: number // 数据项 index
    name: string // 数据项data数组中每一项的 name 属性
    dataType: string // 数据项 type,如关系图中的 'node'(节点), 'edge'(边)
    element: string // 自定义系列中的 el 的 name
}
  • 例子:element: string // 自定义系列中的 el 的 name
chart.setOption({
    // ...
    series: {
        // ...
        type: 'custom', // 自定义
        renderItem: function (params, api) { // custom 系列需要开发者自己提供图形渲染的逻辑。这个渲染逻辑一般命名为 renderItem。
            return {
                type: 'group', // group 是唯一的可以有子节点的容器。group 可以用来整体定位一组图形元素。
                children: [{
                    type: 'circle',
                    name: 'my_el',
                    // ...
                }, {
                    // ...
                }]
            }
        },
        data: [[12, 33]]
    }
})
chart.on('mouseup', {element: 'my_el'}, function () {
    // name 为 'my_el' 的元素被 'mouseup' 时,此方法被回调。
});
  • 可以在回调函数中更新图表本身(setOption)

组件交互的行为事件

  • 在 ECharts 中基本上所有的组件交互行为都会触发相应的事件,常用的事件和事件对应参数在 events 文档中有列出。https://echarts.baidu.com/api.html#events

代码触发 ECharts 中组件的行为

  • 在 ECharts 3 里改为通过调用 myChart.dispatchAction({ type: '' }) 触发图表行为,统一管理了所有动作,也可以方便地根据需要去记录用户的行为路径。
  • 常用的动作和动作对应参数在 action 文档中有列出。https://echarts.baidu.com/api.html#action

——————————————————————————————————-未完待续

经验

  • 在图例中绑定鼠标事件,使空白区域点击也能触发图标点击功能
      chartItem.getZr().on('click', params => {
        const pointInPixel = [params.offsetX, params.offsetY];
        if (chartItem.containPixel({ seriesIndex: 0 }, pointInPixel)) {
          let index = chartItem.convertFromPixel({ seriesIndex: 0 }, pointInPixel)[1]
          let name = this.polar.yAxis.data[index]
          this.chartClick({ name })
        }
      })