diff --git a/common/changes/@visactor/vtable/fix-bug-fix-0.15.1_2023-11-29-08-52.json b/common/changes/@visactor/vtable/fix-bug-fix-0.15.1_2023-11-29-08-52.json new file mode 100644 index 000000000..1c8ba8feb --- /dev/null +++ b/common/changes/@visactor/vtable/fix-bug-fix-0.15.1_2023-11-29-08-52.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vtable", + "comment": "fix: fix merge cell checkbox update", + "type": "patch" + } + ], + "packageName": "@visactor/vtable" +} \ No newline at end of file diff --git a/packages/vtable/examples/list/list-merge-cell.ts b/packages/vtable/examples/list/list-merge-cell.ts index d80ccee4e..a0029912c 100644 --- a/packages/vtable/examples/list/list-merge-cell.ts +++ b/packages/vtable/examples/list/list-merge-cell.ts @@ -1,8 +1,8 @@ import * as VTable from '../../src'; import { bindDebugTool } from '../../src/scenegraph/debug-tool'; const CONTAINER_ID = 'vTable'; -const generatePersons = count => { - return Array.from(new Array(count)).map((_, i) => ({ +const generatePersons = i => { + return { id: i + 1, email1: `${i + 1}@xxx.com`, name: `小明${i + 1}`, @@ -12,11 +12,41 @@ const generatePersons = count => { sex: i % 2 === 0 ? 'boy' : 'girl', work: i % 2 === 0 ? 'back-end engineer' : 'front-end engineer', city: 'beijing' - })); + }; +}; + +const getRecordsWithAjax = (startIndex, num) => { + return new Promise(resolve => { + setTimeout(() => { + const records = []; + for (let i = 0; i < num; i++) { + records.push(generatePersons(startIndex + i)); + } + resolve(records); + }, 500); + }); }; +// create DataSource +const loadedData = {}; +const dataSource = new VTable.data.CachedDataSource({ + get(index) { + // 每一批次请求100条数据 0-99 100-199 200-299 + const loadStartIndex = Math.floor(index / 100) * 100; + // 判断是否已请求过? + if (!loadedData[loadStartIndex]) { + const promiseObject = getRecordsWithAjax(loadStartIndex, 100); // return Promise Object + loadedData[loadStartIndex] = promiseObject; + } + return loadedData[loadStartIndex].then(data => { + return data[index - loadStartIndex]; //获取批次数据列表中的index对应数据 + }); + }, + length: 10000 //all records count +}); + export function createTable() { - const records = generatePersons(10); + // const records = generatePersons(1000); const columns: VTable.ColumnsDefine = [ { field: 'id', @@ -74,7 +104,7 @@ export function createTable() { ]; const option = { container: document.getElementById(CONTAINER_ID), - records, + // records, columns, tooltip: { isShowOverflowTextTooltip: true @@ -108,6 +138,8 @@ export function createTable() { const tableInstance = new VTable.ListTable(option); window.tableInstance = tableInstance; + tableInstance.dataSource = dataSource; + bindDebugTool(tableInstance.scenegraph.stage, { customGrapicKeys: ['col', 'row'] }); // tableInstance.on('sort_click', args => { // tableInstance.updateSortState( diff --git a/packages/vtable/examples/type/checkbox.ts b/packages/vtable/examples/type/checkbox.ts index 20065d679..146455848 100644 --- a/packages/vtable/examples/type/checkbox.ts +++ b/packages/vtable/examples/type/checkbox.ts @@ -20,6 +20,23 @@ export function createTable() { } // checked: false }, + { + title: 'parent', + columns: [ + { + field: 'percent', + title: 'percent', + width: 120, + sort: true + }, + { + field: 'percent', + title: 'percent', + width: 120, + sort: true + } + ] + }, { field: 'percent', title: 'percent', diff --git a/packages/vtable/src/core/BaseTable.ts b/packages/vtable/src/core/BaseTable.ts index 6de4450e9..f3baf4463 100644 --- a/packages/vtable/src/core/BaseTable.ts +++ b/packages/vtable/src/core/BaseTable.ts @@ -2622,7 +2622,7 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { col, row, table: this, - value: this.getCellValue(col, row), + value: customMerge.text, dataValue: this.getCellOriginValue(col, row), cellHeaderPaths: this.getCellHeaderPaths(col, row) }, diff --git a/packages/vtable/src/event/listener/table-group.ts b/packages/vtable/src/event/listener/table-group.ts index cd7136c5e..abac3930a 100644 --- a/packages/vtable/src/event/listener/table-group.ts +++ b/packages/vtable/src/event/listener/table-group.ts @@ -13,6 +13,9 @@ import { Rect } from '../../tools/Rect'; import type { EventManager } from '../event'; import type { BaseTableAPI } from '../../ts-types/base-table'; import type { IIconGraphicAttribute } from '../../scenegraph/graphic/icon'; +import { getCellMergeInfo } from '../../scenegraph/utils/get-cell-merge'; +import type { CheckBox, CheckboxAttributes } from '@visactor/vrender-components'; + // PointerMove敏感度太高了 记录下上一个鼠标位置 在接收到PointerMove事件时做判断 是否到到触发框选或者移动表头操作的标准,防止误触 let LastPointerXY: { x: number; y: number }; let LastBodyPointerXY: { x: number; y: number }; @@ -620,6 +623,23 @@ export function bindTableGroupListener(eventManager: EventManager) { const { col, row } = eventArgsSet.eventArgs; const cellInfo = table.getCellInfo(col, row); + const mergeRange = getCellMergeInfo(table, col, row); + if (mergeRange) { + for (let col = mergeRange.start.col; col <= mergeRange.end.col; col++) { + for (let row = mergeRange.start.row; row <= mergeRange.end.row; row++) { + const cellGroup = table.scenegraph.getCell(col, row); + cellGroup.forEachChildren((checkbox: CheckBox) => { + if (checkbox.name === 'checkbox') { + checkbox.setAttributes({ + checked: (e.target.attribute as CheckboxAttributes).checked, + indeterminate: (e.target.attribute as CheckboxAttributes).indeterminate + }); + } + }); + } + } + } + const cellsEvent: MousePointerCellEvent & { checked: boolean } = { ...cellInfo, event: e.nativeEvent, diff --git a/packages/vtable/src/scenegraph/group-creater/cell-helper.ts b/packages/vtable/src/scenegraph/group-creater/cell-helper.ts index 9e1baa9a0..6570d4559 100644 --- a/packages/vtable/src/scenegraph/group-creater/cell-helper.ts +++ b/packages/vtable/src/scenegraph/group-creater/cell-helper.ts @@ -376,7 +376,7 @@ export function updateCell(col: number, row: number, table: BaseTableAPI, addNew let isMerge; let range; - if (cellLocation !== 'body' || (define as TextColumnDefine)?.mergeCell) { + if (cellLocation !== 'body' || (define as TextColumnDefine)?.mergeCell || table.internalProps.customMergeCell) { // 只有表头或者column配置合并单元格后再进行信息获取 range = table.getCellRange(col, row); isMerge = range.start.col !== range.end.col || range.start.row !== range.end.row; diff --git a/packages/vtable/src/scenegraph/group-creater/column-helper.ts b/packages/vtable/src/scenegraph/group-creater/column-helper.ts index 5f73e2096..f282069ec 100644 --- a/packages/vtable/src/scenegraph/group-creater/column-helper.ts +++ b/packages/vtable/src/scenegraph/group-creater/column-helper.ts @@ -48,7 +48,7 @@ export function createComplexColumn( // // insert cell into column group bottom // y = columnGroup.colHeight; // } - if (columnGroup.lastChild) { + if (columnGroup.lastChild && (columnGroup.lastChild as Group).row === rowStart - 1) { y = (columnGroup.lastChild as Group).attribute.y + (columnGroup.lastChild as Group).attribute.height; } else if (columnGroup.colHeight) { y = columnGroup.colHeight; @@ -150,10 +150,7 @@ export function createComplexColumn( ) ); columnGroup.updateColumnRowNumber(row); - // const height = table.getRowHeight(row); - const height = isMerge - ? table.getRowHeight(row) / (range.end.row - range.start.row + 1) - : table.getRowHeight(row); + const height = table.getRowHeight(row); columnGroup.updateColumnHeight(height); y += height; } else { @@ -176,12 +173,6 @@ export function createComplexColumn( cellTheme ); columnGroup.updateColumnRowNumber(row); - // // const height = cellGroup.attribute.height; - // const height = isMerge - // ? cellGroup.attribute.height / (range.end.row - range.start.row + 1) - // : cellGroup.attribute.height; - // columnGroup.updateColumnHeight(height); - // y += height; if (isMerge) { const rangeHeight = table.getRowHeight(row); const rangeWidth = table.getColWidth(col); diff --git a/packages/vtable/src/scenegraph/group-creater/progress/update-position/dynamic-set-y.ts b/packages/vtable/src/scenegraph/group-creater/progress/update-position/dynamic-set-y.ts index 80958f27e..46e4cf000 100644 --- a/packages/vtable/src/scenegraph/group-creater/progress/update-position/dynamic-set-y.ts +++ b/packages/vtable/src/scenegraph/group-creater/progress/update-position/dynamic-set-y.ts @@ -22,11 +22,11 @@ export async function dynamicSetY(y: number, proxy: SceneProxy) { function move(deltaRow: number, screenTopRow: number, screenTopY: number, y: number, proxy: SceneProxy) { if (deltaRow > 0) { // 向下滚动,顶部cell group移到底部 - moveCell(deltaRow, 'up', screenTopRow, screenTopY, proxy); + moveCell(deltaRow, 'up', screenTopRow, screenTopY, y, proxy); proxy.updateBody(y - proxy.deltaY); } else if (deltaRow < 0) { // 向上滚动,底部cell group移到顶部 - moveCell(-deltaRow, 'down', screenTopRow, screenTopY, proxy); + moveCell(-deltaRow, 'down', screenTopRow, screenTopY, y, proxy); proxy.updateBody(y - proxy.deltaY); } else { // 不改变row,更新body group范围 @@ -39,6 +39,7 @@ async function moveCell( direction: 'up' | 'down', screenTopRow: number, screenTopY: number, + y: number, proxy: SceneProxy ) { // 限制count范围 @@ -197,7 +198,23 @@ async function moveCell( distEndRow > proxy.bodyBottomRow - (proxy.rowEnd - proxy.rowStart + 1) ? 'down' : 'up' // 跳转到底部时,从下向上对齐 ); } - proxy.table.scenegraph.proxy.deltaY = 0; + + // update body position when click scroll bar + if (syncTopRow === proxy.bodyTopRow) { + const cellGroup = proxy.table.scenegraph.highPerformanceGetCell(proxy.bodyLeftCol, syncTopRow, true); + const delaY = cellGroup.attribute.y - y; + proxy.table.scenegraph.proxy.deltaY = delaY; + } else if (syncBottomRow === proxy.bodyBottomRow) { + const cellGroup = proxy.table.scenegraph.highPerformanceGetCell(proxy.bodyLeftCol, syncBottomRow, true); + const delaY = + cellGroup.attribute.y + + cellGroup.attribute.height - + (proxy.table.tableNoFrameHeight - proxy.table.getFrozenRowsHeight()) - + y; + proxy.table.scenegraph.proxy.deltaY = -delaY; + } else { + proxy.table.scenegraph.proxy.deltaY = 0; + } proxy.currentRow = direction === 'up' ? proxy.currentRow + count : proxy.currentRow - count; proxy.totalRow = Math.max(