echarts 基础入门(上)https://developer.aliyun.com/article/1513293?spm=a2c6h.13148508.setting.14.f8774f0euyBLtl
4. 数据转换
“数据转换” 指给定一个“数据集”(dataset)和一个“转换方法”(transform),echarts 生成一个新的“数据集”,然后使用这个新的“数据集”绘制图表。
4.1 数据转换基础使用
例子:三个饼图分别显示了 2011、2012、2013 年的数据。
var option = { dataset: [ { // 这个 dataset 的 index 是 `0`。 source: [ ["Product", "Sales", "Price", "Year"], ["Cake", 123, 32, 2011], ["Cereal", 231, 14, 2011], ["Tofu", 235, 5, 2011], ["Dumpling", 341, 25, 2011], ["Biscuit", 122, 29, 2011], ["Cake", 143, 30, 2012], ["Cereal", 201, 19, 2012], ["Tofu", 255, 7, 2012], ["Dumpling", 241, 27, 2012], ["Biscuit", 102, 34, 2012], ["Cake", 153, 28, 2013], ["Cereal", 181, 21, 2013], ["Tofu", 395, 4, 2013], ["Dumpling", 281, 31, 2013], ["Biscuit", 92, 39, 2013], ["Cake", 223, 29, 2014], ["Cereal", 211, 17, 2014], ["Tofu", 345, 3, 2014], ["Dumpling", 211, 35, 2014], ["Biscuit", 72, 24, 2014], ], // id: 'a' }, { // 这个 dataset 的 index 是 `1`。 // 这个 `transform` 配置,表示,此 dataset 的数据,来自于此 transform 的结果。 transform: { type: "filter", config: { dimension: "Year", value: 2011 }, }, // 我们还可以设置这些可选的属性: `fromDatasetIndex` 或 `fromDatasetId`。 // 这些属性,指定了,transform 的输入,来自于哪个 dataset。例如, // `fromDatasetIndex: 0` 表示输入来自于 index 为 `0` 的 dataset 。又例如, // `fromDatasetId: 'a'` 表示输入来自于 `id: 'a'` 的 dataset。 // 当这些属性都不指定时,默认认为,输入来自于 index 为 `0` 的 dataset 。 }, { // 这个 dataset 的 index 是 `2`。 // 同样,这里因为 `fromDatasetIndex` 和 `fromDatasetId` 都没有被指定, // 那么输入默认来自于 index 为 `0` 的 dataset 。 transform: { // 这个类型为 "filter" 的 transform 能够遍历并筛选出满足条件的数据项。 type: "filter", // 每个 transform 如果需要有配置参数的话,都须配置在 `config` 里。 // 在这个 "filter" transform 中,`config` 用于指定筛选条件。 // 下面这个筛选条件是:选出维度( dimension )'Year' 中值为 2012 的所有 // 数据项。 config: { dimension: "Year", value: 2012 }, }, }, { // 这个 dataset 的 index 是 `3`。 transform: { type: "filter", config: { dimension: "Year", value: 2013 }, }, }, ], series: [ { type: "pie", radius: 50, center: ["25%", "50%"], // 这个饼图系列,引用了 index 为 `1` 的 dataset 。也就是,引用了上述 // 2011 年那个 "filter" transform 的结果。 datasetIndex: 1, }, { type: "pie", radius: 50, center: ["50%", "50%"], datasetIndex: 2, }, { type: "pie", radius: 50, center: ["75%", "50%"], datasetIndex: 3, }, ], };
4.2 数据转换的进阶使用
transform 可以被链式声明,这是一个语法糖。
var option = { dataset: [ { source: [ // 原始数据 ], }, { // 几个 transform 被声明成 array ,他们构成了一个链, // 前一个 transform 的输出是后一个 transform 的输入。 transform: [ { type: "filter", config: { dimension: "Product", value: "Tofu" }, }, { type: "sort", config: { dimension: "Year", order: "desc" }, }, ], }, ], series: { type: "pie", // 这个系列引用上述 transform 的结果。 datasetIndex: 1, }, };
使用 transform 时,可以通过 transform.print: true 打印结果,方便 debug 。这个配置项只在开发环境中生效。
var option = { dataset: [ { source: [], }, { transform: { type: "filter", config: {}, // 配置为 `true` 后, transform 的结果 // 会被 console.log 打印出来。 print: true, }, }, ], // ... };
4.3 数据转换器 "filter"
config.dimension 指定了维度:可以指定维度名或维度 index。
关系操作符:>(gt)、>=(gte)、<(lt)、<=(lte)、=(eq)、!=(ne、<>)、reg。
var option = { dataset: [ { source: [ ["Product", "Sales", "Price", "Year"], ["Cake", 123, 32, 2011], ["Latte", 231, 14, 2011], ["Tofu", 235, 5, 2011], ["Milk Tee", 341, 25, 2011], ["Porridge", 122, 29, 2011], ["Cake", 143, 30, 2012], ["Latte", 201, 19, 2012], ["Tofu", 255, 7, 2012], ["Milk Tee", 241, 27, 2012], ["Porridge", 102, 34, 2012], ["Cake", 153, 28, 2013], ["Latte", 181, 21, 2013], ["Tofu", 395, 4, 2013], ["Milk Tee", 281, 31, 2013], ["Porridge", 92, 39, 2013], ["Cake", 223, 29, 2014], ["Latte", 211, 17, 2014], ["Tofu", 345, 3, 2014], ["Milk Tee", 211, 35, 2014], ["Porridge", 72, 24, 2014], ], }, { transform: { type: "filter", config: { dimension: "Year", "=": 2011 }, // 这个筛选条件表示,遍历数据,筛选出维度( dimension ) // 'Year' 上值为 2011 的所有数据项。 }, }, ], series: { type: "pie", datasetIndex: 1, }, };
也支持逻辑比较操作符,与或非( and | or | not ):
var option = { dataset: [ { source: [ // ... ], }, { transform: { type: "filter", config: { // 使用 and 操作符。 // 类似地,同样的位置也可以使用 “or” 或 “not”。 // 但是注意 “not” 后应该跟一个 {...} 而非 [...] 。 and: [ { dimension: "Year", "=": 2011 }, { dimension: "Price", ">=": 20, "<": 30 }, ], }, // 这个表达的是,选出 2011 年价格大于等于 20 但小于 30 的数据项。 }, }, ], series: { type: "pie", datasetIndex: 1, }, };
and/or/not 自然可以被嵌套,例如:
transform: { type: 'filter', config: { or: [{ and: [{ dimension: 'Price', '>=': 10, '<': 20 }, { dimension: 'Sales', '<': 100 }, { not: { dimension: 'Product', '=': 'Tofu' } }] }, { and: [{ dimension: 'Price', '>=': 10, '<': 20 }, { dimension: 'Sales', '<': 100 }, { not: { dimension: 'Product', '=': 'Cake' } }] }] } }
4.4 数据转换器 "sort"
"sort" 是另一个内置的数据转换器,用于排序数据。目前主要能用于在类目轴( axis.type: 'category' )中显示排过序的数据。例如:
var option = { dataset: [ { dimensions: ["name", "age", "profession", "score", "date"], source: [ [" Hannah Krause ", 41, "Engineer", 314, "2011-02-12"], ["Zhao Qian ", 20, "Teacher", 351, "2011-03-01"], [" Jasmin Krause ", 52, "Musician", 287, "2011-02-14"], ["Li Lei", 37, "Teacher", 219, "2011-02-18"], [" Karle Neumann ", 25, "Engineer", 253, "2011-04-02"], [" Adrian Groß", 19, "Teacher", null, "2011-01-16"], ["Mia Neumann", 71, "Engineer", 165, "2011-03-19"], [" Böhm Fuchs", 36, "Musician", 318, "2011-02-24"], ["Han Meimei ", 67, "Engineer", 366, "2011-03-12"], ], }, { transform: { type: "sort", // 按分数排序 config: { dimension: "score", order: "asc" }, print: true, }, }, ], xAxis: { type: "category" }, yAxis: {}, series: [ { type: "bar", datasetIndex: 1, encode: { x: "name", y: "score", }, }, ], // ... };
5. 坐标轴
5.1 x 轴、y 轴
x 轴和 y 轴都由轴线、刻度、刻度标签、轴标题四个部分组成。
普通的二维数据坐标系都有 x 轴和 y 轴,通常情况下,x 轴显示在图表的底部,y 轴显示在左侧,一般配置如下:
var option = { xAxis: { // ... }, yAxis: { // ... }, };
当 x 轴(水平坐标轴)跨度很大,可以使用 dataZoom 区域缩放的方式,灵活显示数据内容。
var option = { xAxis: { type: "time", name: "销售时间", // ... }, yAxis: { type: "value", name: "销售数量", // ... }, dataZoom: [ // ... ], // ... };
在二维数据中,轴可以有多个。ECharts 中一般情况下单个 grid 组件最多只能放两个 x/y 轴,多于两个 x/y 轴需通过配置 offset 属性防止同个位置多个轴的重叠。两个 x 轴显示在上下,两个 y 轴显示在左右两侧。
var option = { xAxis: { type: "time", name: "销售时间", // ... }, yAxis: [ { type: "value", name: "销售数量", // ... }, { type: "value", name: "销售金额", // ... }, ], // ... };
5.2 轴线
使用 axisLine 修改相关的配置,例如轴线两端的箭头,轴线的样式等。
var option = { xAxis: { axisLine: { symbol: "arrow", lineStyle: { type: "dashed", // ... }, }, // ... }, yAxis: { axisLine: { symbol: "arrow", lineStyle: { type: "dashed", // ... }, }, }, // ... };
5.3 刻度
使用 axisTick 修改相关的配置,例如刻度线的长度,样式等。
var option = { xAxis: { axisTick: { length: 6, lineStyle: { type: "dashed", // ... }, }, // ... }, yAxis: { axisTick: { length: 6, lineStyle: { type: "dashed", // ... }, }, }, // ... };
5.4 刻度标签
使用 axisLabel 修改相关的配置,例如文字对齐方式,自定义刻度标签内容等。
var option = { xAxis: { axisLabel: { formatter: "{value} kg", align: "center", // ... }, // ... }, yAxis: { axisLabel: { formatter: "{value} 元", align: "center", // ... }, }, // ... };
5.5 示例
左侧的 y 轴代表月平均气温,右侧的 y 轴表示降水量,x 轴表示时间。两组 y 轴在一起,反映了平均气温和降水量间的趋势关系。
var option = { tooltip: { trigger: "axis", axisPointer: { type: "cross" }, }, legend: {}, xAxis: [ { type: "category", axisTick: { alignWithLabel: true, }, data: [ "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", ], }, ], yAxis: [ { type: "value", name: "降水量", min: 0, max: 250, position: "right", axisLabel: { formatter: "{value} ml", }, }, { type: "value", name: "温度", min: 0, max: 25, position: "left", axisLabel: { formatter: "{value} °C", }, }, ], series: [ { name: "降水量", type: "bar", yAxisIndex: 0, data: [6, 32, 70, 86, 68.7, 100.7, 125.6, 112.2, 78.7, 48.8, 36.0, 19.3], }, { name: "温度", type: "line", smooth: true, yAxisIndex: 1, data: [ 6.0, 10.2, 10.3, 11.5, 10.3, 13.2, 14.3, 16.4, 18.0, 16.5, 12.0, 5.2, ], }, ], };
6. 图例
通过 legend 设置图例,点击图例可以显示或隐藏该图例对应数据列。
6.1 布局
通过 orient,top,rgiht,left,bottom 设置图例位置。
var option = { legend: { // Try 'horizontal' orient: "vertical", right: 10, top: "center", }, dataset: { source: [ ["product", "2015", "2016", "2017"], ["Matcha Latte", 43.3, 85.8, 93.7], ["Milk Tea", 83.1, 73.4, 55.1], ["Cheese Cocoa", 86.4, 65.2, 82.5], ["Walnut Brownie", 72.4, 53.9, 39.1], ], }, xAxis: { type: "category" }, yAxis: {}, series: [{ type: "bar" }, { type: "bar" }, { type: "bar" }], };
当图例较多时,设置 legend.type: 'scroll' 使用可滚动翻页的图例
var option = { legend: { type: "scroll", orient: "vertical", right: 10, top: 20, bottom: 20, data: ["图例一", "图例二", "图例三" /* ... */, , "图例n"], // ... }, // ... };
6.2 样式
var option = { legend: { data: ["图例一", "图例二", "图例三"], backgroundColor: "#ccc", textStyle: { color: "#ccc", // ... }, // ... }, // ... };
6.3 交互
根据场景需要,图例可支持交互操作,点击控制显示或隐藏对应的数据列;
var option = { legend: { data: ["图例一", "图例二", "图例三"], selected: { 图例一: true, 图例二: true, 图例三: false, }, // ... }, // ... };
7. 事件与行为
ECharts 中的事件名称对应 DOM 事件名称,均为小写的字符串,如下是一个绑定点击操作的示例。
myChart.on("click", function (params) { // 控制台打印数据的名称 console.log(params.name); });
7.1 鼠标事件的处理
ECharts 支持常规的鼠标事件类型,包括 'click'、 'dblclick'、 'mousedown'、 'mousemove'、 'mouseup'、 'mouseover'、 'mouseout'、 'globalout'、 'contextmenu' 事件。例子:点击柱状图后打开相应的百度搜索页面的示例。
// 基于准备好的dom,初始化ECharts实例 // var myChart = echarts.init(document.getElementById('main')); // 指定图表的配置项和数据 var option = { xAxis: { data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"], }, yAxis: {}, series: [ { name: "销量", type: "bar", data: [5, 20, 36, 10, 10, 20], }, ], }; // 使用刚指定的配置项和数据显示图表。 myChart.setOption(option); // 处理点击事件并且跳转到相应的百度搜索页面 myChart.on("click", function (params) { window.open("https://www.baidu.com/s?wd=" + encodeURIComponent(params.name)); });
如何区分鼠标点击到了哪里:
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(节点)上。 } } } });
7.2 组件交互的行为事件
监听图例开关的示例:
// 图例开关的行为只会触发 legendselectchanged 事件 myChart.on("legendselectchanged", function (params) { // 获取点击图例的选中状态 var isSelected = params.selected[params.name]; // 在控制台中打印 console.log((isSelected ? "选中了" : "取消选中了") + "图例" + params.name); // 打印所有图例的状态 console.log(params.selected); });
通过 dispatchAction 去轮流高亮饼图的每个扇形。
var option = { title: { text: "饼图程序调用高亮示例", left: "center", }, tooltip: { trigger: "item", formatter: "{a} <br/>{b} : {c} ({d}%)", }, legend: { orient: "vertical", left: "left", data: ["直接访问", "邮件营销", "联盟广告", "视频广告", "搜索引擎"], }, series: [ { name: "访问来源", type: "pie", radius: "55%", center: ["50%", "60%"], data: [ { value: 335, name: "直接访问" }, { value: 310, name: "邮件营销" }, { value: 234, name: "联盟广告" }, { value: 135, name: "视频广告" }, { value: 1548, name: "搜索引擎" }, ], emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: "rgba(0, 0, 0, 0.5)", }, }, }, ], }; let currentIndex = -1; setInterval(function () { var dataLen = option.series[0].data.length; // 取消之前高亮的图形 myChart.dispatchAction({ type: "downplay", seriesIndex: 0, dataIndex: currentIndex, }); currentIndex = (currentIndex + 1) % dataLen; // 高亮当前图形 myChart.dispatchAction({ type: "highlight", seriesIndex: 0, dataIndex: currentIndex, }); // 显示 tooltip myChart.dispatchAction({ type: "showTip", seriesIndex: 0, dataIndex: currentIndex, }); }, 1000);
7.3 监听 “空白处” 的事件
zrender 事件:当鼠标在任何地方都会被触发
echarts 事件:当鼠标在图形元素上时才能被触发。
myChart.getZr().on("click", function (event) { // 该监听器正在监听一个`zrender 事件`。 }); myChart.on("click", function (event) { // 该监听器正在监听一个`echarts 事件`。 });
有了 zrender 事件,我们就可以实现监听空白处的事件,如下:
myChart.getZr().on("click", function (event) { // 没有 target 意味着鼠标/指针不在任何一个图形元素上,它是从“空白处”触发的。 if (!event.target) { // 点击在了空白处,做些什么。 } });
三:基础配置项
大部分 echarts 样式,布局都可以通过配置项解决,可以自行参考详细的配置项,echarts 配置项,本文档只作常用配置介绍。
1. xAxis x 轴 | yAxis y 轴
直角坐标系中的 x 轴,y 轴,两个选项的配置一模一样。
var option = { xAxis: { type: "category", // 轴类型:'value' 数值轴,适用于连续数据 | 'category' 类目轴,适用于离散的类目数据 | 'time' 时间轴,适用于连续的时序数据 | 'log' 对数轴。适用于对数数据。 data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"], // 类目数据,在类目轴(type: 'category')中有效。 show: true, // 是否显示:默认 true position: "bottom", // x 轴的位置:'top' | 'bottom' name: "x 轴的名字", // 轴名称 nameLocation: "center", // 轴名称显示位置 'start' | 'middle' 或者 'center' | 'end' nameGap: 15, // 轴名称与轴线之间的距离 nameRotate: 30, // 轴名字旋转,角度值 axisLine: { // 轴线配置 show: true, lineStyle: {}, // 轴线样式设置 }, axisTick: { // 轴刻度配置 show: true, alignWithLabel: false, // 刻度线和标签是否对齐 inside: true, // 轴刻度是否朝内 length: 5, // 轴刻度长度 lineStyle: {}, // 轴刻度样式设置 }, axisLabel: { // 刻度标签 show: true, interval: "auto", // 刻度标签间隔显示:0 强制全显示 | 1 间隔一个刻度标签显示 | 2 间隔两个刻度标签显示 inside: false, // 刻度标签是否朝内 rotate: 30, // 刻度标签旋转的角度 }, splitLine: { // 区域中的分隔线 show: true, }, }, yAxis: {}, series: [ { name: "销量", type: "bar", data: [5, 20, 36, 10, 10, 20], }, ], };
2. series 系列列表
每个系列通过 type 决定自己的图表类型。
var option = { series: [ { type: "line", // 折线/面积图 }, { type: "bar", // 柱状图 }, { type: "pie", // 饼图 }, { type: "scatter", // 散点(气泡)图 }, { type: "effectScatter", // 带有涟漪特效动画的散点(气泡)图 }, { type: "radar", // 雷达图 }, { type: "tree", // 树图 }, { type: "sunburst", // 旭日图 }, { type: "candlestick", // K线图 }, { type: "heatmap", // 热力图 }, { type: "map", // 地图 }, { type: "parallel", // 平行坐标系 }, { type: "lines", // 路径图 }, { type: "graph", // 关系图 }, { type: "sankey", // 桑基图 }, { type: "funnel", // 漏斗图 }, { type: "gauge", // 仪表盘 }, { type: "pictorialBar", // 象形柱图 }, { type: "themeRiver", // 主题河流 }, { type: "custom", // 自定义系列 }, ], };
3. title 标题组件
包含主标题和副标题
var option = { xAxis: { data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"], }, yAxis: {}, series: [ { name: "销量", type: "bar", data: [5, 20, 36, 10, 10, 20], }, ], title: { // 主标题和副标题 show: true, // 是否显示 text: "主标题", // 主标题文本,支持使用 \n 换行 link: "http://www.baidu.com", // 主标题文本超链接 target: "blank", // 打开主标题超链接。方式:'self' 当前窗口打开 | 'blank' 新窗口打开 subtext: "副标题", // 副标题文本,支持使用 \n 换行 sublink: "http://wwww.4399.com", // 副标题文本超链接 subtarget: "blank", // 打开副标题超链接 'self' 当前窗口打开 | 'blank' 新窗口打开 }, };
4. legend 图例组件
展示不同系列的图例,系列必须设置有 name 属性,可以通过点击控制系列的显示和隐藏。
var option = { xAxis: { data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"], }, yAxis: {}, series: [ { name: "销量", type: "bar", data: [5, 20, 36, 10, 10, 20], }, ], legend: { type: "plain", // 图例的类型:'plain' 普通图例 | 'scroll' 可滚动图例 left: "auto", // 图例距离容器左侧距离 top: "auto", // 图例距离容器左侧距离 right: "auto", // 图例距离容器左侧距离 bottom: "auto", // 图例距离容器左侧距离 itemGap: 10, // 图例间距 formatter: function (name) { // 格式化图例文本 return "Legend" + name; }, selectedMode: true, // 图例选择模式:true | false | 'single' | 'multiple' icon: "circle", // 图例项 icon:'circle' | 'rect' | 'roundRect' | 'triangle' | 'diamond' | 'pin' | 'arrow' | 'none' }, };
5. tooltip 提示框
提示框可以在很多地方设置,可以设置全局的 tooltip、坐标系中 grid.tooltip、系列中 series.tooltip、系列每个数据项中 series.data.tooltip
字符串模板变量有 {a},{b},{c},{d},{e} 分别表示系列名、数据名、数据值等。当有多系列时可以通过{a0}, {a1}, {a2}等。
不同图表类型下的 {a},{b},{c},{d} 含义不一样。 其中变量{a}, {b}, {c}, {d}在不同图表类型下代表数据含义为:
折线(区域)图、柱状(条形)图、K 线图 : {a}(系列名称),{b}(类目值),{c}(数值), {d}(无)
散点图(气泡)图 : {a}(系列名称),{b}(数据名称),{c}(数值数组), {d}(无)
地图 : {a}(系列名称),{b}(区域名称),{c}(合并数值), {d}(无)
饼图、仪表盘、漏斗图: {a}(系列名称),{b}(数据项名称),{c}(数值), {d}(百分比)
var option = { xAxis: { data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"] }, yAxis: {}, series: [ { name: "销量", type: "bar", data: [5, 20, 36, 10, 10, 20], }, ], tooltip: { position: [10, 10], // 提示框位置:相对于容器左侧 10px, 上侧 10 px formatter: "{a0}<br />{b0}: {c0}", // 提示框浮层内容格式器,支持字符串模板和回调函数 }, };
6. grid 绘图网格
直角坐标系内绘图网格,可以通过该配置设置网格的位置和大小
var option = { xAxis: { data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"], }, yAxis: {}, series: [ { name: "销量", type: "bar", data: [5, 20, 36, 10, 10, 20], }, ], grid: { top: "10%", // grid 组件离容器上侧的距离 left: "20%", // grid 组件离容器左侧的距离 width: "400px", // grid 组件的宽度,默认自适应 }, };
7. toolbox 工具栏
内置有导出图片,数据视图,动态类型切换,数据区域缩放,重置五个工具。
var option = { xAxis: { data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"] }, yAxis: {}, series: [ { name: "销量", type: "bar", data: [5, 20, 36, 10, 10, 20], }, ], toolbox: { show: true, feature: { // 各工具配置项。除了各个内置的工具按钮外,还可以自定义工具按钮。 dataZoom: { // 数据区域缩放。目前只支持直角坐标系的缩放。 yAxisIndex: "none", }, dataView: { readOnly: false }, // 数据视图工具,可以展现当前图表所用的数据,编辑后可以动态更新。 magicType: { type: ["line", "bar"] }, // 动态类型切换 restore: {}, // 配置项还原 saveAsImage: {}, // 保存为图片 }, }, };