高性能多维分析表格实现原理剖析

VTable 是 VisActor 可视化体系中的表格组件库,基于可视化渲染引擎 VRender 进行封装。 VTable 以其优异的性能表现,丰富的可视化能力,迅速得到大量用户的认可。同时也有大批开发者对其实现原理感兴趣,我们将撰写一系列文章来进行详细介绍。

本篇文章介绍一下VTable的架构设计和底层实现。

模块简介

Options

Options 是用户传入的表格配置,用来描述表格的结构、内容和样式。Options中主要有以下几类配置:

  • 列表配置:列表的表头配置,转置配置,以及列(行)对应的单元格类型等
  • 透视表配置:透视表行列表头配置,指标所在位置,以及指标对应的单元格类型等
  • 表格宽高相关配置:表格长宽方向的显示模式(依内容自动宽高、适应容器等),表格的默认宽高等
  • 表格状态相关配置:表格的冻结、排序等状态
  • 表格组件相关配置:表格的标题、菜单、滚动条等组件配置

详细的Options配置可以参考VTable配置文档 www.visactor.io/vtable/opti...

Dataset

用户通过Record将数据传入传入,除了原始数据外,用户还可以通过配置Filter自定义数据的过滤规则,以及通过配置Sort定义数据在表格中的显示顺序;在透视表中,Satistics模块可以对数据进行数据统计,依据用户的配置计算相应的小计、总计、平均等统计信息。

详细的数据统计相关配置可以参考VTable配置文档 www.visactor.io/vtable/opti...

Theme

Theme模块管理表格的全局样式,通过Theme模块可以配置表头单元格和内容单元格的样式(背景、边框、文字样式等),也可以配置表格整体的边框、圆角、阴影等,还可以配置菜单、标题、滚动条等表格组件的样式。

详细的主题相关配置可以参考VTable配置文档 www.visactor.io/vtable/opti...

Layout

Layout模块负责表格的整体布局,包括通过配置生成行列表头,分配单元格的行列号等任务。

在ListTable中,Layout分析columns配置,生成表头单元格信息;在PivotTable中,Layout分析columnTreerowTreecolumnsrows配置,生成行列表头单元格信息;表头单元格的合并信息也在此时产生,以下图为例,由于其中Full Name列配置了多级标题,因此同级的ID列表头为上下两个单元格合并,Full Name列的上层表格为左右两个单元格合并:

在表头单元格信息生成后,表格整体的行列信息(表头区域的行列范围、内容区域的行列范围等),以及表格中每条数据对应的单元格行列坐标也由Layout模块计算得出。

一些布局结构更新操作(树形结构折叠展开,拖拽改变行列位置等),Layout模块会更新表头,表格整体的行列信息和数据对应的单元格行列坐标,随后通过Scenegraph模块更新相应的单元格节点。

State

State模块管理者表格当前的状态,包括冻结、选中、hover、滚动等等的表格状态。在状态改变时,State模块会处理相关的变更信息,改变保存的表格状态,并触发Scenegraph模块的更新,改变相应的单元格节点内容与样式,进而改变画面中表格的展示形态。以列宽改变交互为例:

Event

Event模块负责表格中监听和触发事件,表格内监听的交互事件会触发State模块相应的状态更新,部分表格的状态的更新也会通过Event模块触发表格定义的事件类型。其中Event模块管理事件主要分为三类:

  • 交互事件:Event模块会监听VRender图元的交互事件,并触发相应的表格交互事件(MOUSEMOVE_CELL, CLICK_CELL, MOUSELEAVE_CELL等),供表格内部模块以及用户监听使用。
  • 表格事件:表格事件是指有基础交互触发的表格相应状态改变时,触发的表格定义的事件,例如单元格选择SELECTED_CELL,列宽调整RESIZE_COLUMN,表格滚动SCROLL,拖拽改变表头位置CHANGE_HEADER_POSITION等。
  • 自定义事件:自定义事件是指表格内组件或用户定义的事件,由定义方按需求触发和监听使用,例如显示菜单SHOW_MENU,图例点击切换LEGEND_CHANGE,选择框状态改变CHECKBOX_STATE_CHANGE等。

Scenegraph

Scenegraph模块负责表格场景节点的创建与更新,表格整体场景节点是基于VRender提供的图元创建的场景树结构,按照表格->表头/内容->列->单元格->单元格内容的组织顺序,一层层构建而成。

Scenegraph模块将表格分为以下几个区域:

这几个区域所覆盖的单元格行列区域由Layout模块计算所得,初始化的时候Scenegraph模块会分别创建这个几个区域的的单元格节点。Scenegraph模块除了创建单元格节点外,还提供场景节点相关的查询和更新功能,例如通过行列号查找相应的单元格节点,更新单元格节点内的图元树形,添加和删除单元格节点等。

单元格类型

