Skip to content

Commit

Permalink
fix: 修复明细表自定义列头时, 隐藏列头后出现空白区域 close #3044 (#3046)
Browse files Browse the repository at this point in the history
* fix: 修复明细表自定义列头时, 隐藏列头后出现空白区域 close #3044

* test: 更新快照
  • Loading branch information
lijinke666 authored Dec 20, 2024
1 parent feab43f commit 7e30008
Show file tree
Hide file tree
Showing 13 changed files with 156 additions and 70 deletions.
1 change: 0 additions & 1 deletion jest.config.base.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ module.exports = {
clearMocks: true,
collectCoverage: false,
verbose: true,
forceExit: true,
collectCoverageFrom: [
'src/**/*.{ts,tsx,js,vue}',
'!**/node_modules/**',
Expand Down
27 changes: 27 additions & 0 deletions packages/s2-core/__tests__/data/custom-table-col-fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,30 @@ export const customColMultipleColumns: CustomTreeNode[] = [
children: [],
},
];

export const customColMultipleColumns2: CustomTreeNode[] = [
{
field: 'area',
title: '地区',
children: [
{
field: 'province',
title: '省份',
children: [
{
field: 'type',
title: '类型',
},
],
},
{
field: 'city',
title: '城市',
children: [
{ field: 'price', title: '价格', description: '价格描述' },
{ field: 'number', title: '数量' },
],
},
],
},
];
Original file line number Diff line number Diff line change
@@ -1,5 +1,46 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`TableSheet Custom Tests should calc correctly cell conditions after hide first level node 1`] = `
Array [
Object {
"height": 90,
"width": 80,
"x": 0,
"y": 0,
},
Object {
"height": 30,
"width": 519,
"x": 80,
"y": 0,
},
Object {
"height": 30,
"width": 0,
"x": 0,
"y": 30,
},
Object {
"height": 30,
"width": 519,
"x": 80,
"y": 30,
},
Object {
"height": 30,
"width": 259.5,
"x": 80,
"y": 60,
},
Object {
"height": 30,
"width": 259.5,
"x": 339.5,
"y": 60,
},
]
`;

