From b29647d284c19c22688253661cf299e0b60fc4b6 Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Fri, 28 Mar 2025 16:22:14 +0800 Subject: [PATCH 1/8] fix: fix cell radius set in getCellCornerRadius() --- packages/vtable/src/core/tableHelper.ts | 46 +++++++++++++++++-------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/packages/vtable/src/core/tableHelper.ts b/packages/vtable/src/core/tableHelper.ts index 1a41bccd9c..c8695a2ef1 100644 --- a/packages/vtable/src/core/tableHelper.ts +++ b/packages/vtable/src/core/tableHelper.ts @@ -368,25 +368,43 @@ export function getCellCornerRadius(col: number, row: number, table: BaseTableAP const tableCornerRadius = table.theme.frameStyle.cornerRadius; if (table.theme.cellInnerBorder) { if (Array.isArray(tableCornerRadius)) { + const radius = [0, 0, 0, 0]; if (col === 0 && row === 0) { - return [tableCornerRadius[0], 0, 0, 0]; - } else if (col === table.colCount - 1 && row === 0) { - return [0, tableCornerRadius[1], 0, 0]; - } else if (col === 0 && row === table.rowCount - 1) { - return [0, 0, 0, tableCornerRadius[3]]; - } else if (col === table.colCount - 1 && row === table.rowCount - 1) { - return [0, 0, tableCornerRadius[2], 0]; + // return [tableCornerRadius[0], 0, 0, 0]; + radius[0] = tableCornerRadius[0]; } + if (col === table.colCount - 1 && row === 0) { + // return [0, tableCornerRadius[1], 0, 0]; + radius[1] = tableCornerRadius[1]; + } + if (col === 0 && row === table.rowCount - 1) { + // return [0, 0, 0, tableCornerRadius[3]]; + radius[3] = tableCornerRadius[3]; + } + if (col === table.colCount - 1 && row === table.rowCount - 1) { + // return [0, 0, tableCornerRadius[2], 0]; + radius[2] = tableCornerRadius[2]; + } + return radius; } else if (tableCornerRadius) { + const radius = [0, 0, 0, 0]; if (col === 0 && row === 0) { - return [tableCornerRadius, 0, 0, 0]; - } else if (col === table.colCount - 1 && row === 0) { - return [0, tableCornerRadius, 0, 0]; - } else if (col === 0 && row === table.rowCount - 1) { - return [0, 0, 0, tableCornerRadius]; - } else if (col === table.colCount - 1 && row === table.rowCount - 1) { - return [0, 0, tableCornerRadius, 0]; + // return [tableCornerRadius, 0, 0, 0]; + radius[0] = tableCornerRadius; + } + if (col === table.colCount - 1 && row === 0) { + // return [0, tableCornerRadius, 0, 0]; + radius[1] = tableCornerRadius; + } + if (col === 0 && row === table.rowCount - 1) { + // return [0, 0, 0, tableCornerRadius]; + radius[3] = tableCornerRadius; + } + if (col === table.colCount - 1 && row === table.rowCount - 1) { + // return [0, 0, tableCornerRadius, 0]; + radius[2] = tableCornerRadius; } + return radius; } } return 0; From b5477afa42daf99cf9440b40dd98c610076bf73a Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Fri, 28 Mar 2025 16:35:37 +0800 Subject: [PATCH 2/8] feat: add dynamicUpdateSelectionSize config in theme.selectionStyle --- .../vtable/src/scenegraph/select/update-select-border.ts | 9 +++++---- packages/vtable/src/themes/theme.ts | 3 +++ packages/vtable/src/ts-types/theme.ts | 1 + 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/vtable/src/scenegraph/select/update-select-border.ts b/packages/vtable/src/scenegraph/select/update-select-border.ts index 913aeaa3cc..229e627a1f 100644 --- a/packages/vtable/src/scenegraph/select/update-select-border.ts +++ b/packages/vtable/src/scenegraph/select/update-select-border.ts @@ -153,11 +153,12 @@ function updateComponent( } } + const { dynamicUpdateSelectionSize } = table.theme.selectionStyle; if ( - (isNearRowHeader && selectComp.rect.attribute.stroke[3]) || - (isNearRightRowHeader && selectComp.rect.attribute.stroke[1]) || - (isNearColHeader && selectComp.rect.attribute.stroke[0]) || - (isNearBottomColHeader && selectComp.rect.attribute.stroke[2]) + (isNearRowHeader && (selectComp.rect.attribute.stroke[3] || dynamicUpdateSelectionSize)) || + (isNearRightRowHeader && (selectComp.rect.attribute.stroke[1] || dynamicUpdateSelectionSize)) || + (isNearColHeader && (selectComp.rect.attribute.stroke[0] || dynamicUpdateSelectionSize)) || + (isNearBottomColHeader && (selectComp.rect.attribute.stroke[2] || dynamicUpdateSelectionSize)) ) { if (isNearRowHeader && selectComp.rect.attribute.stroke[3]) { scene.tableGroup.insertAfter( diff --git a/packages/vtable/src/themes/theme.ts b/packages/vtable/src/themes/theme.ts index 5f5d42f438..94004a960a 100644 --- a/packages/vtable/src/themes/theme.ts +++ b/packages/vtable/src/themes/theme.ts @@ -719,6 +719,9 @@ export class TableTheme implements ITableThemeDefine { }, get selectionFillMode(): 'overlay' | 'replace' { return selectionStyle?.selectionFillMode ?? 'overlay'; + }, + get dynamicUpdateSelectionSize(): boolean { + return selectionStyle?.dynamicUpdateSelectionSize ?? false; } }; } diff --git a/packages/vtable/src/ts-types/theme.ts b/packages/vtable/src/ts-types/theme.ts index 87a0924630..9c9f22fc57 100644 --- a/packages/vtable/src/ts-types/theme.ts +++ b/packages/vtable/src/ts-types/theme.ts @@ -154,6 +154,7 @@ export interface ITableThemeDefine { inlineRowBgColor?: string; //交互所在整行的背景颜色 inlineColumnBgColor?: string; //交互所在整列的背景颜色 selectionFillMode?: 'overlay' | 'replace'; //选择框填充模式,overlay表示选择框背景色覆盖在表格上(需要配饰透明度),replace表示背景色替换原有单元格的背景色 + dynamicUpdateSelectionSize?: boolean; // 选择框大小随滚动动态变化,用于冻结并且背景透明的场景,默认false,开启后性能会有一定影响 }; // style for axis From 3ede7c586351a5aabaf59808f4408dc265d2fc33 Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Fri, 28 Mar 2025 16:48:50 +0800 Subject: [PATCH 3/8] chore: update rush change --- .../fix-selected-border-update_2025-03-28-08-48.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 common/changes/@visactor/vtable/fix-selected-border-update_2025-03-28-08-48.json diff --git a/common/changes/@visactor/vtable/fix-selected-border-update_2025-03-28-08-48.json b/common/changes/@visactor/vtable/fix-selected-border-update_2025-03-28-08-48.json new file mode 100644 index 0000000000..e0ad5a0761 --- /dev/null +++ b/common/changes/@visactor/vtable/fix-selected-border-update_2025-03-28-08-48.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vtable", + "comment": "feat: add dynamicUpdateSelectionSize config in theme.selectionStyle", + "type": "none" + } + ], + "packageName": "@visactor/vtable" +} \ No newline at end of file From e30f5f2495e33438764174d8a0de58f0f969abef Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Mon, 31 Mar 2025 19:54:48 +0800 Subject: [PATCH 4/8] fix: fix range cache in _updateSize() --- packages/vtable/src/core/BaseTable.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/vtable/src/core/BaseTable.ts b/packages/vtable/src/core/BaseTable.ts index fb892efe43..4b20088895 100644 --- a/packages/vtable/src/core/BaseTable.ts +++ b/packages/vtable/src/core/BaseTable.ts @@ -1163,6 +1163,9 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { height - ((lineWidths[0] ?? 0) + (shadowWidths[0] ?? 0)) - ((lineWidths[2] ?? 0) + (shadowWidths[2] ?? 0)); } } + + this._clearColRangeWidthsMap(); + this._clearRowRangeHeightsMap(); } updateViewBox(newViewBox: IBoundsLike) { From 0248df6893202a626b322e209d9aea3dd11bdd8c Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Tue, 1 Apr 2025 15:59:54 +0800 Subject: [PATCH 5/8] feat: refactor pivotTable corner with no columns or rows case #3653 --- .../vtable/src/layout/pivot-header-layout.ts | 31 ++++++++++++------- packages/vtable/src/layout/tree-helper.ts | 4 +-- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/packages/vtable/src/layout/pivot-header-layout.ts b/packages/vtable/src/layout/pivot-header-layout.ts index 4998086d7e..bcd20a3740 100644 --- a/packages/vtable/src/layout/pivot-header-layout.ts +++ b/packages/vtable/src/layout/pivot-header-layout.ts @@ -798,6 +798,9 @@ export class PivotHeaderLayoutMap implements LayoutMapAPI { this.rowHierarchyType === 'grid-tree' ? this._getRowHeaderTreeExpandedMaxLevelCount() || this.rowHeaderLevelCount : this.rowHeaderLevelCount; + if (colLevelCount === 0 || rowLevelCount === 0) { + return results; + } if (this.cornerSetting.titleOnDimension === 'all') { if (this.indicatorsAsCol) { if (colDimensionKeys) { @@ -1581,7 +1584,10 @@ export class PivotHeaderLayoutMap implements LayoutMapAPI { !this.dataset.customColTree?.length //根据情况来加的判断条件 之前是只兼容没有设置两个自定义树的情况 现在对有自定义树的情况也处理出现角头 // && !this.dataset.customRowTree?.length ) { - if (this.cornerSetting.titleOnDimension === 'row' && this.cornerSetting.forceShowHeader) { + if ( + (this.cornerSetting.titleOnDimension === 'row' || this.cornerSetting.titleOnDimension === 'all') && + this.cornerSetting.forceShowHeader + ) { count = 1; } else if ( !this._table.isPivotChart() && @@ -1658,7 +1664,10 @@ export class PivotHeaderLayoutMap implements LayoutMapAPI { // && !this.dataset.customColTree !this.dataset.customRowTree?.length //根据情况来加的判断条件 之前是只兼容没有设置两个自定义树的情况 现在对有自定义树的情况也处理出现角头 ) { - if (this.cornerSetting.titleOnDimension === 'column' && this.cornerSetting.forceShowHeader) { + if ( + (this.cornerSetting.titleOnDimension === 'column' || this.cornerSetting.titleOnDimension === 'all') && + this.cornerSetting.forceShowHeader + ) { count = 1; } else if ( !this._table.isPivotChart() && @@ -1714,17 +1723,18 @@ export class PivotHeaderLayoutMap implements LayoutMapAPI { this._rowHeaderLevelCount = count; } get colCount(): number { - return ( - (this._getColumnHeaderTreeExpandedMaxLevelCount() > 0 || + let bodyColCount; + if ( + this._getColumnHeaderTreeExpandedMaxLevelCount() > 0 || this._table.isPivotChart() || (this.dataset.records as Array)?.length > 0 || (this.dataset.records && !Array.isArray(this.dataset.records)) - ? this._columnHeaderCellIds[0]?.length ?? this.columnDimensionTree.tree.size - : 0) + - this.rowHeaderLevelCount + - this.rightHeaderColCount + - this.leftRowSeriesNumberColumnCount - ); // 小心rightFrozenColCount和colCount的循环引用 造成调用栈溢出 + ) { + bodyColCount = (this._columnHeaderCellIds[0]?.length ?? this.columnDimensionTree.tree.size) || 1; + } else { + bodyColCount = 0; + } + return bodyColCount + this.rowHeaderLevelCount + this.rightHeaderColCount + this.leftRowSeriesNumberColumnCount; // 小心rightFrozenColCount和colCount的循环引用 造成调用栈溢出 } get rowCount(): number { return ( @@ -1740,7 +1750,6 @@ export class PivotHeaderLayoutMap implements LayoutMapAPI { this.columnHeaderLevelCount + this.bottomHeaderRowCount // 小心bottomFrozenRowCount和rowCount的循环引用 造成调用栈溢出 ); - // return (this._rowHeaderCellIds?.length ?? 0) + this.columnHeaderLevelCount + this.bottomFrozenRowCount; } get bodyRowSpanCount() { return this.rowDimensionTree.tree.size; diff --git a/packages/vtable/src/layout/tree-helper.ts b/packages/vtable/src/layout/tree-helper.ts index 054afadaa6..8802e553e8 100644 --- a/packages/vtable/src/layout/tree-helper.ts +++ b/packages/vtable/src/layout/tree-helper.ts @@ -169,7 +169,7 @@ export class DimensionTree { size += this.setTreeNode(n, size, node); }); } else { - size = 1; + node.level === -1 ? (size = 0) : (size = 1); // re.totalLevel = Math.max(re.totalLevel, (node.level ?? -1) + 1); } } else if (node.hierarchyState === HierarchyState.expand && children?.length >= 1) { @@ -224,7 +224,7 @@ export class DimensionTree { } else { //树形展示 无children子节点。但不能确定是最后一层的叶子节点 totalLevel还不能确定是计算完整棵树的整体深度 node.hierarchyState = HierarchyState.none; - size = 1; + node.level === -1 ? (size = 0) : (size = 1); } node.size = size; From 7dcd761344f1310c58aab3fe0e9f0352d26e315d Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Tue, 1 Apr 2025 16:01:41 +0800 Subject: [PATCH 6/8] docs: update changlog of rush --- ...53-feature-pivotTable-corner_2025-04-01-08-01.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/@visactor/vtable/3653-feature-pivotTable-corner_2025-04-01-08-01.json diff --git a/common/changes/@visactor/vtable/3653-feature-pivotTable-corner_2025-04-01-08-01.json b/common/changes/@visactor/vtable/3653-feature-pivotTable-corner_2025-04-01-08-01.json new file mode 100644 index 0000000000..fdf2813df7 --- /dev/null +++ b/common/changes/@visactor/vtable/3653-feature-pivotTable-corner_2025-04-01-08-01.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "feat: refactor pivotTable corner with no columns or rows case #3653\n\n", + "type": "none", + "packageName": "@visactor/vtable" + } + ], + "packageName": "@visactor/vtable", + "email": "892739385@qq.com" +} \ No newline at end of file From ca854ac9548c9f8aa45fed45b9ace746ead14bbf Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Tue, 1 Apr 2025 16:25:19 +0800 Subject: [PATCH 7/8] feat: refactor pivotTable corner with no columns or rows case #3653 --- packages/vtable/src/layout/pivot-header-layout.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/vtable/src/layout/pivot-header-layout.ts b/packages/vtable/src/layout/pivot-header-layout.ts index bcd20a3740..007bb98f84 100644 --- a/packages/vtable/src/layout/pivot-header-layout.ts +++ b/packages/vtable/src/layout/pivot-header-layout.ts @@ -1730,7 +1730,9 @@ export class PivotHeaderLayoutMap implements LayoutMapAPI { (this.dataset.records as Array)?.length > 0 || (this.dataset.records && !Array.isArray(this.dataset.records)) ) { - bodyColCount = (this._columnHeaderCellIds[0]?.length ?? this.columnDimensionTree.tree.size) || 1; + bodyColCount = + (this._columnHeaderCellIds[0]?.length ?? this.columnDimensionTree.tree.size) || + (this._indicators?.length > 0 ? 1 : 0); } else { bodyColCount = 0; } From 0ee3ceeaa964372503c4ac010ac4c125e0e03de0 Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Tue, 1 Apr 2025 17:17:19 +0800 Subject: [PATCH 8/8] fix: fix child cell get method in setBodyAndRowHeaderY() --- packages/vtable/src/scenegraph/scenegraph.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/vtable/src/scenegraph/scenegraph.ts b/packages/vtable/src/scenegraph/scenegraph.ts index c598986167..65f288fa19 100644 --- a/packages/vtable/src/scenegraph/scenegraph.ts +++ b/packages/vtable/src/scenegraph/scenegraph.ts @@ -1233,8 +1233,10 @@ export class Scenegraph { */ setBodyAndRowHeaderY(y: number) { // correct y, avoid scroll out of range - const firstBodyCell = this.bodyGroup.firstChild?.firstChild as Group; - const lastBodyCell = this.bodyGroup.firstChild?.lastChild as Group; + const firstBodyCell = + (this.bodyGroup.firstChild?.firstChild as Group) ?? (this.rowHeaderGroup.firstChild?.firstChild as Group); + const lastBodyCell = + (this.bodyGroup.firstChild?.lastChild as Group) ?? (this.rowHeaderGroup.firstChild?.lastChild as Group); if ( y === 0 && firstBodyCell &&