一、需求分析

每次实现各种图表时,总会用到echarts,不得不说确实是一个非常好用的开源库。不过由于需要,这次的需要实现的效果如下:
1.实现一个梯形图(每个数据组对应一个梯形);
2.自定义echarts的右键功能,增加选项可以直接对数据项进行额外的操作;

二、思路及实现

2.1 自定义echarts的鼠标右键事件

我们知道一般在浏览器中鼠标右键点击都有自定义的事件

那么就需要阻止原本的右键事件发生,然后再添加自己的事件。
在eventUtil事件中(为了平衡不同浏览器间实现事件的差异或事件的差异而存在)。
补充1:
eventUtil常用的方法:
(1)addHandler() 常常为对象添加事件并保证兼容性(如DOM0或DOM2级不同的指定方法有很大不同);
(2)removeHandler()相应地是移除事件;
另外,在这个对象中,很多方法参数都是event事件对象,兼容DOM的浏览器会将event对象传入到事件处理程序中,这个event对象也支持许多属性和方法:
currentTarget 其事件处理程序当前正在处理事件的那个元素
preventDefault() 取消事件的默认行为
stopProgagation() 取消事件的进一步捕获或冒泡
targe 事件的实际目标
type 触发的事件类型

分析一下,右键事件的屏蔽应该只当在canvas部分,原本的思路实现,通过捕获到鼠标右键事件,然后自定义想要的效果。结果查询后发现了更简单的方法,果断使用。

document.getElementById('main').oncontextmenu = () => false;

查看echarts开发文档,发现API提供了右键事件接口。于是乎,改写即可。

初步代码如下:
...
//定义自定义菜单项<ul id = "menu"><li class="menu" @click = "choose1">功能1</div><li class="menu" @click = "choose2">功能2</div><li class="menu" @click = "choose3">功能3</div><li class="menu" @click = "choose4">功能4</div><li class="menu" @click = "choose5">功能5</div></ul>
...
//重写mychart的ontextmenu右键事件
myChart.on('contextmenu', function (params) {//获取我们自定义的右键菜单var menu=document.querySelector("#menu");//根据事件对象中鼠标点击的位置,进行定位menu.style.left=window.event.clientX + 40+ 'px';menu.style.top=window.event.clientY - 40 +'px';//改变自定义菜单的宽,让它显示出来menu.style.width = '125px';
});
...

出现的效果如下:

发现问题又来了,图中的菜单项是点击第一个item苹果时出现的,偏移位置太多。一般体验都是点击右键,菜单项出现在点击位置旁,明显我们的菜单定位有问题。另外,菜单项的前面都带上了ul的标志点,查看了一下去掉.通过在样式中设置list-style:none即可去掉。

补充2:
鼠标中参照点不一样,其位置坐标也就不一样,有以下几种情况:
(1)相对于当前页面
pageX、pageY
(2)相对于event事件目标对象也就是鼠标元素(但是Firefox不支持)
offsetX、offsetY
(3)相对于屏幕
screenX、screenY
(4)相对于浏览器窗口(相对于当前屏幕的坐标,忽略了滚动因素)
clientX 、clientY

这里很奇怪,直接在一个html文件中应用时,用的clientX和clientY没有问题,菜单的位置都是在鼠标点击侧,但是用在vue项目中的某个页面时,却出现了上述的问题。于是,将定位改为offsetX、offsetY后,效果如下:

可以看出上图中的菜单项,明显前面的缩进仍然存在呢,这是因为ul的内边距的原因,因此设置padding:0即可。自定义鼠标右键的功能基本上实现了。

2.2 梯形波实现

