logo

S2

  • 使用文档
  • API 文档
  • 图表示例
  • 在线体验
  • 更新日志
  • 所有产品antv logo arrow
  • 2.x
  • 简介
  • 快速上手
  • 基础教程
    • 基本概念
      Updated
    • 表形态
      • 透视表
        Updated
      • 明细表
        Updated
    • 字段标记
      Updated
    • 小计总计
    • 排序
      • 基础排序
        Updated
      • 组内排序
        Updated
    • 主题配置
      Updated
    • Tooltip
      Updated
    • 数据格式化
      New
    • 多行文本
      New
    • 国际化
    • 分页
      New
  • 进阶教程
    • 单元格渲染类型
      • 链接
      • 图片
        New
      • 视频
        New
      • 迷你图表
      • 结合@antv/g2
      • 自定义渲染
    • 自定义
      • 自定义 Hook
        Updated
      • 自定义行列头分组
        New
      • 自定义 Icon
        Updated
      • 自定义单元格对齐方式
        Updated
      • 自定义单元格宽高
        Updated
      • 自定义排序操作
        Updated
      • 自定义折叠/展开节点
        New
    • 交互
      • 基础交互
        Updated
      • 自定义交互
      • 隐藏列头
        Updated
      • 行列宽高调整
        Updated
      • 合并单元格
      • 滚动
        Updated
      • 复制与导出
        New
      • 高亮/选中单元格
        New
    • 分析组件
      • 简介
        New
      • 高级排序
        Updated
      • 维度切换
        Updated
      • 导出
        Updated
      • 分页
        Updated
      • 维度下钻
        Updated
    • 表格组件
      • 编辑表
      • 趋势分析表
        Updated
    • 高清适配
      Updated
    • 获取表格实例
    • 表格自适应
    • 获取单元格数据
      Updated
    • 注册 AntV/G 插件
      New
    • 透视组合图
      Experimental
    • Vue 3.0 组件 (停止维护)
  • 扩展阅读
    • 数据流处理
      • 透视表
      • 明细表
    • 布局流程
      • 透视表
      • 明细表
    • 性能介绍
      Updated
  • 贡献指南
  • 常见问题
  • S2 2.0 升级指南

透视表

上一篇
Vue 3.0 组件 (停止维护)
下一篇
明细表

Resources

Ant Design
Galacea Effects
Umi-React 应用开发框架
Dumi-组件/文档研发工具
ahooks-React Hooks 库

社区

体验科技专栏
seeconfSEE Conf-蚂蚁体验科技大会

帮助

GitHub
StackOverflow

more products更多产品

Ant DesignAnt Design-企业级 UI 设计语言
yuque语雀-知识创作与分享工具
EggEgg-企业级 Node 开发框架
kitchenKitchen-Sketch 工具集
GalaceanGalacean-互动图形解决方案
xtech蚂蚁体验科技
© Copyright 2025 Ant Group Co., Ltd..备案号:京ICP备15032932号-38

Loading...

本文会介绍透视表的数据流处理过程,让读者更直观的了解 S2 内部数据逻辑。

数据处理流程是:

s2-data-process

dataSet

以下图透视表为例:

透视表

以下的代码都是伪代码,只是为了说明关键步骤,数据流处理逻辑大部分都在 data-set 文件夹中。

原始数据

初始配置和数据如下:

const dataCfg = {
fields: {
rows: ['province', 'city'],
columns: ['type', 'sub_type'],
values: ['price'],
},
data: [
{
price: 1,
province: '浙江省',
city: '杭州市',
type: '家具',
sub_type: '桌子',
},
{
price: 2,
province: '浙江省',
city: '绍兴市',
type: '家具',
sub_type: '桌子',
},
{
price: 3,
province: '浙江省',
city: '杭州市',
type: '家具',
sub_type: '沙发',
},
{
price: 4,
province: '浙江省',
city: '绍兴市',
type: '家具',
sub_type: '沙发',
},
]
};
const options = {
width: 600,
height: 600
};
<SheetComponent
dataCfg={dataCfg}
options={options}
sheetType="pivot"
/>

数据处理

processDataCfg

