导读
在蚂蚁的大数据研发平台中,数据表格是一类重要的业务组件。我们需要流畅的展示 SQL 查询出来的上万条结果,并对结果做筛选、排序、搜索、复制、框选、聚合分析等操作。同时也存在数据手工录入的场景,需要表格有可编辑的能力。所以我们最终需要的是一种 JavaScript 版的电子表格,类似一个简单的 Excel 工作簿。
本文记录的是,在开源软件不足以满足需求,同时商业软件价格高、定制难的情况下,我们如何基于开源 Canvas 表格渲染库 AntV S2 来实现拥有诸多功能的 React 大数据表格组件,并且解决了之前商业软件版本实现的性能问题和拓展性问题。
业务场景介绍
Dataphin 是蚂蚁内部的大数据研发平台,同时也有云上版本对外售卖。Dataphin 一站式提供数据采、建、管、用全生命周期的大数据能力。在 Dataphin 中有很多场景都用到了大数据表格。最典型的就是研发模块中,用来展示计算任务的运行结果:
以下是数据表格常用功能的演示:
行列冻结
搜索
筛选 & 排序
框选 & 复制
技术选型:为什么使用 AntV S2 ?
对于复交互的电子表格类组件来说,基于 Canvas 实现会比 DOM 实现有着更大的优势。从性能上说,DOM 渲染需要经过如下的渲染流程,所有的 UI 改动都会涉及内部数据结构的构建、样式的解析、布局的计算。最终才渲染出来:
而 Canvas 的渲染管线就比较简单,Canvas 的 API 直接和 Skia 这样的底层 2D 图形调用相对应,免去了 DOM 的解析和布局流程。所以基于 Canvas 的图形应用,有着更高的性能上限。特别是在富交互,大数据量的场景下。同时基于 Canvas 的应用也更容易编写复杂的图形交互,因为图形不再以矩形作为最小单元,而是可以任意绘制。所以我们在选型时主要考虑基于 Canvas 的产品。下面是对市场上已有的类 Excel 前端表格组件的一些分析:
产品名称 |
技术栈 |
开发商 |
费用 |
结论 |
Canvas |
公司 |
收费 |
市场上最强大的 Excel 组件,但需要比较高的授权费用,同时在多实例、大数据量的场景下,性能比较差,并且很难拓展和定制 UI |
|
Canvas |
个人 |
开源 |
开源的类 Excel 组件。都是个人作品,由社区力量维护,投入的持续性、稳定性无法保障,在产品细节体验上也不如 SpreadJS |
|
DOM |
公司 |
收费 |
DOM 实现。同时需要收费。 |
|
语雀、钉钉等表格服务 |
Canvas |
公司 |
/ |
通过服务化的 SDK 提供前后端一体的服务,而不是单纯的前端组件形式。同时拓展性也不如开源产品。 |
在市场上无法找到合适的选择之后,我们蚂蚁数据智能前端团队选择将内部的交叉表组件孵化为开源的 AntV S2 表格渲染引擎。
S2 是 AntV 团队推出的数据表可视化引擎,旨在提供高性能、易扩展、美观、易用的多维表格。不仅有丰富的分析表格形态,还内置丰富的交互能力,帮助用户更好地看数和做决策。
S 取自于 SpredSheet 的两个 S,2 也代表了透视表中的行列两个维度。S2 不仅有交叉表模式,还支持明细表模式。
明细表 透视表
明细表就是普通的表格。类似 Antd Table 组件。适用于明细数据的展示。比如我们一开始说到的 SQL 查询结果的预览等等。明细表组件流畅在支持 10w+ 条大数据展示的基础上,还支持丰富的交互:单选、刷选、复制到 Excel、快捷键多选、列宽高拖拽调节等等。方便用户快速的对数据做选择和操作。
表格功能实现
S2 的明细表为我们提供了一个很好的基础底座,关于明细表的功能,大家可以参考文档。接下来就聊聊如何在 明细表的基础上,利用 S2 的高拓展性设计,实现一款功能丰富的 React 大数据表格组件。其中一些常用功能内置到了 S2 中,比如行列冻结、复制等。另外还揭秘了一些 S2 的内部实现,比如虚拟滚动的原理。
功能大图
首先看一下大数据表格组件的功能大图:
上图的能力中,包含了数据展示、检索、导出、编辑等核心能力。其中分析方面的公式、聚合等能力是未来规划的。接下去会讲讲目前实现的这些核心功能的设计与实现。
交互
单元格编辑
单元格编辑是大数据表格在交互上遇到的最核心诉求。用户可以直接的编辑数据,录入数据。在手工维度表、调试录入 Mock 数据等等场景有着广泛的使用。由于 S2 的定位是分析表、明细表核心库,所以单元格编辑的能力并没有内置。这个能力需要大数据表格组件来扩展实现。
首先需要考虑的问题便是技术实现上,编辑能力是使用 DOM 还是 Canvas 实现?在功能开发之前,我们调研了业界各类主体基于 Canvas 的电子表格库,结果大致如下:
库 |
单元格编辑实现 |
SpreadJS |
DOM |
语雀表格 |
DOM |
x-spreadsheet |
DOM |
可以看到,主流的实现都选择了 DOM 作为单元格编辑的载体。考虑到光标绘制,文本选中,换行逻辑等等一系列在 DOM 中都将由浏览器实现,在 Canvas 中则需要重新