背景
大数据可视化做为科技与艺术的交叉点,研究他可以更好的为业务和发展带来持续的推进力。而通过具体的案例,可以更深入的理解和使用大数据可视化。大数据可视化中数据处理、流程、工具等要点都可以在案例中得到一个很好的研究和学习。我们在收集大量数据分析比较后,确定使用成都地铁三号线流量数据做为案例的数据源。
分析数据
成都地铁三号线流量数据拿到时的数据是一个二维表格,记录了各个站点在不同时间点的流量。但直接来看这个数据表格的话,还有以下问题:
- 数据过多,难以阅读和理解
- 数据之间对应关系无法直接看到
- 无法与现有地铁站直接对应
在分析数据后,我们发现,他是随时间而变化的连续数据,所以使用折线图非常适用。折线图可以很方便显示在相等时间间隔下数据的趋势。先直接使用 Excel 的图表功能来生成一下。
从上图来看,会比之前的数据要容易理解。但从大数据可视化设计角度来看,还有以下不足:
- 辨识度不高,除去变化特别强烈的站点,其它站点线条混在一起
- 无法产生与真实站点的关联
- 视觉效果还不够有冲击力
- 如果能有动效就更好了
数据展示方案
为解决以上问题,经过大家脑暴决定引入真实地铁地图,在地铁线路上来动态展示流量变化。然后我们按这套方案设计出交互稿与视觉稿。引入地铁地图后我们解决了辨识度不够的问题,每个站点都会有对应的光圈和线条来展示流量,这些数据与真实站点的关联性也更强。专业视觉设计过后地图效果在视觉冲击力也可以给人一个惊艳的感觉。再通过H5技术增加了各种动效,让整个效果更大生动和有交互性,产生更佳的用户体验。
(交互稿)
(视觉稿)
因为时间关系,制作案例的时间比较紧,在对业内开源地图的相关项目比较后,我们确定基于百度地图 API和 Mapv (地理信息可视化开源库)来实现整个大数据可视化的设计思想。
方案开发实现
在分析数据源、视觉稿和基本框架后,在实现上分为以下三层来实现。
其中,动态图表展示层的线条、圆圈动态效果,是开发的中重点和难点。
线条
首先,线条数据是只能通过站点的流量来影射,但每一条的线条的路径数据我们目前并没有。所以只能先做一个小工具来手工绘制线条路径。
(折线生成器)
折线生成器主要记录生成线条数据的折点,但 Mapv 还不能创建补间点,在拼命唤醒各种三角函数知识后,写出以下函数来生成相关补间点。
/*** * 构建补间点 * @param {Array} p1 点1,要有X,Y值 * @param {Array} p2 点1,要有X,Y值 * @return {Array} 返回两点间的点集合数组 */ function getPoint(p1, p2) { // JS Math对象中的三角函数介绍 http://blog.sina.com.cn/s/blog_760e9df90101mtab.html // 三角形斜边分段长 var f = 0.0001; // 要返回的数据 var arr = []; // console.log('p1:' + p1[0] + ',' + p1[1]); // console.log('p2:' + p2[0] + ',' + p2[1]); // 对边 var Xz = p2[0] - p1[0]; // console.log('Xz :' + Xz); // 临边 var Yz = p2[1] - p1[1]; // console.log('Yz :' + Yz); // A角度 var Ca = Math.atan(Math.abs(Xz / Yz)); // console.log('Ca :' + Ca); // 斜边 var Z = Xz / Math.sin(Ca); // console.log('Z :' + Z); // 分段斜边 对应的 对边 var Xn = f * Math.sin(Ca); // console.log('Xn :' + Xn); // 分段斜边 对应的 临边 var Yn = f * Math.cos(Ca); // console.log('Yn :' + Yn); var nums = parseInt(Math.abs(Z / f)); // console.log('nums :' + nums); if (Xz < 0) { Xn = -Xn; } if (Yz < 0) { Yn = -Yn; } for (var i = 1; i <= nums; i++) { arr.push([(p1[0] + (Xn * i)), (p1[1] + (Yn * i))]); } return arr; }
通过这种方式来生成从站点流出的线条,可以更直观的表现流量情况,但因为 Mapv 的限制,不能控制单个线条的显示隐藏,所以线条数量还未能与流量做成映射关系。
定时器
而圆圈的大小则可以与流量做到映射关系。但这里还要与时间轴关联起来,所以要使用定时器。以前定时器都是使用 setInterval() 来实现,现在可以用 requestAnimationFrame() 来实现,但还要对他做一改功能加强,来实现每秒循环次数的可配置。
/*** * 定时执行器 */ var fps = 4; var now; var then = Date.now(); var interval = 1000 / fps; var delta; function tick() { requestAnimationFrame(tick); now = Date.now(); delta = now - then; if (delta > interval) { // 这里不能简单then=now,否则还会出现上边简单做法的细微时间差问题。例如fps=10,每帧100ms,而现在每16ms(60fps)执行一次draw。16*7=112>100,需要7次才实际绘制一次。这个情况下,实际10帧需要112*10=1120ms>1000ms才绘制完成。 then = now - (delta % interval); draw(); // 要定时执行的方法 } }
另外,文字数据展示层的数据变化也对应到定时器中。
地图定制
最后,背景展示层的地图直接使用百度地图底图编辑工具实现即可。只要编辑好地图样式,然后获取样式 JSON ,然后调用 JSAPI 的 setMapStyle 方法。
坑
当然还遇到了不少坑,走了不少弯路。主要遇到以下几个坑:
- Mapv 开发文档不全,作者只给了些 Demo ,具体应用只能自己摸索。
- Mapv 只能把所有线条生成到一个图层中,无法精确控制线条,如果分不同图层显示线条,电脑内存立马就不够用了。
- Mapv 画不出内部渐变的圆圈,只能用模糊边缘来模拟。
总结
数据可视化的定义在不同人眼中是不一样的。我们通过这次成都地铁三号线流量数据案例的演练,对整个流程中数据挖掘、提取、表现、动效等都有了进一步的研究和学习。
同时我们也在思考,有没有可能在单个案例之上,做出一个通用的数据可视化工具,而不只是专门为单独的案例做开发。而集合数据处理、流程、工具、展示的整体可视化工具,就是我们的下一下努力方向,敬请期待。
本文采用「CC BY-SA 4.0 CN」协议转载自互联网、仅供学习交流,内容版权归原作者所有,如涉作品、版权和其他问题请给「我们」留言处理。