ECharts事件处理与旭日图实现
事件处理
ECharts 中我们可以通过监听用户的操作行为来回调对应的函数。
ECharts 通过 on 方法来监听用户的行为,例如监控用户的点击行为。
ECharts 中事件分为两种类型:
用户鼠标操作点击,如 'click'、'dblclick'、'mousedown'、'mousemove'、'mouseup'、'mouseover'、'mouseout'、'globalout'、'contextmenu' 事件。
还有一种是用户在使用可以交互的组件后触发的行为事件,例如在切换图例开关时触发的 'legendselectchanged' 事件),数据区域缩放时触发的 'datazoom' 事件等等。
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); });
一、鼠标事件
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) { alert(params.name); });
1、所有的鼠标事件包含参数 params,这是一个包含点击图形的数据信息的对象,格式如下:
{ // 当前点击的图形元素所属的组件名称, // 其值如 'series'、'markLine'、'markPoint'、'timeLine' 等。 componentType: string, // 系列类型。值可能为:'line'、'bar'、'pie' 等。当 componentType 为 'series' 时有意义。 seriesType: string, // 系列在传入的 option.series 中的 index。当 componentType 为 'series' 时有意义。 seriesIndex: number, // 系列名称。当 componentType 为 'series' 时有意义。 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 }
2、如何区分鼠标点击到了哪里:
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(节点)上。 } } } });
3、使用 query 只对指定的组件的图形元素的触发回调:
chart.on(eventName, query, handler);
query 可为 string 或者 Object。
(1)如果为 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 () {...});
(2)如果为 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' 时,此方法被回调。 });
4、你可以在回调函数中获得这个对象中的数据名、系列名称后在自己的数据仓库中索引得到其它的信息候更新图表,显示浮层等等,如下示例代码:
myChart.on('click', function (parmas) { $.get('detail?q=' + params.name, function (detail) { myChart.setOption({ series: [{ name: 'pie', // 通过饼图表现单个柱子中的数据分布 data: [detail.data] }] }); }); });
二、组件交互的行为事件
在 ECharts 中基本上所有的组件交互行为都会触发相应的事件,常用的事件和事件对应参数在 events 文档中有列出。
下面是监听一个图例开关的示例:
// 图例开关的行为只会触发 legendselectchanged 事件 myChart.on('legendselectchanged', function (params) { // 获取点击图例的选中状态 var isSelected = params.selected[params.name]; // 在控制台中打印 console.log((isSelected ? '选中了' : '取消选中了') + '图例' + params.name); // 打印所有图例的状态 console.log(params.selected); });
三、代码触发 ECharts 中组件的行为
上面我们只说明了用户的交互操作,但有时候我们也会需要在程序里调用方法并触发图表的行为,比如显示 tooltip。
ECharts 通过 dispatchAction({ type: '' }) 来触发图表行为,统一管理了所有动作,也可以根据需要去记录用户的行为路径。
以上实例用于轮播饼图中的 tooltip:
setInterval(function () { var dataLen = option.series[0].data.length; // 取消之前高亮的图形 myChart.dispatchAction({ type: 'downplay', seriesIndex: 0, dataIndex: app.currentIndex }); app.currentIndex = (app.currentIndex + 1) % dataLen; // 高亮当前图形 myChart.dispatchAction({ type: 'highlight', seriesIndex: 0, dataIndex: app.currentIndex }); // 显示 tooltip myChart.dispatchAction({ type: 'showTip', seriesIndex: 0, dataIndex: app.currentIndex }); }, 1000);
旭日图
旭日图(Sunburst)由多层的环形图组成,在数据结构上,内圈是外圈的父节点。因此,它既能像饼图一样表现局部和整体的占比,又能像矩形树图一样表现层级关系。
ECharts 创建旭日图很简单,只需要在 series 配置项中声明类型为 sunburst 即可,data 数据结构以树形结构声明,看下一个简单的实例:
var option = { series: { type: 'sunburst', data: [{ name: 'A', value: 10, children: [{ value: 3, name: 'Aa' }, { value: 5, name: 'Ab' }] }, { name: 'B', children: [{ name: 'Ba', value: 4 }, { name: 'Bb', value: 2 }] }, { name: 'C', value: 3 }] } };
一、颜色等样式调整
默认情况下会使用全局调色盘 color 分配最内层的颜色,其余层则与其父元素同色。
在旭日图中,扇形块的颜色有以下三种设置方式:
- 在 series.data.itemStyle 中设置每个扇形块的样式。
- 在 series.levels.itemStyle 中设置每一层的样式。
- 在 series.itemStyle 中设置整个旭日图的样式。
上述三者的优先级是从高到低的,也就是说,配置了 series.data.itemStyle 的扇形块将会覆盖 series.levels.itemStyle 和 series.itemStyle 的设置。
下面,我们将整体的颜色设为灰色 #aaa,将最内层的颜色设为蓝色 blue,将 Aa、B 这两块设为红色 red。
var option = { series: { type: 'sunburst', data: [{ name: 'A', value: 10, children: [{ value: 3, name: 'Aa', itemStyle: { color: 'red' } }, { value: 5, name: 'Ab' }] }, { name: 'B', children: [{ name: 'Ba', value: 4 }, { name: 'Bb', value: 2 }], itemStyle: { color: 'red' } }, { name: 'C', value: 3 }], itemStyle: { color: '#aaa' }, levels: [{ // 留给数据下钻的节点属性 }, { itemStyle: { color: 'blue' } }] } };
按层配置样式是一个很常用的功能,能够很大程度上提高配置的效率。
二、数据下钻
旭日图默认支持数据下钻,也就是说,当点击了扇形块之后,将以该扇形块的数据作为根节点,进一步显示该数据的细节。
在数据下钻后,图形的中间会出现一个用于返回上一层的图形,该图形的样式可以通过 levels[0] 配置。
var data = [{ name: 'Grandpa', children: [{ name: 'Uncle Leo', value: 15, children: [{ name: 'Cousin Jack', value: 2 }, { name: 'Cousin Mary', value: 5, children: [{ name: 'Jackson', value: 2 }] }, { name: 'Cousin Ben', value: 4 }] }, { name: 'Father', value: 10, children: [{ name: 'Me', value: 5 }, { name: 'Brother Peter', value: 1 }] }] }, { name: 'Nancy', children: [{ name: 'Uncle Nike', children: [{ name: 'Cousin Betty', value: 1 }, { name: 'Cousin Jenny', value: 2 }] }] }]; option = { series: { type: 'sunburst', // highlightPolicy: 'ancestor', data: data, radius: [0, '90%'], label: { rotate: 'radial' } } };
如果不需要数据下钻功能,可以通过将 nodeClick 设置为 false 来关闭,也可以设为 'link',并将 data.link 设为点击扇形块对应打开的链接。
三、高亮相关扇形块
旭日图支持鼠标移动到某扇形块时,高亮相关数据块的操作,可以通过设置 highlightPolicy,包括以下几种高亮方式:
- 'descendant'(默认值):高亮鼠标移动所在扇形块与其后代元素;
- 'ancestor':高亮鼠标所在扇形块与其祖先元素;
- 'self':仅高亮鼠标所在扇形块;
- 'none':不会淡化(downplay)其他元素。
上面提到的"高亮",对于鼠标所在的扇形块,会使用 emphasis 样式;对于其他相关扇形块,则会使用 highlight 样式。通过这种方式,可以很方便地实现突出显示相关数据的需求。
具体来说,对于配置项:
itemStyle: { color: 'yellow', borderWidth: 2, emphasis: { color: 'red' }, highlight: { color: 'orange' }, downplay: { color: '#ccc' } }
highlightPolicy 为 'descendant':
option = { silent: true, series: { radius: ['15%', '95%'], center: ['50%', '60%'], type: 'sunburst', sort: null, highlightPolicy: 'descendant', data: [{ value: 10, children: [{ name: 'target', value: 4, children: [{ value: 2, children: [{ value: 1 }] }, { value: 1 }, { value: 0.5 }] }, { value: 2 }] }, { value: 4, children: [{ children: [{ value: 2 }] }] }], label: { normal: { rotate: 'none', color: '#fff' } }, levels: [], itemStyle: { color: 'yellow', borderWidth: 2 }, emphasis: { itemStyle: { color: 'red' } }, highlight: { itemStyle: { color: 'orange' } }, downplay: { itemStyle: { color: '#ccc' } } } }; setTimeout(function () { myChart.dispatchAction({ type: 'sunburstHighlight', targetNodeId: 'target' }); });
highlightPolicy 为 'ancestor' :
option = { silent: true, series: { radius: ['15%', '95%'], center: ['50%', '60%'], type: 'sunburst', sort: null, highlightPolicy: 'ancestor', data: [{ value: 10, children: [{ value: 4, children: [{ value: 2, children: [{ name: 'target', value: 1 }] }, { value: 1 }, { value: 0.5 }] }, { value: 2 }] }, { value: 4, children: [{ children: [{ value: 2 }] }] }], label: { normal: { rotate: 'none', color: '#fff' } }, levels: [], itemStyle: { color: 'yellow', borderWidth: 2 }, emphasis: { itemStyle: { color: 'red' } }, highlight: { itemStyle: { color: 'orange' } }, downplay: { itemStyle: { color: '#ccc' } } } }; setTimeout(function () { myChart.dispatchAction({ type: 'sunburstHighlight', targetNodeId: 'target' }); });
到此这篇关于ECharts事件处理与实现旭日图的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。