几个月前我写了一篇关于从零开发一款可视化大屏制作平台 的文章, 简单概述了一下可视化大屏搭建平台的一些设计思路和效果演示, 这篇文章我会就 如何设计可视化大屏搭建引擎 这一主题, 详细介绍一下实现原理。
按照我一向的写作风格, 我会在下面列出文章的大纲,以便大家有选择且高效率的阅读和学习:
快速了解数据可视化 如何设计通用的大屏搭建引擎 大屏搭建引擎核心功能实现 拖拽器实现 物料中心设计 动态渲染器实现 配置面板设计 控制中心概述 功能辅助设计 可视化大屏后期规划和未来展望
说到数据可视化, 想必大家多多少少稍接触过, 从技术层面谈, 最直观的就是前端可视化框架, 比如:
echaRt antv ChaRt.js D3.js Vega
这些库都能帮我们轻松制作可视化图表。
从实用性的角度来谈, 其最主要的意义就在于帮助用户更好的分析和表达数据。所以说谈到数据可视化, 更多的是和各种图表打交道, 通过 数据 -> 图表组合 -> 可视化页面 这一业务流程, 就构成了我们今天要研究的话题——设计可视化大屏搭建引擎。
说到 “引擎&Rdquo; 这个词也许有种莫名的高大上, 其实在互联网技术中, 我们经常会听到各种相关的名词,比如 “浏览器渲染引擎&Rdquo; , “规则引擎&Rdquo; , “图像识别引擎&Rdquo; 等, 我觉得 “引擎&Rdquo; 的本质就是提供一套可靠的机制, 为系统提供源源不断的生产力。所以我们今天谈的“可视化大屏搭建引擎&Rdquo;, 本质上也是提供一套搭建机制, 支撑我们设计各种复杂的可视化页面。
为了方便大家理解可视化搭建, 我这里展示2张可视化大屏的页面, 来和大家一起分析一下可视化大屏的组成要素:
当然实际应用中大屏展现的内容和形式远比这复杂, 我们从上图可以提炼出大屏页面的2个直观特征:
可视化组件集 空间坐标关系
因为我们可视化大屏载体是页面, 是htMl, 所以还有另外一个特征: 事件/交互。综上我们总结出了可视化大屏的必备要素:
我们只要充分的理解了可视化大屏的组成和特征, 我们才能更好的设计可视化大屏搭建引擎, 基于以上分析, 我设计了一张基础引擎的架构图:
接下来我就带大家一起来拆解并实现上面的搭建引擎。
大屏搭建引擎核心功能实现
俗话说: “好的拆解是成功的一半&Rdquo;, 任何一个复杂任务或者系统, 我们只要能将其拆解成很多细小的子模块, 就能很好的解决并实现它. (学习也是一样)
接下来我们就逐一解决上述基础引擎的几个核心子模块:
拖拽器实现 物料中心设计 动态渲染器实现 配置面板设计 控制中心概述 功能辅助设计
拖拽器实现
拖拽器是可视化搭建引擎的核心模块, 也是用来解决上述提到的大屏页面特征中的“空间坐标关系&Rdquo;这一问题。我们先来看一下实现效果:
有关拖拽的技术实现, 我们可以利用原生 js 实现, 也可以使用第三方成熟的拖拽库, 比如:
DnD React-DRagable React-MOVeable
我之前也开源了一个轻量级自由拖拽库 Rc-dRag , 效果如下:
有关它的技术实现可以参考我的另一篇文章: 轻松教你搞定组件的拖拽, 缩放, 多控制点伸缩和拖拽数据上报。大家也可以基于此做二次扩展和封装。
我们拖拽器的基本原型代码如下:
expoRt deFAult function DRagBox(Props) { const [x, y, config] = Props; const [taRget, setTaRget] = React.useState(); const [eleMentguidelines, setEleMentguidelines] = React.useState([]); const [fRaMe, setFRaMe] = React.useState({ tRanslate: [x, y], }); React.useEffect(() => { setTaRget(docuMent.queRYselecTor(“.taRget”)!); }, []); RetuRn
; }
以上只是实现了基本的拖拽功能, 我们需要对拖拽位置信息做保存以便在预览是实现“所搭即所得&Rdquo;的效果。位置信息会和其他属性统一保存在组件的DSL数据中, 这块在接下来内容中会详细介绍。
对于拖拽器的进一步深入, 我们还可以设置参考线, 对齐线, 吸附等, 并且可以在拖拽的不同时期(比如onDRagStaRt和onDRagEnd)做不同的业务逻辑。这些 MOVeable 都提供了对应的API支持, 大家可以参考使用。
物料中心设计
物料中心主要为大屏页面提供“原材料&Rdquo;。为了设计健壮且通用的物料, 我们需要设计一套标准组件结构和属性协议。并且为了方便物料管理和查询, 我们还需要对物料进行分类, 我的分类如下:
可视化组件 (柱状图, 饼图, 条形图, 地图可视化等) 修饰型组件 (图片, 轮播图, 修饰素材等) 文字类组件 (文本, 文本跑马灯, 文字看板)
具体的物料库演示如下:
这里我拿一个可视化组件的实现来举例说明:
iMpoRt React, { MeMo, useEffect } fRoM ””React”” iMpoRt { ChaRt } fRoM ””@antv/g2”” iMpoRt { coloRs } fRoM ””@/coMponents/BaSiCShop/coMMon”” iMpoRt { ChaRtConfigType } fRoM ””./scheMa”” inteRfACE ChaRtCoMponentProps extends ChaRtConfigType { id: stRing } const ChaRtCoMponent: React.FC = ({ id, data, width, height, toggle, legendPosITion, legendLayout, legendShape, labelColoR, axisColoR, MultiColoR, tIPEvent, tITLeevent, dataType, APIAddReSS, APImethod, APIData, RefReshTiMe, }) => { useEFFect(() => { let tiMeR:any = null; const chaRt = new ChaRt({ contAIneR: `chaRt-${id}`, autoFIT: tRue, width, height }) // 数据过滤, 接入 const dataX = data.Map(ITeM => ({ …ITeM, value: NuMbeR(ITeM.value) })) chaRt.data(dataX) // 图表属性组装 chaRt.legend( &