一、概述
DataV数据可视化可以通过可视化应用的方式来分析并展示庞杂数据的产品,可以满足多种业务的展示需求。繁多的数据可视化展示需求中,数据表、地图、翻牌器等组件的展示高频出现,在这些基础组件的前提下,一些差异化、定制化展示的需求接踵而来,其中客户在工单中反馈及咨询较为频繁的就是特定(或一些)地点(省市)、类目相关数据表或气泡地图等的筛选交互与展示。
本文主要对datav大屏数据表、气泡地图等组件的筛选交互需求进行一个简单的梳理及样例实现,其中包括单字段单选筛选、单字段多选筛选、多字段共同筛选、字段级联及查询按钮的配置。
二、数据筛选相关交互需求梳理
1. 单字段单选筛选
- 通过“交互”模块实现
- 通过“蓝图编辑器”模块实现
2. 单字段多选筛选
- 两种实现方式及客户使用区别
- 通过“多选下拉框”实现
- 通过“多选框”实现
- 客户使用区别
- datav高级版组件支持受限解决方案
- 部分场景的替代方案-多组件配合动态sql的替代实现方式
3. 多字段筛选
- 临时变量初始化设置
- 拼接动态sql的where条件
- 蓝图编辑器的配置
- 级联的配置
4. 查询按钮
- 取消回调ID触发,改为仅按钮触发
三、需求实现方案样例
1. 样例实现背景
实现方案样例以某APP不同地区的流量(pv)访客数(uv)及“轮播列表”作为展示指标及手段
a. 数据明细表概览
数据表展示的源数据表结构及数据详情如下:
-- 表结构及comment如下createtable syf.datav_province_valuetest( province varchar(50) comment '省',city varchar(50) COMMENT '市',pv INT comment '访问量',uv int comment '独立访客数');-- 查看表的明细数据样例select*from `datav_province_value`
b. 数据维度表概览
-- 维度码表元数据信息createtable syf.datav_province( province varchar(50) COMMENT '省',city varchar(50) COMMENT '市');-- 查看维度码表的数据样例select*from syf.`datav_province`
c. 配置基础轮播表
2. 实现:单字段单选筛选
单字段单选筛选功能较为基础,也可以满足大多数的数据筛选交互场景,datav提供了两种实现方式,第一种是通过“下拉框”的“交互”模块实现,第二种是通过“下拉框”的“蓝图编辑器”模块实现。
在这之前需要按照如下配置单选“下拉框”的维度选项,并更改指标“轮播列表”的筛选条件及接收参数,相关操作及代码:
SELECTdistinctprovince as title FROM syf.datav_province
SELECT*FROM syf.datav_province_valuewhere province=:province
a. 通过交互模块实现
启用“交互”模块的交互事件,在下“拉框内容被选中”的时候将value字段的内容以province的名称抛出参数
b. 通过蓝图编辑器模块实现
使用“蓝图编辑器”功能需要将所需的组件“导出到蓝图编辑器”
在“蓝图编辑器”中进行如下三步操作:
- 配置交互规则,“当下拉框内容被选中”->请求“轮播列表”的数据接口
- 在“串行数据处理”中,查看上游组件参数字段提示
- 通过js代码传递参数province
functionfunc (data, getCallBackValue, getLocalValue) { return { province: data.title}; }
3. 实现:单字段多选筛选
单字段多选筛选功能相对单选来说实现起来有一定难度,因为多选需配合数据库的sql语句实现in (:xxx)的功能,而组件的“交互”模块的回调事件不能抛出复杂对象,这就需要在“蓝图编辑器”中配合js代码返回类似{xxx:['value1','value2','value3']}的数组格式才能进行相关的传参,datav提供了两种实现方式,第一种是通过“多选下拉框”组件实现,第二种是通过“多选框”组件实现。
a. 通过多选下拉框实现
在“画布编辑器”进行如下操作:
- 添加“多选下拉框”,导出组件到“蓝图编辑器”,并拖拽到合适的位置
- 配置组件数据源及下拉数据
在“蓝图编辑器”界面需要进行如下配置:
- 配置组件间交互连线:多选下拉框“下拉框内容被选中时”->轮播列表“请求数据接口”
- 在“串行数据处理”模块通过js代码将参数province_list转换为{x:['value1','value2']}的形式
- 右键组件之间的连线,配置组件间数据传递时的日志方便调试
functionfunc (data, getCallBackValue, getLocalValue) { constresult=data.map((item, index, data) => { returnitem.title }) return { province_list: result }; }
调试预览界面可以查看整个交互过程中参数传递和响应情况
- 当我们在“多选下拉框”选中广东省和山东省时
- 可以在“蓝图日志”中看到传递给“轮播列表”的参数是否正常
- 参数正常,相应列表展示符合预期
b. 通过多选框实现
在“画布编辑器”中的操作同“多选下拉框”
- 添加“多选框”,导出组件到“蓝图编辑器”,并拖拽到合适的位置
- 配置组件数据源及下拉数据
在“蓝图编辑器”中进行如下配置
- “多选框”相比“多选下拉框”在组件交互中间传递的数据有所区别
- 在“串行数据处理”模块中,根据上游组件“多选框”的数据示例处理数据,抛出参数province_list:['value1','value2']用于下游轮播列表组件SQL语句的动态传参
functionfunc (data, getCallBackValue, getLocalValue) { constresult=data.data.map((item, index, data) => { returnitem.value }) return { province_list: result }; }
调试预览界面可以查看整个交互过程中参数传递和响应情况
- 当我们在多选下拉框选中广东省和北京市时
- 在蓝图日志中看到传递给轮播列表的参数是否正常
- 参数正常,相应列表展示符合预期
c. 客户使用区别:多选下拉框与多选框
- 蓝图编辑器中上游组件数据格式不同,参数传递的js处理代码不同
- 多选框会罗列所有取值,空间占用较大
- 多选框包含全选按钮,部分场景下使用较为方便
高级版DataV组件支持受限解决方案
受高级版组件使用限制,不支持“多选框”及“多选下拉框”,部分客户在工单中寻求相关功能的代替解决方案,下面给出部分场景的替代方案,该方案仅适用于类目较少,方便罗列的场景。成果图如下:
- 通过通用标题和开关按钮组合的方式实现多选框,配合蓝图编辑器实现多选的功能配置
- 通过轮播列表来展示,相应的也可以是柱状图或者地图气泡图等其他图表
相关实现步骤如下:
- 添加相关组件、拖拽到画布编辑器相关位置并将开关及轮播列表导出到蓝图编辑器
- 配置轮播列表数据库及动态sql用以适配多选的需求,动态sql包含N个(本例为3个)参数用以标识不同的类目,并通过:province_xx的方式传参,并通过配合case when 语句 及 1=0 的判断句式结合or实现
SELECT*FROM syf.datav_province_valuewherecase when :province_bj =1 then province ='北京市' else 1=0 end or case when :province_gd =1 then province ='广东省' else 1=0 end or case when :province_hlj =1 then province ='黑龙江省' else 1=0 end
- 设置临时变量的初始化参数,用以在打开大屏的时候显示默认数据,需与三个“开关”组件的默认状态保持一致。添加全局节点,初始化临时变量,在“串行数据处理”模块中设置大屏初始化时的临时参数,临时变量的相关内容可以参考官方https://help.aliyun.com/document_detail/142628.html
functionfunc (data, getCallBackValue, getLocalValue) { return { data: [ { name: "privince_bj", // value == 1 默认是开关打开的状态value: 1 }, { name: "privince_gd", value: 1 }, { name: "privince_hlj", value: 1 } ] }; }
- 此方案需要在“蓝图编辑器”中借助“序列执行”组件,在每个“开关”组件有状态变化时,先将“临时变量”的值同步到“全局节点”中,再根据每个类目最新的“临时变量”发起对“轮播列表”的筛选动作
- 根据“开关”组件的最新状态,设置“临时变量”
functionfunc (data, getCallBackValue, getLocalValue) { return { data: [ { name: "privince_gd", value: data.value } ] }; }
- 在“开关”组件“临时变量”同步完毕后,获取所有类目“临时变量”的最新值并通过“轮播列表”向数据库发起请求,达到动态筛选的效果
functionfunc (data, getCallBackValue, getLocalValue) { return { province_bj: getLocalValue('privince_bj') , province_gd: getLocalValue('privince_gd') , province_hlj: getLocalValue('privince_hlj') }; }
- 将所有类目的开关做相同的配置
4. 实现:多字段筛选
多字段筛选的实现方式可以借鉴因高级版DataV不支持多选组件而使用的多组件结合展示图表动态拼接sql的方法,但是相关细节需要进行重构。
待实现的交互需求及成果图如下:
- 三个条件筛选共同作用,分别为:是否直辖市,省、市的筛选
- 省、市之间实现查询条件的级联
- 通过轮播列表来展示,相应的也可以是柱状图或者地图气泡图等其他图表
- 添加相关组件并将需要配置交互动作的导出到“蓝图编辑器”,拖拽到指定的位置,更改“通用标题”、“下拉框”,“开关”组件的默认展示设置
- 在“全局节点”的“全部组件初始化完成时”设置“开关”的初始关闭,初始值变量is_zhixia=0(是否是直辖市),“省”、“市”维度的“多选下拉框”取值的数组及数组长province_list、province_list_len、city_list、city_list_len。
functionfunc (data, getCallBackValue, getLocalValue) { return { data: [ { name: "province_list", value: [] }, { name: "province_list_len", value: 0 }, { name: "city_list", value: [] }, { name: "city_list_len", value: 0 }, { name: "is_zhixia", value: 0 } ] }; }
- 根据三个筛选组件所产生的临时变量,配置轮播列表的动态sql如下,由于js数组并不能直接配置在sql中判断是否为空,所以引入两个xxx_len的变量来进行数组是否为空的判断,当数组不为空时进行相应的筛选,数组为空时抛出恒等的1=1,并用and条件连接多个字段的动态筛选条件
SELECT*FROM syf.datav_province_valuewherecase when :province_list_len >0 then province in(:province_list) else 1=1 end and case when :city_list_len >0 then city in(:city_list) else 1=1 end and case when :is_zhixia =1 then right(province,1)='市' else 1=1 endsql
- 以“省”的“多选下拉框”为例,“市”及“是否直辖市”的配置情况同“省”
- 借助“序列执行”组件,在“下拉框内容被选中时”进行交互操作
- 根据“多选下拉框”的值更改临时变量
- 根据所有临时变量的最新值,对轮播列表发起请求,实现数据的筛选
functionfunc (data, getCallBackValue, getLocalValue) { constresult_province=data.map((item, index, data) => { returnitem.title }) return { data: [ { name: "province_list", value: result_province }, { name: "province_list_len", value: result_province.length } ] }; }
functionfunc (data, getCallBackValue, getLocalValue) { return { province_list: getLocalValue('province_list') , city_list: getLocalValue('city_list') , province_list_len: getLocalValue('province_list_len') , city_list_len: getLocalValue('city_list_len') , is_zhixia: getLocalValue('is_zhixia') } }
- 筛选的级联可以在“省”的“多选下拉框”组件抛出临时变量时,也传递给“市”的下拉框组件中数据库查询的sql语句中实现级联
SELECTdistinctcity as title ,city as value FROM syf.datav_provincewhere province in(:province_list)
5. 实现:查询按钮的实现
“查询按钮”其实类似一个“轮播列表”带参查询sql的触发器,在多字段筛选的基础上,仅需要进行如下几步操作就可以实现该功能。相比于多字段筛选的实现方式,增加按钮的实现方式可以显著的降低查询次数,降低数据库的压力,仅在所有字段条件均配置好的情况下进行筛选,而不是每次和下拉框进行交互的时候都会进行一次查库的操作。配置后效果如图:
- 添加按钮组件并导出到蓝图编辑器,拖拽到相应的画布位置,在全局样式中设置文字内容为“筛选”
- “当点击按钮”时,请求“轮播列表”的数据接口,并在自动弹出的串行数据处理中,传递当前状态下的临时变量。同时取消之前三个下拉框组件到“轮播列表”请求数据接口的触发请求即可通过“查询按钮”来控制筛选进行的时机
functionfunc (data, getCallBackValue, getLocalValue) { return { province_list: getLocalValue('province_list') , city_list: getLocalValue('city_list') , province_list_len: getLocalValue('province_list_len') , city_list_len: getLocalValue('city_list_len') , is_zhixia: getLocalValue('is_zhixia') } }