设想一种交互场景: 页面中有一个下拉列表组件,可选项是广东、湖北、浙江;此外,页面中还有一个饼状图 ,显示的是人口性别比例。
当用户在下拉列表中选择不同的省份,饼状图就相应的显示该省份的人口性别比例,这就是组件联动。
除了上述下拉列表(筛选器组件) 与饼状图(图表组件),其实联动行为可以发生在任意两个或多个组件之间。
-
如两个筛选器组件省份选择器和城市选择器,当我们在省份选择器中选择了一个选项时,另一个城市选择器只能有该省份的城市备选,这就是发生在两个筛选器组件之间的联动。
- 如页面中有一个按天统计的时间趋势图,此外页面中还有其他多个不同类型的统计图表,当用户点击时间趋势图的某一日时,页面中其他多个图表全部变为该日的指标统计图。这就是发生在多个图表组件之间的联动。
联动原理 #
你需要认识三个关键词来了解联动原理,事件组件、影响组件和联动变量
联动是发生在不同组件之间的动态行为。在联动行为发生时,参与其中的每一个组件所扮演的角色是不同的。有的组件是发起联动的主体,有的是被联动的客体。我们把它们分别称作事件组件与影响组件。
联动发生的时候,联动的主体(事件组件)会向联动的客体(影响组件)传递一个变量值,这个变量值被称为联动变量。
需要特别说明的是,一个组件可能在一次联动行为中是事件组件,而在另一场联动行为中则是影响组件,这取决于联动变量传递的方向。
在数说方舟,对联动行为的描述如下: 当一个组件A的点击事件能产生一个字段的值,而这个值被作为另一个组件B的API参数的时候,A和B是有联动关系,此时A是 事件组件,B是影响组件,A组件产生的值是联动变量的值。 再看前面描述的案例:
- 页面中有一个下拉列表组件,可选项是广东、湖北、浙江;此外,页面中还有一个饼状图 ,显示性别比例。
- 当用户在下拉列表中选择省份为湖北,饼状图就相应的显示湖北的人口性别比例
在这个案例中,下拉列表是事件组件,饼状图是影响组件,而省份就是 联动变量,联动时,事件组件把省份 = 湖北这个信息传递给了饼状图。
所以,如果用信息流的视角来说,联动过程的本质,就是事件组件把联动变量传递给影响组件的过程。
图表组件渲染的是API数据,联动发生的时候,影响组件会根据联动变量重新请求一次API,用API返回的数据对图表进行渲染,完成一次联动。
- 正是由于事件组件背后的API返回了不同纬度的数据(dataset)和数据描述信息(meta),才使得它可以产生联动变量
- 正是由于影响组件背后的API可以接收部分参数,才使得联动变量可以作用于它。
因此,是组件背后的API决定了组件在联动行为中的角色和地位。由于不同的API所能传递出的变量,以及所能接受的参数不同,所以不同的组件在联动中扮演的角色也不一样。
1.API的属性决定了组件可能的联动行为
API可以接受哪些参数,决定了组件可以成为哪些联动变量的影响组件,API数据中包含哪些纬度,决定了组件可以成为哪些联动变量的事件组件
假如一个API可以接收一个参数,同时它又包含了这个纬度的数据,那么它可以同时成为这个联动变量的影响组件和 事件组件,即可以联动自身。
基于API的联动行为 #
数据分析与API制作章节提过,方舟默认使用format=matrix请求API,这样请求到的信息中不仅包含数据,同时包含数据的描述信息,这些信息中就包含了parameters和indices.
- parameters描述了API可以接受哪些参数。
- indices描述了API可以传递出来哪些参数。
当一个页面中,所有组件背后的API都提供了以上信息,我们就可以玩一个“连连看”的游戏。这样我们可以通过相同的参数,把页面中的组件尽可能多的“连”起来。连的时候是有方向的,这个方向就是联动的方向。
联动关系的建立 #
如果我们有甲、已、丙三个组件,按照组件背后的API的parameters和indices属性,已经知道:
- 甲组件可以接收变量A,传递变量B、C;
- 乙组件可以接收变量A,传递变量E、F;
- 丙组件可以接收变量E、F,传递变量A、H;
根据上述信息,可绘制如下示意图
2.由API信息可获取组件的联动属性
如果已经明确了甲、乙、丙三组件的出参和入参,按照“连连看”的规则,不难发现组件之间可以有这样的联动关系被建立:
3.为组件自动建立联动关系
上图的联动关系描述是准确的,但在阅读和理解时存在两个问题:
- 当页面中组件较多时候,连接数会迅速增大,不易于管理;
- 图中丙组件传递了A变量,同时影响了甲、乙两组件,图中没有传达"A只被传递了一次"这个信息。
针对上述情况,我们以变量作为图中的一类实体,引入全局变量表的概念,重新绘制这幅图。
4.联动关系的另一种表示
图3与图4是等价的。但图4是一种更方便管理的组织形式。此时,全局变量表中的全部变量,就是形成了全局变量list,当联动行为发生的时候,全局变量list中的每一个变量及其当前值,就被称为全局变量map。
全局变量map与组件之间的关系是实时的,例如丙组件传递出来一个新的A值,这个值将会立即更新全局变量map中的A的变量,随即会被传递给组件甲和乙。
值得注意的是,并非全局变量中的每一个变量都有参与联动,例如图4中的变量B、C、H,都没有形成有效的联动关系(因为图中没有组件可以接收这三个变量),全局变量list只是页面中全部组件背后的API的 parameters 与 indices 的并集.
变量空间 #
认识变量空间 #
全局变量list是一个无重复集合,这在一些特定的场景下无法满足需求,尤其是页面中有“对比”信息要展示时。
设想一种场景:页面中有四个组件,分别是“吴亦凡粉丝性别分布图”、“吴亦凡粉丝年龄分布图”、“蔡徐坤粉丝性别分布图”、“蔡徐坤粉丝年龄分布图”。 其中,甲、丙可以产生性别参数,乙、丁可以接收性别参数。此时我们期待的联动关系是
事件组件 | 联动变量 | 影响组件 |
---|---|---|
吴亦凡粉丝性别分布 | 性别 | 吴亦凡粉丝年龄分布 |
蔡徐坤粉丝性别分布 | 性别 | 蔡徐坤粉丝年龄分布 |
而非:
事件组件 | 联动变量 | 影响组件 |
---|---|---|
吴亦凡粉丝性别分布、蔡徐坤粉丝性别分布 | 性别 | 吴亦凡粉丝年龄分布、蔡徐坤粉丝年龄分布 |
因为按照后者的情况下,我们无论在“吴亦凡粉丝性别分布”还是在“蔡徐坤粉丝性别分布”中选择一个性别,都会同时影响到“吴亦凡粉丝年龄分布”和“蔡徐坤粉丝年龄分布”这两个组件。
但显然前者的“性别”变量是重复的,这与全局变量是一个“无重复集合”的定义不符。
所以我们引入变量空间的概念,其定义如下:
- 变量空间是变量的无重复集合;
- 一个页面中有至少一个变量空间;
- 任何页面均有一个默认的变量空间,即全局变量空间;
- 除全局变量空间外,页面中可以有若干其他局部变量空间;
在引入了多变量空间之后,上述吴亦凡和蔡徐坤在同一个页面内分别显示不同性别粉丝的年龄分布的问题就得到了解决:
变量空间-1
事件组件 | 联动变量 | 影响组件 |
---|---|---|
吴亦凡粉丝性别分布 | 性别 | 吴亦凡粉丝年龄分布 |
变量空间-2
事件组件 | 联动变量 | 影响组件 |
---|---|---|
蔡徐坤粉丝性别分布 | 性别 | 蔡徐坤粉丝年龄分布 |
制造更多的变量空间 #
变量空间是由组件的出参和入参的并集产生的,产生之后组件分别成为了变量的事件组件和影响组件。当我们使某个组件脱离一个变量的时候,就产生了“不参与联动的变量”,如下图所示,我们在联动面板中把丙、乙组件从变量A中移除,并且把丙组件从变量H中移除,就产生了A和H两个不参与联动的变量:
5.组件脱离变量空间时产生了”不参与联动变量
不参与联动的变量是制造一个新的变量空间的基础,当我们需要新建一个变量空间的时候,不参与联动的变量会被全部收录进新的变量空间。
6.不参与联动变量“被收录进另一个变量空间中
在任意一个变量空间内,如果移除一个变量的组件,那么这个组件的变量就会进入“不参与联动”这个特殊空间。 在任意时刻,如果新建一个变量空间,则会将“不参与联动”空间内的所有变量收录到这个新的空间。
组件协同 #
在一个变量空间内,事件组件通过联动变量对影响组件造成影响,这是联动的本质。
值得注意的是,在一个变量空间内,任意一个变量都会有n个事件组件与n个影响组件(n是自然数)。
当一个组件有多个事件组件时,这些事件组件之间的关系就是协同关系。当一个组件有多个影响组件时,这些组件之间的关系也是协同关系。
协同,即意味着组件之间会保持一致的状态。
举例来说,组件甲和乙都是某一个变量空间内的变量A的影响组件,那么当A的值产生变化的时候,组件甲和乙也一同发生变化,这很容易理解,即一个变量的变化同时引起来两个组件的变化。
而还有另一种协同方式也很常见但是常被设计者忽略,那就是事件组件的协同。例如组件丙和丁都是某一个变量空间内变量A的事件组件,那么当A的值产生变化对丙组件和丁组件产生的影响应该是等价的。
具体来讲,如果组件丙是一个“柱状图”,组件丁是一个“饼状图”,这两个图都是表示了性别占比,无论点击哪个图都会产生一个“性别”变量与其他的组件进行联动。若点击饼状图中的某一个性别的时候,表示该性别的扇形有高亮的效果,点击柱状图的时候,表示该性别的柱子也有高亮的效果,那么这两个图表的高亮行为应该是协同的——即点击任何一个图表中的某性别,都会造成两个图表一起高亮相应的性别。
在方舟中进行组件联动设置 #
数说方舟按照上述模型制作,只需在页面中点击“开启联动”按钮,即可生成基于全局变量的联动配置面板。
7.方舟的联动配置面板
用户可以将组件从该面板移除,移除并保存之后会生成“不参与联动”的变量,并且可以利用这些不参与联动的变量创建新的变量空间。
在实现上述模型的过程中,方舟的联动配置还有四个需要注意的点,分别是未编排筛选器、初始化取值、合并变量、更新组件属性
未编排筛选器 #
开启联动时,方舟根据组件背后的API信息,可以自动帮助组件建立联动关系。
但是有一部分组件无法在这一过程中自动找到联动关系——例如日期时间筛选器、输入框等(这类组件背后没有API)。
这种情况下,组件会被放入“未编排筛选器”组件,需要你手动将它们放入联动配置面板的合适位置。
初始化取值 #
事件组件之所以被叫做事件组件,是因为联动关系发生的时候,它组件需要监听到用户的操作事件。
但是在页面初始化加载的时候,尚无任何用户操作事件,此时事件组件无法传值给变量。在页面初始化时如果要设置影响组件的默认值,可以设置初始化取值。一般设置某一个筛选器(例如下拉列表或单选框)的默认值为该变量的初始化取值。这样变量在页面初始加载就可以获得取值。
合并变量 #
变量空间是变量的无重复集合,也就意味着在一个变量空间内变量是唯一的。方舟判断变量是否唯一的方法是按照“同数据源且同字段”的逻辑,此时可能会存在一些风险——如果性别字段分别属于两个底层数据表,那么就会有两个“性别”变量出现在变量空间之中。
这是因为这两个“性别”变量并没有在同一个数据源中,无法被判断为同一个变量。它们仅仅是变量名相同,甚至有时候连变量名都不同(例如分别叫“性别”与“gender”)。
如果我们认为这两个变量需要合并为一个,则可以通过“合并变量”功能,手动将其合并。合并之后两者的影响组件共同成为新变量的影响组件,两者的事件组件共同成为新变量的事件组件。
方舟支持多个变量的合并,并不局限于两个。但是需要注意,因为不同类型的字段接受参数的格式不同,合并的变量必须有同样的字段类型,否则无法合并.
更新组件属性 #
你可以随时对组件进行修改,比如修改组件的类型、名称,甚至修改组件背后的API。
然而,这些改动信息无法实时地同步到联动配置面板,因此如果参与联动的组件发生了变化,尤其是背后API的变化,需要你在联动配置面板中更新组件的属性。