编者按:本文是蚂蚁集团 AntV 工程师索丘在 SEE Conf 2022 的演讲内容,包括演讲视频及文字内容,欢迎享用。
大家好,我是来自蚂蚁集团-数字金融技术部的索丘。今天我给大家带来的分享是《可视化叙事的探索与应用》。可视化叙事是最近几年可视化领域的一个热点方向,这次分享我会结合可视化叙事在蚂蚁中的应用和实践,给大家介绍下什么是可视化叙事,以及我们是如何去设计和实现可视化叙事的引擎能力的。
什么是可视化叙事
这种形式大家估计在短视频网站上面也能经常看到,它讲述的是这十个国家近几十年GDP的变化情况,它通过动态排序图的形式来去讲一个复杂的一个数据集,并给我们展示了这种变化过程。这就是一个很典型的叙事应用场景。
当然,我们还能看到很多其他不同的形式,这些都是对可视化叙事的应用。
- 用动效变化并结合听觉效果,引导用户关注点
- 用交互引导用户探索,并发现问题
我们通过动画效果并结合听觉去引导用户关注,让用户去发现数据里面的关键信息和关键的内容。我们还可以通过创建一些交互式的引导,让用户去交互式地探索数据集的一些信息,然后去发现数据集里面的不同点。
为什么要做可视化叙事
在讲为什么要做之前,我们回过头来看我们为什么要做可视化,可视化是我们将一个抽象的数据统通过可视化的形式给到人,让人来形成洞察,并通过洞察形成最后的决策,所以可视化最终的目的是决策。同理可视化叙事也一样,只是我们今天面向的数据不再是一个单维度的数据,我们面对的是一个多维度的复杂数据,我们如何要从多维度的数据里面快速形成洞察,并做出最后决策。这个就是我们今天要探索和深入的命题,而可视化叙事无疑是一种很好的解法。既然我们发现叙事是一种很好的形式,那么我们要如何在工程中设计和应用叙事的能力呢,让叙事能真正在业务中应用起来。先在讲我们的具体的设计方案之前,然后我们先看一下针对叙事的定义,我们今天做的一些尝试和应用。
这个案例讲的内容是什么是微笑定投,以及某段时间之内达成了多少次微笑。 我们通过折线图并加上描点和标注的形式,简单快速的来说明我们的内容。这个案例通过宏观到微观的视角切换来去讲诉整体的宏观表现 和具体某只基金它在这些行情段里的表现情况,它通过视角的切换来表达整体和局部的关系。
这个案例它讲述的是某个月的收益情况,以及它具体的月收益组成是什么,我这个月到底是亏了还是赚了,还有就是哪个类别对我的收益影响是最大的。
我们通过这种短视频的形式把抽象的数据具象化,然后表达数据信息,这个我们也叫数据视频。所以可视化叙事在实际应用中可以有多种不通的形式。
可视化叙事的设计与实现
在看了上面这些例子之后,我们再回过头来去看,我们是如何设计与实现这些案例的,以及底层的核心能力有哪些,下面我给大家简单介绍我们的设计和实现思路。我们先对叙事的案例做一个简单拆解,以动态排序图为例,它实际上就是多张图连续播发的过程,而每张图它对应的都是一份抽象数据,所以我们本质上就是对数据的连续播放。
声明式图表定义
基于对案例的拆解,我们实现了一套声明式的图表定义,可以简单方便的去定义图表。
Timeline 图表播放
有了图表之后,下一步我们只要把这些图表串联起来,形成连续播放的内容就可以了,基于这个思路,我们在上层实现了 Timeline 的控制,可让图表进行连续播放。这2步就是我们实现一个叙事案例的核心过程,同理我们再来看看其他的案例。
静态卡片和数据视频
数据视频也是一样, 当我们对视频内容拆解后,我们就能发现这个视频它也可以拆成具体的一个个数据帧,每一帧里面它表达的也是一份抽象的数据,而这份数据它背后对应的其实也是一个展示内容,代码形式上面其实就是一个组件。通过对组件的连续播放,就能形成我们看到的样子。
组件 & 变化
看到这里,我想大家一定会好奇更底层到底是怎么实现的。后面我会拿核心的组件和变化给大家简单介绍下更底层的实现思路。
组件
针对组件,我们借鉴了 React 的设计思路,实现了一套可视化组件和生命周期,使用方式基本和 React 一致,不一样是我们是在画布上面,可视化组件我们可以完全类比于 React 组件, 这种形式也可以无缝地和React 结合使用。
变化
变化是叙事的核心,变化的动画处理是我们需要重点去解决和实现的,后面我会以动画为核心简单介绍下我们的动画能力设计和实现。
动画的三个阶段
当我们对动画进行更拆解时,我们会发现动画的变化都可以归类为3个阶段和类型,入场、变化、消失。
1. 入场
2. 变化
3. 消失
识别变化
既然我们已经对动画进行了归类,下面的问题就是我们该如何去识别动画,有了声明式的组件定义之后,我们能很自然地想到利用 DOM Diff 来识别具体变化。diff 的实现和大家理解的过程几乎是一模一样的,这里就不详细介绍了,唯一的不同点是针对删除元素的处理,当一个元素被删除时,我们会等待元素的消失动画执行完后才会从渲染树上拿掉。
动画的声明与定义
当我们识别出具体变化后,我们就可以对每个元素定义动画形式。上面这些就是动态排序图底层动画简化后的过程,我们通过 appear, update, leave 来定义不同阶段的动画行为,然后再通过 Timeline 整体驱动起来。到这里,就基本上给大家演示了整体的设计思路和核心过程了,通过这种形式,我们还可以实现其他不同的变化类型,比如下面例子,更多案例大家可以上我们的官网详细了解。
最后
大家如果对这块感兴趣的话,甚至说想了解更多的内容,可以上我们的官网,也可以关注我们的 GitHub,谢谢大家。