From acb7f7b3af1a8ce42beec2ef7f16ee104912f55f Mon Sep 17 00:00:00 2001 From: biubiukam Date: Sat, 29 Aug 2026 03:10:06 +0800 Subject: [PATCH 1/6] fix: preserve pivot column widths after updateOption --- ...-group-for-first-screen-issue-5298.test.ts | 72 +++++++++++++++++++ .../progress/create-group-for-first-screen.ts | 10 ++- 2 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts diff --git a/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts b/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts new file mode 100644 index 000000000..25371dc65 --- /dev/null +++ b/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts @@ -0,0 +1,72 @@ +// @ts-nocheck +import { createGroupForFirstScreen } from '../src/scenegraph/group-creater/progress/create-group-for-first-screen'; +import { computeColsWidth } from '../src/scenegraph/layout/compute-col-width'; + +jest.mock('../src/scenegraph/layout/compute-col-width', () => ({ + computeColsWidth: jest.fn() +})); +jest.mock('../src/scenegraph/layout/compute-row-height', () => ({ + computeRowsHeight: jest.fn() +})); +jest.mock('../src/scenegraph/group-creater/column', () => ({ + createColGroup: jest.fn() +})); + +describe('createGroupForFirstScreen issue #5298', () => { + test('recalculates unresized columns when some columns keep manual widths', () => { + const makeGroup = () => ({ + firstChild: null, + lastChild: null, + setAttribute: jest.fn(), + setAttributes: jest.fn() + }); + const table = { + widthMode: 'standard', + heightMode: 'standard', + options: {}, + colCount: 3, + rowCount: 3, + frozenColCount: 1, + frozenRowCount: 1, + rowHeaderLevelCount: 1, + leftRowSeriesNumberCount: 0, + rightFrozenColCount: 0, + bottomFrozenRowCount: 0, + isListTable: () => false, + isPivotChart: () => false, + getFrozenColsWidth: () => 0, + getFrozenRowsHeight: () => 0, + scenegraph: { + leftBottomCornerGroup: makeGroup(), + rightTopCornerGroup: makeGroup(), + rightBottomCornerGroup: makeGroup(), + colHeaderGroup: makeGroup(), + rowHeaderGroup: makeGroup(), + bottomFrozenGroup: makeGroup(), + rightFrozenGroup: makeGroup(), + bodyGroup: makeGroup() + }, + internalProps: { + _widthResizedColMap: new Set([0]), + _heightResizedRowMap: new Set() + } + }; + const proxy = { + table, + firstScreenColLimit: 3, + firstScreenRowLimit: 3, + totalCol: 2, + totalRow: 2, + setParamsForRow: jest.fn(), + setParamsForColumn: jest.fn(), + progress: jest.fn(), + colStart: 0, + rowStart: 0 + }; + const groups = [makeGroup(), makeGroup(), makeGroup(), makeGroup(), makeGroup(), makeGroup()]; + + createGroupForFirstScreen(...groups, 0, 0, proxy); + + expect(computeColsWidth).toHaveBeenCalledWith(table, 0, 2); + }); +}); diff --git a/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts b/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts index 01b31ddeb..4014c125c 100644 --- a/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts +++ b/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts @@ -75,9 +75,13 @@ export function createGroupForFirstScreen( distRow = Math.min(proxy.firstScreenRowLimit - 1, table.rowCount - 1); } let bodyDistRow = Math.min(proxy.bodyBottomRow, distRow - table.bottomFrozenRowCount); - if (table.internalProps._widthResizedColMap.size === 0) { - // compute colums width in first screen - computeColsWidth(table, 0, distColForCompute ?? distCol); + const colEndForCompute = distColForCompute ?? distCol; + const hasUnresizedColumns = Array.from({ length: colEndForCompute + 1 }, (_, col) => + table.internalProps._widthResizedColMap.has(col) + ).some(resized => !resized); + if (hasUnresizedColumns) { + // Compute widths for new columns while preserving manually resized columns. + computeColsWidth(table, 0, colEndForCompute); } if (table.internalProps._heightResizedRowMap.size === 0) { From 6a0ef402e97b5a8f7310320cca45024826d0bcdc Mon Sep 17 00:00:00 2001 From: biubiukam Date: Sat, 29 Aug 2026 03:10:55 +0800 Subject: [PATCH 2/6] docs: update changlog of rush --- ...e-5298-clear-col-width-cache_2026-08-28-00-00.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/@visactor/vtable/fix-issue-5298-clear-col-width-cache_2026-08-28-00-00.json diff --git a/common/changes/@visactor/vtable/fix-issue-5298-clear-col-width-cache_2026-08-28-00-00.json b/common/changes/@visactor/vtable/fix-issue-5298-clear-col-width-cache_2026-08-28-00-00.json new file mode 100644 index 000000000..5c3ba761d --- /dev/null +++ b/common/changes/@visactor/vtable/fix-issue-5298-clear-col-width-cache_2026-08-28-00-00.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "packageName": "@visactor/vtable", + "comment": "fix: preserve pivot table column widths after updateOption (#5298)", + "type": "patch" + } + ], + "packageName": "@visactor/vtable", + "email": "biukam.w@gmail.com" +} From 46192b280e6f1f89c20935d286f297d2ff71772e Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Mon, 31 Aug 2026 10:13:00 +0800 Subject: [PATCH 3/6] fix: avoid allocating resized column scan array Co-Authored-By: Claude Sonnet 4.6 --- ...-group-for-first-screen-issue-5298.test.ts | 104 +++++++++++------- .../progress/create-group-for-first-screen.ts | 10 +- 2 files changed, 74 insertions(+), 40 deletions(-) diff --git a/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts b/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts index 25371dc65..893210961 100644 --- a/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts +++ b/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts @@ -13,44 +13,47 @@ jest.mock('../src/scenegraph/group-creater/column', () => ({ })); describe('createGroupForFirstScreen issue #5298', () => { + const makeGroup = () => ({ + firstChild: null, + lastChild: null, + setAttribute: jest.fn(), + setAttributes: jest.fn() + }); + + const createMockTable = () => ({ + widthMode: 'standard', + heightMode: 'standard', + options: {}, + colCount: 3, + rowCount: 3, + frozenColCount: 1, + frozenRowCount: 1, + rowHeaderLevelCount: 1, + leftRowSeriesNumberCount: 0, + rightFrozenColCount: 0, + bottomFrozenRowCount: 0, + isListTable: () => false, + isPivotChart: () => false, + getFrozenColsWidth: () => 0, + getFrozenRowsHeight: () => 0, + scenegraph: { + leftBottomCornerGroup: makeGroup(), + rightTopCornerGroup: makeGroup(), + rightBottomCornerGroup: makeGroup(), + colHeaderGroup: makeGroup(), + rowHeaderGroup: makeGroup(), + bottomFrozenGroup: makeGroup(), + rightFrozenGroup: makeGroup(), + bodyGroup: makeGroup() + }, + internalProps: { + _widthResizedColMap: new Set([0]), + _heightResizedRowMap: new Set() + } + }); + test('recalculates unresized columns when some columns keep manual widths', () => { - const makeGroup = () => ({ - firstChild: null, - lastChild: null, - setAttribute: jest.fn(), - setAttributes: jest.fn() - }); - const table = { - widthMode: 'standard', - heightMode: 'standard', - options: {}, - colCount: 3, - rowCount: 3, - frozenColCount: 1, - frozenRowCount: 1, - rowHeaderLevelCount: 1, - leftRowSeriesNumberCount: 0, - rightFrozenColCount: 0, - bottomFrozenRowCount: 0, - isListTable: () => false, - isPivotChart: () => false, - getFrozenColsWidth: () => 0, - getFrozenRowsHeight: () => 0, - scenegraph: { - leftBottomCornerGroup: makeGroup(), - rightTopCornerGroup: makeGroup(), - rightBottomCornerGroup: makeGroup(), - colHeaderGroup: makeGroup(), - rowHeaderGroup: makeGroup(), - bottomFrozenGroup: makeGroup(), - rightFrozenGroup: makeGroup(), - bodyGroup: makeGroup() - }, - internalProps: { - _widthResizedColMap: new Set([0]), - _heightResizedRowMap: new Set() - } - }; + const table = createMockTable(); const proxy = { table, firstScreenColLimit: 3, @@ -69,4 +72,31 @@ describe('createGroupForFirstScreen issue #5298', () => { expect(computeColsWidth).toHaveBeenCalledWith(table, 0, 2); }); + + test('stops scanning resized columns after finding an unresized column', () => { + const table = createMockTable(); + table.colCount = 10000; + table.widthMode = 'adaptive'; + table.internalProps._widthResizedColMap = { + has: jest.fn(col => col === 0) + }; + const proxy = { + table, + firstScreenColLimit: 3, + firstScreenRowLimit: 3, + totalCol: 2, + totalRow: 2, + setParamsForRow: jest.fn(), + setParamsForColumn: jest.fn(), + progress: jest.fn(), + colStart: 0, + rowStart: 0 + }; + const groups = [makeGroup(), makeGroup(), makeGroup(), makeGroup(), makeGroup(), makeGroup()]; + + createGroupForFirstScreen(...groups, 0, 0, proxy); + + expect(table.internalProps._widthResizedColMap.has).toHaveBeenCalledTimes(2); + expect(computeColsWidth).toHaveBeenCalledWith(table, 0, 9999); + }); }); diff --git a/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts b/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts index 4014c125c..8f8c44df0 100644 --- a/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts +++ b/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts @@ -76,9 +76,13 @@ export function createGroupForFirstScreen( } let bodyDistRow = Math.min(proxy.bodyBottomRow, distRow - table.bottomFrozenRowCount); const colEndForCompute = distColForCompute ?? distCol; - const hasUnresizedColumns = Array.from({ length: colEndForCompute + 1 }, (_, col) => - table.internalProps._widthResizedColMap.has(col) - ).some(resized => !resized); + let hasUnresizedColumns = false; + for (let col = 0; col <= colEndForCompute; col++) { + if (!table.internalProps._widthResizedColMap.has(col)) { + hasUnresizedColumns = true; + break; + } + } if (hasUnresizedColumns) { // Compute widths for new columns while preserving manually resized columns. computeColsWidth(table, 0, colEndForCompute); From 812c564b7043910f969f9749f9dee5548054ff66 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Mon, 31 Aug 2026 10:22:01 +0800 Subject: [PATCH 4/6] fix: preserve unresized row height recalculation Co-Authored-By: Claude Sonnet 4.6 --- ...-group-for-first-screen-issue-5298.test.ts | 50 +++++++++++++++++++ .../progress/create-group-for-first-screen.ts | 21 +++++--- 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts b/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts index 893210961..d17345206 100644 --- a/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts +++ b/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts @@ -1,6 +1,7 @@ // @ts-nocheck import { createGroupForFirstScreen } from '../src/scenegraph/group-creater/progress/create-group-for-first-screen'; import { computeColsWidth } from '../src/scenegraph/layout/compute-col-width'; +import { computeRowsHeight } from '../src/scenegraph/layout/compute-row-height'; jest.mock('../src/scenegraph/layout/compute-col-width', () => ({ computeColsWidth: jest.fn() @@ -99,4 +100,53 @@ describe('createGroupForFirstScreen issue #5298', () => { expect(table.internalProps._widthResizedColMap.has).toHaveBeenCalledTimes(2); expect(computeColsWidth).toHaveBeenCalledWith(table, 0, 9999); }); + + test('recalculates unresized rows when some rows keep manual heights', () => { + const table = createMockTable(); + table.internalProps._heightResizedRowMap = new Set([0]); + const proxy = { + table, + firstScreenColLimit: 3, + firstScreenRowLimit: 3, + totalCol: 2, + totalRow: 2, + setParamsForRow: jest.fn(), + setParamsForColumn: jest.fn(), + progress: jest.fn(), + colStart: 0, + rowStart: 0 + }; + const groups = [makeGroup(), makeGroup(), makeGroup(), makeGroup(), makeGroup(), makeGroup()]; + + createGroupForFirstScreen(...groups, 0, 0, proxy); + + expect(computeRowsHeight).toHaveBeenCalledWith(table, 0, 2); + }); + + test('stops scanning resized rows after finding an unresized row', () => { + const table = createMockTable(); + table.rowCount = 10000; + table.heightMode = 'adaptive'; + table.internalProps._heightResizedRowMap = { + has: jest.fn(row => row === 0) + }; + const proxy = { + table, + firstScreenColLimit: 3, + firstScreenRowLimit: 3, + totalCol: 2, + totalRow: 2, + setParamsForRow: jest.fn(), + setParamsForColumn: jest.fn(), + progress: jest.fn(), + colStart: 0, + rowStart: 0 + }; + const groups = [makeGroup(), makeGroup(), makeGroup(), makeGroup(), makeGroup(), makeGroup()]; + + createGroupForFirstScreen(...groups, 0, 0, proxy); + + expect(table.internalProps._heightResizedRowMap.has).toHaveBeenCalledTimes(2); + expect(computeRowsHeight).toHaveBeenCalledWith(table, 0, 9999); + }); }); diff --git a/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts b/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts index 8f8c44df0..99570540d 100644 --- a/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts +++ b/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts @@ -88,15 +88,20 @@ export function createGroupForFirstScreen( computeColsWidth(table, 0, colEndForCompute); } - if (table.internalProps._heightResizedRowMap.size === 0) { + const rowEndForCompute = + table.options.canvasHeight === 'auto' || table.options.customConfig?.forceComputeAllRowHeight + ? table.rowCount - 1 + : distRowForCompute ?? distRow; + let hasUnresizedRows = false; + for (let row = 0; row <= rowEndForCompute; row++) { + if (!table.internalProps._heightResizedRowMap.has(row)) { + hasUnresizedRows = true; + break; + } + } + if (hasUnresizedRows) { // compute rows height in first screen - computeRowsHeight( - table, - 0, - table.options.canvasHeight === 'auto' || table.options.customConfig?.forceComputeAllRowHeight - ? table.rowCount - 1 - : distRowForCompute ?? distRow - ); //如果配置了 canvasHeight为 'auto', 则一次性将所有行高都计算出来才能满足后续赋值表格高度的使用 + computeRowsHeight(table, 0, rowEndForCompute); //如果配置了 canvasHeight为 'auto', 则一次性将所有行高都计算出来才能满足后续赋值表格高度的使用 if (table.heightMode === 'autoHeight') { bodyDistRow = fillVisibleBodyRows(proxy, bodyDistRow); syncVisibleBodyRows(proxy, bodyDistRow); From ed72fe5d4ea0ab5ced67e45c4cb827782a897354 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Mon, 31 Aug 2026 10:28:21 +0800 Subject: [PATCH 5/6] fix: keep autoHeight row sync independent Co-Authored-By: Claude Sonnet 4.6 --- ...-group-for-first-screen-issue-5298.test.ts | 34 +++++++++++++++++++ .../progress/create-group-for-first-screen.ts | 8 ++--- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts b/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts index d17345206..69bc276fa 100644 --- a/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts +++ b/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts @@ -149,4 +149,38 @@ describe('createGroupForFirstScreen issue #5298', () => { expect(table.internalProps._heightResizedRowMap.has).toHaveBeenCalledTimes(2); expect(computeRowsHeight).toHaveBeenCalledWith(table, 0, 9999); }); + + test('syncs autoHeight visible rows even when all first screen rows keep manual heights', () => { + const table = createMockTable(); + table.heightMode = 'autoHeight'; + table.rowCount = 5; + table.tableNoFrameHeight = 100; + table.getBottomFrozenRowsHeight = () => 0; + table.getRowsHeight = jest.fn((start, end) => (end < 4 ? 50 : 120)); + table.internalProps._heightResizedRowMap = new Set([0, 1, 2]); + const proxy = { + table, + firstScreenColLimit: 3, + firstScreenRowLimit: 3, + bodyBottomRow: 4, + bodyTopRow: 1, + totalActualBodyRowCount: 2, + totalCol: 2, + totalRow: 2, + setParamsForRow: jest.fn(), + setParamsForColumn: jest.fn(), + progress: jest.fn(), + colStart: 0, + rowStart: 0 + }; + const groups = [makeGroup(), makeGroup(), makeGroup(), makeGroup(), makeGroup(), makeGroup()]; + + createGroupForFirstScreen(...groups, 0, 0, proxy); + + expect(computeRowsHeight).not.toHaveBeenCalledWith(table, 0, 2); + expect(computeRowsHeight).toHaveBeenCalledWith(table, 3, 3, false); + expect(computeRowsHeight).toHaveBeenCalledWith(table, 4, 4, false); + expect(proxy.totalRow).toBe(4); + expect(proxy.totalActualBodyRowCount).toBe(4); + }); }); diff --git a/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts b/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts index 99570540d..139c77f4e 100644 --- a/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts +++ b/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts @@ -102,10 +102,10 @@ export function createGroupForFirstScreen( if (hasUnresizedRows) { // compute rows height in first screen computeRowsHeight(table, 0, rowEndForCompute); //如果配置了 canvasHeight为 'auto', 则一次性将所有行高都计算出来才能满足后续赋值表格高度的使用 - if (table.heightMode === 'autoHeight') { - bodyDistRow = fillVisibleBodyRows(proxy, bodyDistRow); - syncVisibleBodyRows(proxy, bodyDistRow); - } + } + if (table.heightMode === 'autoHeight') { + bodyDistRow = fillVisibleBodyRows(proxy, bodyDistRow); + syncVisibleBodyRows(proxy, bodyDistRow); } if (distCol < table.colCount - table.rightFrozenColCount) { From 5c21a99bb1bc9312360139e2f185d7340f899e18 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Mon, 31 Aug 2026 10:49:32 +0800 Subject: [PATCH 6/6] fix: preserve manual row heights during recompute Keep row-height recomputation from touching manually resized rows and avoid using a manual row as the representative height for fixed body rows. Co-Authored-By: Claude Sonnet 4.6 --- ...-group-for-first-screen-issue-5298.test.ts | 96 +++++++++++++++++++ .../progress/create-group-for-first-screen.ts | 4 +- .../scenegraph/layout/compute-row-height.ts | 31 ++++-- 3 files changed, 122 insertions(+), 9 deletions(-) diff --git a/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts b/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts index 69bc276fa..0deaeddde 100644 --- a/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts +++ b/packages/vtable/__tests__/create-group-for-first-screen-issue-5298.test.ts @@ -3,6 +3,10 @@ import { createGroupForFirstScreen } from '../src/scenegraph/group-creater/progr import { computeColsWidth } from '../src/scenegraph/layout/compute-col-width'; import { computeRowsHeight } from '../src/scenegraph/layout/compute-row-height'; +const { computeRowHeight, computeRowsHeight: computeRowsHeightActual } = jest.requireActual( + '../src/scenegraph/layout/compute-row-height' +); + jest.mock('../src/scenegraph/layout/compute-col-width', () => ({ computeColsWidth: jest.fn() })); @@ -183,4 +187,96 @@ describe('createGroupForFirstScreen issue #5298', () => { expect(proxy.totalRow).toBe(4); expect(proxy.totalActualBodyRowCount).toBe(4); }); + + test('does not recompute manually resized rows while filling autoHeight visible rows', () => { + const table = createMockTable(); + table.heightMode = 'autoHeight'; + table.rowCount = 5; + table.tableNoFrameHeight = 100; + table.getBottomFrozenRowsHeight = () => 0; + table.getRowsHeight = jest.fn((start, end) => (end < 4 ? 50 : 120)); + table.internalProps._heightResizedRowMap = new Set([0, 1, 2, 3]); + const proxy = { + table, + firstScreenColLimit: 3, + firstScreenRowLimit: 3, + bodyBottomRow: 4, + bodyTopRow: 1, + totalActualBodyRowCount: 2, + totalCol: 2, + totalRow: 2, + setParamsForRow: jest.fn(), + setParamsForColumn: jest.fn(), + progress: jest.fn(), + colStart: 0, + rowStart: 0 + }; + const groups = [makeGroup(), makeGroup(), makeGroup(), makeGroup(), makeGroup(), makeGroup()]; + + createGroupForFirstScreen(...groups, 0, 0, proxy); + + expect(computeRowsHeight).not.toHaveBeenCalledWith(table, 3, 3, false); + expect(computeRowsHeight).toHaveBeenCalledWith(table, 4, 4, false); + }); + + test('keeps manually resized row height when computing row height directly', () => { + const table = { + internalProps: { + _heightResizedRowMap: new Set([1]) + }, + getRowHeight: jest.fn(() => 42), + isAutoRowHeight: jest.fn() + }; + + expect(computeRowHeight(1, 0, 2, table)).toBe(42); + expect(table.isAutoRowHeight).not.toHaveBeenCalled(); + }); + + test('uses an unresized representative row when filling fixed body row heights', () => { + const setRowHeight = jest.fn(); + const table = { + defaultHeaderRowHeight: 40, + defaultHeaderColWidth: 80, + defaultRowHeight: 33, + heightMode: 'standard', + heightAdaptiveMode: 'all', + autoFillHeight: false, + options: { + defaultRowHeight: 'auto' + }, + rowCount: 4, + colCount: 2, + columnHeaderLevelCount: 1, + rowHeaderLevelCount: 0, + bottomFrozenRowCount: 0, + internalProps: { + _heightResizedRowMap: new Set([1]), + layoutMap: { + getBody: jest.fn(() => ({ + cellType: 'text', + define: {} + })) + }, + transpose: false, + autoWrapText: false, + enableLineBreak: false, + useOneRowHeightFillAll: false + }, + isPivotTable: () => false, + isPivotChart: () => false, + isAutoRowHeight: () => false, + getDefaultRowHeight: jest.fn(row => (row === 1 ? 200 : 33)), + getRowHeight: jest.fn(row => (row === 1 ? 200 : 33)), + _getCellStyle: jest.fn(() => ({})), + _setRowHeight: setRowHeight, + _clearRowRangeHeightsMap: jest.fn() + }; + + computeRowsHeightActual(table, 0, 3); + + expect(table.getDefaultRowHeight).toHaveBeenCalledWith(2); + expect(setRowHeight).not.toHaveBeenCalledWith(1, expect.any(Number)); + expect(setRowHeight).toHaveBeenCalledWith(2, 33); + expect(setRowHeight).toHaveBeenCalledWith(3, 33); + }); }); diff --git a/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts b/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts index 139c77f4e..4e16f0183 100644 --- a/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts +++ b/packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts @@ -14,7 +14,9 @@ function fillVisibleBodyRows(proxy: SceneProxy, distRow: number): number { while (targetRow < bodyBottomRow && table.getRowsHeight(table.frozenRowCount, targetRow) < visibleBodyHeight) { const nextRow = targetRow + 1; - computeRowsHeight(table, nextRow, nextRow, false); + if (!table.internalProps._heightResizedRowMap.has(nextRow)) { + computeRowsHeight(table, nextRow, nextRow, false); + } targetRow = nextRow; } diff --git a/packages/vtable/src/scenegraph/layout/compute-row-height.ts b/packages/vtable/src/scenegraph/layout/compute-row-height.ts index 7ae9074b6..0806eda80 100644 --- a/packages/vtable/src/scenegraph/layout/compute-row-height.ts +++ b/packages/vtable/src/scenegraph/layout/compute-row-height.ts @@ -139,14 +139,13 @@ export function computeRowsHeight( ) { // check fixed style and no wrap situation, fill all row width single compute // traspose table and row indicator pivot table cannot use single row height - const height = computeRowHeight(table.columnHeaderLevelCount, 0, table.colCount - 1, table); - fillRowsHeight( - height, - table.columnHeaderLevelCount, - table.rowCount - 1 - table.bottomFrozenRowCount, - table, - update ? newHeights : undefined - ); + const fillStartRow = table.columnHeaderLevelCount; + const fillEndRow = table.rowCount - 1 - table.bottomFrozenRowCount; + const rowForCompute = getFirstUnresizedRow(table, fillStartRow, fillEndRow); + if (rowForCompute >= 0) { + const height = computeRowHeight(rowForCompute, 0, table.colCount - 1, table); + fillRowsHeight(height, fillStartRow, fillEndRow, table, update ? newHeights : undefined); + } //底部冻结的行行高需要单独计算 for (let row = table.rowCount - table.bottomFrozenRowCount; row <= rowEnd; row++) { const height = computeRowHeight(row, 0, table.colCount - 1, table); @@ -352,6 +351,10 @@ export function computeRowsHeight( } export function computeRowHeight(row: number, startCol: number, endCol: number, table: BaseTableAPI): number { + if (table.internalProps._heightResizedRowMap.has(row)) { + return table.getRowHeight(row); + } + return computeRowHeightInternal(row, startCol, endCol, table, true); } @@ -607,6 +610,9 @@ function fillRowsHeight( return; } for (let row = startRow; row <= endRow; row++) { + if (table.internalProps._heightResizedRowMap.has(row)) { + continue; + } if (newHeights) { newHeights[row] = height; } else { @@ -616,6 +622,15 @@ function fillRowsHeight( table.internalProps.useOneRowHeightFillAll = true; } +function getFirstUnresizedRow(table: BaseTableAPI, startRow: number, endRow: number): number { + for (let row = startRow; row <= endRow; row++) { + if (!table.internalProps._heightResizedRowMap.has(row)) { + return row; + } + } + return -1; +} + /** * @description: compute customRender height * @param {number} col