exports[`TableSheet Custom Tests should calc correctly col index of leaf nodes 1`] = `
Array [
Object {
Expand Down
31 changes: 31 additions & 0 deletions packages/s2-core/__tests__/spreadsheet/custom-table-col-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import type { S2DataConfig, S2Options } from '@/common/interface';
import type { CustomRect } from '@/engine';
import { SpreadSheet, TableSheet } from '@/sheet-type';
import type { Group } from '@antv/g';
import { pick } from 'lodash';
import { waitForRender } from 'tests/util';
import { getContainer } from 'tests/util/helpers';
import { KEY_GROUP_COL_RESIZE_AREA } from '../../src/common/constant';
import {
customColMultipleColumns,
customColMultipleColumns2,
customColSimpleColumns,
} from '../data/custom-table-col-fields';
import { data } from '../data/mock-dataset.json';
Expand Down Expand Up @@ -333,4 +335,33 @@ describe('TableSheet Custom Tests', () => {
);
},
);

// https://github.com/antvis/S2/issues/3044
test('should calc correctly cell conditions after hide first level node', async () => {
// 类型
const hiddenColumns = ['root[&]area[&]province[&]type'];

s2.setDataCfg({
...baseDataConfig,
fields: {
columns: customColMultipleColumns2,
},
});
s2.setOptions({
seriesNumber: {
enable: true,
},
});
await s2.render();

await waitForRender(s2, () => {
s2.interaction.hideColumns(hiddenColumns);
});

const colNodes = s2.facet
.getColNodes()
.map((node) => pick(node, ['x', 'y', 'width', 'height']));

expect(colNodes).toMatchSnapshot();
});
});
2 changes: 1 addition & 1 deletion packages/s2-core/scripts/test-live.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import ora from 'ora';
inquirer.registerPrompt('autocomplete', autoCompletePrompt);

function run(path) {
const command = `cross-env DEBUG_MODE=1 npx jest ${path} --passWithNoTests`;
const command = `cross-env DEBUG_MODE=1 npx jest ${path} --passWithNoTests --detectOpenHandles`;
const jestSpinner = ora(`[测试运行中]: ${command}`).start();

try {
Expand Down
32 changes: 32 additions & 0 deletions packages/s2-core/src/facet/base-facet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,38 @@ export abstract class BaseFacet {
return height;
}

/**
* 根据叶子节点宽度计算所有父级节点宽度和 x 坐标
*/
protected calculateColParentNodeWidthAndX(colLeafNodes: Node[]) {
let prevColParent: Node | null = null;
let i = 0;

const leafNodes = colLeafNodes.slice(0);

while (i < leafNodes.length) {
const node = leafNodes[i++];
const parentNode = node?.parent;

if (prevColParent !== parentNode && parentNode) {
leafNodes.push(parentNode);

const firstVisibleChildNode = parentNode.children?.find(
(childNode) => childNode.width,
);
// 父节点 x 坐标 = 第一个未隐藏的子节点的 x 坐标
const parentNodeX = firstVisibleChildNode?.x || 0;
// 父节点宽度 = 所有子节点宽度之和
const parentNodeWidth = sumBy(parentNode.children, 'width');

parentNode.x = parentNodeX;
parentNode.width = parentNodeWidth;

prevColParent = parentNode;
}
}
}

/**
* 将每一层级的采样节点更新为高度最大的节点 (未隐藏, 非汇总节点)
*/
Expand Down
35 changes: 1 addition & 34 deletions packages/s2-core/src/facet/pivot-facet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export class PivotFacet extends FrozenFacet {
// 1. 计算叶子节点宽度
this.calculateColLeafNodesWidth(layoutResult);
// 2. 根据叶子节点宽度计算所有父级节点宽度和 x 坐标, 便于计算自动换行后节点的真实高度
this.calculateColNodeWidthAndX(colLeafNodes);
this.calculateColParentNodeWidthAndX(colLeafNodes);
// 3. 计算每一层级的采样节点
this.updateColsHierarchySampleMaxHeightNodes(colsHierarchy, rowsHierarchy);
// 4. 计算所有节点的高度
Expand Down Expand Up @@ -376,39 +376,6 @@ export class PivotFacet extends FrozenFacet {
});
}

/**
* Auto column no-leaf node's width and x coordinate
* @param colLeafNodes
*/
protected calculateColNodeWidthAndX(colLeafNodes: Node[]) {
let prevColParent: Node | null = null;
let i = 0;

const leafNodes = colLeafNodes.slice(0);

while (i < leafNodes.length) {
const node = leafNodes[i++];
const parentNode = node?.parent;

if (prevColParent !== parentNode && parentNode) {
leafNodes.push(parentNode);

const firstVisibleChildNode = parentNode.children?.find(
(childNode) => childNode.width,
);
// 父节点 x 坐标 = 第一个未隐藏的子节点的 x 坐标
const parentNodeX = firstVisibleChildNode?.x || 0;
// 父节点宽度 = 所有子节点宽度之和
const parentNodeWidth = sumBy(parentNode.children, 'width');

parentNode.x = parentNodeX;
parentNode.width = parentNodeWidth;

prevColParent = parentNode;
}
}
}

protected getColLeafNodesWidth(
colNode: Node,
colLeafNodes: Node[],
Expand Down
27 changes: 1 addition & 26 deletions packages/s2-core/src/facet/table-facet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ export class TableFacet extends FrozenFacet {
) {
// 先计算宽度, 再计算高度, 确保计算多行文本时能获取到正确的最大文本宽度
this.calculateColLeafNodesWidth(colLeafNodes, colsHierarchy);
this.calculateColNodeWidthAndX(colLeafNodes);
this.calculateColParentNodeWidthAndX(colLeafNodes);
this.updateColsHierarchySampleMaxHeightNodes(colsHierarchy);
this.calculateColNodesHeight(colsHierarchy);
this.updateCustomFieldsSampleNodes(colsHierarchy);
Expand All @@ -520,31 +520,6 @@ export class TableFacet extends FrozenFacet {
});
}

/**
* Auto column no-leaf node's width and x coordinate
* @param colLeafNodes
*/
private calculateColNodeWidthAndX(colLeafNodes: Node[]) {
let prevColParent: Node | null = null;
const leafNodes = colLeafNodes.slice(0);

while (leafNodes.length) {
const node = leafNodes.shift();
const parent = node?.parent;

if (prevColParent !== parent && parent) {
leafNodes.push(parent);
// parent's x = first child's x
parent.x = parent.children[0].x;
// parent's width = all children's width
parent.width = parent.children
.map((childNode) => childNode.width)
.reduce((sum, current) => sum + current, 0);
prevColParent = parent;
}
}
}

private getCompactColNodeWidth(colNode: Node) {
const { theme, dataSet } = this.spreadsheet;
const { bolderText: colCellTextStyle } = theme.colCell!;
Expand Down
2 changes: 1 addition & 1 deletion packages/s2-react/scripts/test-live.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import ora from 'ora';
inquirer.registerPrompt('autocomplete', autoCompletePrompt);

function run(path) {
const command = `cross-env DEBUG_MODE=1 npx jest ${path} --passWithNoTests`;
const command = `cross-env DEBUG_MODE=1 npx jest ${path} --passWithNoTests --detectOpenHandles`;
const jestSpinner = ora(`[测试运行中]: ${command}`).start();

try {
Expand Down
2 changes: 1 addition & 1 deletion s2-site/docs/common/interaction.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ order: 5
| selectedCellsSpotlight | 是否开启选中高亮聚光灯效果 | `boolean` | `false` | |
| hoverHighlight | 鼠标悬停时高亮当前单元格,以及所对应的行头,列头 | `boolean` | `true` | |
| hoverFocus | 鼠标悬停在当前单元格超过默认 800ms 后,保持当前高亮,显示 tooltip,悬停时间通过设置 `duration` 来控制 | `boolean \| {duration: number}` | `true` | |
| hiddenColumnFields | 用于配置默认隐藏的列,透视表需要配置列头唯一 id, 明细表配置列头 field 字段即可 | `string[]` | | |
| hiddenColumnFields | 用于配置默认隐藏的列,`透视表``多列头明细表` 需要配置列头唯一 id, `单列头明细表` 配置列头 field 字段即可 (即:`s2DataConfig.fields.columns`). [了解更多](/manual/advanced/interaction/hide-columns) | `string[]` | | |
| copy | 单元格复制配置 | [Copy](#copy) | | |
| customInteractions | 自定义交互 [详情](/manual/advanced/interaction/custom) | [CustomInteraction[]](#custominteraction) | | |
| scrollSpeedRatio | 用于控制滚动速率,分水平和垂直两个方向,默认为 1 | [ScrollSpeedRatio](#scrollspeedratio) | | |
Expand Down
23 changes: 18 additions & 5 deletions s2-site/docs/manual/advanced/interaction/hide-columns.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,20 @@ const s2Options = {

![preview](https://gw.alipayobjects.com/zos/antfincdn/GHizMg2ok/f8d667c9-910a-40da-a6e3-74c238e7afa8.png)

对于 [自定义列头](/manual/advanced/custom/custom-header#21-%E8%87%AA%E5%AE%9A%E4%B9%89%E5%88%97%E5%A4%B4) 的明细表,指定 `field` 字段。
对于 [自定义列头](/manual/advanced/custom/custom-header#21-%E8%87%AA%E5%AE%9A%E4%B9%89%E5%88%97%E5%A4%B4) 的明细表,需要指定单元格的对应 [节点 id](/api/basic-class/node)

<details>
<summary>如何获取列头 ID?</summary>

```ts | pure
const s2 = new TableSheet()

