From c1bba3cac5bd8acb55a7284b999cff98c7b07717 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Tue, 2 Jul 2024 11:11:44 +0800 Subject: [PATCH 01/11] fix: pivot chart select state #2017 --- packages/vtable/src/layout/pivot-header-layout.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/vtable/src/layout/pivot-header-layout.ts b/packages/vtable/src/layout/pivot-header-layout.ts index 3b3e05641..9e3785c51 100644 --- a/packages/vtable/src/layout/pivot-header-layout.ts +++ b/packages/vtable/src/layout/pivot-header-layout.ts @@ -3159,7 +3159,7 @@ export class PivotHeaderLayoutMap implements LayoutMapAPI { if ((this._table as PivotChart)._selectedDataItemsInChart.length >= 1) { const match = (this._table as PivotChart)._selectedDataItemsInChart.find(item => { for (const itemKey in item) { - if (item[itemKey] !== datum[itemKey]) { + if (typeof item[itemKey] !== 'object' && item[itemKey] !== datum[itemKey]) { return false; } } @@ -3169,7 +3169,7 @@ export class PivotHeaderLayoutMap implements LayoutMapAPI { } else if ((this._table as PivotChart)._selectedDimensionInChart?.length) { // 判断维度点击 const match = (this._table as PivotChart)._selectedDimensionInChart.every(item => { - if (datum[item.key] !== item.value) { + if (typeof item.value !== 'object' && datum[item.key] !== item.value) { return false; } return true; @@ -3184,7 +3184,7 @@ export class PivotHeaderLayoutMap implements LayoutMapAPI { if ((this._table as PivotChart)._selectedDataItemsInChart.length >= 1) { const match = (this._table as PivotChart)._selectedDataItemsInChart.find(item => { for (const itemKey in item) { - if (item[itemKey] !== datum[itemKey]) { + if (typeof item[itemKey] !== 'object' && item[itemKey] !== datum[itemKey]) { return false; } } @@ -3194,7 +3194,7 @@ export class PivotHeaderLayoutMap implements LayoutMapAPI { } else if ((this._table as PivotChart)._selectedDimensionInChart?.length) { // 判断维度点击 const match = (this._table as PivotChart)._selectedDimensionInChart.every(item => { - if (datum[item.key] !== item.value) { + if (typeof item.value !== 'object' && datum[item.key] !== item.value) { return false; } return true; From 0fd92e604f485418da2ae0f22ee70eeeaecb5f48 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Tue, 2 Jul 2024 11:12:03 +0800 Subject: [PATCH 02/11] docs: update changlog of rush --- ...-bug-pivot-chart-selectState_2024-07-02-03-12.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/@visactor/vtable/2017-bug-pivot-chart-selectState_2024-07-02-03-12.json diff --git a/common/changes/@visactor/vtable/2017-bug-pivot-chart-selectState_2024-07-02-03-12.json b/common/changes/@visactor/vtable/2017-bug-pivot-chart-selectState_2024-07-02-03-12.json new file mode 100644 index 000000000..a9ef16d3e --- /dev/null +++ b/common/changes/@visactor/vtable/2017-bug-pivot-chart-selectState_2024-07-02-03-12.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "fix: pivot chart select state #2017\n\n", + "type": "none", + "packageName": "@visactor/vtable" + } + ], + "packageName": "@visactor/vtable", + "email": "892739385@qq.com" +} \ No newline at end of file From 0857badf24c0e9dec51ad5e1116752af61de58e4 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Tue, 2 Jul 2024 16:32:02 +0800 Subject: [PATCH 03/11] feat: add showMoverLine and hideMoverLine api #2009 --- packages/vtable/src/core/BaseTable.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/vtable/src/core/BaseTable.ts b/packages/vtable/src/core/BaseTable.ts index 3edb9108f..85048f79f 100644 --- a/packages/vtable/src/core/BaseTable.ts +++ b/packages/vtable/src/core/BaseTable.ts @@ -4281,4 +4281,22 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { get headerDomContainer() { return this.internalProps.headerDomContainer; } + /** + * 显示移动列或移动行的高亮线 如果(col,row)单元格是列头 则显示高亮列线; 如果(col,row)单元格是行头 则显示高亮行线 + * @param col 在表头哪一列后显示高亮线 + * @param row 在表头哪一行后显示高亮线 + */ + showMoverLine(col: number, row: number) { + this.scenegraph.component.showMoveCol(col, row, 0); + this.scenegraph.renderSceneGraph(); + } + /** + * 隐藏掉移动列或移动行的高亮线 + * @param col + * @param row + */ + hideMoverLine(col: number, row: number) { + this.scenegraph.component.hideMoveCol(); + this.scenegraph.renderSceneGraph(); + } } From 8a8cf9386f705f6a94020ec7e99e0af8337dc616 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Tue, 2 Jul 2024 16:32:52 +0800 Subject: [PATCH 04/11] docs: update changlog of rush --- ...re-add-api-columnresize-line_2024-07-02-08-32.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/@visactor/vtable/2009-feature-add-api-columnresize-line_2024-07-02-08-32.json diff --git a/common/changes/@visactor/vtable/2009-feature-add-api-columnresize-line_2024-07-02-08-32.json b/common/changes/@visactor/vtable/2009-feature-add-api-columnresize-line_2024-07-02-08-32.json new file mode 100644 index 000000000..cc2e32f2b --- /dev/null +++ b/common/changes/@visactor/vtable/2009-feature-add-api-columnresize-line_2024-07-02-08-32.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "feat: add showMoverLine and hideMoverLine api #2009\n\n", + "type": "none", + "packageName": "@visactor/vtable" + } + ], + "packageName": "@visactor/vtable", + "email": "892739385@qq.com" +} \ No newline at end of file From 4349da778cdfb8070541ac989fbda8e408cbe6df Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Wed, 3 Jul 2024 10:31:05 +0800 Subject: [PATCH 05/11] docs: add methods api --- docs/assets/api/en/methods.md | 43 +++++++++++++++++++++++++++ docs/assets/api/zh/methods.md | 43 +++++++++++++++++++++++++++ packages/vtable/src/core/BaseTable.ts | 4 +-- 3 files changed, 88 insertions(+), 2 deletions(-) diff --git a/docs/assets/api/en/methods.md b/docs/assets/api/en/methods.md index 9aeb62807..ce197a838 100644 --- a/docs/assets/api/en/methods.md +++ b/docs/assets/api/en/methods.md @@ -1165,3 +1165,46 @@ Determines whether the cell is in the visible area of the cell. If the cell is c ``` cellIsInVisualView(col: number, row: number) ``` + +## getCellAtRelativePosition(Function) + +Gets the cell position relative to the upper left corner of the table. + +In the case of scrolling, the cells obtained are those after scrolling. For example, if the currently displayed rows are 100-120, the cell position relative to the upper left corner of the table (10,100) is (first column, 103rd row), assuming the row height is 40px. + +``` +/** +* Get the cell information corresponding to the screen coordinates, taking scrolling into account +* @param this +* @param relativeX The left x value, relative to the upper left corner of the container, taking into account the scrolling of the grid +* @param relativeY The left y value, relative to the upper left corner of the container, taking into account the scrolling of the grid +* @returns +*/ +getCellAtRelativePosition(relativeX: number, relativeY: number): CellAddressWithBound +``` + +## showMoverLine(Function) + +Displays a highlighted line for moving columns or rows + +``` +/** +* Display the highlight line of the moving column or row If the (col, row) cell is the column header, the highlight column line is displayed; If the (col, row) cell is the row header, the highlight row line is displayed +* @param col Which column in the table header should be highlighted after? +* @param row The row after which the highlighted line is displayed +*/ +showMoverLine(col: number, row: number) +``` + +## hideMoverLine(Function) + +Hide the highlight line of the moved column or row + +``` +/** +* Hide the highlight line of the moved column or row +* @param col +* @param row +*/ +hideMoverLine(col: number, row: number) +``` diff --git a/docs/assets/api/zh/methods.md b/docs/assets/api/zh/methods.md index 1109e4fe4..a93ddc064 100644 --- a/docs/assets/api/zh/methods.md +++ b/docs/assets/api/zh/methods.md @@ -1163,3 +1163,46 @@ interface ISortedMapItem { ``` cellIsInVisualView(col: number, row: number) ``` + +## getCellAtRelativePosition(Function) + +获取相对于表格左上角的坐标对应的单元格位置。 + +有滚动的情况下,获取的单元格是滚动后的,如当前显示的行是 100-120 行,获取相对于表格左上角(10,100)位置的单元格位置是(第一列,第 103 行),假设行高 40px。 + +``` + /** + * 获取屏幕坐标对应的单元格信息,考虑滚动 + * @param this + * @param relativeX 左边x值,相对于容器左上角,已考虑格滚动情况 + * @param relativeY 左边y值,相对于容器左上角,已考虑格滚动情况 + * @returns + */ + getCellAtRelativePosition(relativeX: number, relativeY: number): CellAddressWithBound +``` + +## showMoverLine(Function) + +显示移动列或移动行的高亮标记线 + +``` + /** + * 显示移动列或移动行的高亮线 如果(col,row)单元格是列头 则显示高亮列线; 如果(col,row)单元格是行头 则显示高亮行线 + * @param col 在表头哪一列后显示高亮线 + * @param row 在表头哪一行后显示高亮线 + */ + showMoverLine(col: number, row: number) +``` + +## hideMoverLine(Function) + +隐藏掉移动列或移动行的高亮线 + +``` + /** + * 隐藏掉移动列或移动行的高亮线 + * @param col + * @param row + */ + hideMoverLine(col: number, row: number) +``` diff --git a/packages/vtable/src/core/BaseTable.ts b/packages/vtable/src/core/BaseTable.ts index 85048f79f..2be31d4d1 100644 --- a/packages/vtable/src/core/BaseTable.ts +++ b/packages/vtable/src/core/BaseTable.ts @@ -1803,8 +1803,8 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { /** * 获取屏幕坐标对应的单元格信息,考虑滚动 * @param this - * @param relativeX 左边x值,相对于容器左上角,考虑表格滚动 - * @param relativeY 左边y值,相对于容器左上角,考虑表格滚动 + * @param relativeX 左边x值,相对于容器左上角,已考虑格滚动情况 + * @param relativeY 左边y值,相对于容器左上角,已考虑格滚动情况 * @returns */ getCellAtRelativePosition(relativeX: number, relativeY: number): CellAddressWithBound { From 4cbfcca9dc5dd5ff39cd1ed067a8c1f8fd1b48cd Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Mon, 1 Jul 2024 17:01:47 +0800 Subject: [PATCH 06/11] feat: add frozenRowCount config in option --- packages/vtable/src/ListTable.ts | 2 +- packages/vtable/src/PivotChart.ts | 3 ++- packages/vtable/src/PivotTable.ts | 3 ++- packages/vtable/src/core/BaseTable.ts | 3 ++- .../progress/create-group-for-first-screen.ts | 16 ++++++++-------- .../scenegraph/group-creater/progress/proxy.ts | 8 ++++---- .../progress/update-position/update-auto-row.ts | 13 +++++-------- .../progress/update-position/util.ts | 9 +++------ .../src/scenegraph/layout/update-height.ts | 4 ++-- packages/vtable/src/scenegraph/scenegraph.ts | 6 +++--- packages/vtable/src/ts-types/base-table.ts | 1 + 11 files changed, 33 insertions(+), 35 deletions(-) diff --git a/packages/vtable/src/ListTable.ts b/packages/vtable/src/ListTable.ts index af30270a6..86f20836c 100644 --- a/packages/vtable/src/ListTable.ts +++ b/packages/vtable/src/ListTable.ts @@ -528,7 +528,7 @@ export class ListTable extends BaseTable implements ListTableAPI { table.rowCount = layoutMap.recordsCount * layoutMap.bodyRowSpanCount + layoutMap.headerLevelCount; // table.frozenColCount = table.options.frozenColCount ?? 0; //这里不要这样写 这个setter会检查扁头宽度 可能将frozenColCount置为0 this.internalProps.frozenColCount = this.options.frozenColCount ?? 0; - table.frozenRowCount = layoutMap.headerLevelCount; + table.frozenRowCount = Math.max(layoutMap.headerLevelCount, this.options.frozenRowCount ?? 0); if (table.bottomFrozenRowCount !== (this.options.bottomFrozenRowCount ?? 0)) { table.bottomFrozenRowCount = this.options.bottomFrozenRowCount ?? 0; diff --git a/packages/vtable/src/PivotChart.ts b/packages/vtable/src/PivotChart.ts index 30b5d7b9a..3bfe1f8a2 100644 --- a/packages/vtable/src/PivotChart.ts +++ b/packages/vtable/src/PivotChart.ts @@ -493,7 +493,8 @@ export class PivotChart extends BaseTable implements PivotChartAPI { table.rowCount = layoutMap.rowCount ?? 0; // table.frozenColCount = layoutMap.rowHeaderLevelCount; //这里不要这样写 这个setter会检查扁头宽度 可能将frozenColCount置为0 table.internalProps.frozenColCount = layoutMap.rowHeaderLevelCount ?? 0; - table.frozenRowCount = layoutMap.headerLevelCount; + // table.frozenRowCount = layoutMap.headerLevelCount; + table.frozenRowCount = Math.max(layoutMap.headerLevelCount, this.options.frozenRowCount ?? 0); if (table.bottomFrozenRowCount !== (layoutMap?.bottomFrozenRowCount ?? 0)) { table.bottomFrozenRowCount = layoutMap?.bottomFrozenRowCount ?? 0; } diff --git a/packages/vtable/src/PivotTable.ts b/packages/vtable/src/PivotTable.ts index 8b1345de3..b190bcbc9 100644 --- a/packages/vtable/src/PivotTable.ts +++ b/packages/vtable/src/PivotTable.ts @@ -495,7 +495,8 @@ export class PivotTable extends BaseTable implements PivotTableAPI { (layoutMap.rowHeaderLevelCount ?? 0) + layoutMap.leftRowSeriesNumberColumnCount, this.options.frozenColCount ?? 0 ); - table.frozenRowCount = layoutMap.headerLevelCount; + // table.frozenRowCount = layoutMap.headerLevelCount; + table.frozenRowCount = Math.max(layoutMap.headerLevelCount, this.options.frozenRowCount ?? 0); if (table.bottomFrozenRowCount !== (this.options.bottomFrozenRowCount ?? 0)) { table.bottomFrozenRowCount = this.options.bottomFrozenRowCount ?? 0; diff --git a/packages/vtable/src/core/BaseTable.ts b/packages/vtable/src/core/BaseTable.ts index 2be31d4d1..13ba70b99 100644 --- a/packages/vtable/src/core/BaseTable.ts +++ b/packages/vtable/src/core/BaseTable.ts @@ -220,7 +220,7 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { // rowCount = 0, // colCount = 0, frozenColCount = 0, - // frozenRowCount = 0, + frozenRowCount, defaultRowHeight = 40, defaultHeaderRowHeight, defaultColWidth = 80, @@ -327,6 +327,7 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { internalProps.pixelRatio = pixelRatio; internalProps.frozenColCount = frozenColCount; + internalProps.frozenRowCount = frozenRowCount; internalProps.defaultRowHeight = defaultRowHeight; internalProps.defaultHeaderRowHeight = defaultHeaderRowHeight ?? defaultRowHeight; // defaultHeaderRowHeight没有设置取defaultRowHeight 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 0755fa15f..b251d645e 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,7 +76,7 @@ export function createGroupForFirstScreen( 0, // colStart table.frozenColCount - 1, // colEnd 0, // rowStart - table.columnHeaderLevelCount - 1, // rowEnd + table.frozenRowCount - 1, // rowEnd table.isListTable() ? 'columnHeader' : 'cornerHeader', // CellType table ); @@ -91,7 +91,7 @@ export function createGroupForFirstScreen( // Math.min(proxy.firstScreenColLimit, table.colCount - 1 - table.rightFrozenColCount), // colEnd distCol - table.rightFrozenColCount, 0, // rowStart - table.columnHeaderLevelCount - 1, // rowEnd + table.frozenRowCount - 1, // rowEnd 'columnHeader', // isHeader table ); @@ -105,7 +105,7 @@ export function createGroupForFirstScreen( yOrigin, 0, // colStart table.leftRowSeriesNumberCount - 1, // colEnd - table.columnHeaderLevelCount, // rowStart + table.frozenRowCount, // rowStart // Math.min(proxy.firstScreenRowLimit, table.rowCount - 1 - table.bottomFrozenRowCount), // rowEnd distRow - table.bottomFrozenRowCount, 'rowHeader', // isHeader @@ -119,7 +119,7 @@ export function createGroupForFirstScreen( yOrigin, table.leftRowSeriesNumberCount, // colStart table.leftRowSeriesNumberCount + table.rowHeaderLevelCount - 1, // colEnd - table.columnHeaderLevelCount, // rowStart + table.frozenRowCount, // rowStart // Math.min(proxy.firstScreenRowLimit, table.rowCount - 1 - table.bottomFrozenRowCount), // rowEnd distRow - table.bottomFrozenRowCount, 'rowHeader', // isHeader @@ -133,7 +133,7 @@ export function createGroupForFirstScreen( yOrigin, table.rowHeaderLevelCount + table.leftRowSeriesNumberCount, // colStart table.frozenColCount - 1, // colEnd - table.columnHeaderLevelCount, // rowStart + table.frozenRowCount, // rowStart // Math.min(proxy.firstScreenRowLimit, table.rowCount - 1 - table.bottomFrozenRowCount), // rowEnd distRow - table.bottomFrozenRowCount, 'body', @@ -240,7 +240,7 @@ export function createGroupForFirstScreen( table.colCount - 1 - table.rightFrozenColCount + 1, // colStart table.colCount - 1, // colEnd 0, // rowStart - table.columnHeaderLevelCount - 1, // rowEnd + table.frozenRowCount - 1, // rowEnd 'columnHeader', // isHeader table ); @@ -252,7 +252,7 @@ export function createGroupForFirstScreen( yOrigin, table.colCount - 1 - table.rightFrozenColCount + 1, // colStart table.colCount - 1, // colEnd - table.columnHeaderLevelCount, // rowStart + table.frozenRowCount, // rowStart // Math.min(proxy.firstScreenRowLimit, table.rowCount - 1 - table.bottomFrozenRowCount), // rowEnd distRow - table.bottomFrozenRowCount, table.isPivotChart() ? 'rowHeader' : 'body', // isHeader @@ -284,7 +284,7 @@ export function createGroupForFirstScreen( table.frozenColCount, // colStart // Math.min(proxy.firstScreenColLimit, table.colCount - 1 - table.rightFrozenColCount), // colEnd distCol - table.rightFrozenColCount, - table.columnHeaderLevelCount, // rowStart + table.frozenRowCount, // rowStart // Math.min(proxy.firstScreenRowLimit, table.rowCount - 1 - table.bottomFrozenRowCount), // rowEnd distRow - table.bottomFrozenRowCount, 'body', // isHeader diff --git a/packages/vtable/src/scenegraph/group-creater/progress/proxy.ts b/packages/vtable/src/scenegraph/group-creater/progress/proxy.ts index d52993b6a..be6b44e8f 100644 --- a/packages/vtable/src/scenegraph/group-creater/progress/proxy.ts +++ b/packages/vtable/src/scenegraph/group-creater/progress/proxy.ts @@ -131,7 +131,7 @@ export class SceneProxy { } setParamsForRow() { - this.bodyTopRow = this.table.columnHeaderLevelCount; + this.bodyTopRow = this.table.frozenRowCount; this.bodyBottomRow = this.table.rowCount - 1 - this.table.bottomFrozenRowCount; // this.bodyLeftCol = 0; // this.bodyRightCol = this.table.colCount - 1 - this.table.rightFrozenColCount; @@ -370,7 +370,7 @@ export class SceneProxy { } // create column - if (this.table.columnHeaderLevelCount) { + if (this.table.frozenRowCount) { // create colGroup const lastColumnGroup = ( this.table.scenegraph.colHeaderGroup.lastChild instanceof Group @@ -387,7 +387,7 @@ export class SceneProxy { this.currentCol + 1, // colStart endCol, // colEnd 0, // rowStart - this.table.columnHeaderLevelCount - 1, // rowEnd + this.table.frozenRowCount - 1, // rowEnd 'columnHeader', // isHeader this.table ); @@ -704,7 +704,7 @@ export class SceneProxy { // } if ( - row >= this.table.columnHeaderLevelCount && // not column header + row >= this.table.frozenRowCount && // not column header row < this.table.rowCount - this.table.bottomFrozenRowCount && // not bottom frozen (row < this.rowStart || row > this.rowEnd) // not in proxy row range ) { diff --git a/packages/vtable/src/scenegraph/group-creater/progress/update-position/update-auto-row.ts b/packages/vtable/src/scenegraph/group-creater/progress/update-position/update-auto-row.ts index 051041227..dda7e6aff 100644 --- a/packages/vtable/src/scenegraph/group-creater/progress/update-position/update-auto-row.ts +++ b/packages/vtable/src/scenegraph/group-creater/progress/update-position/update-auto-row.ts @@ -34,7 +34,7 @@ export function updateAutoRow( } } else { // 估计位置 - y = table.getRowsHeight(table.columnHeaderLevelCount, cellGroup.row - 1); + y = table.getRowsHeight(table.frozenRowCount, cellGroup.row - 1); } if (isValid(y)) { cellGroup.setAttribute('y', y); @@ -61,8 +61,8 @@ export function updateAutoRow( } } else { // 估计位置 - y = table.getRowsHeight(table.columnHeaderLevelCount, cellGroup.row - 1); - // console.log('估计位置', table.getRowsHeight(table.columnHeaderLevelCount, cellGroup.row)); + y = table.getRowsHeight(table.frozenRowCount, cellGroup.row - 1); + // console.log('估计位置', table.getRowsHeight(table.frozenRowCount, cellGroup.row)); } if (isValid(y)) { cellGroup.setAttribute('y', y); @@ -77,11 +77,8 @@ export function updateAutoRow( table.scenegraph.proxy.bodyBottomRow - table.scenegraph.proxy.bodyTopRow + 1 ); // 渐进加载总row数量 - const totalBodyHeight = table.getRowsHeight( - table.columnHeaderLevelCount, - table.columnHeaderLevelCount + totalActualBodyRowCount - ); - const totalHeight = table.getRowsHeight(table.columnHeaderLevelCount, table.rowCount - 1); + const totalBodyHeight = table.getRowsHeight(table.frozenRowCount, table.frozenRowCount + totalActualBodyRowCount); + const totalHeight = table.getRowsHeight(table.frozenRowCount, table.rowCount - 1); table.scenegraph.proxy.yLimitTop = totalBodyHeight / 2; table.scenegraph.proxy.yLimitBottom = totalHeight - totalBodyHeight / 2; diff --git a/packages/vtable/src/scenegraph/group-creater/progress/update-position/util.ts b/packages/vtable/src/scenegraph/group-creater/progress/update-position/util.ts index 3e510473b..79788d12f 100644 --- a/packages/vtable/src/scenegraph/group-creater/progress/update-position/util.ts +++ b/packages/vtable/src/scenegraph/group-creater/progress/update-position/util.ts @@ -28,10 +28,7 @@ export function checkFirstRowMerge(row: number, proxy: SceneProxy) { newCellGroup.col = col; newCellGroup.row = row; - newCellGroup.setAttribute( - 'y', - proxy.table.getRowsHeight(proxy.table.columnHeaderLevelCount, range.start.row - 1) - ); + newCellGroup.setAttribute('y', proxy.table.getRowsHeight(proxy.table.frozenRowCount, range.start.row - 1)); oldCellGroup.parent.insertAfter(newCellGroup, oldCellGroup); oldCellGroup.parent.removeChild(oldCellGroup); @@ -50,7 +47,7 @@ export function checkFirstRowMerge(row: number, proxy: SceneProxy) { export function checkFirstColMerge(col: number, proxy: SceneProxy) { for (let row = 0; row < proxy.table.rowCount; row++) { if ( - (row >= proxy.table.columnHeaderLevelCount && row < proxy.rowStart) || + (row >= proxy.table.frozenRowCount && row < proxy.rowStart) || (row > proxy.rowEnd && row < proxy.table.rowCount - proxy.table.bottomFrozenRowCount) ) { continue; @@ -104,7 +101,7 @@ function clearHadMergedRow(rowStart: number, rowEnd: number, col: number, proxy: cellGroup.setAttributes({ width: 0, height: proxy.table.getRowHeight(cellGroup.row), - y: proxy.table.getRowsHeight(proxy.table.columnHeaderLevelCount, cellGroup.row - 1), + y: proxy.table.getRowsHeight(proxy.table.frozenRowCount, cellGroup.row - 1), x: 0 }); cellGroup.clear(); diff --git a/packages/vtable/src/scenegraph/layout/update-height.ts b/packages/vtable/src/scenegraph/layout/update-height.ts index a6d7ead65..ec86864ad 100644 --- a/packages/vtable/src/scenegraph/layout/update-height.ts +++ b/packages/vtable/src/scenegraph/layout/update-height.ts @@ -44,13 +44,13 @@ export function updateRowHeight(scene: Scenegraph, row: number, detaY: number, s let rowStart = 0; let rowEnd = 0; // 更新header 高度 - if (row < scene.table.columnHeaderLevelCount) { + if (row < scene.table.frozenRowCount) { // scene.colHeaderGroup.setAttribute('height', scene.colHeaderGroup.attribute.height + detaY); // scene.rowHeaderGroup.setAttribute('y', scene.rowHeaderGroup.attribute.y + detaY); // scene.bodyGroup.setAttribute('y', scene.bodyGroup.attribute.y + detaY); rowStart = row + 1; - rowEnd = scene.table.columnHeaderLevelCount - 1; + rowEnd = scene.table.frozenRowCount - 1; } else if (row >= scene.table.rowCount - scene.table.bottomFrozenRowCount) { rowStart = row + 1; rowEnd = scene.table.rowCount - 1; diff --git a/packages/vtable/src/scenegraph/scenegraph.ts b/packages/vtable/src/scenegraph/scenegraph.ts index b4fc87709..b9626d5df 100644 --- a/packages/vtable/src/scenegraph/scenegraph.ts +++ b/packages/vtable/src/scenegraph/scenegraph.ts @@ -370,7 +370,7 @@ export class Scenegraph { this.clear = false; // this.frozenColCount = this.table.rowHeaderLevelCount; this.frozenColCount = this.table.frozenColCount; - this.frozenRowCount = this.table.columnHeaderLevelCount; + this.frozenRowCount = this.table.frozenRowCount; this.proxy = new SceneProxy(this.table); @@ -1905,12 +1905,12 @@ export class Scenegraph { } getCellGroupY(row: number) { - if (row < this.table.columnHeaderLevelCount) { + if (row < this.table.frozenRowCount) { // column header return this.table.getRowsHeight(0, row - 1); } else if (row < this.table.rowCount - this.table.bottomFrozenRowCount) { // body - return this.table.getRowsHeight(this.table.columnHeaderLevelCount, row - 1); + return this.table.getRowsHeight(this.table.frozenRowCount, row - 1); } else if (row < this.table.rowCount) { // bottom frozen return this.table.getRowsHeight(this.table.rowCount - this.table.bottomFrozenRowCount, row - 1); diff --git a/packages/vtable/src/ts-types/base-table.ts b/packages/vtable/src/ts-types/base-table.ts index 745e458e3..d71bfe817 100644 --- a/packages/vtable/src/ts-types/base-table.ts +++ b/packages/vtable/src/ts-types/base-table.ts @@ -271,6 +271,7 @@ export interface BaseTableConstructorOptions { * 当前需要冻结的列数 基本表格生效 */ frozenColCount?: number; + frozenRowCount?: number; rightFrozenColCount?: number; bottomFrozenRowCount?: number; From 5a79a7c3cb76120a9c82e92047116feaf7380b0e Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Wed, 3 Jul 2024 15:38:35 +0800 Subject: [PATCH 07/11] docs: add frozen row docs --- .../demo/en/basic-functionality/frozen-col.md | 2 +- .../demo/en/basic-functionality/frozen-row.md | 154 ++++++++++++++++++ docs/assets/demo/menu.json | 18 +- .../demo/zh/basic-functionality/frozen-col.md | 2 +- .../demo/zh/basic-functionality/frozen-row.md | 154 ++++++++++++++++++ ...{frozen_column.md => frozen_column_row.md} | 0 docs/assets/guide/menu.json | 4 +- ...{frozen_column.md => frozen_column_row.md} | 0 .../option/en/common/option-secondary.md | 4 + .../option/zh/common/option-secondary.md | 4 + 10 files changed, 337 insertions(+), 5 deletions(-) create mode 100644 docs/assets/demo/en/basic-functionality/frozen-row.md create mode 100644 docs/assets/demo/zh/basic-functionality/frozen-row.md rename docs/assets/guide/en/basic_function/{frozen_column.md => frozen_column_row.md} (100%) rename docs/assets/guide/zh/basic_function/{frozen_column.md => frozen_column_row.md} (100%) diff --git a/docs/assets/demo/en/basic-functionality/frozen-col.md b/docs/assets/demo/en/basic-functionality/frozen-col.md index 07d7715ab..e850d75ac 100644 --- a/docs/assets/demo/en/basic-functionality/frozen-col.md +++ b/docs/assets/demo/en/basic-functionality/frozen-col.md @@ -3,7 +3,7 @@ category: examples group: Basic Features title: frozen column cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/preview/frozen-col.gif -link: '../guide/basic_function/frozen_column' +link: '../guide/basic_function/frozen_column_row' option: ListTable#frozenColCount --- diff --git a/docs/assets/demo/en/basic-functionality/frozen-row.md b/docs/assets/demo/en/basic-functionality/frozen-row.md new file mode 100644 index 000000000..ad90db4e0 --- /dev/null +++ b/docs/assets/demo/en/basic-functionality/frozen-row.md @@ -0,0 +1,154 @@ +--- +category: examples +group: Basic Features +title: Freeze Row +cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/preview/frozen-row.gif +link: '../guide/basic_function/frozen_column_row' +option: ListTable#frozenRowCount +--- + +# Freeze Row + +In order to keep these key information rows visible throughout the horizontal scroll, we need to "freeze" these rows. + +## Key Configurations + + - `frozenRowCount` The number of frozen rows (including header), default is the number of header rows + +## Code demo + +```javascript livedemo template=vtable + + let tableInstance; + fetch('https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/North_American_Superstore_Pivot_data.json') + .then(res => res.json()) + .then(data => { + const option = { + records: data, + rows: [ + { + dimensionKey: 'City', + title: 'City', + headerStyle: { + textStick: true, + color: (args) => { + if (args.row < 4) { + return 'red'; + } + return '#000'; + }, + bgColor: (args) => { + if (args.row < 4) { + return 'rgba(255, 0, 0, 0.1)'; + } + return '#fff'; + } + }, + width: 'auto' + } + ], + columns: [ + { + dimensionKey: 'Category', + title: 'Category', + headerStyle: { + textStick: true + }, + width: 'auto' + } + ], + indicators: [ + { + indicatorKey: 'Quantity', + title: 'Quantity', + width: 'auto', + showSort: false, + headerStyle: { + fontWeight: 'normal' + }, + style: { + padding: [16, 28, 16, 28], + color(args) { + if (args.dataValue >= 0) return 'black'; + return 'red'; + }, + bgColor: (args) => { + if (args.row < 4) { + return 'rgba(255, 0, 0, 0.1)'; + } + return '#fff'; + } + } + }, + { + indicatorKey: 'Sales', + title: 'Sales', + width: 'auto', + showSort: false, + headerStyle: { + fontWeight: 'normal' + }, + format: rec => { + return '$' + Number(rec).toFixed(2); + }, + style: { + padding: [16, 28, 16, 28], + color(args) { + if (args.dataValue >= 0) return 'black'; + return 'red'; + }, + bgColor: (args) => { + if (args.row < 4) { + return 'rgba(255, 0, 0, 0.1)'; + } + return '#fff'; + } + } + }, + { + indicatorKey: 'Profit', + title: 'Profit', + width: 'auto', + showSort: false, + headerStyle: { + fontWeight: 'normal' + }, + format: rec => { + return '$' + Number(rec).toFixed(2); + }, + style: { + padding: [16, 28, 16, 28], + color(args) { + if (args.dataValue >= 0) return 'black'; + return 'red'; + }, + bgColor: (args) => { + if (args.row < 4) { + return 'rgba(255, 0, 0, 0.1)'; + } + return '#fff'; + } + } + } + ], + corner: { + titleOnDimension: 'row', + headerStyle: { + textStick: true + } + }, + dataConfig: { + sortRules: [ + { + sortField: 'Category', + sortBy: ['Office Supplies', 'Technology', 'Furniture'] + } + ] + }, + widthMode: 'standard', + frozenRowCount: 4, + }; + tableInstance = new VTable.PivotTable(document.getElementById(CONTAINER_ID), option); + window['tableInstance'] = tableInstance; + }); +``` diff --git a/docs/assets/demo/menu.json b/docs/assets/demo/menu.json index f75067a33..95d5b3bf4 100644 --- a/docs/assets/demo/menu.json +++ b/docs/assets/demo/menu.json @@ -392,7 +392,23 @@ "category": "demo", "group": "Basic Features", "cover": "https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/preview/frozen-col.gif", - "link": "'../../guide/basic_function/frozen_column'", + "link": "'../../guide/basic_function/frozen_column_row'", + "option": "" + } + }, + { + "path": "frozen-row", + "title": { + "zh": "冻结行", + "en": "frozen row" + }, + "meta": { + "title": "frozen row", + "keywords": "", + "category": "demo", + "group": "Basic Features", + "cover": "https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/preview/frozen-row.gif", + "link": "'../../guide/basic_function/frozen_column_row'", "option": "" } }, diff --git a/docs/assets/demo/zh/basic-functionality/frozen-col.md b/docs/assets/demo/zh/basic-functionality/frozen-col.md index b1ebdbfdb..234bc3f34 100644 --- a/docs/assets/demo/zh/basic-functionality/frozen-col.md +++ b/docs/assets/demo/zh/basic-functionality/frozen-col.md @@ -3,7 +3,7 @@ category: examples group: Basic Features title: 冻结列 cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/preview/frozen-col.gif -link: '../guide/basic_function/frozen_column' +link: '../guide/basic_function/frozen_column_row' option: ListTable#frozenColCount --- diff --git a/docs/assets/demo/zh/basic-functionality/frozen-row.md b/docs/assets/demo/zh/basic-functionality/frozen-row.md new file mode 100644 index 000000000..f21fbab68 --- /dev/null +++ b/docs/assets/demo/zh/basic-functionality/frozen-row.md @@ -0,0 +1,154 @@ +--- +category: examples +group: Basic Features +title: 冻结行 +cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/preview/frozen-row.gif +link: '../guide/basic_function/frozen_column_row' +option: ListTable#frozenRowCount +--- + +# 冻结行 + +为了在纵向滚动过程中,始终保持这些关键信息列可见,我们需要将这些行进行“冻结”。 + +## 关键配置 + + - `frozenRowCount` 冻结行数(包含表头) 默认表头行数 + +## 代码演示 + +```javascript livedemo template=vtable + + let tableInstance; + fetch('https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/North_American_Superstore_Pivot_data.json') + .then(res => res.json()) + .then(data => { + const option = { + records: data, + rows: [ + { + dimensionKey: 'City', + title: 'City', + headerStyle: { + textStick: true, + color: (args) => { + if (args.row < 4) { + return 'red'; + } + return '#000'; + }, + bgColor: (args) => { + if (args.row < 4) { + return 'rgba(255, 0, 0, 0.1)'; + } + return '#fff'; + } + }, + width: 'auto' + } + ], + columns: [ + { + dimensionKey: 'Category', + title: 'Category', + headerStyle: { + textStick: true + }, + width: 'auto' + } + ], + indicators: [ + { + indicatorKey: 'Quantity', + title: 'Quantity', + width: 'auto', + showSort: false, + headerStyle: { + fontWeight: 'normal' + }, + style: { + padding: [16, 28, 16, 28], + color(args) { + if (args.dataValue >= 0) return 'black'; + return 'red'; + }, + bgColor: (args) => { + if (args.row < 4) { + return 'rgba(255, 0, 0, 0.1)'; + } + return '#fff'; + } + } + }, + { + indicatorKey: 'Sales', + title: 'Sales', + width: 'auto', + showSort: false, + headerStyle: { + fontWeight: 'normal' + }, + format: rec => { + return '$' + Number(rec).toFixed(2); + }, + style: { + padding: [16, 28, 16, 28], + color(args) { + if (args.dataValue >= 0) return 'black'; + return 'red'; + }, + bgColor: (args) => { + if (args.row < 4) { + return 'rgba(255, 0, 0, 0.1)'; + } + return '#fff'; + } + } + }, + { + indicatorKey: 'Profit', + title: 'Profit', + width: 'auto', + showSort: false, + headerStyle: { + fontWeight: 'normal' + }, + format: rec => { + return '$' + Number(rec).toFixed(2); + }, + style: { + padding: [16, 28, 16, 28], + color(args) { + if (args.dataValue >= 0) return 'black'; + return 'red'; + }, + bgColor: (args) => { + if (args.row < 4) { + return 'rgba(255, 0, 0, 0.1)'; + } + return '#fff'; + } + } + } + ], + corner: { + titleOnDimension: 'row', + headerStyle: { + textStick: true + } + }, + dataConfig: { + sortRules: [ + { + sortField: 'Category', + sortBy: ['Office Supplies', 'Technology', 'Furniture'] + } + ] + }, + widthMode: 'standard', + frozenRowCount: 4, + }; + tableInstance = new VTable.PivotTable(document.getElementById(CONTAINER_ID), option); + window['tableInstance'] = tableInstance; + }); +``` diff --git a/docs/assets/guide/en/basic_function/frozen_column.md b/docs/assets/guide/en/basic_function/frozen_column_row.md similarity index 100% rename from docs/assets/guide/en/basic_function/frozen_column.md rename to docs/assets/guide/en/basic_function/frozen_column_row.md diff --git a/docs/assets/guide/menu.json b/docs/assets/guide/menu.json index 09a36a953..9f5a0d88e 100644 --- a/docs/assets/guide/menu.json +++ b/docs/assets/guide/menu.json @@ -245,10 +245,10 @@ ] }, { - "path": "frozen_column", + "path": "frozen_column_row", "title": { "zh": "冻结", - "en": "frozen column" + "en": "frozen column & row" } }, { diff --git a/docs/assets/guide/zh/basic_function/frozen_column.md b/docs/assets/guide/zh/basic_function/frozen_column_row.md similarity index 100% rename from docs/assets/guide/zh/basic_function/frozen_column.md rename to docs/assets/guide/zh/basic_function/frozen_column_row.md diff --git a/docs/assets/option/en/common/option-secondary.md b/docs/assets/option/en/common/option-secondary.md index 7e73ffd4c..b5663dc8d 100644 --- a/docs/assets/option/en/common/option-secondary.md +++ b/docs/assets/option/en/common/option-secondary.md @@ -68,6 +68,10 @@ Minimum column width limit. If set to true, the column width will be limited to The number of frozen columns +#${prefix} frozenRowCount(number) = 0 + +The number of frozen columns(including the header) + #${prefix} rightFrozenColCount(number) = 0 Freeze Columns Right diff --git a/docs/assets/option/zh/common/option-secondary.md b/docs/assets/option/zh/common/option-secondary.md index 660fe7d7f..20eeec1d9 100644 --- a/docs/assets/option/zh/common/option-secondary.md +++ b/docs/assets/option/zh/common/option-secondary.md @@ -68,6 +68,10 @@ adaptive 模式下高度的适应策略,默认为 'only-body'。 冻结列数 +#${prefix} frozenRowCount(number) = 0 + +冻结行数(包含表头) + #${prefix} rightFrozenColCount(number) = 0 右侧冻结列数 From 7540a2a6d7ac8c7a6fc97812144342318a11d5f5 Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Wed, 3 Jul 2024 15:46:47 +0800 Subject: [PATCH 08/11] docs: fix docs link url --- docs/assets/demo-react/en/custom-layout/cell-custom-dom.md | 2 +- docs/assets/demo-react/zh/custom-layout/cell-custom-dom.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/assets/demo-react/en/custom-layout/cell-custom-dom.md b/docs/assets/demo-react/en/custom-layout/cell-custom-dom.md index 4745ab3d4..0d649a370 100644 --- a/docs/assets/demo-react/en/custom-layout/cell-custom-dom.md +++ b/docs/assets/demo-react/en/custom-layout/cell-custom-dom.md @@ -4,7 +4,7 @@ group: component title: cell custom dom component cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/preview/react-vtable-cell-dom-component.jpeg order: 1-1 -link: '../guide/Developer_Ecology/react' +link: '../../guide/Developer_Ecology/react' --- # cell custom dom component diff --git a/docs/assets/demo-react/zh/custom-layout/cell-custom-dom.md b/docs/assets/demo-react/zh/custom-layout/cell-custom-dom.md index b08666947..0cc54de03 100644 --- a/docs/assets/demo-react/zh/custom-layout/cell-custom-dom.md +++ b/docs/assets/demo-react/zh/custom-layout/cell-custom-dom.md @@ -4,7 +4,7 @@ group: component title: 单元格内dom组件 cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/preview/react-vtable-cell-dom-component.jpeg order: 1-1 -link: '../guide/Developer_Ecology/react' +link: '../../guide/Developer_Ecology/react' --- # 单元格内dom组件 From 58aebb5b07fadd7fe3cde4c58d996bca023865cf Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Tue, 2 Jul 2024 17:47:06 +0800 Subject: [PATCH 09/11] fix: fix select-rect update when scroll #2015 --- ...x-select-rect-update_2024-07-02-09-46.json | 10 + .../scenegraph/select/update-select-border.ts | 221 ++++++++++-------- 2 files changed, 132 insertions(+), 99 deletions(-) create mode 100644 common/changes/@visactor/vtable/fix-select-rect-update_2024-07-02-09-46.json diff --git a/common/changes/@visactor/vtable/fix-select-rect-update_2024-07-02-09-46.json b/common/changes/@visactor/vtable/fix-select-rect-update_2024-07-02-09-46.json new file mode 100644 index 000000000..66cc11f56 --- /dev/null +++ b/common/changes/@visactor/vtable/fix-select-rect-update_2024-07-02-09-46.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vtable", + "comment": "fix: fix select-rect update when scroll #2015", + "type": "none" + } + ], + "packageName": "@visactor/vtable" +} \ No newline at end of file diff --git a/packages/vtable/src/scenegraph/select/update-select-border.ts b/packages/vtable/src/scenegraph/select/update-select-border.ts index e27992e3b..1faa166a8 100644 --- a/packages/vtable/src/scenegraph/select/update-select-border.ts +++ b/packages/vtable/src/scenegraph/select/update-select-border.ts @@ -21,6 +21,7 @@ function updateComponent( key: string, scene: Scenegraph ) { + const table = scene.table; const [startColStr, startRowStr, endColStr, endRowStr] = key.split('-'); const startCol = parseInt(startColStr, 10); const startRow = parseInt(startRowStr, 10); @@ -35,14 +36,14 @@ function updateComponent( let visibleCellRange; switch (selectComp.role) { case 'rowHeader': - visibleCellRange = scene.table.getBodyVisibleRowRange(); + visibleCellRange = table.getBodyVisibleRowRange(); if (visibleCellRange) { computeRectCellRangeStartRow = Math.max(startRow, visibleCellRange.rowStart - 1); computeRectCellRangeEndRow = Math.min(endRow, visibleCellRange.rowEnd + 1); } break; case 'columnHeader': - visibleCellRange = scene.table.getBodyVisibleCellRange(); + visibleCellRange = table.getBodyVisibleCellRange(); if (visibleCellRange) { computeRectCellRangeStartCol = Math.max(startCol, visibleCellRange.colStart - 1); computeRectCellRangeEndCol = Math.min(endCol, visibleCellRange.colEnd + 1); @@ -51,14 +52,14 @@ function updateComponent( case 'cornerHeader': break; case 'bottomFrozen': - visibleCellRange = scene.table.getBodyVisibleCellRange(); + visibleCellRange = table.getBodyVisibleCellRange(); if (visibleCellRange) { computeRectCellRangeStartCol = Math.max(startCol, visibleCellRange.colStart - 1); computeRectCellRangeEndCol = Math.min(endCol, visibleCellRange.colEnd + 1); } break; case 'rightFrozen': - visibleCellRange = scene.table.getBodyVisibleCellRange(); + visibleCellRange = table.getBodyVisibleCellRange(); if (visibleCellRange) { computeRectCellRangeStartRow = Math.max(startRow, visibleCellRange.rowStart - 1); computeRectCellRangeEndRow = Math.min(endRow, visibleCellRange.rowEnd + 1); @@ -71,7 +72,7 @@ function updateComponent( case 'rightBottomCorner': break; default: - visibleCellRange = scene.table.getBodyVisibleCellRange(); + visibleCellRange = table.getBodyVisibleCellRange(); if (visibleCellRange) { computeRectCellRangeStartRow = Math.max(startRow, visibleCellRange.rowStart - 1); computeRectCellRangeEndRow = Math.min(endRow, visibleCellRange.rowEnd + 1); @@ -80,11 +81,11 @@ function updateComponent( } break; } - // const cellRange = scene.table.getCellRange(startCol, startRow); - // const colsWidth = scene.table.getColsWidth(cellRange.start.col, endCol); - // const rowsHeight = scene.table.getRowsHeight(cellRange.start.row, endRow); - const colsWidth = scene.table.getColsWidth(computeRectCellRangeStartCol, computeRectCellRangeEndCol); - const rowsHeight = scene.table.getRowsHeight(computeRectCellRangeStartRow, computeRectCellRangeEndRow); + // const cellRange = table.getCellRange(startCol, startRow); + // const colsWidth = table.getColsWidth(cellRange.start.col, endCol); + // const rowsHeight = table.getRowsHeight(cellRange.start.row, endRow); + const colsWidth = table.getColsWidth(computeRectCellRangeStartCol, computeRectCellRangeEndCol); + const rowsHeight = table.getRowsHeight(computeRectCellRangeStartRow, computeRectCellRangeEndRow); const firstCellBound = scene.highPerformanceGetCell( computeRectCellRangeStartCol, computeRectCellRangeStartRow @@ -112,14 +113,42 @@ function updateComponent( } //#region 判断是不是按着表头部分的选中框 因为绘制层级的原因 线宽会被遮住一半,因此需要动态调整层级 - const isNearRowHeader = scene.table.frozenColCount ? startCol === scene.table.frozenColCount : false; - const isNearRightRowHeader = scene.table.rightFrozenColCount - ? scene.table.rightFrozenColCount > 0 && endCol === scene.table.colCount - scene.table.rightFrozenColCount - 1 + let isNearRowHeader = table.frozenColCount ? startCol === table.frozenColCount : false; + if (!isNearRowHeader && table.frozenColCount && table.scrollLeft > 0) { + const startColRelativePosition = table.getColsWidth(0, startCol - 1) - table.scrollLeft; + if (startColRelativePosition < table.getFrozenColsWidth()) { + isNearRowHeader = true; + } + } + + let isNearRightRowHeader = table.rightFrozenColCount + ? table.rightFrozenColCount > 0 && endCol === table.colCount - table.rightFrozenColCount - 1 : false; - const isNearColHeader = scene.table.frozenRowCount ? startRow === scene.table.frozenRowCount : true; - const isNearBottomColHeader = scene.table.bottomFrozenRowCount - ? endRow === scene.table.rowCount - scene.table.bottomFrozenRowCount - 1 + if (!isNearRightRowHeader && table.rightFrozenColCount) { + const endColRelativePosition = table.getColsWidth(0, endCol) - table.scrollLeft; + if (endColRelativePosition > table.tableNoFrameWidth - table.getRightFrozenColsWidth()) { + isNearRightRowHeader = true; + } + } + + let isNearColHeader = table.frozenRowCount ? startRow === table.frozenRowCount : true; + if (!isNearColHeader && table.frozenRowCount && table.scrollTop > 0) { + const startRowRelativePosition = table.getRowsHeight(0, startRow - 1) - table.scrollTop; + if (startRowRelativePosition < table.getFrozenRowsHeight()) { + isNearColHeader = true; + } + } + + let isNearBottomColHeader = table.bottomFrozenRowCount + ? endRow === table.rowCount - table.bottomFrozenRowCount - 1 : false; + if (!isNearBottomColHeader && table.bottomFrozenRowCount) { + const endRowRelativePosition = table.getRowsHeight(0, endRow) - table.scrollTop; + if (endRowRelativePosition > table.tableNoFrameHeight - table.getBottomFrozenRowsHeight()) { + isNearBottomColHeader = true; + } + } + if ( (isNearRowHeader && selectComp.rect.attribute.stroke[3]) || (isNearRightRowHeader && selectComp.rect.attribute.stroke[1]) || @@ -171,24 +200,23 @@ function updateComponent( //#region 调整层级后 滚动情况下会出现绘制范围出界 如body的选中框 渲染在了rowheader上面,所有需要调整选中框rect的 边界 if ( - selectComp.rect.attribute.x < scene.table.getFrozenColsWidth() && + selectComp.rect.attribute.x < table.getFrozenColsWidth() && // selectComp.rect.attribute.x + selectComp.rect.attribute.width > scene.rowHeaderGroup.attribute.width && - scene.table.scrollLeft > 0 && + table.scrollLeft > 0 && (selectComp.role === 'body' || selectComp.role === 'columnHeader' || selectComp.role === 'bottomFrozen') ) { - const width = selectComp.rect.attribute.width - (scene.table.getFrozenColsWidth() - selectComp.rect.attribute.x); + const width = selectComp.rect.attribute.width - (table.getFrozenColsWidth() - selectComp.rect.attribute.x); selectComp.rect.setAttributes({ - x: selectComp.rect.attribute.x + (scene.table.getFrozenColsWidth() - selectComp.rect.attribute.x), + x: selectComp.rect.attribute.x + (table.getFrozenColsWidth() - selectComp.rect.attribute.x), width: width > 0 ? width : 0 }); - // selectComp.fillhandle.setAttributes({ - // x: selectComp.rect.attribute.x + (scene.table.getFrozenColsWidth() - selectComp.rect.attribute.x), - // width: width > 0 ? width : 0 - // }); + selectComp.fillhandle.setAttributes({ + visible: width > 0 + }); } if ( // selectComp.rect.attribute.x < scene.rightFrozenGroup.attribute.x && - scene.table.getRightFrozenColsWidth() > 0 && // right冻结列存在的情况下 + table.getRightFrozenColsWidth() > 0 && // right冻结列存在的情况下 scene.rightFrozenGroup.attribute.height > 0 && selectComp.rect.attribute.x + selectComp.rect.attribute.width > scene.rightFrozenGroup.attribute.x && (selectComp.role === 'body' || selectComp.role === 'columnHeader' || selectComp.role === 'bottomFrozen') @@ -198,14 +226,13 @@ function updateComponent( x: selectComp.rect.attribute.x, width: width > 0 ? width : 0 }); - // selectComp.fillhandle.setAttributes({ - // x: selectComp.rect.attribute.x, - // width: width > 0 ? width : 0 - // }); + selectComp.fillhandle.setAttributes({ + visible: width - colsWidth > 0 + }); } if ( selectComp.rect.attribute.y < scene.colHeaderGroup.attribute.height && - scene.table.scrollTop > 0 && + table.scrollTop > 0 && (selectComp.role === 'body' || selectComp.role === 'rowHeader' || selectComp.role === 'rightFrozen') ) { const height = @@ -214,10 +241,9 @@ function updateComponent( y: selectComp.rect.attribute.y + (scene.colHeaderGroup.attribute.height - selectComp.rect.attribute.y), height: height > 0 ? height : 0 }); - // selectComp.fillhandle.setAttributes({ - // y: selectComp.rect.attribute.y + (scene.colHeaderGroup.attribute.height - selectComp.rect.attribute.y), - // height: height > 0 ? height : 0 - // }); + selectComp.fillhandle.setAttributes({ + visible: height > 0 + }); } if ( scene.bottomFrozenGroup.attribute.width > 0 && @@ -230,10 +256,9 @@ function updateComponent( y: selectComp.rect.attribute.y, height: height > 0 ? height : 0 }); - // selectComp.fillhandle.setAttributes({ - // y: selectComp.fillhandle.attribute.y, - // height: height > 0 ? height : 0 - // }); + selectComp.fillhandle.setAttributes({ + visible: height - rowsHeight > 0 + }); } //#endregion } else { @@ -265,7 +290,7 @@ function updateComponent( if (typeof selectComp.rect.attribute.lineWidth === 'number') { diffSize = Math.ceil(selectComp.rect.attribute.lineWidth / 2); } - if (endCol === scene.table.colCount - 1) { + if (endCol === table.colCount - 1) { if (Array.isArray(selectComp.rect.attribute.lineWidth)) { diffSize = Math.ceil((selectComp.rect.attribute.lineWidth[1] ?? 0) / 2); } @@ -289,7 +314,7 @@ function updateComponent( // width: selectComp.rect.attribute.width - diffSize // }); } - if (endRow === scene.table.rowCount - 1) { + if (endRow === table.rowCount - 1) { if (Array.isArray(selectComp.rect.attribute.lineWidth)) { diffSize = Math.ceil((selectComp.rect.attribute.lineWidth[2] ?? 0) / 2); } @@ -321,6 +346,7 @@ export function updateCellSelectBorder( selectRange: CellRange & { skipBodyMerge?: boolean }, ifExtendSelectRange: boolean = true ) { + const table = scene.table; const newStartCol = selectRange.start.col; const newStartRow = selectRange.start.row; const newEndCol = selectRange.end.col; @@ -329,18 +355,18 @@ export function updateCellSelectBorder( let startCol = Math.max(Math.min(newEndCol, newStartCol), 0); let startRow = Math.max(Math.min(newEndRow, newStartRow), 0); - let endCol = Math.min(Math.max(newEndCol, newStartCol), scene.table.colCount - 1); - let endRow = Math.min(Math.max(newEndRow, newStartRow), scene.table.rowCount - 1); + let endCol = Math.min(Math.max(newEndCol, newStartCol), table.colCount - 1); + let endRow = Math.min(Math.max(newEndRow, newStartRow), table.rowCount - 1); //#region region 校验四周的单元格有没有合并的情况,如有则扩大范围 const extendSelectRange = () => { let isExtend = false; for (let col = startCol; col <= endCol; col++) { if (col === startCol) { for (let row = startRow; row <= endRow; row++) { - if (!scene.table.isHeader(col, row) && skipBodyMerge) { + if (!table.isHeader(col, row) && skipBodyMerge) { continue; } - const mergeInfo = getCellMergeInfo(scene.table, col, row); + const mergeInfo = getCellMergeInfo(table, col, row); if (mergeInfo && mergeInfo.start.col < startCol) { startCol = mergeInfo.start.col; isExtend = true; @@ -350,11 +376,11 @@ export function updateCellSelectBorder( } if (!isExtend && col === endCol) { for (let row = startRow; row <= endRow; row++) { - if (!scene.table.isHeader(col, row) && skipBodyMerge) { + if (!table.isHeader(col, row) && skipBodyMerge) { continue; } - const mergeInfo = getCellMergeInfo(scene.table, col, row); - if (mergeInfo && Math.min(mergeInfo.end.col, scene.table.colCount - 1) > endCol) { + const mergeInfo = getCellMergeInfo(table, col, row); + if (mergeInfo && Math.min(mergeInfo.end.col, table.colCount - 1) > endCol) { endCol = mergeInfo.end.col; isExtend = true; break; @@ -370,10 +396,10 @@ export function updateCellSelectBorder( for (let row = startRow; row <= endRow; row++) { if (row === startRow) { for (let col = startCol; col <= endCol; col++) { - if (!scene.table.isHeader(col, row) && skipBodyMerge) { + if (!table.isHeader(col, row) && skipBodyMerge) { continue; } - const mergeInfo = getCellMergeInfo(scene.table, col, row); + const mergeInfo = getCellMergeInfo(table, col, row); if (mergeInfo && mergeInfo.start.row < startRow) { startRow = mergeInfo.start.row; isExtend = true; @@ -383,11 +409,11 @@ export function updateCellSelectBorder( } if (!isExtend && row === endRow) { for (let col = startCol; col <= endCol; col++) { - if (!scene.table.isHeader(col, row) && skipBodyMerge) { + if (!table.isHeader(col, row) && skipBodyMerge) { continue; } - const mergeInfo = getCellMergeInfo(scene.table, col, row); - if (mergeInfo && Math.min(mergeInfo.end.row, scene.table.rowCount - 1) > endRow) { + const mergeInfo = getCellMergeInfo(table, col, row); + if (mergeInfo && Math.min(mergeInfo.end.row, table.rowCount - 1) > endRow) { endRow = mergeInfo.end.row; isExtend = true; break; @@ -423,66 +449,63 @@ export function updateCellSelectBorder( let needRightTopCornerHeader = false; let needRightBottomCornerHeader = false; let needLeftBottomCornerHeader = false; - if (startCol <= scene.table.frozenColCount - 1 && startRow <= scene.table.frozenRowCount - 1) { + if (startCol <= table.frozenColCount - 1 && startRow <= table.frozenRowCount - 1) { needCornerHeader = true; } - if (endCol >= scene.table.colCount - scene.table.rightFrozenColCount && startRow <= scene.table.frozenRowCount - 1) { + if (endCol >= table.colCount - table.rightFrozenColCount && startRow <= table.frozenRowCount - 1) { needRightTopCornerHeader = true; } - if (startCol <= scene.table.frozenColCount - 1 && endRow >= scene.table.rowCount - scene.table.bottomFrozenRowCount) { + if (startCol <= table.frozenColCount - 1 && endRow >= table.rowCount - table.bottomFrozenRowCount) { needLeftBottomCornerHeader = true; } - if ( - endCol >= scene.table.colCount - scene.table.rightFrozenColCount && - endRow >= scene.table.rowCount - scene.table.bottomFrozenRowCount - ) { + if (endCol >= table.colCount - table.rightFrozenColCount && endRow >= table.rowCount - table.bottomFrozenRowCount) { needRightBottomCornerHeader = true; } if ( - startCol <= scene.table.frozenColCount - 1 && - endRow >= scene.table.frozenRowCount && - startRow <= scene.table.rowCount - scene.table.bottomFrozenRowCount - 1 + startCol <= table.frozenColCount - 1 && + endRow >= table.frozenRowCount && + startRow <= table.rowCount - table.bottomFrozenRowCount - 1 ) { needRowHeader = true; } if ( - endCol >= scene.table.colCount - scene.table.rightFrozenColCount && - endRow >= scene.table.frozenRowCount && - startRow <= scene.table.rowCount - scene.table.bottomFrozenRowCount - 1 + endCol >= table.colCount - table.rightFrozenColCount && + endRow >= table.frozenRowCount && + startRow <= table.rowCount - table.bottomFrozenRowCount - 1 ) { needRightRowHeader = true; } if ( - startRow <= scene.table.frozenRowCount - 1 && - endCol >= scene.table.frozenColCount && - startCol <= scene.table.colCount - scene.table.rightFrozenColCount - 1 + startRow <= table.frozenRowCount - 1 && + endCol >= table.frozenColCount && + startCol <= table.colCount - table.rightFrozenColCount - 1 ) { needColumnHeader = true; } if ( - endRow >= scene.table.rowCount - scene.table.bottomFrozenRowCount && - endCol >= scene.table.frozenColCount && - startCol <= scene.table.colCount - scene.table.rightFrozenColCount - 1 + endRow >= table.rowCount - table.bottomFrozenRowCount && + endCol >= table.frozenColCount && + startCol <= table.colCount - table.rightFrozenColCount - 1 ) { needBottomColumnHeader = true; } if ( - startCol <= scene.table.colCount - scene.table.rightFrozenColCount - 1 && - endCol >= scene.table.frozenColCount && - startRow <= scene.table.rowCount - scene.table.bottomFrozenRowCount - 1 && - endRow >= scene.table.frozenRowCount + startCol <= table.colCount - table.rightFrozenColCount - 1 && + endCol >= table.frozenColCount && + startRow <= table.rowCount - table.bottomFrozenRowCount - 1 && + endRow >= table.frozenRowCount ) { needBody = true; } // TODO 可以尝试不拆分三个表头和body【前提是theme中合并配置】 用一个SelectBorder 需要结合clip,并动态设置border的范围【依据区域范围 已经是否跨表头及body】 if (needCornerHeader) { - const cornerEndCol = Math.min(endCol, scene.table.frozenColCount - 1); - const cornerEndRow = Math.min(endRow, scene.table.frozenRowCount - 1); + const cornerEndCol = Math.min(endCol, table.frozenColCount - 1); + const cornerEndRow = Math.min(endRow, table.frozenRowCount - 1); const strokeArray = [true, !needColumnHeader, !needRowHeader, true]; scene.createCellSelectBorder( startCol, @@ -495,8 +518,8 @@ export function updateCellSelectBorder( ); } if (needRightTopCornerHeader) { - const cornerStartCol = Math.max(startCol, scene.table.colCount - scene.table.rightFrozenColCount); - const cornerEndRow = Math.min(endRow, scene.table.frozenRowCount - 1); + const cornerStartCol = Math.max(startCol, table.colCount - table.rightFrozenColCount); + const cornerEndRow = Math.min(endRow, table.frozenRowCount - 1); const strokeArray = [true, true, !needRightRowHeader, !needColumnHeader]; scene.createCellSelectBorder( cornerStartCol, @@ -510,8 +533,8 @@ export function updateCellSelectBorder( } if (needLeftBottomCornerHeader) { - const cornerEndCol = Math.min(endCol, scene.table.frozenColCount - 1); - const cornerStartRow = Math.max(startRow, scene.table.rowCount - scene.table.bottomFrozenRowCount); + const cornerEndCol = Math.min(endCol, table.frozenColCount - 1); + const cornerStartRow = Math.max(startRow, table.rowCount - table.bottomFrozenRowCount); const strokeArray = [!needRowHeader, !needBottomColumnHeader, true, true]; scene.createCellSelectBorder( startCol, @@ -524,8 +547,8 @@ export function updateCellSelectBorder( ); } if (needRightBottomCornerHeader) { - const cornerStartCol = Math.max(startCol, scene.table.colCount - scene.table.rightFrozenColCount); - const cornerStartRow = Math.max(startRow, scene.table.rowCount - scene.table.bottomFrozenRowCount); + const cornerStartCol = Math.max(startCol, table.colCount - table.rightFrozenColCount); + const cornerStartRow = Math.max(startRow, table.rowCount - table.bottomFrozenRowCount); const strokeArray = [!needRightRowHeader, true, true, !needBottomColumnHeader]; scene.createCellSelectBorder( cornerStartCol, @@ -538,9 +561,9 @@ export function updateCellSelectBorder( ); } if (needColumnHeader) { - const columnHeaderStartCol = Math.max(startCol, scene.table.frozenColCount); - const columnHeaderEndCol = Math.min(endCol, scene.table.colCount - scene.table.rightFrozenColCount - 1); - const columnHeaderEndRow = Math.min(endRow, scene.table.frozenRowCount - 1); + const columnHeaderStartCol = Math.max(startCol, table.frozenColCount); + const columnHeaderEndCol = Math.min(endCol, table.colCount - table.rightFrozenColCount - 1); + const columnHeaderEndRow = Math.min(endRow, table.frozenRowCount - 1); const strokeArray = [true, !needRightTopCornerHeader, !needBody, !needCornerHeader]; scene.createCellSelectBorder( columnHeaderStartCol, @@ -553,9 +576,9 @@ export function updateCellSelectBorder( ); } if (needBottomColumnHeader) { - const columnHeaderStartCol = Math.max(startCol, scene.table.frozenColCount); - const columnHeaderEndCol = Math.min(endCol, scene.table.colCount - scene.table.rightFrozenColCount - 1); - const columnHeaderStartRow = Math.max(startRow, scene.table.rowCount - scene.table.bottomFrozenRowCount); + const columnHeaderStartCol = Math.max(startCol, table.frozenColCount); + const columnHeaderEndCol = Math.min(endCol, table.colCount - table.rightFrozenColCount - 1); + const columnHeaderStartRow = Math.max(startRow, table.rowCount - table.bottomFrozenRowCount); const strokeArray = [!needBody, !needRightBottomCornerHeader, true, !needLeftBottomCornerHeader]; scene.createCellSelectBorder( columnHeaderStartCol, @@ -568,9 +591,9 @@ export function updateCellSelectBorder( ); } if (needRowHeader) { - const columnHeaderStartRow = Math.max(startRow, scene.table.frozenRowCount); - const columnHeaderEndRow = Math.min(endRow, scene.table.rowCount - scene.table.bottomFrozenRowCount - 1); - const columnHeaderEndCol = Math.min(endCol, scene.table.frozenColCount - 1); + const columnHeaderStartRow = Math.max(startRow, table.frozenRowCount); + const columnHeaderEndRow = Math.min(endRow, table.rowCount - table.bottomFrozenRowCount - 1); + const columnHeaderEndCol = Math.min(endCol, table.frozenColCount - 1); const strokeArray = [!needCornerHeader, !needBody, !needLeftBottomCornerHeader, true]; scene.createCellSelectBorder( startCol, @@ -583,9 +606,9 @@ export function updateCellSelectBorder( ); } if (needRightRowHeader) { - const columnHeaderStartRow = Math.max(startRow, scene.table.frozenRowCount); - const columnHeaderEndRow = Math.min(endRow, scene.table.rowCount - scene.table.bottomFrozenRowCount - 1); - const columnHeaderStartCol = Math.max(startCol, scene.table.colCount - scene.table.rightFrozenColCount); + const columnHeaderStartRow = Math.max(startRow, table.frozenRowCount); + const columnHeaderEndRow = Math.min(endRow, table.rowCount - table.bottomFrozenRowCount - 1); + const columnHeaderStartCol = Math.max(startCol, table.colCount - table.rightFrozenColCount); const strokeArray = [!needRightTopCornerHeader, true, !needRightBottomCornerHeader, !needBody]; scene.createCellSelectBorder( columnHeaderStartCol, @@ -598,10 +621,10 @@ export function updateCellSelectBorder( ); } if (needBody) { - const columnHeaderStartCol = Math.max(startCol, scene.table.frozenColCount); - const columnHeaderStartRow = Math.max(startRow, scene.table.frozenRowCount); - const columnHeaderEndCol = Math.min(endCol, scene.table.colCount - scene.table.rightFrozenColCount - 1); - const columnHeaderEndRow = Math.min(endRow, scene.table.rowCount - scene.table.bottomFrozenRowCount - 1); + const columnHeaderStartCol = Math.max(startCol, table.frozenColCount); + const columnHeaderStartRow = Math.max(startRow, table.frozenRowCount); + const columnHeaderEndCol = Math.min(endCol, table.colCount - table.rightFrozenColCount - 1); + const columnHeaderEndRow = Math.min(endRow, table.rowCount - table.bottomFrozenRowCount - 1); const strokeArray = [!needColumnHeader, !needRightRowHeader, !needBottomColumnHeader, !needRowHeader]; scene.createCellSelectBorder( columnHeaderStartCol, From 5af55037001423c3adf26cf227e8603261b54034 Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Wed, 3 Jul 2024 16:08:29 +0800 Subject: [PATCH 10/11] fix: fix selected highlight update when scrolling #2028 --- .../vtable/fix-highlight-update_2024-07-03-08-08.json | 10 ++++++++++ .../graphic/contributions/group-contribution-render.ts | 5 +++-- 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 common/changes/@visactor/vtable/fix-highlight-update_2024-07-03-08-08.json diff --git a/common/changes/@visactor/vtable/fix-highlight-update_2024-07-03-08-08.json b/common/changes/@visactor/vtable/fix-highlight-update_2024-07-03-08-08.json new file mode 100644 index 000000000..2e4509a7e --- /dev/null +++ b/common/changes/@visactor/vtable/fix-highlight-update_2024-07-03-08-08.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vtable", + "comment": "fix: fix selected highlight update when scrolling #2028", + "type": "none" + } + ], + "packageName": "@visactor/vtable" +} \ No newline at end of file diff --git a/packages/vtable/src/scenegraph/graphic/contributions/group-contribution-render.ts b/packages/vtable/src/scenegraph/graphic/contributions/group-contribution-render.ts index 33699feb9..370056650 100644 --- a/packages/vtable/src/scenegraph/graphic/contributions/group-contribution-render.ts +++ b/packages/vtable/src/scenegraph/graphic/contributions/group-contribution-render.ts @@ -827,11 +827,12 @@ export class AdjustColorGroupBeforeRenderContribution implements IGroupRenderCon // 处理hover颜色 if ((group as Group).role === 'cell') { const table = (group.stage as any).table as BaseTableAPI; - if (table && table.stateManager.interactionState !== InteractionState.scrolling) { + if (table) { const selectColor = getCellSelectColor(group as Group, table); if (selectColor) { + // show select highlight when scrolling (group.attribute as any)._vtableHightLightFill = selectColor; - } else { + } else if (table.stateManager.interactionState !== InteractionState.scrolling) { const hoverColor = getCellHoverColor(group as Group, table); if (hoverColor) { (group.attribute as any)._vtableHightLightFill = hoverColor; From 89cb688b1266bb9e9c6c3affd01a192200804a98 Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Wed, 3 Jul 2024 16:15:42 +0800 Subject: [PATCH 11/11] fix: fix test judgement in customMergeCell #2031 --- .../fix-customMergeCell-text_2024-07-03-08-15.json | 10 ++++++++++ packages/vtable/src/core/BaseTable.ts | 8 ++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 common/changes/@visactor/vtable/fix-customMergeCell-text_2024-07-03-08-15.json diff --git a/common/changes/@visactor/vtable/fix-customMergeCell-text_2024-07-03-08-15.json b/common/changes/@visactor/vtable/fix-customMergeCell-text_2024-07-03-08-15.json new file mode 100644 index 000000000..875c1d4de --- /dev/null +++ b/common/changes/@visactor/vtable/fix-customMergeCell-text_2024-07-03-08-15.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vtable", + "comment": "fix: fix test judgement in customMergeCell #2031", + "type": "none" + } + ], + "packageName": "@visactor/vtable" +} \ No newline at end of file diff --git a/packages/vtable/src/core/BaseTable.ts b/packages/vtable/src/core/BaseTable.ts index 13ba70b99..8d61bd60d 100644 --- a/packages/vtable/src/core/BaseTable.ts +++ b/packages/vtable/src/core/BaseTable.ts @@ -2865,7 +2865,7 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { if ( customMerge && customMerge.range && - (customMerge.text || customMerge.customLayout || customMerge.customRender) + (isValid(customMerge.text) || customMerge.customLayout || customMerge.customRender) ) { return customMerge.range; } @@ -2880,7 +2880,11 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { getCustomMerge(col: number, row: number) { if (this.internalProps.customMergeCell) { const customMerge = this.internalProps.customMergeCell(col, row, this); - if (customMerge && customMerge.range && (customMerge.text || customMerge.customLayout || this.customRender)) { + if ( + customMerge && + customMerge.range && + (isValid(customMerge.text) || customMerge.customLayout || this.customRender) + ) { if (customMerge.style) { const styleClass = this.internalProps.bodyHelper.getStyleClass('text'); const style = customMerge.style;