单元格节点会依据当前单元格类型,在单元格中创建相应的图元:

  • text/link: text/link类型单元格中为Text图元,link类型会有不同的样式及点击跳转交互
  • image/video: image/video类型单元格中为Image图元,video类型有点击播放交互
  • progressbar: progressbar类型单元格为进度图,其中为Rect图元和Text图元的组合
  • sparkline: sparkline类型单元格为迷你图,其中为Line图元和Symbol等图元的组合
  • checkbox: checkbox类型单元格为选中框,其中为Symbol图元和Text等图元的组合
  • chart: chart类型单元格为图表,其中为VChart图表实例

单元格中如果有图标(表头单元格或内容单元格配置icon属性),相应的Image图元也会创建在相应的单元格节点中。

ProgressProxy

ProgressProxyScenegraph模块中的一个子模块,主要负责大数据量下首屏和交互时的性能优化。ProgressProxy模块会定义场景节点中维护的行列最大数量限制,以避免超大数据量下,场景节点过多导致的超长创建和更新时间。在首屏加载过程中,ProgressProxy模块会控制节点的创建,首先创建屏幕范围内的单元格,随后异步渐进完成场景节点的创建。在大数据量滚动时,ProgressProxy模块会动态更新场景节点,滚动期间,按照滚动的方向,一部分单元格会更新其在场景树中的位置,并更新单元格内的图元,完成滚动效果。

Render

VTable的底层渲染由VRender实现,Scenegraph模块组织好的场景树会加载到VRender的Stage中,进行渲染;VRender提供的按需重绘及合并异步渲染能能力,支持了VTable的高性能渲染需求。

VRender参考 github.com/VisActor/VR...

从数据到画面

初始化

接下来,我们来简单介绍一下VTable初始化一个表格的完整流程:

  1. 基础模块初始化

第一步,在创建VTable实例后,会初始化各个模块,创建表格渲染的Canvas元素。Scenegraph模块会创建VRender Stage,用来管理整个渲染过程,并生成基础的场景节点结构;Event模块会绑定表格内使用的交互事件,表格事件和自定义事件;State模块会依据options配置设置表格初始的各项状态。Layout模块依据options计算行列表头信息,以及表格整体的行列信息,从而得到每条数据对应的行列坐标。

  1. 接收处理数据

第二步,数据处理,已经用户配置的过滤和排序规则,处理Record数据。如果有树形结构和数据分析的需求,会进一步处理数据,生成相应的结果信息。完成数据处理后,会更新Layout模块中的表格行列数目信息。

  1. 场景节点生成与渲染

第三步,创建场景节点,依据布局结果和数据,生成相应的单元格场景节点。随后会依据样式配置表格根节点的边框等属性,并生成表格配套组件和其对应的场景节点。最后,依据body部分的单元格尺寸,更新相应容器的尺寸和滚动条节点的状态(尺寸、位置)。

完成所有场景节点的创建更新后,VRender Stage开始渲染整个场景树,表格就在Canvas元素中被绘制出来了。

状态更新

我们再以拖拽改变列宽为例,简单介绍一下VTable状态更新的完整流程:

  1. 接收mousedown事件,如果鼠标位置在列边缘,则开始拖拽改变列宽。State模块改变当前状态,并记录初始鼠标位置;Scenegraph模块显示列宽调整辅助组件,并触发表格重绘。
  1. 接收mousemove事件,如果在拖拽改变列宽过程中,State模块依据初始鼠标位置和当前鼠标位置,计算新列宽;Scenegraph模块更新相应节点的宽度属性和布局,以及列宽调整辅助组件的位置;State模块触发表格事件RESIZE_COLUMNScenegraph模块触发表格重绘。
  1. 接收mouseup事件,如果在拖拽改变列宽过程中,State模块结束列宽调整状态,并触发RESIZE_COLUMN_ENDScenegraph模块隐藏列宽调整辅助组件,并触发表格重绘。

欢迎交流

联系方式

项目官网:www.visactor.io/vtable

微信公众号(通过公众号菜单可以加入微信群和飞书群):

twiter:twitter.com/xuanhun1

今夜无月,期待你点亮星空,感谢Star:

githubgithub.com/VisActor/VT...

更多参考:

  1. 基于 VTable 的多维数据展示的原理与实践 - 掘金
  2. VTable------不只是高性能的多维数据分析表格,开源,免费,百万数据秒级渲染
  3. VisActor------面向叙事的智能可视化解决方案 - 掘金
  4. 火山引擎DataWind产品可视化能力揭秘 - 掘金
  5. 更多 VTable 示例
相关推荐
子兮曰8 小时前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰8 小时前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万9 小时前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝9 小时前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋9 小时前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
龙亘川10 小时前
明月照湾区,智启新赛道:从顶流文旅IP盛会看智慧文旅升级路径
人工智能·智慧城市·开源软件·数据可视化
Asa1213810 小时前
R语言实现多组学因子分析(MOFA)
数据分析
卡布鲁10 小时前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
龙亘川11 小时前
一网统管AI平台民生业务实践:基于城市数字底座赋能公积金业务服务升级
大数据·安全·智慧城市·开源软件·数据可视化·政务
漂着的圆木11 小时前
Agent 功能参与度:Copilot 怎么算
sql·数据分析·agent·githubcopilot·度量