接下来,就是万分重要的梯形波的实现了。研究echarts良久后,有一些思路。最初的想的实现方法有三种:
(1)利用漏斗图 (因为最开始看到了其中有矩形,但是发现虽然可以提取出单个梯形,但还要确定矩形的大小、位置,两位漏斗图没有坐标轴,因此还要自定义坐标系与之相关联,于是放弃此方法)
(2)自定义系列(最初想通过polygon多边形和polyline折线自定义实现的,结果后来发现折线图是最简单的,于是就改成了折线图)
(3)折线图(原理就是定点连线,毕竟所谓的梯形波形起始点和结束点还有高都是代表有具体的含义,都可确定点的)
最终效果图:

补充3:
实现过程中发现坐标轴也是有些意思,不仔细的话就会不知道到底是哪里的问题。不用的坐标系对应的参数和操作方式存在差异,echarts中坐标系分为五种cartesian2d(笛卡尔坐标系也就是直角坐标系)、calender(日历坐标系)、geo(可视化地理坐标)、polar(极坐标系)、singAxios(单轴坐标系)。
echarts中直角坐标系也有好几种轴:类目轴(category适用于离散的数据)、数据轴(value)、时间轴(time适用于连续的数据)、对数轴(log)。
目前接触的也就两类:
(1)类目轴+value轴
value轴的刻度也有两种分配方式:通过Interval强行分配、自动根据数据值分配;
这时候后series里的数据为一维的即[10,11,3,1,2,2,5],分别与类目轴中的data一一对应,以上面的柱状图为例则苹果:10,香蕉:11,哈密瓜:3……不过这种情况,如果设置了多个series,后一个series中的数据仍旧会按类目轴定位。

   series: [{name: '销量',type: 'bar',data: [11, 5, 1,2, 2, 5]}, {name: '销量1',type: 'bar',data: [13, 6, 1,2, 3, 8]},]

如下图所示,某些情况下会发生重叠。

所以判断某个轴是否是类目轴,就看该轴是否设置了data(!这和series中的data不一样)
(2)value轴+value轴
可自己设置刻度值x、y轴均可,但实际数据还是由series对象中的data指定。且此时的data为多维数组,[一维数据,二维数据,其他],根据实际需要将数据映射到对应的坐标轴,利用.coord(),详细参见echarts配置项开发文档。

另外,鼠标放置在某个数据项上显示的悬浮框内容的设置:
(1)可以通过formatter字符串模板来设置,在折线图中用到的{a}代表系列名称、{b}代表类目值、{c}代表数据值;
(2)更可以通过formatter:function(params){}自定义的函数来展示想要的效果,params参数是一个对象,具体包含的参数查询配置文档。其中更是可以返回html标签元素

也是可以识别的。

2.3 后续
在上面的基础上,想模拟波形抖动的毛刺,于是利用Math.random()产生多个固定范围的随机数据,且隔一段时间刷新数据,以此来模拟波形的抖动。

1.如上图展示的,首先我模拟了多个数据,使之位于上底所对应的x轴范围区域内,利用Math.random()方法,生成的是0-1间的数,可任意组合为想要的范围。例如10-25间,Math.random() * 5 +10,注意要不要对小数进行处理。

2.由于产生随机数的过程中,可能会产生相同的数据。故有必要对数据去重,方法,则是利用indexOf确认是否存在相同的,对存在数组中的生成数据,只有当对前数组元素查找结果返回为-1时,才将其添加到新的数据组中,这样就进行筛选了。

3.另外还需要对数据数组排序,因为绘图时以点描线,要得到理想的形状当然要按顺序来实现咯。排序采用sort()方法,这个方法详解参见之前的文章(js常用点)对其有仔细的解答。在这之后当然就可将x轴数据再结合模拟对应的y轴数据,波动范围当然就在20左右,最后将数据放入series数组的目标成员的data中即可。

//比较函数
var compare = function (x, y) {if (x < y) {return -1;} else if (x > y) {return 1;} else {return 0;}
}
arr.sort(compare);

4.这时的锯齿波形已经出现了,但动态还需要刷新上底的数据,故用setInterval()方法,定时刷新数据并调用setOption()方法,初见成效:

