echarts实现自动轮播tooltip
最近需要实现echarts图形中hover效果轮播(即tooltip在各个数据点上轮流显示)的功能,以下就是我学习的一个过程,只是提供思路,具体场景需要自己修改。(仅针对echarts 2.2.7及以下版本,最后的代码有3.0以上的使用方法以及插件代码链接)
源码:https://github.com/chengwubin/echarts-tooltip-auto-show
关于echarts大家可以查看官网文档。
文档中有这么一段话:
自2.1.8起,我们为echarts开发了专门的合并压缩工具echarts-optimizer。如你所发现的,build文件夹下已经包含了由echarts-optimizer生成的单文件:
- dist(文件夹) : 经过合并、压缩的单文件
- echarts.js : 这是包含AMD加载器的echarts主文件,需要通过script最先引入
- chart(文件夹) : echarts-optimizer通过依赖关系分析同时去除与echarts.js的重复模块后为echarts的每一个图表类型单独打包生成一个独立文件,根据应用需求可实现图表类型按需加载
- line.js : 折线图(如需折柱动态类型切换,require时还需要echarts/chart/bar)
- bar.js : 柱形图(如需折柱动态类型切换,require时还需要echarts/chart/line)
- scatter.js : 散点图
- k.js : K线图
- pie.js : 饼图(如需饼漏斗图动态类型切换,require时还需要echarts/chart/funnel)
- radar.js : 雷达图
- map.js : 地图
- force.js : 力导向布局图(如需力导和弦动态类型切换,require时还需要echarts/chart/chord)
- chord.js : 和弦图(如需力导和弦动态类型切换,require时还需要echarts/chart/force)
- funnel.js : 漏斗图(如需饼漏斗图动态类型切换,require时还需要echarts/chart/pie)
- gauge.js : 仪表盘
- eventRiver.js : 事件河流图
- treemap.js : 矩阵树图
- venn.js : 韦恩图
- source(文件夹) : 经过合并,但并没有压缩的单文件,内容同dist,可用于调试
要的就是source文件下面的文件,可以调试,把source下面的echarts-all.js导入自己的工程,在找一个例子就可以运行看效果了。
- <div id="chart" style="width: 800px; height: 500px;">
- </div>
- <span id="hover-console"></span>
- <span id="console"></span>
- <script src="./js/echarts-all.js"></script>
- <script type="text/javascript">
- // 基于准备好的dom,初始化echarts图表
- var myChart = echarts.init(document.getElementById('chart'));
- console.log(myChart);
- var option = {
- tooltip: {
- show: true
- },
- legend: {
- data:['销量']
- },
- xAxis : [
- {
- type : 'category',
- data : ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
- }
- ],
- yAxis : [
- {
- type : 'value'
- }
- ],
- series : [
- {
- "name":"销量",
- "type":"bar",
- "data":[5, 20, 40, 10, 10, 20]
- }
- ]
- };
- // 为echarts对象加载数据
- myChart.setOption(option);
- var ecConfig = echarts.config;
- function eConsole(param) {
- var mes = '【' + param.type + '】';
- if (typeof param.seriesIndex != 'undefined') {
- mes += ' seriesIndex : ' + param.seriesIndex;
- mes += ' dataIndex : ' + param.dataIndex;
- }
- if (param.type == 'hover') {
- document.getElementById('hover-console').innerHTML = 'Event Console : ' + mes;
- }
- else {
- document.getElementById('console').innerHTML = mes;
- }
- }
- function eHover(param) {
- var mes = '【' + param.type + '】';
- if (typeof param.seriesIndex != 'undefined') {
- mes += ' seriesIndex : ' + param.seriesIndex;
- mes += ' dataIndex : ' + param.dataIndex;
- }
- document.getElementById('hover-console').innerHTML = 'Event Console : ' + mes;
- }
- myChart.on(ecConfig.EVENT.HOVER, eHover);
- </script>
先说一下大概思路,由于是canvas上面绘图,所以界面上没有对应的dom元素,所以没法用js中的事件来控制。
我们要触发事件,就需要先得到图上面的数据元素,然后再考虑怎么触发事件。
稍微看一下源码,就发现里面经常出现zrender,所以要先弄清楚zrender做什么的,查看zrender资料。
看了zrender的介绍,大概知道是用来处理canvas的绘画的,同时还封装了dom的事件(模拟)。
了解了zrender之后还是继续调试看源码,echarts-all.js文件太大,不太方便,可以下载zrender的源码查看对应的代码文件。
最开始我是想从例子中的hover事件入手,进行调试查看,最后查看到实际是mousemove事件触发的,然后发现zrender中有个storage。
查看了一下storage:
- /**
- * 内容仓库 (M)
- * @alias module:zrender/Storage
- * @constructor
- */
- var Storage = function () {
- // 所有常规形状,id索引的map
- this._elements = {};
- this._roots = [];
- this._displayList = [];
- this._displayListLen = 0;
- };
是不是发现了新大陆!!!_elements,对,我们要的就是它。
但是怎么得到呢,后面在echarts中找到了getZrender(),添加代码:
- var zrender = myChart.getZrender();
- var elements = zrender.storage._elements;
- console.log(elements);
运行后可以在console中看见elements的内容:
确实是我们想要的。
然后就是要处理触发事件了,怎么在指定坐标触发事件呢?网上查了查没查到相关信息,很多网友说的是不能再指定坐标触发事件,当时我就懵逼了!!!
但是想想,zrender里面封装了事件的,可以看看怎么从这里入手,是的,最后找到了解决办法:
- zrender.trigger('mousemove', {
- zrenderX: style.x,
- zrenderY: style.y
- });
试了下,成功了!!!!!!
说的比较粗糙,此文仅供参考,如过您有更好的方法希望能够分享出来,大家一起学习,哈哈!
下面贴上完整代码:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <style>
- .chart {
- height: 500px;
- width: 800px;
- }
- </style>
- </head>
- <body>
- <div id="chart" class="chart">
- </div>
- <span id="hover-console"></span>
- <span id="console"></span>
- <script src="./js/echarts-all.js"></script>
- <script type="text/javascript">
- // 基于准备好的dom,初始化echarts图表
- var myChart = echarts.init(document.getElementById('chart'));
- console.log(myChart);
- var option = {
- tooltip: {
- show: true
- },
- legend: {
- data:['销量']
- },
- xAxis : [
- {
- type : 'category',
- data : ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
- }
- ],
- yAxis : [
- {
- type : 'value'
- }
- ],
- series : [
- {
- "name":"销量",
- "type":"bar",
- "data":[5, 20, 40, 10, 10, 20]
- }
- ]
- };
- // 为echarts对象加载数据
- myChart.setOption(option);
- var ecConfig = echarts.config;
- function eHover(param) {
- var mes = '【' + param.type + '】';
- if (typeof param.seriesIndex != 'undefined') {
- mes += ' seriesIndex : ' + param.seriesIndex;
- mes += ' dataIndex : ' + param.dataIndex;
- }
- document.getElementById('hover-console').innerHTML = 'Event Console : ' + mes;
- }
- myChart.on(ecConfig.EVENT.HOVER, eHover);
- //可以获取有效的数据元素,数据元素属性包含坐标点和长宽(如果页面有变化需要重新获取)
- var counts = option.series[0].data.length;
- setTimeout(function() {
- autoHover();
- setInterval(autoHover, 1000 * counts);
- }, 1000);
- function autoHover() {
- var zrender = myChart.getZrender();
- var elements = zrender.storage._elements;
- var times = 0;
- console.log(elements);
- for (var key in elements) {
- var style = elements[key].style;
- //根据series中的一系列name值对elements进行归类排序,然后在进行hover
- //过滤条件需要完善
- if (elements[key]._echartsData) {
- console.log(style);
- (function (style, times) {
- setTimeout(function () {
- zrender.trigger('mousemove', {
- zrenderX: Math.ceil(style.x + style.width/2),
- zrenderY: Math.ceil(style.y + style.height/2)
- });
- }, 1000 * times);
- })(style, times);
- times++;
- times %= counts;
- }
- }
- }
- </script>
- </body>
- </html>
当鼠标触发hover时要取消自动效果,这个就大家自己解决了!哈哈
第一次发文,见笑了!
PS:这个问题发现上面的处理不合适哈,echarts中提供了tooltip显示的方法,一直没更新,今天得空更新下。
为了解决有鼠标触发hover时怎么控制轮播效果的停止和开始,更细的去查看echarts和zrender的事件,看来看去感觉外部处理很困难,最后思路还是回到了tooltip上。
最后发现tooltip中其实是有提供showTip和hideTip方法,然后看echarts文档上component中的tooltip也有写这两个方法,然后添加代码:
- var tooltip = myChart.component.tooltip;
- //showTip方法参数请参见echarts文档
- tooltip.showTip({seriesIndex: '1', dataIndex: '1'});
运行发现根本没效果(bar类型)。。。。。。。。。。。。。调试发现tooltip中showTip()源码:
- if (isAxisTrigger) {
- var dataIndex = params.dataIndex;
- switch (chart.type) {
- case ecConfig.CHART_TYPE_LINE:
- case ecConfig.CHART_TYPE_BAR:
- case ecConfig.CHART_TYPE_K:
- case ecConfig.CHART_TYPE_RADAR:
- //问题就在这儿,serie.data[0].value是什么鬼?
- if (this.component.polar == null || serie.data[0].value.length <= dataIndex) {
- return;
- }
- var polarIndex = serie.polarIndex || 0;
- var vector = this.component.polar.getVector(polarIndex, dataIndex, 'max');
- this._event = {
- zrenderX: vector[0],
- zrenderY: vector[1]
- };
- this._showPolarTrigger(polarIndex, dataIndex);
- break;
- }
- }
然后在github上查看以前的版本,发现早在echarts 1.4版本中就加入了showTip()hideTip()的功能了,提交链接。
可以看见showTip():
- 1 + if (isAxisTrigger) {
- 2 + // axis trigger 3 + var dataIndex = params.dataIndex;
- 4 + switch (chart.type) {
- 5 + case ecConfig.CHART_TYPE_LINE :
- 6 + case ecConfig.CHART_TYPE_BAR :
- 7 + case ecConfig.CHART_TYPE_K :
- 8 + if (typeof xAxis == 'undefined'
- 9 + || typeof yAxis == 'undefined'
- 10 + || serie.data.length <= dataIndex
- 11 + ) {
- 12 + return;
- 13 + }
- 14 + var xAxisIndex = serie.xAxisIndex || 0;
- 15 + var yAxisIndex = serie.yAxisIndex || 0;
- 16 + if (xAxis.getAxis(xAxisIndex).type
- 17 + == ecConfig.COMPONENT_TYPE_AXIS_CATEGORY
- 18 + ) {
- 19 + // 横轴是类目20 + _event = {
- 21 + zrenderX : xAxis.getAxis(xAxisIndex).getCoordByIndex(dataIndex),
- 22 + zrenderY : grid.getY() + (grid.getYend() - grid.getY()) / 4
- 23 + };
- 24 + }
- 25 + else {
- 26 + // 纵轴是类目27 + _event = {
- 28 + zrenderX : grid.getX() + (grid.getXend() - grid.getX()) / 4,
- 29 + zrenderY : yAxis.getAxis(yAxisIndex).getCoordByIndex(dataIndex)
- 30 + };
- 31 + }
- 32 + _showAxisTrigger(
- 33 + xAxisIndex,
- 34 + yAxisIndex,
- 35 + dataIndex
- 36 + );
- 37 + break;
- 38 + case ecConfig.CHART_TYPE_RADAR :
- 39 + if (typeof polar == 'undefined'
- 40 + || serie.data[0].value.length <= dataIndex
- 41 + ) {
- 42 + return;
- 43 + }
- 44 + var polarIndex = serie.polarIndex || 0;
- 45 + var vector = polar.getVector(polarIndex, dataIndex, 'max')
- 46 + _event = {
- 47 + zrenderX : vector[0],
- 48 + zrenderY : vector[1]
- 49 + };
- 50 + _showPolarTrigger(
- 51 + polarIndex,
- 52 + dataIndex
- 53 + );
- 54 + break;
- 55 + }
- 56 + }
我顺便找了一下是在2.2.2-到2.2.3版本中被改了。
下面这段代码被改过了:
- switch (chart.type) {
- case ecConfig.CHART_TYPE_LINE :
- case ecConfig.CHART_TYPE_BAR :
- case ecConfig.CHART_TYPE_K :
- //应该只是想删掉这个项,结果把处理程序也删了
- //case ecConfig.CHART_TYPE_TREEMAP :
- if (this.component.xAxis == null
- || this.component.yAxis == null
- || serie.data.length <= dataIndex
- ) {
- return;
- }
- var xAxisIndex = serie.xAxisIndex || 0;
- var yAxisIndex = serie.yAxisIndex || 0;
- if (this.component.xAxis.getAxis(xAxisIndex).type
- === ecConfig.COMPONENT_TYPE_AXIS_CATEGORY
- ) {
- // 横轴是类目
- this._event = {
- zrenderX: this.component.xAxis.getAxis(xAxisIndex)
- .getCoordByIndex(dataIndex),
- zrenderY: this.component.grid.getY()
- + (this.component.grid.getYend()
- - this.component.grid.getY()
- ) / 4
- };
- }
- else {
- // 纵轴是类目
- this._event = {
- zrenderX: this.component.grid.getX()
- + (this.component.grid.getXend()
- - this.component.grid.getX()
- ) / 4,
- zrenderY: this.component.yAxis.getAxis(yAxisIndex)
- .getCoordByIndex(dataIndex)
- };
- }
- this._showAxisTrigger(
- xAxisIndex,
- yAxisIndex,
- dataIndex
- );
- break;
OK,把这个段删除的代码复制到你引用的echarts源码tooltip.js中,然后要合并的就重新合并压缩吧。
贴上例子:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <style>
- .chart {
- height: 500px;
- width: 800px;
- }
- </style>
- </head>
- <body>
- <div id="chart" class="chart">
- </div>
- <span id="hover-console"></span>
- <span id="console"></span>
- <script src="./js/jquery.js"></script>
- <script src="./js/echarts-all.js"></script>
- <script type="text/javascript">
- // 基于准备好的dom,初始化echarts图表
- var myChart = echarts.init(document.getElementById('chart'));
- var option = {
- tooltip: {
- show: true29
- },
- legend: {
- data: ['销量']
- },
- xAxis: [
- {
- type: 'category',
- data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
- }
- ],
- yAxis: [
- {
- type: 'value'
- }
- ],
- series: [
- {
- "name": "销量",
- "type": "bar",
- "data": [5, 20, 40, 10, 10, 20]
- }
- ]
- };
- // 为echarts对象加载数据
- myChart.setOption(option);
- var timer = 0;
- var total = option.xAxis[0].data.length;
- var count = 0;
- var tooltip = myChart.component.tooltip;
- function autoTip() {
- timer = setInterval(function () {
- var curr = count % total;
- //3.0以上版本的showTip使用方式
- //myChart.dispatchAction({type: 'showTip', seriesIndex: '1', dataIndex: '1'});
- tooltip.showTip({seriesIndex: '0', dataIndex: curr});
- count += 1;
- }, 1000);
- }
- autoTip();
- var zRender = myChart.getZrender();
- //mousemove和mouseout总是成对出现,而且out先出现。。。。所以没法解决鼠标hover时暂停自动tip的效果
- zRender.on('mousemove', function (param) {
- console.log('move')
- if (timer) {
- clearInterval(timer);
- timer = 0;
- }
- });
- zRender.on('mouseout', function (param) {
- console.log('OUT');
- if (param.event) {
- //判断坐标是否在图表上,然后在处理应该可以实现
- if (!timer) {
- autoTip();
- }
- }
- });
- </script>
- </body>
- </html>
补充:
3.0以上的实现方法已经在github共享了代码,可以直接下载使用,如有问题欢迎补充纠正:
https://github.com/chengwubin/echarts-tooltip-auto-show
echarts实现自动轮播tooltip的更多相关文章
- [个人项目] echarts 实现数据(tooltip)自动轮播插件
前言 最近, 工作中要做类似这种的项目. 用到了百度的 echarts 这个开源的数据可视化的框架. 因为投屏项目不像PC端的WEB, 它不允许用户用鼠标键盘等交互. 有些图表只能看到各部分的占比情况 ...
- 使用ViewPager实现自动轮播
很多APP中都实现了类似引导页的自动轮播,不由得想到昨天的引导页上修改一下代码实现轮播. 其实大体上只需要添加一个线程循环执行就可以了. 项目已同步至:https://github.com/nanch ...
- ViewPager自动轮播
Android使用ViewPager实现左右循环滑动及轮播效果 ViewPager是一个常用的android组件,不过通常我们使用ViewPager的时候不能实现左右无限循环滑动,在滑到边界的时候 ...
- jQuery实现选项联动轮播
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 仿网易新闻 ViewPager 实现图片自动轮播
新闻 App 首页最上方一般会循环播放热点图片,如下图所示. 本文主要介绍了利用 ViewPager 实现轮播图片,图片下方加上小圆点指示器标记当前位置,并利用 Timer+Handler 实现了自动 ...
- ios - 图片自动轮播定时器(NSTimer)以及消息循环模式简介
本文只是演示如何设置图片轮播的定时器. 创建全局变量NSTimer 程序启动后就开始轮播图片,所以在- (void)viewDidLoad中就启动定时器. 将定时器放入消息循环池中.- (void)v ...
- Jquery+css实现图片无缝滚动轮播
Today,在XX学院的教学视频中,偶尔看到了Jquery+css实现图片无缝滚动轮播视频教程,虽然以前已写过类似的,但是我感觉他学的比较精简.为了方便以后做项目时直接拷贝,特地写出来,顺便和大家分享 ...
- 讲解版的自动轮播(新手福利)样式和js就不分离了为了看的方便
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- javascript焦点图左右按钮简单自动轮播
这里把css和html合在一块写了,这块代码只是布局和样式不是重点 <!DOCTYPE html> <html> <head> <meta charset=& ...
随机推荐
- c# in out ref关键字
class in_out_ref { #region in 关键字 delegate void DContravariant<in A>(A argumen); static void o ...
- HBase原理–所有Region切分的细节都在这里了
本文由 网易云发布. 作者:范欣欣(本篇文章仅限内部分享,如需转载,请联系网易获取授权.) Region自动切分是HBase能够拥有良好扩张性的最重要因素之一,也必然是所有分布式系统追求无限 ...
- 【ocp-12c】最新Oracle OCP-071考试题库(41题)
41.(8-14) choose two View the Exhibit and examine the structure of the ORDERS table. The columns ORD ...
- 几种封装javaBean的方法
开发框架时,经常需要使用java对象(javaBean)的属性来封装程序的数据,封装javaBean的方法有很多,比如反射,内省,以及使用工具类.下面从反射开始介绍. 1.javaBean介绍: 简介 ...
- Ubuntu下增加eclipse菜单图标并配置java path(解决点击图标不能启动eclipse的问题)
Ubuntu下增加eclipse菜单图标 Ubuntu的菜单图标在/usr/share/applications目录下. 1. 在/usr/share/applications目录下新建eclipse ...
- Optional类
参照: 一篇简单使用介绍 官网详细用法介绍 包含各种例子的cheetsheet 一个封装某个value的容器 一般可用于方法返回值类型,提醒调用方,这个值可能为null,所以需要处理(因为空指针异常是 ...
- 无比迅速敏捷地开发iOS超精美控件
目录 前言 设计 编码 PaintCode 前言 自从人生第一篇博客<iOS中的预编译指令的初步探究>问世以来 浏览量竟然达到了360多,(路过的大神勿笑!)这些浏览量使我兴奋异常但又令我 ...
- Safari 不能播放Video ,Chrome等可以 问题解决。
1 原因分析 https://www.zhihu.com/question/41818719 2 代码实现 1 注意点: 请求时 : header中 range 请求多少长度 代码要返回相应的长度 ...
- 配置不同站点不同版本PHP
Apache 配置 1.常规手动部署apache方法(不会apache配置的请先移步看下Apache基本手工配置方法),解压fcgid,取其mod_fcgid.so至modules目录 2.打开htt ...
- [转] ELK 之 Logstash
[From] https://blog.csdn.net/iguyue/article/details/77006201 ELK 之 Logstash 简介: ELK 之 LogstashLogsta ...