这一步主要是对用户传入的配置根据当前的表格类型进行配置转换,主要是处理 fields 的信息,增加 meta 配置,并根据 valueInCols 配置,在rows或者columns中增加 $$extra$$ 指标字段。

transformIndexesData

在这一步,S2 会将用户传入的 data 信息做映射转换,从一维数组转换为多维数组 indexesData,并在转换过程中生成行列头的维度信息 rowPivotMeta,colPivotMeta。索引建立后,后续获取数据就能通过映射快速查询,增加查询效率。

以下面的数据为例:

{
price: 4,
province: '浙江省',
city: '绍兴市',
type: '家具',
sub_type: '沙发',
};

首先,处理数据,提取当前明细数据在初始配置条件下的行、列维度结果。

const rowDimensionValues = transformDimensionsValues(data, ['province', 'city']); // 结果是 ['浙江省', '绍兴市']
const colDimensionValues = transformDimensionsValues(data, ['type', 'sub_type']); // 结果是 ['家具', '沙发']

然后,根据数据的行列维度结果和 fields 配置信息,S2 会同步的生成 indexesData, rowPivotMeta 和 colPivotMeta

// indexesData 使用 prefix 区分普通数据和下钻数据
const prefix = 'province[&]city[&]type[&]sub_type';
// getDataPath 内部同步生成 rowPivotMeta 和 colPivotMeta 信息
// 第 0 位 始终是小计、总计的专属位,明细数据都是从第 1 位开始
const rowPath = getDataPath(rowDimensionValues); // 结果是 [1, 2];
const colPath = getDataPath(colDimensionValues); // 结果是 [1, 2];
const dataPath =[prefix, ...rowPath.concat(...colPath)] ; // 结果是 ['province[&]city[&]type[&]sub_type', 1, 2, 1, 2];
const indexesData={};
lodash.set(indexesData, dataPath, currentData);

对于表场景查询频率非常高,透视表本身的展现形式也表达了一种树形结构,因此我们选择了构建树形 Map 结构来实现 rowPivotMeta 和 colPivotMeta。

最后,按照上述流程,遍历所有数据,就能得到最终的 indexesData, rowPivotMeta 和 colPivotMeta,可以通过 S2 实例中的 dataSet 字段查看详情:

indexesDatarowPivotMeta

handleSort

rowPivotMeta 和 colPivotMeta 都是 Map 结构,当 Map 结构获取 keys 或者 values 时,是结果按照插入顺序排序的。当存在 sortParams 时,我们希望获取的结果顺序就是排序后的顺序,所以在这一步,会根据排序配置,重新生成 Map 结构,使之满足排序后的结果。在后续布局时,就无需在重新排序,可以加速布局效率。

数据获取

获取单个数据

当渲染透视表数据单元格时,需要获取对应的展示内容(数据)。举个示例,需要右下角单元格数据时,代码如下:

const data = getCellData({
query: { province: '浙江省', city: '绍兴市', type: '家具', sub_type: '沙发', $$extra$$: 'price' }
});

实现过程是,先拿到行、列维度枚举值:

const rowDimensionValues = transformDimensionsValues(query, ['province', 'city']); // ['浙江省', '绍兴市']
const colDimensionValues = transformDimensionsValues(query, ['type', 'sub_type', '$$extra$$']); // ['家具', '沙发', 'price']

然后通过枚举值获取数据查询路径,并从前面生成的多维数组中拿到具体数据。

const path = getDataPath({ rowDimensionValues, colDimensionValues });
const rawData = lodash.get(indexesData, path);

在拿到数据后,我们需要为原始数据增加 $$extra$$ 等信息,用于标识所选择的具体是哪个维度,因此,内部使用了 CellData 类对 rawData 进行包裹,对其行为进行增强。

const data = CellData.getCellData(rawData, query[EXTRA_FIELD]);
console.log(data); // { raw: rawData, extraField: "xxx" }

获取多个数据

如果想获取多个单元格数据,其大致流程和获取单个数据一致;获取多个单元格数据允许有维度缺失,会返回多个符合 query 的数据。

比如获取浙江省下的所有信息示例代码如下:

const dataList = getMultiData({
query: { province: '浙江省', $$extra$$: 'price' }
});

总结下,获取数据是通过查询条件,构造当前查询条件对应的数据路径,然后从多维数组中直接拿取。