await s2.render()

console.log(s2.facet.getColNodes())
```

</details>

```ts
const s2DataConfig = {
Expand All @@ -81,14 +94,14 @@ const s2DataConfig = {

const s2Options = {
interaction: {
hiddenColumnFields: ['a-1-1']
hiddenColumnFields: ['root[&]a-1[&]a-1-1']
}
}
```

### 2. 透视表

透视表存在多列头,需要指定列头对应的 [节点 id](/api/basic-class/node), 如果是 [自定义列头](/manual/advanced/custom/custom-header#12-%E8%87%AA%E5%AE%9A%E4%B9%89%E5%88%97%E5%A4%B4) , 那么和明细表相同,指定 `field` 字段即可,这里不再赘述。
透视表存在多列头,需要指定列头对应的 [节点 id](/api/basic-class/node), [自定义列头](/manual/advanced/custom/custom-header#12-%E8%87%AA%E5%AE%9A%E4%B9%89%E5%88%97%E5%A4%B4) 同理,这里不再赘述。

<details>
<summary>如何获取列头 ID?</summary>
Expand Down Expand Up @@ -158,7 +171,7 @@ const s2Options = {
[查看所有 API](/api/basic-class/interaction)

```ts
const s2 = new PivotSheet(...)
const s2 = new TableSheet(...)

const hiddenColumnFields = ['province', 'type', 'price']
s2.interaction.hideColumns(hiddenColumnFields)
Expand All @@ -171,7 +184,7 @@ s2.interaction.hideColumns(hiddenColumnFields)
```ts
import { S2Event } from '@antv/s2'

const s2 = new PivotSheet(...);
const s2 = new TableSheet(...);

s2.on(S2Event.COL_CELL_EXPANDED, (cell) => {
console.log('列头展开', cell);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fetch(
height: 480,
interaction: {
// 透视表默认隐藏需要指定唯一列头 id
// 可通过 `s2.facet.getColNodes()` 获取列头节点查看i d
// 可通过 `s2.facet.getColNodes()` 获取列头节点查看 id
hiddenColumnFields: ['root[&]家具[&]沙发[&]number'],
},
tooltip: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ fetch('https://assets.antv.antgroup.com/s2/basic-table-mode.json')
height: 480,
interaction: {
// 默认隐藏 [省份] 和 [价格]
// 如果是自定义列头, 需要指定 `id`, 可通过 `s2.facet.getColNodes()` 获取列头节点查看 id
hiddenColumnFields: ['province', 'price'],
},
tooltip: {
Expand Down

0 comments on commit 7e30008

Please sign in to comment.