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

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 示例
相关推荐
光影少年5 分钟前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
As977_6 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
susu10830189118 分钟前
vue3 css的样式如果background没有,如何覆盖有background的样式
前端·css
Ocean☾10 分钟前
前端基础-html-注册界面
前端·算法·html
Dragon Wu12 分钟前
前端 Canvas 绘画 总结
前端
CodeToGym16 分钟前
Webpack性能优化指南:从构建到部署的全方位策略
前端·webpack·性能优化
~甲壳虫17 分钟前
说说webpack中常见的Loader?解决了什么问题?
前端·webpack·node.js
~甲壳虫21 分钟前
说说webpack proxy工作原理?为什么能解决跨域
前端·webpack·node.js
Cwhat23 分钟前
前端性能优化2
前端
Tianyanxiao38 分钟前
如何利用探商宝精准营销,抓住行业机遇——以AI技术与大数据推动企业信息精准筛选
大数据·人工智能·科技·数据分析·深度优先·零售