From 367ca45357343be3003af2304d794d493df1da6b Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Thu, 24 Aug 2023 18:38:11 +0800 Subject: [PATCH 1/5] feat: add api for updateAutoWrapText widthMode heightMode #240 --- packages/vtable/examples/menu.ts | 21 +++ .../updateOption/update-autoWrapText.ts | 86 ++++++++++++ .../examples/updateOption/update-columns.ts | 129 ++++++++++++++++++ .../updateOption/update-heightMode.ts | 87 ++++++++++++ .../examples/updateOption/update-widthMode.ts | 87 ++++++++++++ packages/vtable/src/ListTable.ts | 17 ++- packages/vtable/src/core/BaseTable.ts | 34 ++++- 7 files changed, 450 insertions(+), 11 deletions(-) create mode 100644 packages/vtable/examples/updateOption/update-autoWrapText.ts create mode 100644 packages/vtable/examples/updateOption/update-columns.ts create mode 100644 packages/vtable/examples/updateOption/update-heightMode.ts create mode 100644 packages/vtable/examples/updateOption/update-widthMode.ts diff --git a/packages/vtable/examples/menu.ts b/packages/vtable/examples/menu.ts index d3e84ff95..1364e99c5 100644 --- a/packages/vtable/examples/menu.ts +++ b/packages/vtable/examples/menu.ts @@ -445,6 +445,27 @@ export const menus = [ } ] }, + { + menu: 'updateOption', + children: [ + { + path: 'updateOption', + name: 'update-autoWrapText' + }, + { + path: 'updateOption', + name: 'update-columns' + }, + { + path: 'updateOption', + name: 'update-widthMode' + }, + { + path: 'updateOption', + name: 'update-heightMode' + } + ] + }, { menu: '业务方', children: [ diff --git a/packages/vtable/examples/updateOption/update-autoWrapText.ts b/packages/vtable/examples/updateOption/update-autoWrapText.ts new file mode 100644 index 000000000..8f84330cd --- /dev/null +++ b/packages/vtable/examples/updateOption/update-autoWrapText.ts @@ -0,0 +1,86 @@ +import * as VTable from '../../src'; +const Table_CONTAINER_DOM_ID = 'vTable'; +const generatePersons = count => { + return Array.from(new Array(count)).map((_, i) => ({ + id: i + 1, + email1: `${i + 1}@xxx.com`, + name: `小明${i + 1}`, + lastName: '王', + date1: '2022年9月1日', + tel: '000-0000-0000', + sex: i % 2 === 0 ? 'boy fdsa fds gds' : 'girl', + work: i % 2 === 0 ? 'back-end engineer' : 'front-end engineer', + city: 'beijing' + })); +}; + +export function createTable() { + const records = generatePersons(50); + const columns: VTable.ColumnsDefine = [ + { + field: 'id', + caption: 'ID', + width: 120, + sort: true + }, + { + field: 'email1', + caption: 'email', + width: 200, + sort: true + }, + { + caption: 'full name', + columns: [ + { + field: 'name', + caption: 'First Name', + width: 200 + }, + { + field: 'name', + caption: 'Last Name', + width: 200 + } + ] + }, + { + field: 'date1', + caption: 'birthday', + width: 200 + }, + { + field: 'sex', + caption: 'sex', + width: 53 + }, + { + field: 'tel', + caption: 'telephone', + width: 100 + }, + { + field: 'work', + caption: 'job', + width: 100 + }, + { + field: 'city', + caption: 'city', + width: 150 + } + ]; + const option = { + container: document.getElementById(Table_CONTAINER_DOM_ID), + records, + columns, + defaultRowHeight: 50 + // autoWrapText: true, + }; + const tableInstance = new VTable.ListTable(option); + setTimeout(() => { + tableInstance.updateAutoWrapText(true); + }, 2000); + + (window as any).tableInstance = tableInstance; +} diff --git a/packages/vtable/examples/updateOption/update-columns.ts b/packages/vtable/examples/updateOption/update-columns.ts new file mode 100644 index 000000000..1e632a3e2 --- /dev/null +++ b/packages/vtable/examples/updateOption/update-columns.ts @@ -0,0 +1,129 @@ +import * as VTable from '../../src'; +const Table_CONTAINER_DOM_ID = 'vTable'; +const generatePersons = count => { + return Array.from(new Array(count)).map((_, i) => ({ + id: i + 1, + email1: `${i + 1}@xxx.com`, + name: `小明${i + 1}`, + lastName: '王', + date1: '2022年9月1日', + tel: '000-0000-0000', + sex: i % 2 === 0 ? 'boy fdsa fds gds' : 'girl', + work: i % 2 === 0 ? 'back-end engineer' : 'front-end engineer', + city: 'beijing' + })); +}; + +export function createTable() { + const records = generatePersons(50); + const columns: VTable.ColumnsDefine = [ + { + field: 'id', + caption: 'ID', + width: 120, + sort: true + }, + { + field: 'email1', + caption: 'email', + width: 200, + sort: true + }, + { + caption: 'full name', + columns: [ + { + field: 'name', + caption: 'First Name', + width: 200 + }, + { + field: 'name', + caption: 'Last Name', + width: 200 + } + ] + }, + { + field: 'date1', + caption: 'birthday', + width: 200 + }, + { + field: 'sex', + caption: 'sex', + width: 53 + }, + { + field: 'tel', + caption: 'telephone', + width: 100 + }, + { + field: 'work', + caption: 'job', + width: 100 + }, + { + field: 'city', + caption: 'city', + width: 150 + } + ]; + const option = { + container: document.getElementById(Table_CONTAINER_DOM_ID), + records, + columns, + defaultRowHeight: 50, + // autoWrapText: true, + heightMode: 'autoWrapText' + }; + const tableInstance = new VTable.ListTable(option); + setTimeout(() => { + tableInstance.updateColumns([ + { + field: 'id', + caption: 'ID updated', + width: 120, + sort: true + }, + { + caption: 'full name updated', + columns: [ + { + field: 'name', + caption: 'First Name', + width: 200 + }, + { + field: 'name', + caption: 'Last Name', + width: 200 + } + ] + }, + { + field: 'sex', + caption: 'sex updated', + width: 53 + }, + { + field: 'tel', + caption: 'telephone updated', + width: 100 + }, + { + field: 'work', + caption: 'job updated', + width: 100 + }, + { + field: 'city', + caption: 'city updated', + width: 150 + } + ]); + }, 2000); + + (window as any).tableInstance = tableInstance; +} diff --git a/packages/vtable/examples/updateOption/update-heightMode.ts b/packages/vtable/examples/updateOption/update-heightMode.ts new file mode 100644 index 000000000..bc7818de2 --- /dev/null +++ b/packages/vtable/examples/updateOption/update-heightMode.ts @@ -0,0 +1,87 @@ +import * as VTable from '../../src'; +const Table_CONTAINER_DOM_ID = 'vTable'; +const generatePersons = count => { + return Array.from(new Array(count)).map((_, i) => ({ + id: i + 1, + email1: `${i + 1}@xxx.com`, + name: `小明${i + 1}`, + lastName: '王', + date1: '2022年9月1日', + tel: '000-0000-0000', + sex: i % 2 === 0 ? 'boy fdsa fds gds' : 'girl', + work: i % 2 === 0 ? 'back-end engineer' : 'front-end engineer', + city: 'beijing' + })); +}; + +export function createTable() { + const records = generatePersons(50); + const columns: VTable.ColumnsDefine = [ + { + field: 'id', + caption: 'ID', + width: 120, + sort: true + }, + { + field: 'email1', + caption: 'email', + width: 200, + sort: true + }, + { + caption: 'full name', + columns: [ + { + field: 'name', + caption: 'First Name', + width: 200 + }, + { + field: 'name', + caption: 'Last Name', + width: 200 + } + ] + }, + { + field: 'date1', + caption: 'birthday', + width: 200 + }, + { + field: 'sex', + caption: 'sex', + width: 53 + }, + { + field: 'tel', + caption: 'telephone', + width: 100 + }, + { + field: 'work', + caption: 'job', + width: 100 + }, + { + field: 'city', + caption: 'city', + width: 150 + } + ]; + const option = { + container: document.getElementById(Table_CONTAINER_DOM_ID), + records, + columns, + defaultRowHeight: 50 + // autoWrapText: true, + }; + const tableInstance = new VTable.ListTable(option); + setTimeout(() => { + tableInstance.heightMode = 'adaptive'; + tableInstance.clearScenegraphRerender(); + }, 2000); + + (window as any).tableInstance = tableInstance; +} diff --git a/packages/vtable/examples/updateOption/update-widthMode.ts b/packages/vtable/examples/updateOption/update-widthMode.ts new file mode 100644 index 000000000..79be25dc6 --- /dev/null +++ b/packages/vtable/examples/updateOption/update-widthMode.ts @@ -0,0 +1,87 @@ +import * as VTable from '../../src'; +const Table_CONTAINER_DOM_ID = 'vTable'; +const generatePersons = count => { + return Array.from(new Array(count)).map((_, i) => ({ + id: i + 1, + email1: `${i + 1}@xxx.com`, + name: `小明${i + 1}`, + lastName: '王', + date1: '2022年9月1日', + tel: '000-0000-0000', + sex: i % 2 === 0 ? 'boy fdsa fds gds' : 'girl', + work: i % 2 === 0 ? 'back-end engineer' : 'front-end engineer', + city: 'beijing' + })); +}; + +export function createTable() { + const records = generatePersons(50); + const columns: VTable.ColumnsDefine = [ + { + field: 'id', + caption: 'ID', + width: 120, + sort: true + }, + { + field: 'email1', + caption: 'email', + width: 200, + sort: true + }, + { + caption: 'full name', + columns: [ + { + field: 'name', + caption: 'First Name', + width: 200 + }, + { + field: 'name', + caption: 'Last Name', + width: 200 + } + ] + }, + { + field: 'date1', + caption: 'birthday', + width: 200 + }, + { + field: 'sex', + caption: 'sex', + width: 53 + }, + { + field: 'tel', + caption: 'telephone', + width: 100 + }, + { + field: 'work', + caption: 'job', + width: 100 + }, + { + field: 'city', + caption: 'city', + width: 150 + } + ]; + const option = { + container: document.getElementById(Table_CONTAINER_DOM_ID), + records, + columns, + defaultRowHeight: 50 + // autoWrapText: true, + }; + const tableInstance = new VTable.ListTable(option); + setTimeout(() => { + tableInstance.widthMode = 'adaptive'; + tableInstance.clearScenegraphRerender(); + }, 2000); + + (window as any).tableInstance = tableInstance; +} diff --git a/packages/vtable/src/ListTable.ts b/packages/vtable/src/ListTable.ts index c34d38d60..1e9f1a875 100644 --- a/packages/vtable/src/ListTable.ts +++ b/packages/vtable/src/ListTable.ts @@ -94,13 +94,20 @@ export class ListTable extends BaseTable implements ListTableAPI { set columns(columns: ColumnsDefine) { this.internalProps.columns = columns; this.options.columns = columns; + } + /** + * Sets the define of the column. + */ + updateColumns(columns: ColumnsDefine) { + this.internalProps.columns = columns; + this.options.columns = columns; this.refreshHeader(); - //需要异步等待其他事情都完成后再绘制 - setTimeout(() => { - this.render(); - }, 0); + this.scenegraph.clearCells(); + this.headerStyleCache = new Map(); + this.bodyStyleCache = new Map(); + this.scenegraph.createSceneGraph(); + this.render(); } - /** *@deprecated 请使用columns */ diff --git a/packages/vtable/src/core/BaseTable.ts b/packages/vtable/src/core/BaseTable.ts index 521fb9f7f..7e517b7bc 100644 --- a/packages/vtable/src/core/BaseTable.ts +++ b/packages/vtable/src/core/BaseTable.ts @@ -643,6 +643,7 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { set widthMode(widthMode: WidthModeDef) { if (widthMode !== this._widthMode) { this._widthMode = widthMode; + this.options.widthMode = widthMode; } } get heightMode(): HeightModeDef { @@ -651,6 +652,7 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { set heightMode(heightMode: HeightModeDef) { if (heightMode !== this._heightMode) { this._heightMode = heightMode; + this.options.heightMode = heightMode; } } get autoFillWidth(): boolean { @@ -1844,6 +1846,17 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { this.clearColWidthCache(); this.clearRowHeightCache(); } + /** + * 重新创建场景树并重新渲染 + */ + clearScenegraphRerender() { + this.refreshHeader(); + this.scenegraph.clearCells(); + this.headerStyleCache = new Map(); + this.bodyStyleCache = new Map(); + this.scenegraph.createSceneGraph(); + this.render(); + } /** * 获取固定行总高 * @returns @@ -2253,17 +2266,22 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { * Set the autoWrapText */ set autoWrapText(autoWrapText: boolean) { + this.internalProps.autoWrapText = autoWrapText; + this.options.autoWrapText = autoWrapText; + } + updateAutoWrapText(autoWrapText: boolean) { if (this.internalProps.autoWrapText === autoWrapText) { return; } this.internalProps.autoWrapText = autoWrapText; this.options.autoWrapText = autoWrapText; - if (this.internalProps.layoutMap) { - //后面如果修改是否转置 - this.refreshHeader(); - // if (this.internalProps.autoRowHeight) this.computeRowsHeight(); - this.render(); - } + // if (this.heightMode === 'autoHeight' || this.heightMode === 'adaptive') { + this.scenegraph.clearCells(); + this.headerStyleCache = new Map(); + this.bodyStyleCache = new Map(); + this.scenegraph.createSceneGraph(); + this.render(); + // } } /** @@ -2272,6 +2290,10 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { get theme(): TableTheme { return this.internalProps.theme; } + set theme(theme: TableTheme) { + this.internalProps.theme = themes.of(theme ?? themes.DEFAULT); + this.options.theme = theme; + } /** * 设置主题 */ From 934c5c1f6a020abaedab44d0296f65f87a693305 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Thu, 24 Aug 2023 18:38:29 +0800 Subject: [PATCH 2/5] docs: update changlog of rush --- ...re-update-single-option-item_2023-08-24-10-38.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 common/changes/@visactor/vtable/240-feature-update-single-option-item_2023-08-24-10-38.json diff --git a/common/changes/@visactor/vtable/240-feature-update-single-option-item_2023-08-24-10-38.json b/common/changes/@visactor/vtable/240-feature-update-single-option-item_2023-08-24-10-38.json new file mode 100644 index 000000000..dce7575e7 --- /dev/null +++ b/common/changes/@visactor/vtable/240-feature-update-single-option-item_2023-08-24-10-38.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "feat: add api for updateAutoWrapText widthMode heightMode #240\n\n", + "type": "patch", + "packageName": "@visactor/vtable" + } + ], + "packageName": "@visactor/vtable", + "email": "892739385@qq.com" +} \ No newline at end of file From b12c833d6f46b77593673c0e5f7568de35e8d0ed Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Fri, 25 Aug 2023 16:34:51 +0800 Subject: [PATCH 3/5] refactor: optimize performance when window resize Compute RowHeight ColWidth #249 --- packages/vtable/src/scenegraph/scenegraph.ts | 13 ++++++++++--- packages/vtable/src/ts-types/base-table.ts | 3 ++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/vtable/src/scenegraph/scenegraph.ts b/packages/vtable/src/scenegraph/scenegraph.ts index c5f4cccc6..02bbf3c6b 100644 --- a/packages/vtable/src/scenegraph/scenegraph.ts +++ b/packages/vtable/src/scenegraph/scenegraph.ts @@ -723,9 +723,16 @@ export class Scenegraph { } resize() { - this.recalculateColWidths(); - - this.recalculateRowHeights(); + if (this.table.widthMode === 'adaptive') { + this.recalculateColWidths(); + } + if (this.table.heightMode === 'adaptive') { + this.recalculateRowHeights(); + } else if (this.table.widthMode === 'adaptive') { + this.table.clearRowHeightCache(); + computeRowsHeight(this.table, 0, this.table.columnHeaderLevelCount - 1); + computeRowsHeight(this.table, this.proxy.rowStart, this.proxy.rowEnd); + } this.dealWidthMode(); this.dealHeightMode(); diff --git a/packages/vtable/src/ts-types/base-table.ts b/packages/vtable/src/ts-types/base-table.ts index bb16bb39f..6b05f0b23 100644 --- a/packages/vtable/src/ts-types/base-table.ts +++ b/packages/vtable/src/ts-types/base-table.ts @@ -553,7 +553,8 @@ export interface BaseTableAPI { isPivotChart: (() => boolean) & (() => boolean); _clearColRangeWidthsMap: (col?: number) => void; _clearRowRangeHeightsMap: (row?: number) => void; - + clearRowHeightCache: () => void; + clearColWidthCache: () => void; toggleHierarchyState: (col: number, row: number) => void; resize: () => void; From d9a1ec9beae7d2ce5e2542aec0d2f28feb48b365 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Fri, 25 Aug 2023 16:35:08 +0800 Subject: [PATCH 4/5] docs: update changlog of rush --- ...re-update-single-option-item_2023-08-25-08-35.json | 11 +++++++++++ packages/vtable/examples/list/list.ts | 7 +++++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 common/changes/@visactor/vtable/240-feature-update-single-option-item_2023-08-25-08-35.json diff --git a/common/changes/@visactor/vtable/240-feature-update-single-option-item_2023-08-25-08-35.json b/common/changes/@visactor/vtable/240-feature-update-single-option-item_2023-08-25-08-35.json new file mode 100644 index 000000000..740e36d2e --- /dev/null +++ b/common/changes/@visactor/vtable/240-feature-update-single-option-item_2023-08-25-08-35.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "refactor: optimize performance when window resize Compute RowHeight ColWidth #249\n\n", + "type": "patch", + "packageName": "@visactor/vtable" + } + ], + "packageName": "@visactor/vtable", + "email": "892739385@qq.com" +} \ No newline at end of file diff --git a/packages/vtable/examples/list/list.ts b/packages/vtable/examples/list/list.ts index 32063bb15..c330a9da0 100644 --- a/packages/vtable/examples/list/list.ts +++ b/packages/vtable/examples/list/list.ts @@ -15,7 +15,7 @@ const generatePersons = count => { }; export function createTable() { - const records = generatePersons(1000000); + const records = generatePersons(1000); const columns: VTable.ColumnsDefine = [ { field: 'id', @@ -73,7 +73,10 @@ export function createTable() { const option = { container: document.getElementById(Table_CONTAINER_DOM_ID), records, - columns + columns, + autoWrapText: true, + heightMode: 'autoHeight', + widthMode: 'adaptive' }; const tableInstance = new VTable.ListTable(option); (window as any).tableInstance = tableInstance; From b22df7f222db0fcf942f83a3f866f8e6bd46fc73 Mon Sep 17 00:00:00 2001 From: fangsmile <892739385@qq.com> Date: Fri, 25 Aug 2023 16:43:16 +0800 Subject: [PATCH 5/5] refactor: rename renderWithRecreateCells --- packages/vtable/examples/list/list.ts | 10 +++++----- .../vtable/examples/updateOption/update-heightMode.ts | 2 +- .../vtable/examples/updateOption/update-widthMode.ts | 2 +- packages/vtable/src/core/BaseTable.ts | 2 +- packages/vtable/src/ts-types/base-table.ts | 2 ++ 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/vtable/examples/list/list.ts b/packages/vtable/examples/list/list.ts index c330a9da0..3b3c0b0d1 100644 --- a/packages/vtable/examples/list/list.ts +++ b/packages/vtable/examples/list/list.ts @@ -15,7 +15,7 @@ const generatePersons = count => { }; export function createTable() { - const records = generatePersons(1000); + const records = generatePersons(1000000); const columns: VTable.ColumnsDefine = [ { field: 'id', @@ -73,10 +73,10 @@ export function createTable() { const option = { container: document.getElementById(Table_CONTAINER_DOM_ID), records, - columns, - autoWrapText: true, - heightMode: 'autoHeight', - widthMode: 'adaptive' + columns + // autoWrapText: true, + // heightMode: 'autoHeight', + // widthMode: 'adaptive' }; const tableInstance = new VTable.ListTable(option); (window as any).tableInstance = tableInstance; diff --git a/packages/vtable/examples/updateOption/update-heightMode.ts b/packages/vtable/examples/updateOption/update-heightMode.ts index bc7818de2..5b949bdfe 100644 --- a/packages/vtable/examples/updateOption/update-heightMode.ts +++ b/packages/vtable/examples/updateOption/update-heightMode.ts @@ -80,7 +80,7 @@ export function createTable() { const tableInstance = new VTable.ListTable(option); setTimeout(() => { tableInstance.heightMode = 'adaptive'; - tableInstance.clearScenegraphRerender(); + tableInstance.renderWithRecreateCells(); }, 2000); (window as any).tableInstance = tableInstance; diff --git a/packages/vtable/examples/updateOption/update-widthMode.ts b/packages/vtable/examples/updateOption/update-widthMode.ts index 79be25dc6..f853a6f86 100644 --- a/packages/vtable/examples/updateOption/update-widthMode.ts +++ b/packages/vtable/examples/updateOption/update-widthMode.ts @@ -80,7 +80,7 @@ export function createTable() { const tableInstance = new VTable.ListTable(option); setTimeout(() => { tableInstance.widthMode = 'adaptive'; - tableInstance.clearScenegraphRerender(); + tableInstance.renderWithRecreateCells(); }, 2000); (window as any).tableInstance = tableInstance; diff --git a/packages/vtable/src/core/BaseTable.ts b/packages/vtable/src/core/BaseTable.ts index 7e517b7bc..c16f92d91 100644 --- a/packages/vtable/src/core/BaseTable.ts +++ b/packages/vtable/src/core/BaseTable.ts @@ -1849,7 +1849,7 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { /** * 重新创建场景树并重新渲染 */ - clearScenegraphRerender() { + renderWithRecreateCells() { this.refreshHeader(); this.scenegraph.clearCells(); this.headerStyleCache = new Map(); diff --git a/packages/vtable/src/ts-types/base-table.ts b/packages/vtable/src/ts-types/base-table.ts index 6b05f0b23..396844082 100644 --- a/packages/vtable/src/ts-types/base-table.ts +++ b/packages/vtable/src/ts-types/base-table.ts @@ -563,6 +563,8 @@ export interface BaseTableAPI { getTargetColAt: (absoluteX: number) => { col: number; left: number; right: number; width: number } | null; getTargetRowAt: (absoluteY: number) => { row: number; top: number; bottom: number; height: number } | null; + + renderWithRecreateCells: () => void; //#endregion tableAPI } export interface ListTableProtected extends IBaseTableProtected {