From 2601e657c747fe304ce5ae99150fb282f767b374 Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Mon, 21 Apr 2025 17:39:38 +0800 Subject: [PATCH 1/2] fix: fix merge cell autoHeight #3752 --- .../fix-large-merge-autoHeight_2025-04-21-09-39.json | 10 ++++++++++ .../vtable/src/scenegraph/layout/compute-row-height.ts | 6 ++++-- packages/vtable/src/ts-types/base-table.ts | 3 +++ 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 common/changes/@visactor/vtable/fix-large-merge-autoHeight_2025-04-21-09-39.json diff --git a/common/changes/@visactor/vtable/fix-large-merge-autoHeight_2025-04-21-09-39.json b/common/changes/@visactor/vtable/fix-large-merge-autoHeight_2025-04-21-09-39.json new file mode 100644 index 0000000000..66f8a119d1 --- /dev/null +++ b/common/changes/@visactor/vtable/fix-large-merge-autoHeight_2025-04-21-09-39.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vtable", + "comment": "fix: fix merge cell autoHeight #3752", + "type": "none" + } + ], + "packageName": "@visactor/vtable" +} \ No newline at end of file diff --git a/packages/vtable/src/scenegraph/layout/compute-row-height.ts b/packages/vtable/src/scenegraph/layout/compute-row-height.ts index 27dc00c478..ac5f2e52f6 100644 --- a/packages/vtable/src/scenegraph/layout/compute-row-height.ts +++ b/packages/vtable/src/scenegraph/layout/compute-row-height.ts @@ -639,8 +639,9 @@ function computeCustomRenderHeight(col: number, row: number, table: BaseTableAPI const padding = getQuadProps(getProp('padding', actStyle, col, row, table)); height += padding[0] + padding[2]; } + const minSingleRowHeight = table.options.customConfig?.minSingleRowHeight ?? 2; return { - height: height / spanRow, + height: Math.max(height / spanRow, minSingleRowHeight), renderDefault }; } @@ -880,7 +881,8 @@ function computeTextHeight(col: number, row: number, cellType: ColumnTypeOption, } } } - return (Math.max(maxHeight, iconHeight) + padding[0] + padding[2]) / spanRow; + const minSingleRowHeight = table.options.customConfig?.minSingleRowHeight ?? 2; + return Math.max((Math.max(maxHeight, iconHeight) + padding[0] + padding[2]) / spanRow, minSingleRowHeight); } function getCellRect(col: number, row: number, table: BaseTableAPI) { diff --git a/packages/vtable/src/ts-types/base-table.ts b/packages/vtable/src/ts-types/base-table.ts index 5802c9e5ef..0bf44d7939 100644 --- a/packages/vtable/src/ts-types/base-table.ts +++ b/packages/vtable/src/ts-types/base-table.ts @@ -573,6 +573,9 @@ export interface BaseTableConstructorOptions { // 是否禁用内置图表激活 disableBuildInChartActive?: boolean; + + // 多行合并行号自动计算时单行最小行高,用在大量行合并的情况下,行高自动计算过小导致无法显示完整内容 + minSingleRowHeight?: number; }; // 部分特殊配置,兼容xTable等作用 animationAppear?: boolean | IAnimationAppear; From 799174cad083dbe8f871455417720702a84395ef Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Mon, 21 Apr 2025 17:41:44 +0800 Subject: [PATCH 2/2] feat: optimize large merge cell stick-text performance --- .../vtable/src/scenegraph/stick-text/index.ts | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/packages/vtable/src/scenegraph/stick-text/index.ts b/packages/vtable/src/scenegraph/stick-text/index.ts index 3c09560f7a..e152931819 100644 --- a/packages/vtable/src/scenegraph/stick-text/index.ts +++ b/packages/vtable/src/scenegraph/stick-text/index.ts @@ -45,6 +45,9 @@ export function handleTextStick(table: BaseTableAPI) { return; } + const horizontalUpdateTimeStamp = Date.now(); + const verticalUpdateTimeStamp = Date.now(); + // column header for (let row = 0; row < frozenRowCount; row++) { if (colEnd < colStart) { @@ -61,7 +64,8 @@ export function handleTextStick(table: BaseTableAPI) { table.tableNoFrameWidth - table.getRightFrozenColsWidth() + table.tableX, changedCells, style?.textStickBaseOnAlign, - table + table, + horizontalUpdateTimeStamp ); } }); @@ -87,7 +91,8 @@ export function handleTextStick(table: BaseTableAPI) { table.tableNoFrameHeight - table.getBottomFrozenRowsHeight() + table.tableY, changedCells, style?.textStickBaseOnAlign, - table + table, + verticalUpdateTimeStamp ); } }); @@ -109,7 +114,8 @@ export function handleTextStick(table: BaseTableAPI) { table.tableNoFrameHeight - table.getBottomFrozenRowsHeight() + table.tableY, changedCells, style?.textStickBaseOnAlign, - table + table, + verticalUpdateTimeStamp ); } }); @@ -129,7 +135,8 @@ export function handleTextStick(table: BaseTableAPI) { table.tableNoFrameWidth - table.getRightFrozenColsWidth() + table.tableX, changedCells, style?.textStickBaseOnAlign, - table + table, + horizontalUpdateTimeStamp ); } }); @@ -147,7 +154,8 @@ function adjustCellContentVerticalLayout( maxTop: number, changedCells: Map, textStickBaseOnAlign: boolean | undefined, - table: BaseTableAPI + table: BaseTableAPI, + updateTimeStamp: number ) { if ( isNumber(cellGroup.mergeStartCol) && @@ -158,11 +166,17 @@ function adjustCellContentVerticalLayout( const { colStart, colEnd, rowStart, rowEnd } = getCellMergeRange(cellGroup, table.scenegraph); for (let col = colStart; col <= colEnd; col++) { for (let row = rowStart; row <= rowEnd; row++) { - const singleCellGroup = table.scenegraph.getCell(col, row); + const singleCellGroup = table.scenegraph.highPerformanceGetCell(col, row); if (singleCellGroup.role !== 'cell') { continue; } - dealVertical(singleCellGroup, minTop, maxTop, changedCells, textStickBaseOnAlign); + if ((singleCellGroup as any).updateTimeStamp !== updateTimeStamp) { + dealVertical(singleCellGroup, minTop, maxTop, changedCells, textStickBaseOnAlign); + (singleCellGroup as any).updateTimeStamp = updateTimeStamp; + } else { + // do nothing + // console.log('ignore'); + } } } } else { @@ -260,7 +274,8 @@ function adjustCellContentHorizontalLayout( maxLeft: number, changedCells: Map, textStickBaseOnAlign: boolean | undefined, - table: BaseTableAPI + table: BaseTableAPI, + updateTimeStamp: number ) { if ( isNumber(cellGroup.mergeStartCol) && @@ -275,7 +290,13 @@ function adjustCellContentHorizontalLayout( if (singleCellGroup.role !== 'cell') { continue; } - dealHorizontal(singleCellGroup, minLeft, maxLeft, changedCells, textStickBaseOnAlign); + if ((singleCellGroup as any).updateTimeStamp !== updateTimeStamp) { + dealHorizontal(singleCellGroup, minLeft, maxLeft, changedCells, textStickBaseOnAlign); + (singleCellGroup as any).updateTimeStamp = updateTimeStamp; + } else { + // do nothing + // console.log('ignore'); + } } } } else {