不过那密集的数据点标识却不是我们想要的,因此,将symbol设为‘none’隐藏掉了所有的数据点图标,但关键地方的点也不在了。几番折腾后,终于是发现了markPoint这个好用的属性,而且其中symbol的默认是一个倒立的水珠状即‘pin’,很坑的是文档在列出markPoint.symbol.type的属性时,并没有写singleCircle( ⊙ o ⊙ )啊!真得抓狂,很久很久我去研究series中的symbol时发现其默认类型是singleCircle,试了一下才有效果的,所以官方配置文档能不能走心一点,让菜鸟少走些弯路。。

5.很愉快的最终效果(动态图就懒得弄了,直接截了个图,它其实是在动态变化的):

可以看到其中还添加了dataZoom缩放组件,坐标轴的刻度值也是通过formatter规范化了的。这过程中也遇到了一些小坑:
已解决:
(1)实现动态效果后,发现右侧的边始终会不时的消失再现,几乎是同步数据的刷新时间。——>这是因为echarts的图例都默认开启了animation动画效果,渲染就是从左向右动态变化的一个过程,导致了上面的问题。——>设置animation:false即可。

(2)设置dataZoom缩放组件,发现放大到某个点时,梯形变成了矩形或者都不在了。

仔细观察发现这些情况发生在,关键点经放大后不在可视化范围内,查看配置文档发现一切源于filterMode这个属性,‘filter’/’weakFilter’/’empty’这三个属性都会对数据进行不同情况的过滤,导致放大后点不在可视区域就被丢弃了,因此描点就变了。将其设置为none即不会过滤,只会改变坐标轴。
常用参数:
type:‘slider’滑动块、’inside’内部滑动块;
xAxisIndex:0 / yIndex:0
表明当前控制的坐标轴是第一个x轴和第一个y,这种对于有多个坐标轴时就是非常有用的。

(3)另外,markPoint的模拟点,鼠标放置在上面时,没有原来的动态放大效果。不知道要怎么弄?
已解决:发现可以将line的hoverAnimation属性应用于markPoint中,但是需要注意这个属性和line本身属性animation是相关联的,必须为true时才效,即使设置了markPoint的animation为true也不会生效。
必须line.animation:true + line.markPoint.hoverAnimation 同时存在才可生效!很明显这和我们的(1)相矛盾了。

未解决:
(1)echarts右键事件只对于选中的数据项有效,折线图就是选中某个数据点时才有效,不同于折线柱状图则只要在对应的数据item上右键就可触发,因为整个柱状相当于一个数据点。不知道有没有一种方法只要进入该目标折线区域下就可以触发?

