首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据可视化之MarkPoint

数据可视化之MarkPoint

作者头像
Peter Lu
发布2018-06-20 10:11:00
1K0
发布2018-06-20 10:11:00
举报
文章被收录于专栏:LETLET

MarkPoint是什么效果?如上图,一闪一闪亮晶晶的效果,这是在Echarts中对应的效果。我最早看到的是腾讯的一个Flash的版本,显示当前QQ在线人数的全国分布效果,感觉效果很炫,当时也在想,怎么用JS,HTML5来做出类似的效果,但说实话,没什么思路,甚至怀疑JS是否做不出来这种逼真的效果来。终于看到Echarts中提供了这个功能。下面就扒开她绚丽的衣着,一起走进MarkPoint的世界。

数据

首先还是先看看数据上的逻辑。上图是一个数据格式,placeList包括每一个关键点的名称和坐标位置,而在风格中主要有name,可以设置为强中弱三种,分别对应MarkPoint图中白蓝绿三种效果,类型是中国地图,而具体的风格在存储在markPoint字段中。我们在看看markPoint字段里面是什么内容。

如上就是markPoint里面的主要内容,这里,每一个点是一个钻石(diamond)的样式,符号大小,还有一个effect的属性,这就是它的动画风格,而data则用来加载placeList的信息。

综上所述,对于使用者而言,指定好要显示markPoint的位置,也就是placeList,然后在赋予它们的具体效果,中国范围,强弱类型以及具体的形状(钻石,矩形或圆形等),这样就可以得到MarkPoint这样的闪烁效果。

原理

其实说原理有点夸大其词。通过数据层面,可以看出来每一个点都是独立的,如果你放大后,基本可以判断出来各自完成自己的动画效果,并一致循环下去。如果缩小后,你会发现所有的markPoint并不是同步的,频率各不相同,显得杂乱无章。(推荐TED的视频:The First Secret of Great Design - Tony Fadell - TED Talks)。

这样,这个问题就分解成了两个部分:

  • 如何模拟每一个点的闪烁效果
  • 如何管理大规模的点的闪烁周期

闪烁效果的实现

如上,是同一个markPoint在不同帧下的效果,大家可以想想一下这样一个从小到大然后再到小的过程,则完成了闪烁的效果,如果你足够细心会发现里面有一个blur的平滑效果,这样会让闪烁有一个平滑的效果,类似字体的抗锯齿,看起来有一种朦胧的感觉。当然,blur这个效果是怎么实现的?其实在之前风向图和热点图中都采用了这个技术,就是和上一帧的图片进行一个半透明的叠加。然后在配合一个动画特效(animation effect),闪烁的效果就完成了。

多点闪烁动画的实现

如上是在某一帧的截图。俗话说的好,一花独放不是春,所以如何控制这么多的点,风格各不相同的markPoint,而且频率各不相同,这就涉及到动画类和随机数之间的内容,同时在框架上能够贯穿整个渲染周期。

我们看一下在Echarts上的流程,先是初始化的流程:

如同,MarkPoint的数据初始化主要是Map类读取数据,然后在Base中调用getLargeMarkPointShape来创建这些点。

在Base中,调用animationEffect指定单个MarkPoint的闪烁风格,这里需要额外说明一下,虽然在数据中动画风格只是简单的show:true.但实际上,最终是采用的config.js中默认的动画风格,比如周期,是否循环,跳动等,如下图所示:

而在ecEffect中,调用largePoint来随机设置,实现各自不同的动画周期。从而完成整改初始化的过程。

初始化结束后,则进入到了渲染阶段。渲染是采用的zrender框架,而markPoint则是由Animation来驱动,每一帧都会调用update,在onframe中来设置每一个点当前的状态,比如大小,根据时间周期下,线性插值计算出它应该的大小(下面会详细说明),最后调用Symbol::buildPath实现所有markPoint的闪烁效果。

这就是初始化准备和渲染周期的大致一个过程,下面对主要功能模块进行介绍

实现代码

如上,只是指定了blur为true,则实现了平滑效果,简单不?其实这用了一个双缓存的技术,在zrender中有一个Layer对象,每一帧都会叠加上一帧的效果,并保存。具体的实现可以参阅zrender的Layer类,比较简单。

闪烁动画有点复杂,首先,怎么控制一个markPoint从大到小的这样一个线性变换的过程,动画类是如何控制的,另外对于不同的markPoint,有这么多点,同一帧下每个点对应的风格也不尽相同,这又是如何控制的。

首先,这要介绍一下zrender中的Animation类,一个非常好用强大的类,先看看使用代码,如下:

首先,这是一个when.js风格的使用方式,该动画主要用来控制effectShape的‘style’属性,即每一帧来对style属性进行更新。那更新什么内容呢?这就是clip对象了。

这里有四个when,再加上最上面的随机的初始大小,也就是说一个周期有5个控制点,其中clip1 = 100,而clip2 = 0,,这里对应的是该控制点对应markPoint的size的百分比。也就是在这个周期中,按照如下的插值算法来控制该点的size。不知道说清楚了没有,可以自己调试一下代码看看。

这是在一帧下插值计算当前size的百分比,这里采用的线性插值,还有其他多种算法可以选择,这里是size,所以用的最简单的线性插值,你也可以实现轨迹,或者加速度等不同的公式来实现对应的效果。

插值计算完了,付给对应的style中randomMap+i属性上。这里,一共常见了20个Animation类,这样就会有20个动画效果,来实现频率各自不同的闪烁效果。最后会调用zrender的refresh,最终来到Symbol的渲染阶段。这里,每一个点根据自己的索引选择对应的缩放比例percent,然后进入下面的绘制阶段。

另外,在对每一个点的渲染函数中,进行了进一步的优化,代码如下,根据大小进行了简化。

Ok,到此,我想到的关于MarkPoint的内容都已经完毕,另外这个类涉及到一个大规模点渲染,等有机会对这方面详细研究后在和大家分享。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-01-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 LET 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数据
  • 原理
    • 闪烁效果的实现
      • 多点闪烁动画的实现
      • 实现代码
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档