业内解决方案
数据可视化工具算是一种图表低代码实现平台。已有的低代码平台如阿里的低代码引擎( Low-Code Engine)支持图表类组件生成页面。
国外专门做图表可视化低代码的有 superset、metabase;国内有 dataease、tableau;百度 Sugar BI。
前端关键技术点
按照功能我们可以把配置时前端进行如图的模块分层。数据可视化工具前端页面一般包括物料区、搭建区和配置区三部分。
-
物料区:放置常用的组件。基础组件一般包括下拉框、输入框、日期选择框等;可视化组件包括折线图、饼图、柱状图、散点图等;其他物料包括图片素材等。物料区的组件用户对其进行拖拉放置到搭建区使用。
-
搭建区:就是用户编辑可视化大屏的地方。搭建区应包括拖拽组件、画布功能和生成响应式、跨平台的网页的能力。辅助功能包括给用户提供参考线、网格线以及一些复制、粘贴、删除的快捷功能。
-
配置区:用户选中组件后,对组件的样式、属性、事件/交互进行设置的地方。样式配置对于基础组件、可视化组件以及其他组件有不同的属性设置。基础组件的样式配置一般有字体大小、字体颜色、背景颜色、位置、宽度、高度等。对于可视化组件的样式需要根据不同的图表类型设置不同的样式。比如饼状图要设置饼图半径大小、显示标签位置等,而柱状图要设置柱子的粗细、柱子颜色等。属性配置同样也是不一样的。整理下表:
| 样式配置 | 属性配置 | 事件/交互配置 | |
|---|---|---|---|
| 基础组件 | 字体大小、字体颜色、背景颜色、位置、宽度、高度等。 | 对应组件 props 属性信息。如输入框组件(以 antdv为例)包括:placeholder、defaultValue、allowClear等 | 对应组件事件,如按钮组件有 click 事件。 |
| 可视化组件 | 位置、宽度、高度等。 | 对应 echarts 组件 setOption 里面的设置,包括 title、legend、xAxis、yAxis 等。以及数据项绑定也在此完成。 | 点击 click 事件和 hover 事件等。 |
| 其他 | 位置、宽度、高度等。 | 素材图片有 click 事件。 |
下面就各个模块的细节展开描述。
拖拽器
从物料区的组件可以拖拽到搭建区,对于可视化组件数据项绑定也需要进行数据的拖拽。对于拖拽技术的实现有以下几种:
-
原生 js 实现,给组件添加 draggable 属性。实现 dragstart 和 drop 两个事件。dragstart 事件,在拖拽刚开始时触发。它主要用于将拖拽的组件信息传递给画布。drop 事件,在拖拽结束时触发。主要用于接收拖拽的组件信息。
-
第三方成熟的拖拽库。vue 使用的库有 vuedraggable,vuedraggable 底层使用的是 sortablejs。react 组件库常用的是 react-dragable、react-moveable。
画布控制
整个画布应该包括移动组件、缩放组件、吸附、撤销重做等功能。实现思路是编辑区的画布使用相对定位 position: relative,每个组件设为绝对定位 position: absolute。这样我们就可以根据组件的 left 和 top 属性定位其在画布的位置。
缩放移动组件:当选中组件时,会出现8个圆点,帮助用户进行移动和缩放操作。可以将其封装成一个缩放移动组件,包在每个图表组件外层。移动缩放逻辑进行抽象。
撤销重做:用一个数组保存用户编辑的快照数据,同时记录当前的快照索引。撤销需要将快照索引减1,然后将对应的快照数据赋值给画布。重做只在撤销操作后显示,需要将快照索引加1,然后将对应的快照数据赋值给画布。
物料中心和配置区
当用户在物料中心的将组件拖放在搭建区的时候,该组件对应的配置属性要显示出来。可以给物料中心的每个组件的生成对应的配置文件。首先对组件的公共配置进行抽象生成公共配置,然后在为各个组件扩展其不同的配置。图表配置区属性设置可以参考 ChartCube 样式:ChartCube - 在线图表制作工具
底层搭建协议
底层搭建协议是数据可视化工具的基础,是数据映射的规范。一个页面可以划分为一个个的组件,这些组件可以使用 DSL 来描述。通常采用 JSON Schema 格式。以下是通过 TypeScript 接口形式定义的页面结构示例:
type Page = {
/** 页面标题 */
title: string;
/** favicon 地址 */
favicon: string;
/** 页面路由 */
path: string;
/** 组件列表 */
components: Component[]
}
type Component = {
/** 组件名称 */
name: string;
/** 组件类型 */
type: string;
/** 组件配置对象 */
config: Config
}
type Config = {
/** 样式配置 */
attrConfig: AttrConfig;
/** 属性配置 */
propConfig: PropConfig;
/** 事件配置 */
methodsConfig: MethodsConfig;
}
type AttrConfig = {
/** 绝对定位 top */
top: number;
/** 绝对定位 left */
left: number;
/** 组件宽度 */
width: number;
/** 组件高度 */
height: number;
...
}
type PropConfig = {
/** x轴绑定数据 */
xAxis: string[];
/** y轴绑定数据 */
yAxis: string[];
...
}
type MethodsConfig = {
/** 事件类型 */
type: string;
/** 事件名称 */
name: string;
/** 回调函数 */
fn: Function
}
数据映射就是将 JSON 数据转为页面可渲染的组件,以及配置区的配置信息;逆过程将页面的组件和它的配置信息转为 JSON 数据。将这份 JSON 数据保存在后台。实现细节包括组件渲染和属性联动两部分。
组件渲染:搭建区的每个组件拥有唯一的组件ID。组件信息包括组件的 ID、组件类型。根据组件信息可以确定组件的类型。根据配置信息的位置信息、数据绑定信息可以将其渲染在搭建区。
属性联动:在配置区对组件的信息编辑后,应该在搭建区实时响应,显示在组件上。本质是搭建区组件绑定的数据和配置区的数据是同一份数据,即可实现属性和组件的联动。
数据映射需要我们将组件的 JSON 数据保存在一个地方,同时应该具有响应式,达到配置区和搭建区的联动。在 Vue 中,有以下几种实现方案:
-
Provide/Inject 实现。在根级组件进行数据的管理。
-
Vue 状态管理库 Pinia。
-
父组件 Props 层层传递。
跨平台
根据绝对定位组件在网页配置时是自由的,可以任意放置不同位置。位置信息会存放在样式 JSON 数据中。组件的渲染是根据 JSON 数据动态变化的。在用户侧渲染的时候根据设备的不同,按照一定的规则进行渲染。PC 端与用户拖拉拽布局的页面样式保持一致,所见即所得。在手机端,为了图表能正常显示,用户可以看清,规定每个图表单独占一行显示,具体显示规则见”发布“章节。
除了上面的组件位置跨平台适用 PC 端和手机端,另一方面 echats 的 SVG 渲染模式内存占用更低,本身是支持手机端显示,为跨平台显示提供了可能。
发布
完成配置的资源最终要以网页的形式发布出去。不同配置页面共用同一个容器页面进行渲染。在用户侧的渲染流程如下:
容器页面负责发布后页面的呈现。容器页面跟搭建区很相近。搭建区有 PC 和移动端预览,而发布后的容器页面在用户实际使用时,也会有设备的差异。根据路由上页面 ID 的不同,在页面加载的时候请求后端数据,请求该页面的组件 JSON 数据。在渲染页面前会进行数据的解析,对于属性数据和事件直接绑定在对应的组件上。对于组件的位置信息则需要根据当前设备进一步判断渲染规则:
● 当前设备是 PC 端,则直接根据组件的位置信息进行渲染。
● 当前设备不是 PC 端时,则需要判断组件的宽度和设备宽度的关系。如果组件宽度大于设备宽度,需要根据宽度比(组件宽度/设备宽度)对组件进行缩小,缩小后让其一行显示;如果组件宽度小于等于设备宽度,则直接居中一行显示。
● 如果当前设备不是 PC 端时,调整 echarts 渲染模式为 SVG,优化渲染。
低代码开源工具-03-一个低代码(可视化拖拽)教学项目 | Echo Blog
从零设计可视化大屏搭建引擎
试着换个角度理解低代码平台设计的本质