From 6c797c641fe48a817a21ebeb45dee569671870d1 Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Wed, 20 Aug 2025 11:50:31 +0800 Subject: [PATCH 01/11] fix: fix type in SearchComponentOption --- .../src/search-component/search-component.ts | 234 +++++++----------- 1 file changed, 88 insertions(+), 146 deletions(-) diff --git a/packages/vtable-search/src/search-component/search-component.ts b/packages/vtable-search/src/search-component/search-component.ts index 8357022274..90c6b98d8f 100644 --- a/packages/vtable-search/src/search-component/search-component.ts +++ b/packages/vtable-search/src/search-component/search-component.ts @@ -1,6 +1,6 @@ import type * as VTable from '@visactor/vtable'; -import { ITableAnimationOption } from '@visactor/vtable/src/ts-types'; -import { EasingType } from '@visactor/vtable/src/vrender'; +import type { ITableAnimationOption } from '@visactor/vtable/src/ts-types'; +import type { EasingType } from '@visactor/vtable/src/vrender'; import { isValid } from '@visactor/vutils'; type IVTable = VTable.ListTable | VTable.PivotTable | VTable.PivotChart; @@ -11,7 +11,6 @@ export type QueryResult = { row?: number; value?: string; indexNumber?: number[]; - }[]; }; @@ -24,9 +23,7 @@ export type SearchComponentOption = { queryMethod?: (queryStr: string, value: string, option?: { col: number; row: number; table: IVTable }) => boolean; treeQueryMethod?: (queryStr: string, node: any, fieldsToSearch?: string[], option?: { table: IVTable }) => boolean; fieldsToSearch?: string[]; - scrollOption: ITableAnimationOption; - - + scrollOption?: ITableAnimationOption; callback?: (queryResult: QueryResult, table: IVTable) => void; }; @@ -42,17 +39,14 @@ function defalultQueryMethod(queryStr: string, value: string) { return isValid(queryStr) && isValid(value) && value.toString().includes(queryStr); } function defalultTreeQueryMethod(queryStr: string, node: any, fieldsToSearch?: string[]) { - if (!isValid(queryStr)) return false; + if (!isValid(queryStr)) { + return false; + } // 如果没有传 fieldsToSearch,则用 node 的全部 key - const searchFields = (Array.isArray(fieldsToSearch) && fieldsToSearch.length > 0) - ? fieldsToSearch - : Object.keys(node); - - return searchFields.some(field => - isValid(node?.[field]) && - node[field].toString().includes(queryStr) - ); + const searchFields = Array.isArray(fieldsToSearch) && fieldsToSearch.length > 0 ? fieldsToSearch : Object.keys(node); + + return searchFields.some(field => isValid(node?.[field]) && node[field].toString().includes(queryStr)); } export class SearchComponent { table: IVTable; @@ -64,7 +58,6 @@ export class SearchComponent { treeQueryMethod: (queryStr: string, node: any, fieldsToSearch?: string[], option?: { table: IVTable }) => boolean; fieldsToSearch: string[]; - callback?: (queryResult: QueryResult, table: IVTable) => void; queryStr: string; @@ -90,10 +83,11 @@ export class SearchComponent { this.queryMethod = option.queryMethod || defalultQueryMethod; this.treeQueryMethod = option.treeQueryMethod || defalultTreeQueryMethod; this.fieldsToSearch = option.fieldsToSearch || []; - this.isTree = false - this.treeIndex = 0 + this.isTree = false; + this.treeIndex = 0; this.callback = option.callback; - this.scrollOption = option.scrollOption || { duration: 900, easing: 'quartIn' as EasingType } as ITableAnimationOption + this.scrollOption = + option.scrollOption || ({ duration: 900, easing: 'quartIn' as EasingType } as ITableAnimationOption); this.table.registerCustomCellStyle('__search_component_highlight', this.highlightCellStyle as any); this.table.registerCustomCellStyle('__search_component_focuse', this.focuseHighlightCellStyle as any); } @@ -108,10 +102,8 @@ export class SearchComponent { results: this.queryResult }; } - this.isTree = this.table.options.columns.some((item: any) => item.tree) - this.treeIndex = this.isTree - ? this.table.options.columns.findIndex((item: any) => item.tree) - : 0; + this.isTree = this.table.options.columns.some((item: any) => item.tree); + this.treeIndex = this.isTree ? this.table.options.columns.findIndex((item: any) => item.tree) : 0; if (this.isTree) { // 如果传入单一节点也能处理 const colEnd = this.table.colCount; @@ -127,7 +119,6 @@ export class SearchComponent { start: { row: null, col: 0 }, end: { row: null, col: colEnd } } - }); } @@ -141,7 +132,6 @@ export class SearchComponent { this.jumpToCell({ IndexNumber: this.queryResult[0].indexNumber }); - if (this.callback) { this.callback( { @@ -162,69 +152,62 @@ export class SearchComponent { index: 0, results: this.queryResult }; - } else { - for (let row = 0; row < this.table.rowCount; row++) { - for (let col = 0; col < this.table.colCount; col++) { - if (this.skipHeader && this.table.isHeader(col, row)) { - continue; - } - const value = this.table.getCellValue(col, row); - if (this.queryMethod(this.queryStr, value, { col, row, table: this.table })) { - // deal merge cell - const mergeCell = this.table.getCellRange(col, row); - if (mergeCell.start.col !== mergeCell.end.col || mergeCell.start.row !== mergeCell.end.row) { - // find is cell already in queryResult - let isIn = false; - for (let i = this.queryResult.length - 1; i >= 0; i--) { - if (this.queryResult[i].col === mergeCell.start.col && this.queryResult[i].row === mergeCell.start.row) { - isIn = true; - break; - } - } - if (!isIn) { - this.queryResult.push({ - col: mergeCell.start.col, - row: mergeCell.start.row, - range: mergeCell, - value - }); + } + for (let row = 0; row < this.table.rowCount; row++) { + for (let col = 0; col < this.table.colCount; col++) { + if (this.skipHeader && this.table.isHeader(col, row)) { + continue; + } + const value = this.table.getCellValue(col, row); + if (this.queryMethod(this.queryStr, value, { col, row, table: this.table })) { + // deal merge cell + const mergeCell = this.table.getCellRange(col, row); + if (mergeCell.start.col !== mergeCell.end.col || mergeCell.start.row !== mergeCell.end.row) { + // find is cell already in queryResult + let isIn = false; + for (let i = this.queryResult.length - 1; i >= 0; i--) { + if (this.queryResult[i].col === mergeCell.start.col && this.queryResult[i].row === mergeCell.start.row) { + isIn = true; + break; } - } else { + } + if (!isIn) { this.queryResult.push({ - col, - row, + col: mergeCell.start.col, + row: mergeCell.start.row, + range: mergeCell, value }); } + } else { + this.queryResult.push({ + col, + row, + value + }); } } } - this.updateCellStyle(); - - if (this.callback) { - this.callback( - { - queryStr: this.queryStr, - results: this.queryResult - }, - this.table - ); - } - - if (this.autoJump) { - return this.next(); - } - return { - index: 0, - results: this.queryResult - }; } + this.updateCellStyle(); + if (this.callback) { + this.callback( + { + queryStr: this.queryStr, + results: this.queryResult + }, + this.table + ); + } - - - - + if (this.autoJump) { + return this.next(); + } + return { + index: 0, + results: this.queryResult + }; } updateCellStyle(highlight: boolean = true) { @@ -247,9 +230,9 @@ export class SearchComponent { while (this.table.isHeader(0, i)) { i++; } - let row = this.getBodyRowIndexByRecordIndex(indexNumber) + i; - range.start.row = row - range.end.row = row + const row = this.getBodyRowIndexByRecordIndex(indexNumber) + i; + range.start.row = row; + range.end.row = row; this.table.arrangeCustomCellStyle( { @@ -257,10 +240,8 @@ export class SearchComponent { }, highlight ? '__search_component_focuse' : null ); - } else { for (let i = 0; i < this.queryResult.length; i++) { - const { col, row, range } = this.queryResult[i]; if (range) { this.table.arrangeCustomCellStyle( @@ -280,7 +261,6 @@ export class SearchComponent { } } } - } next() { @@ -291,11 +271,9 @@ export class SearchComponent { }; } if (this.isTree) { - if (this.currentIndex !== -1) { const { range, indexNumber } = this.queryResult[this.currentIndex]; - if (range) { let i = 0; @@ -303,9 +281,9 @@ export class SearchComponent { while (this.table.isHeader(0, i)) { i++; } - let row = this.getBodyRowIndexByRecordIndex(indexNumber) + i; - range.start.row = row - range.end.row = row + const row = this.getBodyRowIndexByRecordIndex(indexNumber) + i; + range.start.row = row; + range.end.row = row; this.table.arrangeCustomCellStyle( { range @@ -329,9 +307,9 @@ export class SearchComponent { while (this.table.isHeader(0, i)) { i++; } - let row = this.getBodyRowIndexByRecordIndex(indexNumber) + i; - range.start.row = row - range.end.row = row + const row = this.getBodyRowIndexByRecordIndex(indexNumber) + i; + range.start.row = row; + range.end.row = row; this.table.arrangeCustomCellStyle( { range @@ -339,9 +317,7 @@ export class SearchComponent { '__search_component_focuse' ); } - } else { - if (this.currentIndex !== -1) { const { col, row, range } = this.queryResult[this.currentIndex]; @@ -390,8 +366,6 @@ export class SearchComponent { this.jumpToCell({ col, row }); } - - return { index: this.currentIndex, results: this.queryResult @@ -415,13 +389,10 @@ export class SearchComponent { while (this.table.isHeader(0, i)) { i++; } - let row = this.getBodyRowIndexByRecordIndex(indexNumber) + i; + const row = this.getBodyRowIndexByRecordIndex(indexNumber) + i; range.start.row = row; range.end.row = row; - this.table.arrangeCustomCellStyle( - { range }, - '__search_component_highlight' - ); + this.table.arrangeCustomCellStyle({ range }, '__search_component_highlight'); } } @@ -440,29 +411,19 @@ export class SearchComponent { while (this.table.isHeader(0, i)) { i++; } - let row = this.getBodyRowIndexByRecordIndex(indexNumber) + i; + const row = this.getBodyRowIndexByRecordIndex(indexNumber) + i; range.start.row = row; range.end.row = row; - this.table.arrangeCustomCellStyle( - { range }, - '__search_component_focuse' - ); + this.table.arrangeCustomCellStyle({ range }, '__search_component_focuse'); } - } else { // 普通表格处理 if (this.currentIndex !== -1) { const { col, row, range } = this.queryResult[this.currentIndex]; if (range) { - this.table.arrangeCustomCellStyle( - { range }, - '__search_component_highlight' - ); + this.table.arrangeCustomCellStyle({ range }, '__search_component_highlight'); } else { - this.table.arrangeCustomCellStyle( - { col, row }, - '__search_component_highlight' - ); + this.table.arrangeCustomCellStyle({ col, row }, '__search_component_highlight'); } } @@ -473,15 +434,9 @@ export class SearchComponent { const { col, row, range } = this.queryResult[this.currentIndex]; if (range) { - this.table.arrangeCustomCellStyle( - { range }, - '__search_component_focuse' - ); + this.table.arrangeCustomCellStyle({ range }, '__search_component_focuse'); } else { - this.table.arrangeCustomCellStyle( - { col, row }, - '__search_component_focuse' - ); + this.table.arrangeCustomCellStyle({ col, row }, '__search_component_focuse'); } this.jumpToCell({ col, row }); @@ -493,43 +448,32 @@ export class SearchComponent { }; } - - jumpToCell(params: { col?: number; row?: number, IndexNumber?: number[] }) { - + jumpToCell(params: { col?: number; row?: number; IndexNumber?: number[] }) { if (this.isTree) { - const { IndexNumber } = params - let indexNumbers = [...IndexNumber] + const { IndexNumber } = params; + const indexNumbers = [...IndexNumber]; - let tmp = [...indexNumbers] - let tmpNumber = 0 + const tmp = [...indexNumbers]; + let tmpNumber = 0; let i = 0; while (tmpNumber < tmp.length - 1) { - tmpNumber++ - let indexNumber = indexNumbers.slice(0, tmpNumber) + tmpNumber++; + const indexNumber = indexNumbers.slice(0, tmpNumber); // 如果是表头就往下偏移 while (this.table.isHeader(0, i)) { i++; } - let row = this.getBodyRowIndexByRecordIndex(indexNumber) + i; + const row = this.getBodyRowIndexByRecordIndex(indexNumber) + i; - const hierarchyState = this.table.getHierarchyState( - this.treeIndex, - row - ); + const hierarchyState = this.table.getHierarchyState(this.treeIndex, row); if (hierarchyState !== 'expand') { - - this.table.toggleHierarchyState( - this.treeIndex, - row - ); + this.table.toggleHierarchyState(this.treeIndex, row); } } - this.table.scrollToRow(this.getBodyRowIndexByRecordIndex(indexNumbers) + i, this.scrollOption) - - + this.table.scrollToRow(this.getBodyRowIndexByRecordIndex(indexNumbers) + i, this.scrollOption); } else { const { col, row } = params; // if focus cell out of screen, jump to cell @@ -539,8 +483,6 @@ export class SearchComponent { this.table.scrollToCell({ col, row }); } } - - } getBodyRowIndexByRecordIndex(index: number | number[]): number { if (Array.isArray(index) && index.length === 1) { From dcf52a2abc4f1d79695a75765fc5f9a866f2640c Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Wed, 20 Aug 2025 14:52:47 +0800 Subject: [PATCH 02/11] fix: getLayoutRowTree api error #4346 --- packages/vtable/src/layout/tree-helper.ts | 50 ++++++++++++----------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/packages/vtable/src/layout/tree-helper.ts b/packages/vtable/src/layout/tree-helper.ts index 88db904a93..0000bd2640 100644 --- a/packages/vtable/src/layout/tree-helper.ts +++ b/packages/vtable/src/layout/tree-helper.ts @@ -421,30 +421,32 @@ export type LayouTreeNode = { }; export function generateLayoutTree(tree: LayouTreeNode[], children: ITreeLayoutHeadNode[]) { - children?.forEach((node: ITreeLayoutHeadNode) => { - const diemnsonNode: { - dimensionKey?: string; - indicatorKey?: string; - value: string; - virtual?: boolean; - hierarchyState: HierarchyState; - children: ITreeLayoutHeadNode[]; - levelSpan: number; - } = { - dimensionKey: node.dimensionKey, - indicatorKey: node.indicatorKey, - value: node.value, - hierarchyState: node.hierarchyState, - children: undefined, - virtual: node.virtual ?? false, - levelSpan: node.levelSpan ?? 1 - }; - tree.push(diemnsonNode); - if (node.children) { - diemnsonNode.children = []; - generateLayoutTree(diemnsonNode.children, node.children); - } - }); + if (Array.isArray(children)) { + children?.forEach((node: ITreeLayoutHeadNode) => { + const diemnsonNode: { + dimensionKey?: string; + indicatorKey?: string; + value: string; + virtual?: boolean; + hierarchyState: HierarchyState; + children: ITreeLayoutHeadNode[]; + levelSpan: number; + } = { + dimensionKey: node.dimensionKey, + indicatorKey: node.indicatorKey, + value: node.value, + hierarchyState: node.hierarchyState, + children: undefined, + virtual: node.virtual ?? false, + levelSpan: node.levelSpan ?? 1 + }; + tree.push(diemnsonNode); + if (node.children) { + diemnsonNode.children = []; + generateLayoutTree(diemnsonNode.children, node.children); + } + }); + } } //#endregion From 1bede9b4d64553eec6ccf894416c470fb88b6f98 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Wed, 20 Aug 2025 14:53:21 +0800 Subject: [PATCH 03/11] docs: update changlog of rush --- ...g-getlayoutrowtree-api-error_2025-08-20-06-53.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/@visactor/vtable/4346-bug-getlayoutrowtree-api-error_2025-08-20-06-53.json diff --git a/common/changes/@visactor/vtable/4346-bug-getlayoutrowtree-api-error_2025-08-20-06-53.json b/common/changes/@visactor/vtable/4346-bug-getlayoutrowtree-api-error_2025-08-20-06-53.json new file mode 100644 index 0000000000..5ddad5b943 --- /dev/null +++ b/common/changes/@visactor/vtable/4346-bug-getlayoutrowtree-api-error_2025-08-20-06-53.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "fix: getLayoutRowTree api error #4346\n\n", + "type": "none", + "packageName": "@visactor/vtable" + } + ], + "packageName": "@visactor/vtable", + "email": "892739385@qq.com" +} \ No newline at end of file From 5521ede213c9f3f69bfe19dd2ff19c057044a37b Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Fri, 22 Aug 2025 14:26:04 +0800 Subject: [PATCH 04/11] fix: when has many columns expand columnTree scenegraph node y error #4357 --- packages/vtable/src/scenegraph/group-creater/column-helper.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/vtable/src/scenegraph/group-creater/column-helper.ts b/packages/vtable/src/scenegraph/group-creater/column-helper.ts index cedabbbd17..ee9d107a2b 100644 --- a/packages/vtable/src/scenegraph/group-creater/column-helper.ts +++ b/packages/vtable/src/scenegraph/group-creater/column-helper.ts @@ -59,6 +59,9 @@ export function createComplexColumn( y = (columnGroup.lastChild as Group).attribute.y + (columnGroup.lastChild as Group).attribute.height; } else if (columnGroup.colHeight) { y = columnGroup.colHeight; + } else if (rowStart >= table.columnHeaderLevelCount) { + // 这个if判断为了解决#4357 当传入的rowStart例如50但是columnGroup中并没有其他cell的情况下,上面逻辑有问题y赋值的0 导致新建单元格错位 + y = table.getRowsHeight(table.columnHeaderLevelCount, rowStart - 1); } for (let j = rowStart; j <= rowEnd; j++) { From 6e8bd98672f0de01add94c424fc61deda12cc714 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Fri, 22 Aug 2025 14:26:34 +0800 Subject: [PATCH 05/11] docs: update changlog of rush --- ...g-scenegraph-origanize-error_2025-08-22-06-26.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/@visactor/vtable/4357-bug-scenegraph-origanize-error_2025-08-22-06-26.json diff --git a/common/changes/@visactor/vtable/4357-bug-scenegraph-origanize-error_2025-08-22-06-26.json b/common/changes/@visactor/vtable/4357-bug-scenegraph-origanize-error_2025-08-22-06-26.json new file mode 100644 index 0000000000..33083ab485 --- /dev/null +++ b/common/changes/@visactor/vtable/4357-bug-scenegraph-origanize-error_2025-08-22-06-26.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "fix: when has many columns expand columnTree scenegraph node y error #4357\n\n", + "type": "none", + "packageName": "@visactor/vtable" + } + ], + "packageName": "@visactor/vtable", + "email": "892739385@qq.com" +} \ No newline at end of file From 50009da827af9bccae0ece404fc9f0e91f6cadd7 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Fri, 22 Aug 2025 17:15:00 +0800 Subject: [PATCH 06/11] refactor: contextmenu-click event arguments #4364 --- packages/vtable/src/event/event.ts | 4 - .../vtable/src/event/listener/table-group.ts | 93 ++++++++++++------- .../base-table/right-button-click.ts | 33 ------- 3 files changed, 60 insertions(+), 70 deletions(-) delete mode 100644 packages/vtable/src/event/self-event-listener/base-table/right-button-click.ts diff --git a/packages/vtable/src/event/event.ts b/packages/vtable/src/event/event.ts index d8736770a0..8732793d21 100644 --- a/packages/vtable/src/event/event.ts +++ b/packages/vtable/src/event/event.ts @@ -35,7 +35,6 @@ import { bindButtonClickEvent } from './component/button'; import { bindIconClickEvent } from './self-event-listener/base-table/icon'; import { bindDropdownMenuEvent } from './self-event-listener/base-table/dropdown-menu'; import { bindDBClickAutoColumnWidthEvent } from './self-event-listener/base-table/dbclick-auto-column-width'; -import { rightButtonClickEvent } from './self-event-listener/base-table/right-button-click'; export class EventManager { table: BaseTableAPI; @@ -180,9 +179,6 @@ export class EventManager { // button click bindButtonClickEvent(this.table); - - // right button click - rightButtonClickEvent(this.table); } dealTableHover(eventArgsSet?: SceneEvent) { diff --git a/packages/vtable/src/event/listener/table-group.ts b/packages/vtable/src/event/listener/table-group.ts index ee81b8941e..fe2afcd0e9 100644 --- a/packages/vtable/src/event/listener/table-group.ts +++ b/packages/vtable/src/event/listener/table-group.ts @@ -696,43 +696,70 @@ export function bindTableGroupListener(eventManager: EventManager) { //处理监听的右键事件 const { col, row } = eventArgsSet.eventArgs; - if ((table as any).hasListeners(TABLE_EVENT_TYPE.CONTEXTMENU_CELL)) { - const cellInfo = table.getCellInfo(col, row); - let icon; - let position; - if (eventArgsSet.eventArgs?.target) { - const iconInfo = getIconAndPositionFromTarget(eventArgsSet.eventArgs?.target); - if (iconInfo) { - icon = iconInfo.icon; - position = iconInfo.position; + if (col >= 0 && row >= 0) { + const ranges = table.getSelectedCellRanges(); + let cellInRange = false; + if (ranges.length > 0) { + for (let i = 0; i < ranges.length; i++) { + const range = ranges[i]; + const startCol = range.start.col; + const endCol = range.end.col; + const startRow = range.start.row; + const endRow = range.end.row; + if ( + (col >= startCol && col <= endCol && row >= startRow && row <= endRow) || // 左上向右下选择 + (col >= endCol && col <= startCol && row >= endRow && row <= startRow) || // 右下向左上选择 + (col >= startCol && col <= endCol && row >= endRow && row <= startRow) || // 左下向右上选择 + (col >= endCol && col <= startCol && row >= startRow && row <= endRow) // 右上向左下选择 + ) { + cellInRange = true; + break; + } } } - const cellsEvent: MousePointerMultiCellEvent = { - ...cellInfo, - event: e.nativeEvent, - cells: [], - targetIcon: icon - ? { - name: icon.name, - position: position, - funcType: (icon as any).attribute.funcType - } - : undefined, - target: eventArgsSet?.eventArgs?.target, - mergeCellInfo: eventArgsSet.eventArgs?.mergeInfo - }; - if (table.options.eventOptions?.contextmenuReturnAllSelectedCells ?? true) { - if (cellInRanges(table.stateManager.select.ranges, col, row)) { - // 用户右键点击已经选中的区域 - // const { start, end } = eventManager.selection.range; - cellsEvent.cells = table.getSelectedCellInfos(); - } else { - // 用户右键点击新单元格 - cellsEvent.cells = [[cellInfo]]; - } + + if (!cellInRange) { + table.selectCell(col, row); } - table.fireListeners(TABLE_EVENT_TYPE.CONTEXTMENU_CELL, cellsEvent); + if ((table as any).hasListeners(TABLE_EVENT_TYPE.CONTEXTMENU_CELL)) { + const cellInfo = table.getCellInfo(col, row); + let icon; + let position; + if (eventArgsSet.eventArgs?.target) { + const iconInfo = getIconAndPositionFromTarget(eventArgsSet.eventArgs?.target); + if (iconInfo) { + icon = iconInfo.icon; + position = iconInfo.position; + } + } + const cellsEvent: MousePointerMultiCellEvent = { + ...cellInfo, + event: e.nativeEvent, + cells: [], + targetIcon: icon + ? { + name: icon.name, + position: position, + funcType: (icon as any).attribute.funcType + } + : undefined, + target: eventArgsSet?.eventArgs?.target, + mergeCellInfo: eventArgsSet.eventArgs?.mergeInfo + }; + if (table.options.eventOptions?.contextmenuReturnAllSelectedCells ?? true) { + if (cellInRanges(table.stateManager.select.ranges, col, row)) { + // 用户右键点击已经选中的区域 + // const { start, end } = eventManager.selection.range; + cellsEvent.cells = table.getSelectedCellInfos(); + } else { + // 用户右键点击新单元格 + cellsEvent.cells = [[cellInfo]]; + } + } + + table.fireListeners(TABLE_EVENT_TYPE.CONTEXTMENU_CELL, cellsEvent); + } } } }); diff --git a/packages/vtable/src/event/self-event-listener/base-table/right-button-click.ts b/packages/vtable/src/event/self-event-listener/base-table/right-button-click.ts deleted file mode 100644 index 7c5545011a..0000000000 --- a/packages/vtable/src/event/self-event-listener/base-table/right-button-click.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { TABLE_EVENT_TYPE } from '../../../core/TABLE_EVENT_TYPE'; -import type { BaseTableAPI } from '../../../ts-types/base-table'; - -export function rightButtonClickEvent(table: BaseTableAPI) { - table.on(TABLE_EVENT_TYPE.CONTEXTMENU_CELL, e => { - console.log(TABLE_EVENT_TYPE.CONTEXTMENU_CELL, e); - const { col, row } = e; - const ranges = table.getSelectedCellRanges(); - let cellInRange = false; - if (ranges.length > 0) { - for (let i = 0; i < ranges.length; i++) { - const range = ranges[i]; - const startCol = range.start.col; - const endCol = range.end.col; - const startRow = range.start.row; - const endRow = range.end.row; - if ( - (col >= startCol && col <= endCol && row >= startRow && row <= endRow) || // 左上向右下选择 - (col >= endCol && col <= startCol && row >= endRow && row <= startRow) || // 右下向左上选择 - (col >= startCol && col <= endCol && row >= endRow && row <= startRow) || // 左下向右上选择 - (col >= endCol && col <= startCol && row >= startRow && row <= endRow) // 右上向左下选择 - ) { - cellInRange = true; - break; - } - } - } - - if (!cellInRange) { - table.selectCell(col, row); - } - }); -} From 4bbb777c2c855675fe0b2e6da253ad88a9146799 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Fri, 22 Aug 2025 17:16:16 +0800 Subject: [PATCH 07/11] docs: update changlog of rush --- ...ck-cornerCell-arguments-cell_2025-08-22-09-16.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/@visactor/vtable/4364-bug-right-click-cornerCell-arguments-cell_2025-08-22-09-16.json diff --git a/common/changes/@visactor/vtable/4364-bug-right-click-cornerCell-arguments-cell_2025-08-22-09-16.json b/common/changes/@visactor/vtable/4364-bug-right-click-cornerCell-arguments-cell_2025-08-22-09-16.json new file mode 100644 index 0000000000..f60086d7e1 --- /dev/null +++ b/common/changes/@visactor/vtable/4364-bug-right-click-cornerCell-arguments-cell_2025-08-22-09-16.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "refactor: contextmenu-click event arguments #4364\n\n", + "type": "none", + "packageName": "@visactor/vtable" + } + ], + "packageName": "@visactor/vtable", + "email": "892739385@qq.com" +} \ No newline at end of file From 78dc7a355681d0077007cf9c2d4a94c9f142514f Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Mon, 25 Aug 2025 11:10:14 +0800 Subject: [PATCH 08/11] fix: syncHierarchyState api error #4346 --- packages/vtable/src/PivotTable.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vtable/src/PivotTable.ts b/packages/vtable/src/PivotTable.ts index 3d03d72d33..0fe902bed1 100644 --- a/packages/vtable/src/PivotTable.ts +++ b/packages/vtable/src/PivotTable.ts @@ -612,7 +612,7 @@ export class PivotTable extends BaseTable implements PivotTableAPI { if (sourceNode.value === targetNode.value && sourceNode.dimensionKey === targetNode.dimensionKey) { targetNode.hierarchyState = targetNode.hierarchyState ?? (targetNode?.children ? sourceNode.hierarchyState : undefined); - (targetNode?.children as IHeaderTreeDefine[])?.forEach((targetChildNode: IHeaderTreeDefine, index: number) => { + (targetNode?.children as IHeaderTreeDefine[])?.forEach?.((targetChildNode: IHeaderTreeDefine, index: number) => { if (sourceNode?.children?.[index] && targetChildNode) { const beforeRowDimension = sourceNode.children.find( (item: any) => item.dimensionKey === targetChildNode.dimensionKey && item.value === targetChildNode.value From 29e7beaea2a1b9d9e7216f66664eac90150811ee Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Tue, 26 Aug 2025 10:23:24 +0800 Subject: [PATCH 09/11] docs: update question docs --- docs/assets/faq/en/8-How to insert sparklines in table.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/assets/faq/en/8-How to insert sparklines in table.md b/docs/assets/faq/en/8-How to insert sparklines in table.md index cfe91fb140..182e27416e 100644 --- a/docs/assets/faq/en/8-How to insert sparklines in table.md +++ b/docs/assets/faq/en/8-How to insert sparklines in table.md @@ -8,6 +8,8 @@ A mini-line chart reflecting the dynamics of a set of data needs to be displayed In VTable, you can specify the column to be a sparkline type cell by setting `cellType` to `sparkline` in `columns`. +If the chart is more complex, you can use the PivotChart module to configure the API of VChart. + 1. sparkLine data The data specified by the `sparkline` type cell can be an array of numbers (the number will default to y field in the sparkline, and x field will be automatically filled in order), or it can be an array of x, y objects: From f9aa96d964e46cd1973c63ec949b43bbc0b171e5 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Thu, 28 Aug 2025 16:23:17 +0800 Subject: [PATCH 10/11] fix: columnWidthConfig not work when just has indicator on pivot table #4388 --- packages/vtable/src/layout/pivot-header-layout.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vtable/src/layout/pivot-header-layout.ts b/packages/vtable/src/layout/pivot-header-layout.ts index 2cfbb34064..79d8b700e9 100644 --- a/packages/vtable/src/layout/pivot-header-layout.ts +++ b/packages/vtable/src/layout/pivot-header-layout.ts @@ -3392,10 +3392,10 @@ export class PivotHeaderLayoutMap implements LayoutMapAPI { needLowestLevel_colPaths = true; needLowestLevel_rowPaths = true; } - if (colHeaderPaths.length >= this._getColumnHeaderTreeExpandedMaxLevelCount()) { + if ((colHeaderPaths?.length ?? 0) && colHeaderPaths.length >= this._getColumnHeaderTreeExpandedMaxLevelCount()) { needLowestLevel_colPaths = true; } - if (rowHeaderPaths.length >= this._getRowHeaderTreeExpandedMaxLevelCount()) { + if ((rowHeaderPaths?.length ?? 0) && rowHeaderPaths.length >= this._getRowHeaderTreeExpandedMaxLevelCount()) { needLowestLevel_rowPaths = true; } let col; From 9eff1357b6315b5c4428bec80d5f55e55e5e187d Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Thu, 28 Aug 2025 16:23:46 +0800 Subject: [PATCH 11/11] docs: update changlog of rush --- ...-bug-columnwidthconfig-error_2025-08-28-08-23.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/@visactor/vtable/4388-bug-columnwidthconfig-error_2025-08-28-08-23.json diff --git a/common/changes/@visactor/vtable/4388-bug-columnwidthconfig-error_2025-08-28-08-23.json b/common/changes/@visactor/vtable/4388-bug-columnwidthconfig-error_2025-08-28-08-23.json new file mode 100644 index 0000000000..cc8f04751e --- /dev/null +++ b/common/changes/@visactor/vtable/4388-bug-columnwidthconfig-error_2025-08-28-08-23.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "fix: columnWidthConfig not work when just has indicator on pivot table #4388\n\n", + "type": "none", + "packageName": "@visactor/vtable" + } + ], + "packageName": "@visactor/vtable", + "email": "892739385@qq.com" +} \ No newline at end of file