补充4:
getElementById(‘id’): 通过id匹配;
getElementByTagName(): 返回指定标签名的对象集合;
querySelector(‘#id’) : 获取文档中id匹配的元素(第一个)
querySelectAll() :同上,不过是用于匹配选择到的所有元素
另外,总体前面两种和后面的query区别:
(1)前者是动态,后者是静态的。比如,如果我通过getElementById(菜单id)获取到了一个菜单项,之后我们又添加了一个菜单项,使用刚刚获取到的菜单项就会发现已经包含了新增的菜单项,但query则不会包含。
(2)兼容性差异。
(3)都不能查找匹配伪元素。

如何利用echarts3绘制梯形波图相关推荐

  1. j散度matlab,利用Matlab绘制梯度图、散度图、旋度图。.doc

    利用Matlab绘制梯度图.散度图.旋度图..doc 题 目电磁场理论实验姓 名学 号班 级任课老师实验日期2013年 10月 19日 一.实验目的: 1.利用Matlab绘制梯度图: 2.利用Mat ...

  2. python绘制折线图保存_Python利用matplotlib绘制折线图的新手教程

    前言 matplotlib是Python中的一个第三方库.主要用于开发2D图表,以渐进式.交互式的方式实现数据可视化,可以更直观的呈现数据,使数据更具说服力. 一.安装matplotlib pip i ...

  3. 利用 CoreGraphics 绘制折线图

    效果与元素分析 实现效果图如下: 首先对折线图进行元素分割 包含以下六部分元素 渐变背景 折线 折线上的点 折线范围内渐变 参考线 文本显示的 Label 除了6之外,其他几个元素都在 draw(_: ...

  4. Python中利用Matplotlib绘制多图并合并展示

    有个需求就是利用Matplotlib画几个像模像样的统计图然后合并在一张图中,因为此前很少用这方面的东西,所以折腾了不少时间,今天介绍一下. 1.subplot多合一 其实,利用python 的mat ...

  5. 利用matplotlib绘制圆环图的案例

    一.概念介绍 圆环图(Donut Chart),又称为环形图,甜甜圈图.它从饼图变形而来,单环的作用上与饼图相似,用于展示定性数据中小类占大类的比例关系. Q: 那既然都有饼图了,为什么还要圆环图呢? ...

  6. 利用matplotlib绘制马赛克图的案例

    一.概念介绍 马赛克图(Mosaic plot),基于列联表的数据排布,展现二维定性变量下的取值大小,我们可以将它想象成三维柱状图的俯视,颜色差异或面积大小常被用于区分每个块的赋值大小. · 什么是列 ...

  7. R语言中如何利用ggplot2绘制qq图和boxplot图

    文章目录 绘制qq图 函数介绍 geom_qq() 参数介绍 注意事项 例子 Using to explore the distribution of a variable 绘制boxplot 函数介 ...

  8. python【Matlibplot绘图库】利用matlibplot绘制雷达图

    文章目录 1.基本构造 2.比较功能 1.基本构造 之前在一些数据分析案例中看到用 Go 语言绘制的雷达图,非常的漂亮,就想着用matlibplot.pyplot也照着画一个,遗憾的是matlibpl ...

  9. 利用python绘制雪景图_python绘制雪景图

    本文实例为大家分享了python绘制雪景图的具体代码,供大家参考,具体内容如下 绘制雪景图,应用到turtle和random. from turtle import * from random imp ...

最新文章

  1. 卷积神经网络(CNN)张量(图像)的尺寸和参数计算(深度学习)
  2. java qq协议 c#,C# WebQQ协议群发机器人(三)
  3. _linux运维正确安装oracle流程
  4. java 注解开发_Java中的注解到底是如何工作的?
  5. ubuntu下matplotlib 升级
  6. Hibernate级联操作 注解
  7. 回顾2016,展望2017
  8. 基于 Java 2 运行时安全模型的线程协作--转
  9. 记一次Spring boot 和Vue的前后端分离的入门培训
  10. 如何理解矩阵特征值?
  11. vue与php接口对接,怎样使用vue项目中api接口
  12. 微信开发者工具不显示二维码问题
  13. 大端模式 小端模式学习笔记
  14. python爬虫教程-Python爬虫全集
  15. (已解决)MAC JAVA错误:Cocoa AWT: Not running on AppKit thread 0 when expected
  16. 何宾 单片机原理及应用_stc单片机原理及应用.pdf
  17. js获取客户端ip地址
  18. Oracle中对时间操作的一些总结
  19. Linux 并发测试工具 httpd-tools工具的安装和使用
  20. CocosCreator 子弹运动轨迹的绘制

热门文章

  1. Android 蓝牙开关
  2. 【Java】判断是否是IE浏览器
  3. 台式计算机不用待机还是关机好,电脑有必要每天关机吗 电脑不关机能工作的时间及危害...
  4. 《西虹市首富》文章相关代码分享
  5. SpringBoot 零基础教学
  6. 不能接收彩信的原因及自动收发彩信解决方案
  7. RTMP推流协议视频智能分析/人脸识别/直播点播平台EasyDSS接口调用注意事项介绍
  8. python3命令需要使用命令行开发者工具_3 个 Python 命令行工具
  9. 计算机信息系统物理安全防护措施,信息物理系统安全威胁与防护措施
  10. 【阅读笔记】《人月神话》思想提炼