diff --git a/jest.config.base.js b/jest.config.base.js
index af2e973948..6d436dcbee 100644
--- a/jest.config.base.js
+++ b/jest.config.base.js
@@ -7,7 +7,6 @@ module.exports = {
clearMocks: true,
collectCoverage: false,
verbose: true,
- forceExit: true,
collectCoverageFrom: [
'src/**/*.{ts,tsx,js,vue}',
'!**/node_modules/**',
diff --git a/packages/s2-core/__tests__/data/custom-table-col-fields.ts b/packages/s2-core/__tests__/data/custom-table-col-fields.ts
index a7cadc1437..5e9fbbc95d 100644
--- a/packages/s2-core/__tests__/data/custom-table-col-fields.ts
+++ b/packages/s2-core/__tests__/data/custom-table-col-fields.ts
@@ -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: '数量' },
+ ],
+ },
+ ],
+ },
+];
diff --git a/packages/s2-core/__tests__/spreadsheet/__snapshots__/custom-table-col-spec.ts.snap b/packages/s2-core/__tests__/spreadsheet/__snapshots__/custom-table-col-spec.ts.snap
index e7310e8255..aa55c6bcec 100644
--- a/packages/s2-core/__tests__/spreadsheet/__snapshots__/custom-table-col-spec.ts.snap
+++ b/packages/s2-core/__tests__/spreadsheet/__snapshots__/custom-table-col-spec.ts.snap
@@ -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 {
diff --git a/packages/s2-core/__tests__/spreadsheet/custom-table-col-spec.ts b/packages/s2-core/__tests__/spreadsheet/custom-table-col-spec.ts
index 9c84fffe1b..0ec0afe282 100644
--- a/packages/s2-core/__tests__/spreadsheet/custom-table-col-spec.ts
+++ b/packages/s2-core/__tests__/spreadsheet/custom-table-col-spec.ts
@@ -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';
@@ -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();
+ });
});
diff --git a/packages/s2-core/scripts/test-live.mjs b/packages/s2-core/scripts/test-live.mjs
index ac491d2ea5..5acde67f40 100644
--- a/packages/s2-core/scripts/test-live.mjs
+++ b/packages/s2-core/scripts/test-live.mjs
@@ -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 {
diff --git a/packages/s2-core/src/facet/base-facet.ts b/packages/s2-core/src/facet/base-facet.ts
index 440fffcd59..0ea141855f 100644
--- a/packages/s2-core/src/facet/base-facet.ts
+++ b/packages/s2-core/src/facet/base-facet.ts
@@ -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;
+ }
+ }
+ }
+
/**
* 将每一层级的采样节点更新为高度最大的节点 (未隐藏, 非汇总节点)
*/
diff --git a/packages/s2-core/src/facet/pivot-facet.ts b/packages/s2-core/src/facet/pivot-facet.ts
index cad5b22972..dc423659eb 100644
--- a/packages/s2-core/src/facet/pivot-facet.ts
+++ b/packages/s2-core/src/facet/pivot-facet.ts
@@ -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. 计算所有节点的高度
@@ -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[],
diff --git a/packages/s2-core/src/facet/table-facet.ts b/packages/s2-core/src/facet/table-facet.ts
index aae599341b..5e26b85d9f 100644
--- a/packages/s2-core/src/facet/table-facet.ts
+++ b/packages/s2-core/src/facet/table-facet.ts
@@ -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);
@@ -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!;
diff --git a/packages/s2-react/scripts/test-live.mjs b/packages/s2-react/scripts/test-live.mjs
index 72d2d0a299..5ce0d08372 100644
--- a/packages/s2-react/scripts/test-live.mjs
+++ b/packages/s2-react/scripts/test-live.mjs
@@ -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 {
diff --git a/s2-site/docs/common/interaction.zh.md b/s2-site/docs/common/interaction.zh.md
index bfba535e98..b07d72a0ec 100644
--- a/s2-site/docs/common/interaction.zh.md
+++ b/s2-site/docs/common/interaction.zh.md
@@ -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) | | |
diff --git a/s2-site/docs/manual/advanced/interaction/hide-columns.zh.md b/s2-site/docs/manual/advanced/interaction/hide-columns.zh.md
index bb41106c36..e7e7a06f09 100644
--- a/s2-site/docs/manual/advanced/interaction/hide-columns.zh.md
+++ b/s2-site/docs/manual/advanced/interaction/hide-columns.zh.md
@@ -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)。
+
+
+ 如何获取列头 ID?
+
+```ts | pure
+const s2 = new TableSheet()
+
+await s2.render()
+
+console.log(s2.facet.getColNodes())
+```
+
+
```ts
const s2DataConfig = {
@@ -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) 同理,这里不再赘述。
如何获取列头 ID?
@@ -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)
@@ -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);
diff --git a/s2-site/examples/interaction/advanced/demo/pivot-hide-columns.ts b/s2-site/examples/interaction/advanced/demo/pivot-hide-columns.ts
index 502f131e14..3a925318e3 100644
--- a/s2-site/examples/interaction/advanced/demo/pivot-hide-columns.ts
+++ b/s2-site/examples/interaction/advanced/demo/pivot-hide-columns.ts
@@ -44,7 +44,7 @@ fetch(
height: 480,
interaction: {
// 透视表默认隐藏需要指定唯一列头 id
- // 可通过 `s2.facet.getColNodes()` 获取列头节点查看i d
+ // 可通过 `s2.facet.getColNodes()` 获取列头节点查看 id
hiddenColumnFields: ['root[&]家具[&]沙发[&]number'],
},
tooltip: {
diff --git a/s2-site/examples/interaction/advanced/demo/table-hide-columns.ts b/s2-site/examples/interaction/advanced/demo/table-hide-columns.ts
index 7a7333357a..636ab26332 100644
--- a/s2-site/examples/interaction/advanced/demo/table-hide-columns.ts
+++ b/s2-site/examples/interaction/advanced/demo/table-hide-columns.ts
@@ -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: {