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 diff --git a/packages/vtable-gantt/src/Gantt.ts b/packages/vtable-gantt/src/Gantt.ts index 08ea5a8104..4abe2c78f2 100644 --- a/packages/vtable-gantt/src/Gantt.ts +++ b/packages/vtable-gantt/src/Gantt.ts @@ -782,13 +782,13 @@ export class Gantt extends EventTarget { // index + this.taskListTableInstance.columnHeaderLevelCount // ); // } - if (this.taskListTableInstance.rowHierarchyType === 'tree' && typeof index === 'number') { - //如果是树形结构 需要获取数据源对应的索引 - index = this.taskListTableInstance.getRecordIndexByCell( - 0, - index + this.taskListTableInstance.columnHeaderLevelCount - ); - } + // if (this.taskListTableInstance.rowHierarchyType === 'tree' && typeof index === 'number') { + // //如果是树形结构 需要获取数据源对应的索引 + // index = this.taskListTableInstance.getRecordIndexByCell( + // 0, + // index + this.taskListTableInstance.columnHeaderLevelCount + // ); + // } this.taskListTableInstance.updateRecords([record], [index]); } /** @@ -942,11 +942,20 @@ export class Gantt extends EventTarget { if (Array.isArray(task_index)) { const index = (task_index as number[])[0]; const sub_index = (task_index as number[])[1]; - this._updateRecordToListTable(record, isValid(sub_index) ? [index, sub_index] : index); + // this._updateRecordToListTable(record, isValid(sub_index) ? [index, sub_index] : index); + this._updateRecordToListTable(record, task_index); this._refreshTaskBar(index, sub_index); return; } const index = task_index as number; + + // if (this.taskListTableInstance.rowHierarchyType === 'tree' && typeof index === 'number') { + // //如果是树形结构 需要获取数据源对应的索引 + // index = this.taskListTableInstance.getRecordIndexByCell( + // 0, + // index + this.taskListTableInstance.columnHeaderLevelCount + // ); + // } this._updateRecordToListTable(record, index); this._refreshTaskBar(index, undefined); } diff --git a/packages/vtable/src/layout/pivot-header-layout.ts b/packages/vtable/src/layout/pivot-header-layout.ts index 4998086d7e..007bb98f84 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,20 @@ 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) || + (this._indicators?.length > 0 ? 1 : 0); + } else { + bodyColCount = 0; + } + return bodyColCount + this.rowHeaderLevelCount + this.rightHeaderColCount + this.leftRowSeriesNumberColumnCount; // 小心rightFrozenColCount和colCount的循环引用 造成调用栈溢出 } get rowCount(): number { return ( @@ -1740,7 +1752,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; 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 &&