Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 修复明细表自定义列头时, 隐藏列头后出现空白区域 close #3044 #3046

Merged
merged 2 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

没有任何改动, 移动到 base-facet, 给明细表复用, 多列头下隐藏透视表之前修复过, 现在保持两边逻辑统一

// 父节点宽度 = 所有子节点宽度之和
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 @@ -501,7 +501,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 @@ -511,31 +511,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
Loading