diff --git a/common/config/rush/version-policies.json b/common/config/rush/version-policies.json index 3ca1699e0..b293aa8ee 100644 --- a/common/config/rush/version-policies.json +++ b/common/config/rush/version-policies.json @@ -1 +1,9 @@ -[{"definitionName":"lockStepVersion","policyName":"vtableMain","version":"0.15.5","mainProject":"@visactor/vtable","nextBump":"patch"}] +[ + { + "definitionName": "lockStepVersion", + "policyName": "vtableMain", + "version": "0.16.0", + "mainProject": "@visactor/vtable", + "nextBump": "minor" + } +] \ No newline at end of file diff --git a/docs/assets/api/en/methods.md b/docs/assets/api/en/methods.md index 8b26c7297..f2f889311 100644 --- a/docs/assets/api/en/methods.md +++ b/docs/assets/api/en/methods.md @@ -647,4 +647,62 @@ End editing Get all data of the current table ## dataSouce(CachedDataSource) -Set the data source for the VTable table component instance. For specific usage, please refer to [Asynchronous data lazy loading demo](../demo/performance/async-data) and [Tutorial](../guide/data/async_data) \ No newline at end of file +Set the data source for the VTable table component instance. For specific usage, please refer to [Asynchronous data lazy loading demo](../demo/performance/async-data) and [Tutorial](../guide/data/async_data) + +## addRecords(Function) + + Add data, support multiple pieces of data + +** Note: ListTable specific interface ** + +``` + /** + * Add data to support multiple pieces of data + * @param records multiple data + * @param recordIndex The position to be inserted into the data source, starting from 0. If recordIndex is not set, it will be appended to the end by default. + * If the sorting rule recordIndex is set to be invalid, the sorting logic will be automatically adapted to determine the insertion order. + * recordIndex can be obtained through the interface getRecordShowIndexByCell + */ + addRecords(records: any[], recordIndex?: number) +``` + +## addRecord(Function) + + Add data, single piece of data + +** Note: ListTable specific interface ** + +``` + /** + * Add data single data + * @param record data + * @param recordIndex The position to be inserted into the data source, starting from 0. If recordIndex is not set, it will be appended to the end by default. + * If the sorting rule recordIndex is set to be invalid, the sorting logic will be automatically adapted to determine the insertion order. + * recordIndex can be obtained through the interface getRecordShowIndexByCell + */ + addRecord(record: any, recordIndex?: number) +``` + +## deleteRecords(Function) + +Delete data supports multiple pieces of data + +** Note: ListTable specific interface ** + +``` + /** + * Delete data supports multiple pieces of data + * @param recordIndexs The index of the data to be deleted (the entry index displayed in the body) + */ + deleteRecords(recordIndexs: number[]) +``` + +## getRecordShowIndexByCell(Function) + +Get the index of the current cell data in the body part, that is, remove the index of the header level number by the row and column number. + +** ListTable proprietary ** +``` + /** Get the display index of the current cell in the body part (row/col-headerLevelCount). Note: ListTable specific interface */ + getRecordShowIndexByCell(col: number, row: number): number +``` \ No newline at end of file diff --git a/docs/assets/api/zh/methods.md b/docs/assets/api/zh/methods.md index 8e43b3829..1a0c2d1d1 100644 --- a/docs/assets/api/zh/methods.md +++ b/docs/assets/api/zh/methods.md @@ -651,4 +651,59 @@ use case: 点击图例项后 更新过滤规则 来更新图表 获取当前表格的全部数据 ## dataSouce(CachedDataSource) -给VTable表格组件实例设置数据源,具体使用可以参考[异步懒加载数据demo](../demo/performance/async-data)及[教程](../guide/data/async_data) \ No newline at end of file +给VTable表格组件实例设置数据源,具体使用可以参考[异步懒加载数据demo](../demo/performance/async-data)及[教程](../guide/data/async_data) + +## addRecords(Function) + + 添加数据,支持多条数据 + +** ListTable 专有 ** +``` + /** + * 添加数据 支持多条数据 + * @param records 多条数据 + * @param recordIndex 向数据源中要插入的位置,从0开始。不设置recordIndex的话 默认追加到最后。 + * 如果设置了排序规则recordIndex无效,会自动适应排序逻辑确定插入顺序。 + * recordIndex 可以通过接口getRecordShowIndexByCell获取 + */ + addRecords(records: any[], recordIndex?: number) +``` + +## addRecord(Function) + + 添加数据,单条数据 + +** ListTable 专有 ** +``` + /** + * 添加数据 单条数据 + * @param record 数据 + * @param recordIndex 向数据源中要插入的位置,从0开始。不设置recordIndex的话 默认追加到最后。 + * 如果设置了排序规则recordIndex无效,会自动适应排序逻辑确定插入顺序。 + * recordIndex 可以通过接口getRecordShowIndexByCell获取 + */ + addRecord(record: any, recordIndex?: number) +``` + +## deleteRecords(Function) + +删除数据 支持多条数据 + +** ListTable 专有 ** +``` + /** + * 删除数据 支持多条数据 + * @param recordIndexs 要删除数据的索引(显示到body中的条目索引) + */ + deleteRecords(recordIndexs: number[]) +``` + +## getRecordShowIndexByCell(Function) + +获取当前单元格数据在body部分的索引,即通过行列号去除表头层级数的索引 + +** ListTable 专有 ** +``` + /** 获取当前单元格在body部分的展示索引(row / col-headerLevelCount)。注:ListTable特有接口 */ + getRecordShowIndexByCell(col: number, row: number): number +``` \ No newline at end of file diff --git a/docs/assets/demo/en/edit/add-delete-records.md b/docs/assets/demo/en/edit/add-delete-records.md new file mode 100644 index 000000000..3955e3d95 --- /dev/null +++ b/docs/assets/demo/en/edit/add-delete-records.md @@ -0,0 +1,183 @@ +--- +category: examples +group: edit +title: add or delete records +cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/preview/performance.gif +--- + +# Add and delete data dynamically + +Add and delete data dynamically,Right-click and the Modify Data menu is displayed + +## Key Configurations + +- addRecords api +- addRecord api +- deleteRecords api +- changeCellValue api + +## Code demo + +```javascript livedemo template=vtable +const input_editor = new VTable_editors.InputEditor(); +VTable.register.editor('input-editor', input_editor); +function generateRandomString(length) { + let result = ''; + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + for (let i = 0; i < length; i++) { + result += characters.charAt(Math.floor(Math.random() * characters.length)); + } + return result; +} +function generateRandomHobbies() { + const hobbies = [ + 'Reading books', + 'Playing video games', + 'Watching movies', + 'Cooking', + 'Hiking', + 'Traveling', + 'Photography', + 'Playing musical instruments', + 'Gardening', + 'Painting', + 'Writing', + 'Swimming' + ]; + + const numHobbies = Math.floor(Math.random() * 3) + 1; // 生成 1-3 之间的随机整数 + const selectedHobbies = []; + + for (let i = 0; i < numHobbies; i++) { + const randomIndex = Math.floor(Math.random() * hobbies.length); + const hobby = hobbies[randomIndex]; + selectedHobbies.push(hobby); + hobbies.splice(randomIndex, 1); // 确保每个爱好只选一次 + } + + return selectedHobbies.join(', '); +} +function generateRandomBirthday() { + const start = new Date('1970-01-01'); + const end = new Date('2000-12-31'); + const randomDate = new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())); + const year = randomDate.getFullYear(); + const month = randomDate.getMonth() + 1; + const day = randomDate.getDate(); + return `${year}-${month < 10 ? '0' + month : month}-${day < 10 ? '0' + day : day}`; +} + +function generateRandomPhoneNumber() { + const areaCode = ['130', '131', '132', '133', '134', '135', '136', '137', '138', '139', '150', '151', '152', '153', '155', '156', '157', '158', '159', '170', '176', '177', '178', '180', '181', '182', '183', '184', '185', '186', '187', '188', '189']; + const prefix = areaCode[Math.floor(Math.random() * areaCode.length)]; + const suffix = String(Math.random()).substr(2, 8); + return prefix + suffix; +} + +const generatePersons = (count) => { + return Array.from(new Array(count)).map((_, i) => { + const first=generateRandomString(10); + const last=generateRandomString(4); + return { + id: i+1, + email1: `${first}_${last}@xxx.com`, + name: first, + lastName: last, + hobbies: generateRandomHobbies(), + birthday: generateRandomBirthday(), + tel: generateRandomPhoneNumber(), + sex: i % 2 === 0 ? 'boy' : 'girl', + work: i % 2 === 0 ? 'back-end engineer' : 'front-end engineer', + city: 'beijing', + }}); +}; + + +const records = generatePersons(1000); +const columns = [ + { + field: 'id', + title: 'ID', + width: 80, + sort: true, + }, + { + field: 'email1', + title: 'email', + width: 250, + sort: true, + }, + { + field: 'full name', + title: 'Full name', + columns: [ + { + field: 'name', + title: 'First Name', + width: 120, + }, + { + field: 'lastName', + title: 'Last Name', + width: 100, + }, + ], + }, + { + field: 'hobbies', + title: 'hobbies', + width: 200, + }, + { + field: 'birthday', + title: 'birthday', + width: 120, + }, + { + field: 'sex', + title: 'sex', + width: 100, + }, + { + field: 'tel', + title: 'telephone', + width: 150, + }, + { + field: 'work', + title: 'job', + width: 200, + }, + { + field: 'city', + title: 'city', + width: 150, + }, +]; +const option = { + records, + columns, + menu:{ + contextMenuItems:["insert records bellow","insert blank row bellow",'modify cell value','delete records'] + }, + editor: 'input-editor' +}; +const tableInstance = new VTable.ListTable(document.getElementById(CONTAINER_ID),option); +window['tableInstance'] = tableInstance; + +tableInstance.on('dropdown_menu_click', (args) => { + console.log('dropdown_menu_click',args); + if(args.menuKey==="insert records bellow"){ + const recordIndex=tableInstance.getRecordShowIndexByCell(args.col,args.row); + tableInstance.addRecords(generatePersons(1),recordIndex+1); + }else if(args.menuKey==="insert blank row bellow"){ + const recordIndex=tableInstance.getRecordShowIndexByCell(args.col,args.row); + tableInstance.addRecord({},recordIndex+1); + }else if(args.menuKey==="delete records"){ + const recordIndex=tableInstance.getRecordShowIndexByCell(args.col,args.row); + tableInstance.deleteRecords([recordIndex]); + }else if(args.menuKey==="modify cell value"){ + tableInstance.startEditCell(args.col,args.row); + } +}) +``` diff --git a/docs/assets/demo/en/edit/pivot-table-editor.md b/docs/assets/demo/en/edit/pivot-table-editor.md index 7f0a15d59..23af36078 100644 --- a/docs/assets/demo/en/edit/pivot-table-editor.md +++ b/docs/assets/demo/en/edit/pivot-table-editor.md @@ -1,6 +1,6 @@ --- category: examples -group: table-type +group: edit title: pivot table edit data cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/preview/pivot-table-editor.gif link: '../guide/edit/edit_cell' diff --git a/docs/assets/demo/en/interaction/dblclick-resize-col-width.md b/docs/assets/demo/en/interaction/dblclick-resize-col-width.md new file mode 100644 index 000000000..47e1590bc --- /dev/null +++ b/docs/assets/demo/en/interaction/dblclick-resize-col-width.md @@ -0,0 +1,113 @@ +--- +category: examples +group: Interaction +title: Column width automatically adapts to content when double-clicking +cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/preview/dblclick-resize-col-width.gif +link: '/interaction/resize_column_width' +option: ListTable#columnResizeMode +--- + +# Double-click the column width to automatically adapt to the content + +Double-click on the column interval line to automatically calculate the column width based on the current cell content. + +## Key Configurations + + +## Code demo + +```javascript livedemo template=vtable + +let tableInstance; + fetch('https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/North_American_Superstore_Pivot_data.json') + .then((res) => res.json()) + .then((data) => { + +const option = { + columnResizeMode:'header', + records:data, + enableDataAnalysis: true, + "rows": [ + { + "dimensionKey": "City", + "title": "City", + "headerStyle": { + "textStick": true + }, + "width": "auto", + }, + ], + "columns": [ + { + "dimensionKey": "Category", + "title": "Category", + "headerStyle": { + "textStick": true + }, + "width": "auto", + }, + ], + "indicators": [ + { + "indicatorKey": "Quantity", + "title": "Quantity", + "showSort": false, + "headerStyle":{ + fontWeight: "normal", + }, + style:{ + padding:[16,28,16,28], + color(args){ + if(args.dataValue>=0) + return 'black'; + return 'red' + } + } + }, + { + "indicatorKey": "Sales", + "title": "Sales", + "showSort": false, + "headerStyle":{ + fontWeight: "normal", + }, + style:{ + padding:[16,28,16,28], + color(args){ + if(args.dataValue>=0) + return 'black'; + return 'red' + } + } + }, + { + "indicatorKey": "Profit", + "title": "Profit", + "showSort": false, + "headerStyle":{ + fontWeight: "normal", + }, + style:{ + padding:[16,28,16,28], + color(args){ + if(args.dataValue>=0) + return 'black'; + return 'red' + } + } + } + ], + "corner": { + "titleOnDimension": "row", + "headerStyle": { + "textStick": true + } + }, + //columnResizeType:'all', + widthMode:'standard', + defaultColWidth:120, +}; +tableInstance = new VTable.PivotTable(document.getElementById(CONTAINER_ID),option); +window['tableInstance'] = tableInstance; + }) +``` diff --git a/docs/assets/demo/menu.json b/docs/assets/demo/menu.json index 7fd95e0cb..5ae9a4fa5 100644 --- a/docs/assets/demo/menu.json +++ b/docs/assets/demo/menu.json @@ -518,15 +518,13 @@ "title": { "zh": "调整列宽", "en": "Adjust column width" - }, - "meta": { - "title": "Adjust column width", - "keywords": "", - "category": "demo", - "group": "Interaction", - "cover": "https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/preview/resize-col-width.gif", - "link": "'../../guide/interaction_and_event/resize_column_width'", - "option": "" + } + }, + { + "path": "dblclick-resize-col-width", + "title": { + "zh": "双击列宽自动适应内容", + "en": "dblclick resize column width" } }, { @@ -808,8 +806,8 @@ { "path": "edit", "title": { - "zh": "编辑", - "en": "edit" + "zh": "编辑数据", + "en": "edit data" }, "children": [ { @@ -832,6 +830,13 @@ "zh": "透视表编辑数据", "en": "PivotTable edit data" } + }, + { + "path": "add-delete-records", + "title": { + "zh": "动态新增删除数据", + "en": "Dynamically adjust data" + } } ] }, diff --git a/docs/assets/demo/zh/edit/add-delete-records.md b/docs/assets/demo/zh/edit/add-delete-records.md new file mode 100644 index 000000000..d5ddad2ee --- /dev/null +++ b/docs/assets/demo/zh/edit/add-delete-records.md @@ -0,0 +1,183 @@ +--- +category: examples +group: edit +title: 动态添加删除数据 +cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/preview/performance.gif +--- + +# 动态添加删除数据 + +动态添加删除数据,右键弹出修改数据菜单。 + +## 关键配置 + +- addRecords 接口调用 +- addRecord 接口调用 +- deleteRecords 接口调用 +- changeCellValue 接口调用 + +## 代码演示 + +```javascript livedemo template=vtable +const input_editor = new VTable_editors.InputEditor(); +VTable.register.editor('input-editor', input_editor); +function generateRandomString(length) { + let result = ''; + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + for (let i = 0; i < length; i++) { + result += characters.charAt(Math.floor(Math.random() * characters.length)); + } + return result; +} +function generateRandomHobbies() { + const hobbies = [ + 'Reading books', + 'Playing video games', + 'Watching movies', + 'Cooking', + 'Hiking', + 'Traveling', + 'Photography', + 'Playing musical instruments', + 'Gardening', + 'Painting', + 'Writing', + 'Swimming' + ]; + + const numHobbies = Math.floor(Math.random() * 3) + 1; // 生成 1-3 之间的随机整数 + const selectedHobbies = []; + + for (let i = 0; i < numHobbies; i++) { + const randomIndex = Math.floor(Math.random() * hobbies.length); + const hobby = hobbies[randomIndex]; + selectedHobbies.push(hobby); + hobbies.splice(randomIndex, 1); // 确保每个爱好只选一次 + } + + return selectedHobbies.join(', '); +} +function generateRandomBirthday() { + const start = new Date('1970-01-01'); + const end = new Date('2000-12-31'); + const randomDate = new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())); + const year = randomDate.getFullYear(); + const month = randomDate.getMonth() + 1; + const day = randomDate.getDate(); + return `${year}-${month < 10 ? '0' + month : month}-${day < 10 ? '0' + day : day}`; +} + +function generateRandomPhoneNumber() { + const areaCode = ['130', '131', '132', '133', '134', '135', '136', '137', '138', '139', '150', '151', '152', '153', '155', '156', '157', '158', '159', '170', '176', '177', '178', '180', '181', '182', '183', '184', '185', '186', '187', '188', '189']; + const prefix = areaCode[Math.floor(Math.random() * areaCode.length)]; + const suffix = String(Math.random()).substr(2, 8); + return prefix + suffix; +} + +const generatePersons = (count) => { + return Array.from(new Array(count)).map((_, i) => { + const first=generateRandomString(10); + const last=generateRandomString(4); + return { + id: i+1, + email1: `${first}_${last}@xxx.com`, + name: first, + lastName: last, + hobbies: generateRandomHobbies(), + birthday: generateRandomBirthday(), + tel: generateRandomPhoneNumber(), + sex: i % 2 === 0 ? 'boy' : 'girl', + work: i % 2 === 0 ? 'back-end engineer' : 'front-end engineer', + city: 'beijing', + }}); +}; + + +const records = generatePersons(1000); +const columns = [ + { + field: 'id', + title: 'ID', + width: 80, + sort: true, + }, + { + field: 'email1', + title: 'email', + width: 250, + sort: true, + }, + { + field: 'full name', + title: 'Full name', + columns: [ + { + field: 'name', + title: 'First Name', + width: 120, + }, + { + field: 'lastName', + title: 'Last Name', + width: 100, + }, + ], + }, + { + field: 'hobbies', + title: 'hobbies', + width: 200, + }, + { + field: 'birthday', + title: 'birthday', + width: 120, + }, + { + field: 'sex', + title: 'sex', + width: 100, + }, + { + field: 'tel', + title: 'telephone', + width: 150, + }, + { + field: 'work', + title: 'job', + width: 200, + }, + { + field: 'city', + title: 'city', + width: 150, + }, +]; +const option = { + records, + columns, + menu:{ + contextMenuItems:["向下插入数据","向下插入空行",'修改值','删除该行'] + }, + editor: 'input-editor' +}; +const tableInstance = new VTable.ListTable(document.getElementById(CONTAINER_ID),option); +window['tableInstance'] = tableInstance; + +tableInstance.on('dropdown_menu_click', (args) => { + console.log('dropdown_menu_click',args); + if(args.menuKey==="向下插入数据"){ + const recordIndex=tableInstance.getRecordShowIndexByCell(args.col,args.row); + tableInstance.addRecords(generatePersons(1),recordIndex+1); + }else if(args.menuKey==="向下插入空行"){ + const recordIndex=tableInstance.getRecordShowIndexByCell(args.col,args.row); + tableInstance.addRecord({},recordIndex+1); + }else if(args.menuKey==="删除该行"){ + const recordIndex=tableInstance.getRecordShowIndexByCell(args.col,args.row); + tableInstance.deleteRecords([recordIndex]); + }else if(args.menuKey==="修改值"){ + tableInstance.startEditCell(args.col,args.row); + } +}) +``` diff --git a/docs/assets/demo/zh/edit/pivot-table-editor.md b/docs/assets/demo/zh/edit/pivot-table-editor.md index f58adb91b..be88bd366 100644 --- a/docs/assets/demo/zh/edit/pivot-table-editor.md +++ b/docs/assets/demo/zh/edit/pivot-table-editor.md @@ -1,6 +1,6 @@ --- category: examples -group: table-type +group: edit title: 透视表格编辑数据 cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/preview/pivot-table-editor.gif link: '../guide/edit/edit_cell' diff --git a/docs/assets/demo/zh/interaction/dblclick-resize-col-width.md b/docs/assets/demo/zh/interaction/dblclick-resize-col-width.md new file mode 100644 index 000000000..10d5fa4d2 --- /dev/null +++ b/docs/assets/demo/zh/interaction/dblclick-resize-col-width.md @@ -0,0 +1,113 @@ +--- +category: examples +group: Interaction +title: 双击列宽自动适应内容 +cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/preview/dblclick-resize-col-width.gif +link: '/interaction/resize_column_width' +option: ListTable#columnResizeMode +--- + +# 双击列宽自动适应内容 + +在列间隔线上双击,按当前单元格内容自动计算列宽。 + +## 关键配置 + + +## 代码演示 + +```javascript livedemo template=vtable + +let tableInstance; + fetch('https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/North_American_Superstore_Pivot_data.json') + .then((res) => res.json()) + .then((data) => { + +const option = { + columnResizeMode:'header', + records:data, + enableDataAnalysis: true, + "rows": [ + { + "dimensionKey": "City", + "title": "City", + "headerStyle": { + "textStick": true + }, + "width": "auto", + }, + ], + "columns": [ + { + "dimensionKey": "Category", + "title": "Category", + "headerStyle": { + "textStick": true + }, + "width": "auto", + }, + ], + "indicators": [ + { + "indicatorKey": "Quantity", + "title": "Quantity", + "showSort": false, + "headerStyle":{ + fontWeight: "normal", + }, + style:{ + padding:[16,28,16,28], + color(args){ + if(args.dataValue>=0) + return 'black'; + return 'red' + } + } + }, + { + "indicatorKey": "Sales", + "title": "Sales", + "showSort": false, + "headerStyle":{ + fontWeight: "normal", + }, + style:{ + padding:[16,28,16,28], + color(args){ + if(args.dataValue>=0) + return 'black'; + return 'red' + } + } + }, + { + "indicatorKey": "Profit", + "title": "Profit", + "showSort": false, + "headerStyle":{ + fontWeight: "normal", + }, + style:{ + padding:[16,28,16,28], + color(args){ + if(args.dataValue>=0) + return 'black'; + return 'red' + } + } + } + ], + "corner": { + "titleOnDimension": "row", + "headerStyle": { + "textStick": true + } + }, + //columnResizeType:'all', + widthMode:'standard', + defaultColWidth:120, +}; +tableInstance = new VTable.PivotTable(document.getElementById(CONTAINER_ID),option); +window['tableInstance'] = tableInstance; + }) +``` diff --git a/docs/assets/guide/en/basic_function/row_height_column_width.md b/docs/assets/guide/en/basic_function/row_height_column_width.md index afeff858d..833dc6dd2 100644 --- a/docs/assets/guide/en/basic_function/row_height_column_width.md +++ b/docs/assets/guide/en/basic_function/row_height_column_width.md @@ -121,7 +121,7 @@ const table = new VTable.ListTable({ ## Automatically calculate row height based on content (autoRowHeight) -When the contents of some column cells are longer and wrap, the cells may need a larger row height to display the content. by setting `autoRowHeight` for `true`, VTable can automatically calculate row heights based on content, based on fontSize and lineHeight. The following code example shows how to configure the entire table to automatically calculate row heights based on content: +When the contents of some column cells are longer and wrap, the cells may need a larger row height to display the content. by setting `autoRowHeight` for `true`, VTable can automatically calculate row heights based on content, based on fontSize and lineHeight(font height),include padding. The following code example shows how to configure the entire table to automatically calculate row heights based on content: ```javascript const table = new VTable.ListTable({ @@ -154,7 +154,7 @@ The calculation mode of table row height `heightMode` can also be configured as - Standard mode (standard): Use `defaultRowHeight` and `defaultHeaderRowHeight` as the row height. - Adaptive container height mode (adaptive): Use the height of the container to allocate the height of each row. -- Automatic line height mode (autoHeight): Automatically calculate line height based on content, based on fontSize and lineHeight. The related configuration item `autoWrapText` automatically wraps lines, and can calculate the line height based on the multi-line text content after line wrapping. +- Automatic line height mode (autoHeight): Automatically calculate line height based on content, based on fontSize and lineHeight(font height),include padding. The related configuration item `autoWrapText` automatically wraps lines, and can calculate the line height based on the multi-line text content after line wrapping. # FAQ ## Setting Adaptive Content for Specific Columns to Calculate Column Width diff --git a/docs/assets/guide/en/cell_type/text.md b/docs/assets/guide/en/cell_type/text.md index 3a60aa08b..fde6b377d 100644 --- a/docs/assets/guide/en/cell_type/text.md +++ b/docs/assets/guide/en/cell_type/text.md @@ -18,9 +18,8 @@ VTable supports setting various styles for text type data. The following are the * `fontVariant`: Defines the font weight of the text. * `fontStyle`: Defines the font style of the text. * `textOverflow`: Set the omitted form of the text, it should be noted that if autoWrapText is set with line wrapping, the configuration is invalid. -* `lineHeight`: Set the line height for the cell text content. -* `underline`: Set the line height for the cell text content. -* `lineHeight`: Set the underscore for the text content of the cell. +* `lineHeight`: Set the text font height for the cell text content. +* `underline`: Set the underscore for the text content of the cell. * `lineThrough`: Set the dash for the cell text content. * `textStick`: Set whether the text of the cell has an adsorption effect \[The text can dynamically adjust the position when scrolling] * `autoWrapText`: Sets whether cells wrap themselves. diff --git a/docs/assets/guide/en/data/data_format.md b/docs/assets/guide/en/data/data_format.md index 761a261ac..4c5248640 100644 --- a/docs/assets/guide/en/data/data_format.md +++ b/docs/assets/guide/en/data/data_format.md @@ -289,9 +289,22 @@ const option = { const tableInstance = new VTable.PivotTable(option); ``` -## Reset records interface +## Data interface + +### Reset data You can use setRecords to change table data. Please check the api documentation for details. +### adding data +You can use `addRecords` or `addRecord` to add table data. Please check the api documentation for details. + +### delete data +Table data can be deleted using `deleteRecords`. Please check the api documentation for details. + +### change the data +There is currently no dedicated interface for modifying data, but it can be achieved by combining the interfaces for deleting and adding data. First call `deleteRecords` and then `addRecords`. + +Or you can modify a certain data field using the `changeCellValue` interface. + ## summarize In this tutorial, we learned how to use tabular data in VTable. We first learned what data means in tables, and the data formats of two tables in VTable (basic table and pivot table). In order to help you better understand the correspondence between data formats and tables, we discussed the correspondence between basic tables and pivot tables respectively. diff --git a/docs/assets/guide/en/interaction/resize_column_width.md b/docs/assets/guide/en/interaction/resize_column_width.md index a35c48b6d..c94028d8c 100644 --- a/docs/assets/guide/en/interaction/resize_column_width.md +++ b/docs/assets/guide/en/interaction/resize_column_width.md @@ -1,25 +1,1048 @@ # Column width adjustment -In practical applications, the data lengths in tables tend to vary, and columns with longer data may affect the layout of other columns. In order to better display the data, we need to adjust the column width according to the data content. VTable provides column width adjustment function, so that users can easily adjust the column width of the table according to their needs. +In practical applications, data lengths in tables often vary, and columns with longer data may affect the layout of other columns. In order to better display the data, we need to adjust the column width according to the data content. VTable provides a column width adjustment function so that users can easily adjust the table column width according to their needs. ![image](https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/a2c7623458257d1562627090b.gif) ## Adjust column width switch -We can set it up. `columnResizeMode` To enable or disable column width adjustment. This configuration item has the following optional values: +We can turn on or off the column width adjustment function by setting `columnResizeMode`. This configuration item has the following optional values: -* 'All ': The column width can be adjusted for the entire column including the cells at the header and body -* 'None ': disable adjusting column width -* 'Header ': The column width can only be adjusted in the header of the table -* 'Body ': column width can only be adjusted in body cells +* 'all': The entire column, including the cells at the header and body, can adjust the column width. +* 'none': disable column width adjustment +* 'header': Column width can only be adjusted in units at the header +* 'body': Column width can only be adjusted in body cells + +## Adjust column width limits + +In actual projects, we may need to impose certain restrictions on the column width. Although the column width can be dragged, it cannot be infinitely reduced or enlarged. At this time, we can limit the minimum and maximum column width of each column by setting columns.minWidth and columns.maxWidth. +``` + columns: [ + { + ... + minWidth: '50px', + maxWidth: '200px }, + { + ... + minWidth: '100px', + maxWidth: '300px' + } + ]; +``` +After setting, the column width will not exceed the set range when dragging and adjusting. + + + +## Column width adjustment scope +Configuration items (pivot table and perspective chart support): +``` + /** + * The effective range of adjusting column width: 'column' | 'indicator' | 'all' | 'indicatorGroup', single column | by indicator | all columns | multiple indicators belonging to the same dimension value + */ + columnResizeType?: 'column' | 'indicator' | 'all' | 'indicatorGroup'; +``` +- `column`: Default value, only adjusts the width of the current column; +- `indicator`: The column widths of the same indicator columns are adjusted together; +- `all`: The column widths of all columns are adjusted together; +- `indicatorGroup`: Indicator columns of the same group are adjusted together. For example, there are two indicators under the Northeast dimension value: sales and profit. When the column width of sales is adjusted, the profit column will also be adjusted; + +## Column width adjustment scope configuration example +In the example below columnResizeType is set to all. +```javascript livedemo template=vtable +const data=[ + { + "10002": "36004.12287902832", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "36004.12287902832", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Bookcases" + }, + { + "10002": "-1646.5089945793152", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-1646.5089945793152", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Bookcases" + }, + { + "10002": "10899.361869812012", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "10899.361869812012", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Bookcases" + }, + { + "10002": "1339.4909970760345", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "1339.4909970760345", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Bookcases" + }, + { + "10002": "24157.178108215332", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "24157.178108215332", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Bookcases" + }, + { + "10002": "-1997.9050402641296", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-1997.9050402641296", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Bookcases" + }, + { + "10002": "43819.33399963379", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "43819.33399963379", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Bookcases" + }, + { + "10002": "-1167.6339691877365", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-1167.6339691877365", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Bookcases" + }, + { + "10002": "101781.32774353027", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "101781.32774353027", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Chairs" + }, + { + "10002": "4027.58094894886", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "4027.58094894886", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Chairs" + }, + { + "10002": "45176.44617843628", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "45176.44617843628", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Chairs" + }, + { + "10002": "6612.087041854858", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "6612.087041854858", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Chairs" + }, + { + "10002": "85230.64583206177", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "85230.64583206177", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Chairs" + }, + { + "10002": "6592.718985438347", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "6592.718985438347", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Chairs" + }, + { + "10002": "96260.68257522583", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "96260.68257522583", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Chairs" + }, + { + "10002": "9357.765951037407", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "9357.765951037407", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Chairs" + }, + { + "10002": "30072.729959964752", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "30072.729959964752", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Furnishings" + }, + { + "10002": "7641.274031370878", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "7641.274031370878", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Furnishings" + }, + { + "10002": "17306.68389749527", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "17306.68389749527", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Furnishings" + }, + { + "10002": "3442.686985105276", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "3442.686985105276", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Furnishings" + }, + { + "10002": "15254.369949698448", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "15254.369949698448", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Furnishings" + }, + { + "10002": "-3906.223020374775", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-3906.223020374775", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Furnishings" + }, + { + "10002": "29071.379935264587", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "29071.379935264587", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Furnishings" + }, + { + "10002": "5881.414980173111", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "5881.414980173111", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Furnishings" + }, + { + "10002": "84754.5619468689", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "84754.5619468689", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Tables" + }, + { + "10002": "1482.6120259165764", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "1482.6120259165764", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Tables" + }, + { + "10002": "43916.19310760498", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "43916.19310760498", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Tables" + }, + { + "10002": "-4623.056034088135", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-4623.056034088135", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Tables" + }, + { + "10002": "39154.970703125", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "39154.970703125", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Tables" + }, + { + "10002": "-3559.6519879102707", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-3559.6519879102707", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Tables" + }, + { + "10002": "39139.806856155396", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "39139.806856155396", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Tables" + }, + { + "10002": "-11025.375987529755", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-11025.375987529755", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Tables" + }, + { + "10002": "30236.3359644413", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "30236.3359644413", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Appliances" + }, + { + "10002": "8261.27197098732", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "8261.27197098732", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Appliances" + }, + { + "10002": "19525.326094150543", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "19525.326094150543", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Appliances" + }, + { + "10002": "4123.939019560814", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "4123.939019560814", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Appliances" + }, + { + "10002": "23582.032926678658", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "23582.032926678658", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Appliances" + }, + { + "10002": "-2638.6159623861313", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "-2638.6159623861313", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Appliances" + }, + { + "10002": "34188.466317892075", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "34188.466317892075", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Appliances" + }, + { + "10002": "8391.413984239101", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "8391.413984239101", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Appliances" + }, + { + "10002": "9212.066044569016", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "9212.066044569016", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Art" + }, + { + "10002": "2374.101003214717", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "2374.101003214717", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Art" + }, + { + "10002": "4655.6219692230225", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "4655.6219692230225", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Art" + }, + { + "10002": "1058.5850008130074", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1058.5850008130074", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Art" + }, + { + "10002": "5765.340019583702", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "5765.340019583702", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Art" + }, + { + "10002": "1195.1630011796951", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1195.1630011796951", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Art" + }, + { + "10002": "7485.764034986496", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "7485.764034986496", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Art" + }, + { + "10002": "1899.942004531622", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1899.942004531622", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Art" + }, + { + "10002": "55961.11282122135", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "55961.11282122135", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Binders" + }, + { + "10002": "16096.799980849028", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "16096.799980849028", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Binders" + }, + { + "10002": "37030.34099626541", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "37030.34099626541", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Binders" + }, + { + "10002": "3900.6622482538223", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "3900.6622482538223", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Binders" + }, + { + "10002": "56923.28208118677", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "56923.28208118677", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Binders" + }, + { + "10002": "-1043.632896721363", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "-1043.632896721363", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Binders" + }, + { + "10002": "53497.99653959274", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "53497.99653959274", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Binders" + }, + { + "10002": "11267.932148218155", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "11267.932148218155", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Binders" + }, + { + "10002": "4118.099995136261", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "4118.099995136261", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Envelopes" + }, + { + "10002": "1908.761996269226", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1908.761996269226", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Envelopes" + }, + { + "10002": "3345.555993080139", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "3345.555993080139", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Envelopes" + }, + { + "10002": "1465.4750101566315", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1465.4750101566315", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Envelopes" + }, + { + "10002": "4636.871988296509", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "4636.871988296509", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Envelopes" + }, + { + "10002": "1777.5259877443314", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1777.5259877443314", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Envelopes" + }, + { + "10002": "4375.874011039734", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "4375.874011039734", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Envelopes" + }, + { + "10002": "1812.4089943170547", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1812.4089943170547", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Envelopes" + }, + { + "10002": "923.2159950733185", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "923.2159950733185", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Fasteners" + }, + { + "10002": "275.19199895858765", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "275.19199895858765", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Fasteners" + }, + { + "10002": "503.3160014152527", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "503.3160014152527", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Fasteners" + }, + { + "10002": "173.71899946779013", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "173.71899946779013", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Fasteners" + }, + { + "10002": "778.0299946069717", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "778.0299946069717", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Fasteners" + }, + { + "10002": "236.6199992671609", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "236.6199992671609", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Fasteners" + }, + { + "10002": "819.7179999351501", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "819.7179999351501", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Fasteners" + }, + { + "10002": "263.98999811708927", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "263.98999811708927", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Fasteners" + }, + { + "10002": "5078.726016759872", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "5078.726016759872", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Labels" + }, + { + "10002": "2303.1279985904694", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "2303.1279985904694", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Labels" + }, + { + "10002": "2353.179967880249", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "2353.179967880249", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Labels" + }, + { + "10002": "1040.771997153759", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1040.771997153759", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Labels" + }, + { + "10002": "2451.4719779491425", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "2451.4719779491425", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Labels" + }, + { + "10002": "1073.0799936652184", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1073.0799936652184", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Labels" + }, + { + "10002": "2602.934000492096", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "2602.934000492096", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Labels" + }, + { + "10002": "1129.2839995622635", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1129.2839995622635", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Labels" + }, + { + "10002": "26663.717969417572", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "26663.717969417572", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Paper" + }, + { + "10002": "12119.230026364326", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "12119.230026364326", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Paper" + } +]; +const option = { + records:data, + "rowTree": [ + { + "dimensionKey": "230627170530016", + "value": "Furniture", + hierarchyState: 'expand', + "children": [ + { + "dimensionKey": "230627170530068", + "value": "Bookcases", + hierarchyState: 'collapse', + }, + { + "dimensionKey": "230627170530068", + "value": "Chairs", + hierarchyState: 'collapse', + }, + { + "dimensionKey": "230627170530068", + "value": "Furnishings" + }, + { + "dimensionKey": "230627170530068", + "value": "Tables" + } + ] + }, + { + "dimensionKey": "230627170530016", + "value": "Office Supplies", + "children": [ + { + "dimensionKey": "230627170530068", + "value": "Appliances" + }, + { + "dimensionKey": "230627170530068", + "value": "Art" + }, + { + "dimensionKey": "230627170530068", + "value": "Binders" + }, + { + "dimensionKey": "230627170530068", + "value": "Envelopes" + }, + { + "dimensionKey": "230627170530068", + "value": "Fasteners" + }, + { + "dimensionKey": "230627170530068", + "value": "Labels" + }, + { + "dimensionKey": "230627170530068", + "value": "Paper" + }, + { + "dimensionKey": "230627170530068", + "value": "Storage" + }, + { + "dimensionKey": "230627170530068", + "value": "Supplies" + } + ] + }, + { + "dimensionKey": "230627170530016", + "value": "Technology", + "children": [ + { + "dimensionKey": "230627170530068", + "value": "Accessories" + }, + { + "dimensionKey": "230627170530068", + "value": "Copiers" + }, + { + "dimensionKey": "230627170530068", + "value": "Machines" + }, + { + "dimensionKey": "230627170530068", + "value": "Phones" + } + ] + } +], + "columnTree": [ + { + "dimensionKey": "230627170530059", + "value": "West", + "children": [ + { + "dimensionKey": "230627170530056", + "value": "Sales", + "indicatorKey": "230627170530019" + }, + { + "dimensionKey": "230627170530056", + "value": "Profit", + "indicatorKey": "230627170530022" + } + ] + }, + { + "dimensionKey": "230627170530059", + "value": "South", + "children": [ + { + "dimensionKey": "230627170530056", + "value": "Sales", + "indicatorKey": "230627170530019" + }, + { + "dimensionKey": "230627170530056", + "value": "Profit", + "indicatorKey": "230627170530022" + } + ] + }, + { + "dimensionKey": "230627170530059", + "value": "Central", + "children": [ + { + "dimensionKey": "230627170530056", + "value": "Sales", + "indicatorKey": "230627170530019" + }, + { + "dimensionKey": "230627170530056", + "value": "Profit", + "indicatorKey": "230627170530022" + } + ] + }, + { + "dimensionKey": "230627170530059", + "value": "East", + "children": [ + { + "dimensionKey": "230627170530056", + "value": "Sales", + "indicatorKey": "230627170530019" + }, + { + "dimensionKey": "230627170530056", + "value": "Profit", + "indicatorKey": "230627170530022" + } + ] + } +], +"rows": [ + { + "dimensionKey": "230627170530016", + "title": "Catogery", + "width": "auto", + }, + { + "dimensionKey": "230627170530068", + "title": "Sub-Catogery", + "width": "auto", + }, + ], + "columns": [ + { + "dimensionKey": "230627170530059", + "title": "Region", + "headerStyle": { + "textStick": true + }, + "width": "auto", + }, + ], + "indicators": [ + { + "indicatorKey": "230627170530019", + "title": "Sales", + "width": "auto", + "showSort": false, + "headerStyle":{ + fontWeight: "normal", + }, + "format":(rec)=>{ + if(rec) + return '$'+Number(rec['230627170530019']).toFixed(2); + return ''; + }, + style:{ + padding:[16,28,16,28], + color(args){ + if(args.dataValue>=0) + return 'black'; + return 'red' + } + } + }, + { + "indicatorKey": "230627170530022", + "title": "Profit", + "width": "auto", + "showSort": false, + "headerStyle":{ + fontWeight: "normal", + }, + "format":(rec)=>{if(rec) + return '$'+Number(rec['230627170530022']).toFixed(2); + return '';}, + style:{ + padding:[16,28,16,28], + color(args){ + if(args.dataValue>=0) + return 'black'; + return 'red' + } + } + } + ], + "corner": { + "titleOnDimension": "row", + "headerStyle": { + "textStick": true + } + }, + widthMode:'standard', + rowHierarchyIndent: 20, +columnResizeType: 'all' +}; +const tableInstance = new VTable.PivotTable(document.getElementById(CONTAINER_ID), option); + +``` +## Double-click automatic column width +When users are browsing data and find that the data is collapsed and want to view the complete data, they can expand the column width by content through double-click interaction. + +But if the content is too long, you will find that the content is still omitted. This is because we have an internal default configuration of maximum column width `limitMaxAutoWidth: 450`, which limits the calculated maximum column width to 450. At this time, you can adjust this value to meet the needs. Or you can configure automatic row height to display rows (do not turn it on unless necessary, there is a certain performance overhead): +``` + heightMode:'autoHeight', + autoWrapText:true, +``` ## Adjust column width interaction effect configuration -When making column width adjustment, we can customize the style of the column width marker line. exist `theme.columnResize` Object, we can set the following configuration items: +When adjusting the column width, we can customize the style of the column width mark line. In the `theme.columnResize` object, we can set the following configuration items: -* lineColor: the color of the line -* bgColor: the color of the background line -* lineWidth: the line width of the line -* Width: the width of the background line +* lineColor: the color of the line +* bgColor: background line color +* lineWidth: line width of the straight line +* width: width of background line ```javascript { @@ -39,31 +1062,12 @@ In this way we can see an interaction effect similar to the following: ![image](https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/0a2e223bdcd7410c08f6a6a0d.png) -## Adjust column width limit - -In actual projects, we may need to limit the column width to a certain extent. Although we can drag and drop the column width, we cannot reduce or increase it indefinitely. At this time, we can limit the minimum and maximum column widths of each column by setting columns.minWidth and columns.maxWidth. - - columns: [ - { - ... - minWidth: '50px', - maxWidth: '200px }, - { - ... - minWidth: '100px', - maxWidth: '300px' - } - ]; - -Once set, the column width will not exceed the set range when dragged to adjust. - -## sample code +### Style example Based on the above configuration, we can implement a simple VTable example showing how to adjust the column width: ```javascript livedemo template=vtable -const myVTable = new ListTable({ - container: document.getElementById(CONTAINER_ID), +const myVTable = new VTable.ListTable(document.getElementById(CONTAINER_ID), { columnResizeMode: 'header', columns : [ { @@ -115,5 +1119,3 @@ const myVTable = new ListTable({ }) }); ``` - -So far, this tutorial has completed the explanation of how to adjust and configure the width in VTable, I hope it will be helpful to you. diff --git a/docs/assets/guide/en/table_type/Pivot_table/pivot_table_dataAnalysis.md b/docs/assets/guide/en/table_type/Pivot_table/pivot_table_dataAnalysis.md index 1b1c625b0..c98e6d7ef 100644 --- a/docs/assets/guide/en/table_type/Pivot_table/pivot_table_dataAnalysis.md +++ b/docs/assets/guide/en/table_type/Pivot_table/pivot_table_dataAnalysis.md @@ -15,6 +15,7 @@ const option={ rows:['region','province'], //row dimensions columns:['year','quarter'], //column dimensions indicators:['sales','profit'], //Indicators + enableDataAnalysis: true, //Whether to enable data analysis function records:[ //Data source。 If summary data is passed in, use user incoming data { region:'东北', @@ -172,14 +173,16 @@ According to the above traversed structure, a dimension tree will be generated,

Correspondence between data source entries and cells

-### 自定义维度树 -虽然具有分析能力的多维表格可以自动分析各个维度的维度值组成行列表头的树形结构,并且可以根据`dataConfig.sortRules`进行排序,但具有复杂业务逻辑的场景还是期望可以能够**自定义行列表头维度值**及顺序。那么可以通过rowTree和columnTree来实现这些业务需求场景。 +### Custom dimension tree +Although multi-dimensional tables with analytical capabilities can automatically analyze the dimension values of each dimension to form a tree structure of row and column headers, and can be sorted according to `dataConfig.sortRules`, scenarios with complex business logic still expect to be able to **customize Row column header dimension value ** and order. Then these business requirement scenarios can be realized through rowTree and columnTree. +- enableDataAnalysis needs to be set to false to turn off the analysis of aggregated data within VTable. +

custom rowTree columnTree

-自定义树的配置: +Custom tree configuration: ``` const option = { rowTree: [{ @@ -319,4 +322,4 @@ VTable official website example: https://visactor.io/vtable/demo/table-type/pivo The complexity of the custom tree lies in the formation of the row, column and dimension trees. You can choose to use it according to the business scenario. If you have complex sorting, aggregation or paging rules, you can choose to use a custom method. -**Note: If you choose the custom tree configuration method, there will be no data aggregation capability, that is, one of the matched data entries will be used as the cell indicator value. ** \ No newline at end of file +**Note: If you choose the custom tree configuration method, the data aggregation capability inside the VTable will not be enabled, that is, one of the matched data entries will be used as the cell indicator value. ** \ No newline at end of file diff --git a/docs/assets/guide/en/table_type/Pivot_table/pivot_table_overview.md b/docs/assets/guide/en/table_type/Pivot_table/pivot_table_overview.md index 873b9ec52..87e8981d5 100644 --- a/docs/assets/guide/en/table_type/Pivot_table/pivot_table_overview.md +++ b/docs/assets/guide/en/table_type/Pivot_table/pivot_table_overview.md @@ -100,48 +100,6 @@ We will take the configuration of the pivot table in the following figure as an }, } ], - rowTree: [ - { - dimensionKey: '类别', - value: '办公用品', - children: [ - { dimensionKey: '子类别', value: '电脑' }, - ... - ] - }, - { - dimensionKey: '类别', - value: '家具', - children: [ - { dimensionKey: '子类别', value: '衣柜' }, - ... - ] - }, - ], - columnTree: [ - { - dimensionKey: '地区', - value: '东北', - children: [ - { - dimensionKey: '邮寄方式', - value: '一级', - children: [ - { - indicatorKey: '1', - value: '销售额' // 可不填 - }, - { - indicatorKey: '2', - value: '利润' - } - ] - }, - ... - ] - }, - ... - ], indicators: [ { indicatorKey: '1', @@ -154,8 +112,7 @@ We will take the configuration of the pivot table in the following figure as an ], } -In the above configuration, rowTree and columnTree are one tree respectively**Dimension tree**, the node of the tree defines the key and value, and the value is**Dimension value**Will be displayed in the header cell. The leaf node of the tree may be the name of Metirc. In the current example, Metirc is displayed as a column, which is configured in the leaf node of columnTree. The value of the Metirc node may not be configured to be displayed in the header cell using the title defined in indicators. -Rows and columns define the corresponding**Dimensions**Basic information, including title, headerStyle, format, etc. +In the above configuration, rows and columns define the **dimension** basic information corresponding to the row header and column header, including title, headerStyle, format, etc. -Indicators define**Metirc**Basic information, including title, style, format, etc. +indicators define the basic information of indicators, including title, style, format, etc. \ No newline at end of file diff --git a/docs/assets/guide/en/table_type/Pivot_table/pivot_table_useage.md b/docs/assets/guide/en/table_type/Pivot_table/pivot_table_useage.md index 9f86cb298..9375a1a5f 100644 --- a/docs/assets/guide/en/table_type/Pivot_table/pivot_table_useage.md +++ b/docs/assets/guide/en/table_type/Pivot_table/pivot_table_useage.md @@ -4,21 +4,834 @@ In this section, we will introduce the core configuration items of pivot tables The following are the Key Configurations items and their descriptions for using pivot tables: -* `container`: The container DOM element of the table, which needs to have width and height. -* `records`: The data of the table, represented as an array. -* `indicators`: The specific configuration of each Metirc in the pivot table. -* `columns`: The list header corresponds to the style and format configuration of each level of Dimension. -* `rows`: The row header corresponds to the style and format configuration of each level of Dimension. -* `columnTree`: List header Dimension tree. -* `rowTree`: Row header Dimension tree. -* `rowHierarchyType`: Show as tree or grid. -* `showRowHeader`: Whether to display the row header, the default is true. n -* `showColumnHeader`: Whether to display the list header, the default is true. -* `corner`: The configuration and style of the corner header are customized. +* `container`: The container DOM element of the table, which needs to have width and height. +* `records`: table data, expressed in array form. +* `indicators`: The specific configuration of each indicator in the pivot table. +* `columns`: The column header corresponds to the style and format configuration of various levels of dimensions. +* `rows`: The row header corresponds to the style and format configuration of dimensions at all levels. +* `enableDataAnalysis`: Enable VTable's ability to analyze perspective structures, the default is false. If you pass in custom columnTree and rowTree, please turn it off. If you do not pass in columnTree and rowTree, please turn it on. +* `columnTree`: Customize the list header dimension tree (custom capability). Generally, this tree structure only needs to be configured when there are special sorting requirements for dimension values. +* `rowTree`: Customize the row header dimension tree (customization capability). Generally, this tree structure needs to be configured when there are special sorting requirements for dimension values. +* `rowHierarchyType`: tree hierarchical display or tile display. +* `hideIndicatorName`: Whether it is necessary to hide the indicator name on the header. Default is false. +* `showRowHeader`: Whether to display the row header, the default is true. +* `showColumnHeader`: Whether to display the column header, the default is true. +* `corner`: Various configurations and style customization of the corner table header. ## Example: Create a simple pivot table -Here is a simple example of how to use a pivot table to present data: TODO +Here is a simple example of how to use a pivot table to present data: + +- enableDataAnalysis needs to be set to true + +```javascript livedemo template=vtable +const data=[ + { + "10002": "36004.12287902832", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "36004.12287902832", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Bookcases" + }, + { + "10002": "-1646.5089945793152", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-1646.5089945793152", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Bookcases" + }, + { + "10002": "10899.361869812012", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "10899.361869812012", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Bookcases" + }, + { + "10002": "1339.4909970760345", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "1339.4909970760345", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Bookcases" + }, + { + "10002": "24157.178108215332", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "24157.178108215332", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Bookcases" + }, + { + "10002": "-1997.9050402641296", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-1997.9050402641296", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Bookcases" + }, + { + "10002": "43819.33399963379", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "43819.33399963379", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Bookcases" + }, + { + "10002": "-1167.6339691877365", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-1167.6339691877365", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Bookcases" + }, + { + "10002": "101781.32774353027", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "101781.32774353027", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Chairs" + }, + { + "10002": "4027.58094894886", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "4027.58094894886", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Chairs" + }, + { + "10002": "45176.44617843628", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "45176.44617843628", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Chairs" + }, + { + "10002": "6612.087041854858", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "6612.087041854858", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Chairs" + }, + { + "10002": "85230.64583206177", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "85230.64583206177", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Chairs" + }, + { + "10002": "6592.718985438347", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "6592.718985438347", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Chairs" + }, + { + "10002": "96260.68257522583", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "96260.68257522583", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Chairs" + }, + { + "10002": "9357.765951037407", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "9357.765951037407", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Chairs" + }, + { + "10002": "30072.729959964752", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "30072.729959964752", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Furnishings" + }, + { + "10002": "7641.274031370878", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "7641.274031370878", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Furnishings" + }, + { + "10002": "17306.68389749527", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "17306.68389749527", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Furnishings" + }, + { + "10002": "3442.686985105276", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "3442.686985105276", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Furnishings" + }, + { + "10002": "15254.369949698448", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "15254.369949698448", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Furnishings" + }, + { + "10002": "-3906.223020374775", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-3906.223020374775", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Furnishings" + }, + { + "10002": "29071.379935264587", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "29071.379935264587", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Furnishings" + }, + { + "10002": "5881.414980173111", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "5881.414980173111", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Furnishings" + }, + { + "10002": "84754.5619468689", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "84754.5619468689", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Tables" + }, + { + "10002": "1482.6120259165764", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "1482.6120259165764", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Tables" + }, + { + "10002": "43916.19310760498", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "43916.19310760498", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Tables" + }, + { + "10002": "-4623.056034088135", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-4623.056034088135", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Tables" + }, + { + "10002": "39154.970703125", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "39154.970703125", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Tables" + }, + { + "10002": "-3559.6519879102707", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-3559.6519879102707", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Tables" + }, + { + "10002": "39139.806856155396", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "39139.806856155396", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Tables" + }, + { + "10002": "-11025.375987529755", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-11025.375987529755", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Tables" + }, + { + "10002": "30236.3359644413", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "30236.3359644413", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Appliances" + }, + { + "10002": "8261.27197098732", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "8261.27197098732", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Appliances" + }, + { + "10002": "19525.326094150543", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "19525.326094150543", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Appliances" + }, + { + "10002": "4123.939019560814", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "4123.939019560814", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Appliances" + }, + { + "10002": "23582.032926678658", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "23582.032926678658", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Appliances" + }, + { + "10002": "-2638.6159623861313", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "-2638.6159623861313", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Appliances" + }, + { + "10002": "34188.466317892075", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "34188.466317892075", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Appliances" + }, + { + "10002": "8391.413984239101", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "8391.413984239101", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Appliances" + }, + { + "10002": "9212.066044569016", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "9212.066044569016", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Art" + }, + { + "10002": "2374.101003214717", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "2374.101003214717", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Art" + }, + { + "10002": "4655.6219692230225", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "4655.6219692230225", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Art" + }, + { + "10002": "1058.5850008130074", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1058.5850008130074", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Art" + }, + { + "10002": "5765.340019583702", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "5765.340019583702", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Art" + }, + { + "10002": "1195.1630011796951", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1195.1630011796951", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Art" + }, + { + "10002": "7485.764034986496", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "7485.764034986496", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Art" + }, + { + "10002": "1899.942004531622", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1899.942004531622", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Art" + }, + { + "10002": "55961.11282122135", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "55961.11282122135", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Binders" + }, + { + "10002": "16096.799980849028", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "16096.799980849028", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Binders" + }, + { + "10002": "37030.34099626541", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "37030.34099626541", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Binders" + }, + { + "10002": "3900.6622482538223", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "3900.6622482538223", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Binders" + }, + { + "10002": "56923.28208118677", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "56923.28208118677", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Binders" + }, + { + "10002": "-1043.632896721363", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "-1043.632896721363", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Binders" + }, + { + "10002": "53497.99653959274", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "53497.99653959274", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Binders" + }, + { + "10002": "11267.932148218155", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "11267.932148218155", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Binders" + }, + { + "10002": "4118.099995136261", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "4118.099995136261", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Envelopes" + }, + { + "10002": "1908.761996269226", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1908.761996269226", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Envelopes" + }, + { + "10002": "3345.555993080139", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "3345.555993080139", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Envelopes" + }, + { + "10002": "1465.4750101566315", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1465.4750101566315", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Envelopes" + }, + { + "10002": "4636.871988296509", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "4636.871988296509", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Envelopes" + }, + { + "10002": "1777.5259877443314", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1777.5259877443314", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Envelopes" + }, + { + "10002": "4375.874011039734", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "4375.874011039734", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Envelopes" + }, + { + "10002": "1812.4089943170547", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1812.4089943170547", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Envelopes" + }, + { + "10002": "923.2159950733185", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "923.2159950733185", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Fasteners" + }, + { + "10002": "275.19199895858765", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "275.19199895858765", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Fasteners" + }, + { + "10002": "503.3160014152527", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "503.3160014152527", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Fasteners" + }, + { + "10002": "173.71899946779013", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "173.71899946779013", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Fasteners" + }, + { + "10002": "778.0299946069717", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "778.0299946069717", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Fasteners" + }, + { + "10002": "236.6199992671609", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "236.6199992671609", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Fasteners" + }, + { + "10002": "819.7179999351501", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "819.7179999351501", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Fasteners" + }, + { + "10002": "263.98999811708927", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "263.98999811708927", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Fasteners" + }, + { + "10002": "5078.726016759872", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "5078.726016759872", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Labels" + }, + { + "10002": "2303.1279985904694", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "2303.1279985904694", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Labels" + }, + { + "10002": "2353.179967880249", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "2353.179967880249", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Labels" + }, + { + "10002": "1040.771997153759", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1040.771997153759", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Labels" + }, + { + "10002": "2451.4719779491425", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "2451.4719779491425", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Labels" + }, + { + "10002": "1073.0799936652184", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1073.0799936652184", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Labels" + }, + { + "10002": "2602.934000492096", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "2602.934000492096", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Labels" + }, + { + "10002": "1129.2839995622635", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1129.2839995622635", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Labels" + }, + { + "10002": "26663.717969417572", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "26663.717969417572", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Paper" + }, + { + "10002": "12119.230026364326", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "12119.230026364326", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Paper" + } +]; +const option = { + records:data, + rows: ["230627170530016","230627170530068"], + columns: [ "230627170530059"], + indicators: [ + { + "indicatorKey": "230627170530019", + "title": "Sales", + "width": "auto", + "showSort": false, + "headerStyle":{ + fontWeight: "normal", + }, + "format":(value)=>{ + if(value) + return '$'+Number(value).toFixed(2); + return ''; + }, + style:{ + padding:[16,28,16,28], + color(args){ + if(args.dataValue>=0) + return 'black'; + return 'red' + } + } + }, + { + "indicatorKey": "230627170530022", + "title": "Profit", + "width": "auto", + "showSort": false, + "headerStyle":{ + fontWeight: "normal", + }, + "format":(value)=>{ + if(value) + return '$'+Number(value).toFixed(2); + return ''; + }, + style:{ + padding:[16,28,16,28], + color(args){ + if(args.dataValue>=0) + return 'black'; + return 'red' + } + } + } + ], + "corner": { + "titleOnDimension": "row", + "headerStyle": { + "textStick": true + } + }, + widthMode:'standard', + enableDataAnalysis: true, + defaultHeaderColWidth:150, + rowHierarchyIndent: 20 +}; +const tableInstance = new VTable.PivotTable(document.getElementById(CONTAINER_ID), option); + +``` +## Example: Customize row header column header tree structure +In the following example, in order to make the display order of each dimension value of the table header meet the requirements, we set two fields: rowTree and columnTree, which represent the tree structure of the row header and column header respectively. You can see the difference in the display order of the tree structure latitude values analyzed by VTable above. +- enableDataAnalysis needs to be set to false ```javascript livedemo template=vtable const data=[ @@ -762,7 +1575,6 @@ const data=[ } ]; const option = { - container: document.getElementById(CONTAINER_ID), records:data, "rowTree": [ { @@ -772,22 +1584,22 @@ const option = { "children": [ { "dimensionKey": "230627170530068", - "value": "Bookcases", - hierarchyState: 'collapse', + "value": "Furnishings" }, { "dimensionKey": "230627170530068", - "value": "Chairs", - hierarchyState: 'collapse', + "value": "Tables" }, - { + { "dimensionKey": "230627170530068", - "value": "Furnishings" + "value": "Bookcases", + hierarchyState: 'collapse', }, { "dimensionKey": "230627170530068", - "value": "Tables" - } + "value": "Chairs", + hierarchyState: 'collapse', + }, ] }, { @@ -796,27 +1608,27 @@ const option = { "children": [ { "dimensionKey": "230627170530068", - "value": "Appliances" + "value": "Envelopes" }, { "dimensionKey": "230627170530068", - "value": "Art" + "value": "Fasteners" }, { "dimensionKey": "230627170530068", - "value": "Binders" + "value": "Labels" }, { "dimensionKey": "230627170530068", - "value": "Envelopes" + "value": "Appliances" }, { "dimensionKey": "230627170530068", - "value": "Fasteners" + "value": "Art" }, { "dimensionKey": "230627170530068", - "value": "Labels" + "value": "Binders" }, { "dimensionKey": "230627170530068", @@ -996,7 +1808,6 @@ const option = { widthMode:'standard', rowHierarchyIndent: 20 }; -const tableInstance = new VTable.PivotTable(option); - +const tableInstance = new VTable.PivotTable(document.getElementById(CONTAINER_ID), option); ``` diff --git a/docs/assets/guide/en/theme_and_style/style.md b/docs/assets/guide/en/theme_and_style/style.md index 9c2dbe5e6..06f95e282 100644 --- a/docs/assets/guide/en/theme_and_style/style.md +++ b/docs/assets/guide/en/theme_and_style/style.md @@ -22,7 +22,7 @@ Configure headerStyle in each item of columns. If it is in the pivot table, it c headerStyle: { bgColor: 'red', autoWrapText: true, - lineHeight: '2em', + lineHeight: 20, lineClamp: 'auto', textBaseline: "top", color:"yellow" @@ -49,7 +49,7 @@ Configure style in each item of columns. If it is in the pivot table, it corresp style: { bgColor: 'green', autoWrapText: true, - lineHeight: '1em', + lineHeight: 20, lineClamp: 'auto', textBaseline: "top", color:"yellow" @@ -93,7 +93,7 @@ Contains the following configuration items: ### Line height, line feed settings -* `lineHeight`: set row height for cell +* `lineHeight`: set text height for cell content * `textOverflow`: Sets the ellipsed form of the text. This configuration has no effect if autoWrapText sets line wrapping ### Underscore, underline settings @@ -115,7 +115,9 @@ Contains the following configuration items: ### Cell Tag -`mark`: Set whether the cell has a record style +`marked`: Set whether the cell has a record style + +![image](https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/guide/cell-marked.jpeg) ### line wrapping diff --git a/docs/assets/guide/en/theme_and_style/theme.md b/docs/assets/guide/en/theme_and_style/theme.md index 8aba20499..1b431f8ba 100644 --- a/docs/assets/guide/en/theme_and_style/theme.md +++ b/docs/assets/guide/en/theme_and_style/theme.md @@ -121,7 +121,7 @@ const tableInstance = new vTable.ListTable(option); color: '#1B1F23', bgColor: '#EEF1F5', font: '500 12px PingFang SC', - lineHeight: '16px', + lineHeight: 16, borderColor: '#e1e4e8', padding: [8, 12, 8, 12], }, @@ -129,7 +129,7 @@ const tableInstance = new vTable.ListTable(option); color: '#1B1F23', bgColor: '#EEF1F5', font: '500 12px PingFang SC', - lineHeight: '16px', + lineHeight: 16, borderColor: '#e1e4e8', padding: [8, 12, 8, 12], hover: {//hover状态单元格样式 @@ -157,7 +157,7 @@ const tableInstance = new vTable.ListTable(option); } }, borderColor: '#e1e4e8', - lineHeight: '18px', + lineHeight: 18, hover: { cellBgColor: '#d6e6fe', inlineRowBgColor: '#F3F8FF', diff --git a/docs/assets/guide/zh/basic_function/row_height_column_width.md b/docs/assets/guide/zh/basic_function/row_height_column_width.md index e3a395b55..724afda2a 100644 --- a/docs/assets/guide/zh/basic_function/row_height_column_width.md +++ b/docs/assets/guide/zh/basic_function/row_height_column_width.md @@ -16,7 +16,7 @@ - 标准模式(standard):采用 `defaultRowHeight` 及 `defaultHeaderRowHeight` 作为行高。 - 自适应容器高度模式(adaptive):使用容器的高度分配每行高度。 -- 自动行高模式(autoHeight):根据内容自动计算行高,计算依据fontSize和lineHeight。相关搭配设置项`autoWrapText`自动换行,可以根据换行后的多行文本内容来计算行高。 +- 自动行高模式(autoHeight):根据内容自动计算行高,计算依据fontSize和lineHeight(文字行高),以及padding。相关搭配设置项`autoWrapText`自动换行,可以根据换行后的多行文本内容来计算行高。 # 行高相关配置 diff --git a/docs/assets/guide/zh/cell_type/text.md b/docs/assets/guide/zh/cell_type/text.md index 0a2d1e0eb..19db5ccb0 100644 --- a/docs/assets/guide/zh/cell_type/text.md +++ b/docs/assets/guide/zh/cell_type/text.md @@ -18,9 +18,8 @@ VTable 支持为文本类型数据设置多样化的样式,以下为文本类 - `fontVariant`:定义文本的字体粗细。 - `fontStyle`:定义文本的字体样式。 - `textOverflow`:设置文本的省略形式,需要注意的是:如果autoWrapText设置了自动换行,该配置无效。 -- `lineHeight`:为单元格文本内容设置行高。 -- `underline`:为单元格文本内容设置行高。 -- `lineHeight`:为单元格文本内容设置下划线。 +- `lineHeight`:为单元格文本内容设置文字行高。 +- `underline`:为单元格文本内容设置下划线。 - `lineThrough`:为单元格文本内容设置中划线。 - `textStick`:设置单元格的文本是否带有吸附效果【当滚动时文本可动态调整位置】 - `autoWrapText`:设置单元格是否自动换行。 diff --git a/docs/assets/guide/zh/data/data_format.md b/docs/assets/guide/zh/data/data_format.md index 8af75333c..f6239ff40 100644 --- a/docs/assets/guide/zh/data/data_format.md +++ b/docs/assets/guide/zh/data/data_format.md @@ -280,9 +280,22 @@ const tableInstance = new VTable.PivotTable(document.getElementById(CONTAINER_ID ``` -## 重置数据接口 +## 数据接口 + +### 重置数据 可以使用setRecords 来改变表格数据。具体可查看api文档。 +### 添加数据 +可以使用`addRecords` 或者 `addRecord` 来新增表格数据。具体可查看api文档。 + +### 删除数据 +可以使用`deleteRecords` 来删除表格数据。具体可查看api文档。 + +### 修改数据 +目前还没有专门的修改数据的接口 不过可以结合删除和添加数据的接口来实现,先调用`deleteRecords`再调用`addRecords`。 + +或者可以修改某一个数据字段利用`changeCellValue`接口来实现。 + ## 总结 在本教程中,我们学习了如何在 VTable使用表格数据。我们首先了解了数据在表格中的意义,以及 VTable 中两种表格(基本表格和透视表格)的数据格式形式。为了帮助家更好地理解数据格式与表格的对应关系,我们分别讨论了基本表格和透视表格的对应关系。 \ No newline at end of file diff --git a/docs/assets/guide/zh/interaction/resize_column_width.md b/docs/assets/guide/zh/interaction/resize_column_width.md index 5a15dbcef..aacbec781 100644 --- a/docs/assets/guide/zh/interaction/resize_column_width.md +++ b/docs/assets/guide/zh/interaction/resize_column_width.md @@ -12,32 +12,7 @@ * 'header': 只能在表头处单元调整列宽 * 'body': 只能在body单元格调整列宽 -## 调整列宽交互效果配置 - -在进行列宽调整时,我们可以自定义调整列宽标记线的样式。在 `theme.columnResize` 对象中,我们可以设置以下配置项: -* lineColor: 直线的颜色 -* bgColor: 背景线的颜色 -* lineWidth: 直线的线宽 -* width: 背景线的宽度 - -```javascript -{ - theme: - { - columnResize : { - lineColor: 'blue', - bgColor: 'red', - lineWidth: 1, - width: 5 - } - } -} -``` - -这样我们就可以看到类似如下的交互效果: - -![image](https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/0a2e223bdcd7410c08f6a6a0d.png) ## 调整列宽限制 @@ -57,63 +32,7 @@ 设置后,列宽在拖拽调整时将不超过设定范围。 -## 样式示例 -根据上述配置,我们可以实现一个简单的 VTable 示例,展示如何调整列宽: - -```javascript livedemo template=vtable -const myVTable = new VTable.ListTable(document.getElementById(CONTAINER_ID), { - columnResizeMode: 'header', - columns : [ - { - "field": "订单 ID", - "title": "订单 ID", - "sort": true, - "width":'auto', - }, - { - "field": "邮寄方式", - "title": "邮寄方式" - }, - { - "field": "类别", - "title": "类别" - }, - { - "field": "子类别", - "title": "子类别" - }, - { - "field": "销售额", - "title": "销售额" - }, - ], - "records": [ - { - "订单 ID": "CN-2019-1973789", - "邮寄方式": "标准级", - "类别": "办公用品", - "子类别": "信封", - "销售额": "125.44" - }, - { - "订单 ID": "CN-2019-1973789", - "邮寄方式": "标准级", - "类别": "办公用品", - "子类别": "装订机", - "销售额": "31.92", - }, - ], - theme: VTable.themes.BRIGHT.extends({ - columnResize: { - lineColor: 'blue', - bgColor: 'lightgray', - lineWidth: 2, - width: 10 - } - }) -}); -``` ## 列宽调整作用范围 配置项(透视表及透视图支持): @@ -127,6 +46,7 @@ const myVTable = new VTable.ListTable(document.getElementById(CONTAINER_ID), { - `indicator`:相同指标列的列宽一并调整; - `all`:所有列的列宽一并调整; - `indicatorGroup`:同一组的指标列一并调整,如东北维度值下有两个指标为:销售额和利润,当调整销售额的列宽时,利润列也会进行调整; + ## 列宽调整作用范围配置示例 在下面的示例中将columnResizeType设置为all。 ```javascript livedemo template=vtable @@ -1108,3 +1028,97 @@ columnResizeType: 'all' const tableInstance = new VTable.PivotTable(document.getElementById(CONTAINER_ID), option); ``` + +## 双击自动列宽 +当用户在浏览数据时,发现数据被折叠想要查看完整数据,可以通过双击交互来按内容展开列宽。 + +但是内容如果过长,你会发现内容还是被缺省了,这个是因为我们内部有个最大列宽的默认配置`limitMaxAutoWidth: 450`限制计算出的最大列宽为450,这个时候你可以调整这个值来满足需求。或者可以配置自动行高来折行展示(非必要不要开启,有一定性能开销): +``` + heightMode:'autoHeight', + autoWrapText:true, +``` + +## 调整列宽交互效果配置 + +在进行列宽调整时,我们可以自定义调整列宽标记线的样式。在 `theme.columnResize` 对象中,我们可以设置以下配置项: + +* lineColor: 直线的颜色 +* bgColor: 背景线的颜色 +* lineWidth: 直线的线宽 +* width: 背景线的宽度 + +```javascript +{ + theme: + { + columnResize : { + lineColor: 'blue', + bgColor: 'red', + lineWidth: 1, + width: 5 + } + } +} +``` + +这样我们就可以看到类似如下的交互效果: + +![image](https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/0a2e223bdcd7410c08f6a6a0d.png) + +### 样式示例 + +根据上述配置,我们可以实现一个简单的 VTable 示例,展示如何调整列宽: + +```javascript livedemo template=vtable +const myVTable = new VTable.ListTable(document.getElementById(CONTAINER_ID), { + columnResizeMode: 'header', + columns : [ + { + "field": "订单 ID", + "title": "订单 ID", + "sort": true, + "width":'auto', + }, + { + "field": "邮寄方式", + "title": "邮寄方式" + }, + { + "field": "类别", + "title": "类别" + }, + { + "field": "子类别", + "title": "子类别" + }, + { + "field": "销售额", + "title": "销售额" + }, + ], + "records": [ + { + "订单 ID": "CN-2019-1973789", + "邮寄方式": "标准级", + "类别": "办公用品", + "子类别": "信封", + "销售额": "125.44" + }, + { + "订单 ID": "CN-2019-1973789", + "邮寄方式": "标准级", + "类别": "办公用品", + "子类别": "装订机", + "销售额": "31.92", + }, + ], + theme: VTable.themes.BRIGHT.extends({ + columnResize: { + lineColor: 'blue', + bgColor: 'lightgray', + lineWidth: 2, + width: 10 + } + }) +}); +``` diff --git a/docs/assets/guide/zh/table_type/Pivot_table/pivot_table_dataAnalysis.md b/docs/assets/guide/zh/table_type/Pivot_table/pivot_table_dataAnalysis.md index 0880c7a1b..0f61bf506 100644 --- a/docs/assets/guide/zh/table_type/Pivot_table/pivot_table_dataAnalysis.md +++ b/docs/assets/guide/zh/table_type/Pivot_table/pivot_table_dataAnalysis.md @@ -15,6 +15,7 @@ const option={ rows:['region','province'], //行维度 columns:['year','quarter'], //列维度 indicators:['sales','profit'], //指标 + enableDataAnalysis: true, //是否开启数据分析功能 records:[ //数据源 如果传入了汇总数据则使用用户传入数据 { region:'东北', @@ -175,6 +176,8 @@ filterRules: [ ### 自定义维度树 虽然具有分析能力的多维表格可以自动分析各个维度的维度值组成行列表头的树形结构,并且可以根据`dataConfig.sortRules`进行排序,但具有复杂业务逻辑的场景还是期望可以能够**自定义行列表头维度值**及顺序。那么可以通过rowTree和columnTree来实现这些业务需求场景。 +- enableDataAnalysis需设置为false来关闭VTable内部聚合数据的分析。 +

custom rowTree columnTree

@@ -320,4 +323,4 @@ VTable官网示例:https://visactor.io/vtable/demo/table-type/pivot-table. 自定义树的复杂在于组建行列维度树,可酌情根据业务场景来选择使用,如果具有复杂的排序、汇总或分页规则可选择使用自定义方式。 -**注意:如果选择自定义树的配置方式将没有数据聚合能力,即匹配到的数据条目中的某一条作为单元格指标值。** \ No newline at end of file +**注意:如果选择自定义树的配置方式将不开启VTable内部的数据聚合能力,即匹配到的数据条目中的某一条作为单元格指标值。** \ No newline at end of file diff --git a/docs/assets/guide/zh/table_type/Pivot_table/pivot_table_overview.md b/docs/assets/guide/zh/table_type/Pivot_table/pivot_table_overview.md index 2ace4c490..98a83df2d 100644 --- a/docs/assets/guide/zh/table_type/Pivot_table/pivot_table_overview.md +++ b/docs/assets/guide/zh/table_type/Pivot_table/pivot_table_overview.md @@ -107,48 +107,6 @@ VTable透视表在数据分析方面具有以下优势: }, } ], - rowTree: [ - { - dimensionKey: '类别', - value: '办公用品', - children: [ - { dimensionKey: '子类别', value: '电脑' }, - ... - ] - }, - { - dimensionKey: '类别', - value: '家具', - children: [ - { dimensionKey: '子类别', value: '衣柜' }, - ... - ] - }, - ], - columnTree: [ - { - dimensionKey: '地区', - value: '东北', - children: [ - { - dimensionKey: '邮寄方式', - value: '一级', - children: [ - { - indicatorKey: '1', - value: '销售额' // 可不填 - }, - { - indicatorKey: '2', - value: '利润' - } - ] - }, - ... - ] - }, - ... - ], indicators: [ { indicatorKey: '1', @@ -161,8 +119,6 @@ VTable透视表在数据分析方面具有以下优势: ], } -在上面这份配置中,rowTree和columnTree分别是一棵**维度树**,树的结点定义了key和value,value是**维度值**会显示到表头单元格中。树的叶节点可能为指标名称,在当前的示例中指标以列展示,则配置在了columnTree的叶节点中,其中指标结点的value可不配置会使用indicators中定义的title显示在表头单元格中。 - -rows和columns定义了行表头和列表头对应的**维度**基本信息,包括title,headerStyle, format等。 +在上面这份配置中,rows和columns定义了行表头和列表头对应的**维度**基本信息,包括title,headerStyle, format等。 indicators定义了**指标**的基本信息,包括title,style, format等。 diff --git a/docs/assets/guide/zh/table_type/Pivot_table/pivot_table_useage.md b/docs/assets/guide/zh/table_type/Pivot_table/pivot_table_useage.md index b631ffad7..a97f85e25 100644 --- a/docs/assets/guide/zh/table_type/Pivot_table/pivot_table_useage.md +++ b/docs/assets/guide/zh/table_type/Pivot_table/pivot_table_useage.md @@ -9,16 +9,829 @@ * `indicators`: 透视表中各个指标的具体配置。 * `columns`:列表头对应各级维度的样式及format配置。 * `rows`:行表头对应各级维度的样式及format配置。 -* `columnTree`:列表头维度树。 -* `rowTree`:行表头维度树。 +* `enableDataAnalysis`: 开启VTable分析透视结构能力,默认为false。如果传入自定义的columnTree和rowTree请关闭,如果不传columnTree和rowTree请开启。 +* `columnTree`:自定义列表头维度树(自定义能力),一般当有维度值特殊排序要求的情况下才需要配置这个树结构。 +* `rowTree`:自定义行表头维度树(自定义能力),一般当有维度值特殊排序要求的情况下才需要配置这个树结构。 * `rowHierarchyType`:树形层级展示还是平铺展示。 -* `showRowHeader`:是否显示行表头,默认为 true。n +* `hideIndicatorName`:是否需要将表头上的指标名称隐藏掉。默认为 false。 +* `showRowHeader`:是否显示行表头,默认为 true。 * `showColumnHeader`:是否显示列表头,默认为 true。 * `corner`:角表头各项配置及样式自定义。 ## 示例:创建一个简单的透视表 -下面是一个简单的示例,演示如何使用透视表来展示数据:TODO +下面是一个简单的示例,演示如何使用透视表来展示数据: + +- enableDataAnalysis需设置为true + +```javascript livedemo template=vtable +const data=[ + { + "10002": "36004.12287902832", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "36004.12287902832", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Bookcases" + }, + { + "10002": "-1646.5089945793152", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-1646.5089945793152", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Bookcases" + }, + { + "10002": "10899.361869812012", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "10899.361869812012", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Bookcases" + }, + { + "10002": "1339.4909970760345", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "1339.4909970760345", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Bookcases" + }, + { + "10002": "24157.178108215332", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "24157.178108215332", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Bookcases" + }, + { + "10002": "-1997.9050402641296", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-1997.9050402641296", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Bookcases" + }, + { + "10002": "43819.33399963379", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "43819.33399963379", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Bookcases" + }, + { + "10002": "-1167.6339691877365", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-1167.6339691877365", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Bookcases" + }, + { + "10002": "101781.32774353027", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "101781.32774353027", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Chairs" + }, + { + "10002": "4027.58094894886", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "4027.58094894886", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Chairs" + }, + { + "10002": "45176.44617843628", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "45176.44617843628", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Chairs" + }, + { + "10002": "6612.087041854858", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "6612.087041854858", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Chairs" + }, + { + "10002": "85230.64583206177", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "85230.64583206177", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Chairs" + }, + { + "10002": "6592.718985438347", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "6592.718985438347", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Chairs" + }, + { + "10002": "96260.68257522583", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "96260.68257522583", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Chairs" + }, + { + "10002": "9357.765951037407", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "9357.765951037407", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Chairs" + }, + { + "10002": "30072.729959964752", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "30072.729959964752", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Furnishings" + }, + { + "10002": "7641.274031370878", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "7641.274031370878", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Furnishings" + }, + { + "10002": "17306.68389749527", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "17306.68389749527", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Furnishings" + }, + { + "10002": "3442.686985105276", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "3442.686985105276", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Furnishings" + }, + { + "10002": "15254.369949698448", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "15254.369949698448", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Furnishings" + }, + { + "10002": "-3906.223020374775", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-3906.223020374775", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Furnishings" + }, + { + "10002": "29071.379935264587", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "29071.379935264587", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Furnishings" + }, + { + "10002": "5881.414980173111", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "5881.414980173111", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Furnishings" + }, + { + "10002": "84754.5619468689", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "84754.5619468689", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Tables" + }, + { + "10002": "1482.6120259165764", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "1482.6120259165764", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Tables" + }, + { + "10002": "43916.19310760498", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "43916.19310760498", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Tables" + }, + { + "10002": "-4623.056034088135", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-4623.056034088135", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Tables" + }, + { + "10002": "39154.970703125", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "39154.970703125", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Tables" + }, + { + "10002": "-3559.6519879102707", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-3559.6519879102707", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Tables" + }, + { + "10002": "39139.806856155396", + "10003": "230627170530019", + "230627170530016": "Furniture", + "230627170530019": "39139.806856155396", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Tables" + }, + { + "10002": "-11025.375987529755", + "10003": "230627170530022", + "230627170530016": "Furniture", + "230627170530022": "-11025.375987529755", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Tables" + }, + { + "10002": "30236.3359644413", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "30236.3359644413", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Appliances" + }, + { + "10002": "8261.27197098732", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "8261.27197098732", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Appliances" + }, + { + "10002": "19525.326094150543", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "19525.326094150543", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Appliances" + }, + { + "10002": "4123.939019560814", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "4123.939019560814", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Appliances" + }, + { + "10002": "23582.032926678658", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "23582.032926678658", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Appliances" + }, + { + "10002": "-2638.6159623861313", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "-2638.6159623861313", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Appliances" + }, + { + "10002": "34188.466317892075", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "34188.466317892075", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Appliances" + }, + { + "10002": "8391.413984239101", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "8391.413984239101", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Appliances" + }, + { + "10002": "9212.066044569016", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "9212.066044569016", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Art" + }, + { + "10002": "2374.101003214717", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "2374.101003214717", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Art" + }, + { + "10002": "4655.6219692230225", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "4655.6219692230225", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Art" + }, + { + "10002": "1058.5850008130074", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1058.5850008130074", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Art" + }, + { + "10002": "5765.340019583702", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "5765.340019583702", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Art" + }, + { + "10002": "1195.1630011796951", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1195.1630011796951", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Art" + }, + { + "10002": "7485.764034986496", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "7485.764034986496", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Art" + }, + { + "10002": "1899.942004531622", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1899.942004531622", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Art" + }, + { + "10002": "55961.11282122135", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "55961.11282122135", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Binders" + }, + { + "10002": "16096.799980849028", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "16096.799980849028", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Binders" + }, + { + "10002": "37030.34099626541", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "37030.34099626541", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Binders" + }, + { + "10002": "3900.6622482538223", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "3900.6622482538223", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Binders" + }, + { + "10002": "56923.28208118677", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "56923.28208118677", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Binders" + }, + { + "10002": "-1043.632896721363", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "-1043.632896721363", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Binders" + }, + { + "10002": "53497.99653959274", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "53497.99653959274", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Binders" + }, + { + "10002": "11267.932148218155", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "11267.932148218155", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Binders" + }, + { + "10002": "4118.099995136261", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "4118.099995136261", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Envelopes" + }, + { + "10002": "1908.761996269226", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1908.761996269226", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Envelopes" + }, + { + "10002": "3345.555993080139", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "3345.555993080139", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Envelopes" + }, + { + "10002": "1465.4750101566315", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1465.4750101566315", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Envelopes" + }, + { + "10002": "4636.871988296509", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "4636.871988296509", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Envelopes" + }, + { + "10002": "1777.5259877443314", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1777.5259877443314", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Envelopes" + }, + { + "10002": "4375.874011039734", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "4375.874011039734", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Envelopes" + }, + { + "10002": "1812.4089943170547", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1812.4089943170547", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Envelopes" + }, + { + "10002": "923.2159950733185", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "923.2159950733185", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Fasteners" + }, + { + "10002": "275.19199895858765", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "275.19199895858765", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Fasteners" + }, + { + "10002": "503.3160014152527", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "503.3160014152527", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Fasteners" + }, + { + "10002": "173.71899946779013", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "173.71899946779013", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Fasteners" + }, + { + "10002": "778.0299946069717", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "778.0299946069717", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Fasteners" + }, + { + "10002": "236.6199992671609", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "236.6199992671609", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Fasteners" + }, + { + "10002": "819.7179999351501", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "819.7179999351501", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Fasteners" + }, + { + "10002": "263.98999811708927", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "263.98999811708927", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Fasteners" + }, + { + "10002": "5078.726016759872", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "5078.726016759872", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Labels" + }, + { + "10002": "2303.1279985904694", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "2303.1279985904694", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Labels" + }, + { + "10002": "2353.179967880249", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "2353.179967880249", + "230627170530056": "Sales", + "230627170530059": "South", + "230627170530068": "Labels" + }, + { + "10002": "1040.771997153759", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1040.771997153759", + "230627170530056": "Profit", + "230627170530059": "South", + "230627170530068": "Labels" + }, + { + "10002": "2451.4719779491425", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "2451.4719779491425", + "230627170530056": "Sales", + "230627170530059": "Central", + "230627170530068": "Labels" + }, + { + "10002": "1073.0799936652184", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1073.0799936652184", + "230627170530056": "Profit", + "230627170530059": "Central", + "230627170530068": "Labels" + }, + { + "10002": "2602.934000492096", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "2602.934000492096", + "230627170530056": "Sales", + "230627170530059": "East", + "230627170530068": "Labels" + }, + { + "10002": "1129.2839995622635", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "1129.2839995622635", + "230627170530056": "Profit", + "230627170530059": "East", + "230627170530068": "Labels" + }, + { + "10002": "26663.717969417572", + "10003": "230627170530019", + "230627170530016": "Office Supplies", + "230627170530019": "26663.717969417572", + "230627170530056": "Sales", + "230627170530059": "West", + "230627170530068": "Paper" + }, + { + "10002": "12119.230026364326", + "10003": "230627170530022", + "230627170530016": "Office Supplies", + "230627170530022": "12119.230026364326", + "230627170530056": "Profit", + "230627170530059": "West", + "230627170530068": "Paper" + } +]; +const option = { + records:data, + rows: ["230627170530016","230627170530068"], + columns: [ "230627170530059"], + indicators: [ + { + "indicatorKey": "230627170530019", + "title": "Sales", + "width": "auto", + "showSort": false, + "headerStyle":{ + fontWeight: "normal", + }, + "format":(value)=>{ + if(value) + return '$'+Number(value).toFixed(2); + return ''; + }, + style:{ + padding:[16,28,16,28], + color(args){ + if(args.dataValue>=0) + return 'black'; + return 'red' + } + } + }, + { + "indicatorKey": "230627170530022", + "title": "Profit", + "width": "auto", + "showSort": false, + "headerStyle":{ + fontWeight: "normal", + }, + "format":(value)=>{ + if(value) + return '$'+Number(value).toFixed(2); + return ''; + }, + style:{ + padding:[16,28,16,28], + color(args){ + if(args.dataValue>=0) + return 'black'; + return 'red' + } + } + } + ], + "corner": { + "titleOnDimension": "row", + "headerStyle": { + "textStick": true + } + }, + widthMode:'standard', + enableDataAnalysis: true, + defaultHeaderColWidth:150, + rowHierarchyIndent: 20 +}; +const tableInstance = new VTable.PivotTable(document.getElementById(CONTAINER_ID), option); + +``` +## 示例:自定义行表头列表头树结构 +在下面示例中为了让表头各维度值的显示顺序符合需求,我们设置了rowTree和columnTree两个字段,分别表示行表头和列表头的树结构。可以看出和上面VTable分析出的树结构纬度值显示顺序的差别。 +- enableDataAnalysis需设置为false ```javascript livedemo template=vtable const data=[ @@ -771,22 +1584,22 @@ const option = { "children": [ { "dimensionKey": "230627170530068", - "value": "Bookcases", - hierarchyState: 'collapse', + "value": "Furnishings" }, { "dimensionKey": "230627170530068", - "value": "Chairs", - hierarchyState: 'collapse', + "value": "Tables" }, - { + { "dimensionKey": "230627170530068", - "value": "Furnishings" + "value": "Bookcases", + hierarchyState: 'collapse', }, { "dimensionKey": "230627170530068", - "value": "Tables" - } + "value": "Chairs", + hierarchyState: 'collapse', + }, ] }, { @@ -795,27 +1608,27 @@ const option = { "children": [ { "dimensionKey": "230627170530068", - "value": "Appliances" + "value": "Envelopes" }, { "dimensionKey": "230627170530068", - "value": "Art" + "value": "Fasteners" }, { "dimensionKey": "230627170530068", - "value": "Binders" + "value": "Labels" }, { "dimensionKey": "230627170530068", - "value": "Envelopes" + "value": "Appliances" }, { "dimensionKey": "230627170530068", - "value": "Fasteners" + "value": "Art" }, { "dimensionKey": "230627170530068", - "value": "Labels" + "value": "Binders" }, { "dimensionKey": "230627170530068", @@ -997,5 +1810,4 @@ const option = { }; const tableInstance = new VTable.PivotTable(document.getElementById(CONTAINER_ID), option); - ``` diff --git a/docs/assets/guide/zh/theme_and_style/style.md b/docs/assets/guide/zh/theme_and_style/style.md index 6dc0d45d7..f4d4ef94d 100644 --- a/docs/assets/guide/zh/theme_and_style/style.md +++ b/docs/assets/guide/zh/theme_and_style/style.md @@ -22,7 +22,7 @@ VTable 中单元格的style细化配置,包括单元格样式、表头单元 headerStyle: { bgColor: 'red', autoWrapText: true, - lineHeight: '2em', + lineHeight: 20, lineClamp: 'auto', textBaseline: "top", color:"yellow" @@ -49,7 +49,7 @@ VTable 中单元格的style细化配置,包括单元格样式、表头单元 style: { bgColor: 'green', autoWrapText: true, - lineHeight: '1em', + lineHeight: 20, lineClamp: 'auto', textBaseline: "top", color:"yellow" @@ -93,7 +93,7 @@ style 提供了一系列的单元格配置式,简要介绍如下。 ### 行高、换行设置 -* `lineHeight`:为单格设置行高 +* `lineHeight`:为单格内容设置文字行高 * `textOverflow`:设置文本的省略形式。如果 autoWrapText 设置自动换行,该配置无效 ### 下划线、划线设置 @@ -115,7 +115,9 @@ style 提供了一系列的单元格配置式,简要介绍如下。 ### 单元格标记 -`mark`:设置单元格是否有记样式 +`marked`:设置单元格是否有记样式 + +![image](https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/guide/cell-marked.jpeg) ### 自动换行 diff --git a/docs/assets/guide/zh/theme_and_style/theme.md b/docs/assets/guide/zh/theme_and_style/theme.md index 09aabcec5..3213f5cf5 100644 --- a/docs/assets/guide/zh/theme_and_style/theme.md +++ b/docs/assets/guide/zh/theme_and_style/theme.md @@ -121,7 +121,7 @@ const tableInstance = new vTable.ListTable(option); color: '#1B1F23', bgColor: '#EEF1F5', font: '500 12px PingFang SC', - lineHeight: '16px', + lineHeight: 16, borderColor: '#e1e4e8', padding: [8, 12, 8, 12], }, @@ -129,7 +129,7 @@ const tableInstance = new vTable.ListTable(option); color: '#1B1F23', bgColor: '#EEF1F5', font: '500 12px PingFang SC', - lineHeight: '16px', + lineHeight: 16, borderColor: '#e1e4e8', padding: [8, 12, 8, 12], hover: {//hover状态单元格样式 @@ -157,7 +157,7 @@ const tableInstance = new vTable.ListTable(option); } }, borderColor: '#e1e4e8', - lineHeight: '18px', + lineHeight: 18, hover: { cellBgColor: '#d6e6fe', inlineRowBgColor: '#F3F8FF', diff --git a/docs/assets/option/en/common/option-secondary.md b/docs/assets/option/en/common/option-secondary.md index dfaf00b75..89efdf5fb 100644 --- a/docs/assets/option/en/common/option-secondary.md +++ b/docs/assets/option/en/common/option-secondary.md @@ -26,7 +26,7 @@ The calculation mode of table row height, which can be 'standard' (standard mode - 'standard': use `defaultRowHeight` and `defaultHeaderRowHeight` as row height. - 'adaptive': Use the height of the container to assign the height of each row. -- 'autoHeight': Automatically calculate line height based on content, based on fontSize and lineHeight. The related collocation setting item `autoWrapText` automatically wraps the line, and the line height can be calculated according to the content of the multi-line text after the line wrap. +- 'autoHeight': Automatically calculate line height based on content, based on fontSize and lineHeight(font height),include padding. The related collocation setting item `autoWrapText` automatically wraps the line, and the line height can be calculated according to the content of the multi-line text after the line wrap. #${prefix} autoWrapText(boolean) = false diff --git a/docs/assets/option/en/common/style.md b/docs/assets/option/en/common/style.md index f1c9717bc..fbbb3f8c7 100644 --- a/docs/assets/option/en/common/style.md +++ b/docs/assets/option/en/common/style.md @@ -77,7 +77,7 @@ Set the border dashed style of the cell ) }} #${prefix} lineHeight(number) -Set the line height of the text content in the cell +Set the text font line height of the text content in the cell #${prefix} underline(UnderlinePropertyDefine) Set the underline for the text content of the cell diff --git a/docs/assets/option/zh/common/option-secondary.md b/docs/assets/option/zh/common/option-secondary.md index 6d5a8b288..e9bb49eeb 100644 --- a/docs/assets/option/zh/common/option-secondary.md +++ b/docs/assets/option/zh/common/option-secondary.md @@ -26,7 +26,7 @@ - 'standard':采用 `defaultRowHeight` 及 `defaultHeaderRowHeight` 作为行高。 - 'adaptive':使用容器的高度分配每行高度。 -- 'autoHeight':根据内容自动计算行高,计算依据 fontSize 和 lineHeight。相关搭配设置项`autoWrapText`自动换行,可以根据换行后的多行文本内容来计算行高。 +- 'autoHeight':根据内容自动计算行高,计算依据 fontSize 和 lineHeight(文字行高),以及padding。相关搭配设置项`autoWrapText`自动换行,可以根据换行后的多行文本内容来计算行高。 #${prefix} autoWrapText(boolean) = false diff --git a/docs/assets/option/zh/common/style.md b/docs/assets/option/zh/common/style.md index e1ac0a40e..8f5b54bdc 100644 --- a/docs/assets/option/zh/common/style.md +++ b/docs/assets/option/zh/common/style.md @@ -78,7 +78,7 @@ ) }} #${prefix} lineHeight(number) -为单元格文本内容设置行高 +为单元格文本内容设置文字行高 #${prefix} underline(UnderlinePropertyDefine) 为单元格文本内容设置下划线 diff --git a/docs/assets/option/zh/custom-element/text-custom-element.md b/docs/assets/option/zh/custom-element/text-custom-element.md index cc5acbfa3..2f919fda5 100644 --- a/docs/assets/option/zh/custom-element/text-custom-element.md +++ b/docs/assets/option/zh/custom-element/text-custom-element.md @@ -70,7 +70,7 @@ type TextBaselineType = 'top' | 'middle' | 'bottom' | 'alphabetic'; ${prefix} lineHeight (number) -文本行高。 +文字行高。 ${prefix} underline (number) diff --git a/packages/react-vtable/package.json b/packages/react-vtable/package.json index f211d5b88..bc4fe798c 100644 --- a/packages/react-vtable/package.json +++ b/packages/react-vtable/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/react-vtable", - "version": "0.15.5", + "version": "0.16.0", "description": "The react version of VTable", "keywords": [ "react", @@ -96,4 +96,4 @@ "axios": "^1.4.0", "@types/react-is": "^17.0.3" } -} +} \ No newline at end of file diff --git a/packages/vtable-editors/package.json b/packages/vtable-editors/package.json index 2770f8bb6..7dbe32cfd 100644 --- a/packages/vtable-editors/package.json +++ b/packages/vtable-editors/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/vtable-editors", - "version": "0.15.5", + "version": "0.16.0", "description": "", "sideEffects": false, "main": "cjs/index.js", @@ -65,4 +65,4 @@ "name": "VisActor", "url": "https://www.visactor.io/" } -} +} \ No newline at end of file diff --git a/packages/vtable/CHANGELOG.json b/packages/vtable/CHANGELOG.json index 1c8873989..362c315eb 100644 --- a/packages/vtable/CHANGELOG.json +++ b/packages/vtable/CHANGELOG.json @@ -2,14 +2,20 @@ "name": "@visactor/vtable", "entries": [ { - "version": "0.15.5", - "tag": "@visactor/vtable_v0.15.5", - "date": "Fri, 08 Dec 2023 09:17:16 GMT", + "version": "0.16.0", + "tag": "@visactor/vtable_v0.16.0", + "date": "Fri, 08 Dec 2023 09:27:10 GMT", "comments": { "none": [ { "comment": "fix: updateOption to update updateEventBinder\n\n" }, + { + "comment": "fix: columnResizeType: all invalid\n\n" + }, + { + "comment": "docs: refix lineheight description\n\n" + }, { "comment": "fix: fix tree structure bottom frozen update" }, @@ -37,6 +43,14 @@ { "comment": "feat: overlay default and hover colors" } + ], + "minor": [ + { + "comment": "feat: add api addRecords\n\n" + }, + { + "comment": "feat: add api delRecords\n\n" + } ] } }, @@ -606,4 +620,4 @@ } } ] -} +} \ No newline at end of file diff --git a/packages/vtable/CHANGELOG.md b/packages/vtable/CHANGELOG.md index e00f13dfb..17d553192 100644 --- a/packages/vtable/CHANGELOG.md +++ b/packages/vtable/CHANGELOG.md @@ -1,5 +1,18 @@ # Change Log - @visactor/vtable +This log was last generated on Fri, 08 Dec 2023 09:27:10 GMT and should not be manually modified. + +## 0.16.0 +Fri, 08 Dec 2023 09:27:10 GMT + +### Minor changes + +- feat: add api addRecords + + +- feat: add api delRecords + + This log was last generated on Fri, 08 Dec 2023 09:17:16 GMT and should not be manually modified. ## 0.15.5 @@ -8,8 +21,8 @@ Fri, 08 Dec 2023 09:17:16 GMT ### Updates - fix: updateOption to update updateEventBinder - - +- fix: columnResizeType: all invalid +- docs: refix lineheight description - fix: fix tree structure bottom frozen update - feat: axis support chart padding config - fix: fix limit column width adaptive update diff --git a/packages/vtable/examples/list/list-add-records.ts b/packages/vtable/examples/list/list-add-records.ts new file mode 100644 index 000000000..87d5f790a --- /dev/null +++ b/packages/vtable/examples/list/list-add-records.ts @@ -0,0 +1,102 @@ +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) => ({ + 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' : 'girl', + work: i % 2 === 0 ? 'back-end engineer' : 'front-end engineer', + city: 'beijing' + })); +}; + +export function createTable() { + const records = generatePersons(20); + const columns: VTable.ColumnsDefine = [ + { + field: '', + title: '行号', + width: 80, + fieldFormat(data, col, row, table) { + return row - 1; + } + }, + { + field: 'id', + title: 'ID', + width: '1%', + minWidth: 200, + sort: true + }, + { + field: 'email1', + title: 'email', + width: 200, + sort: true + }, + { + title: 'full name', + columns: [ + { + field: 'name', + title: 'First Name', + width: 200 + }, + { + field: 'name', + title: 'Last Name', + width: 200 + } + ] + }, + + { + field: 'tel', + title: 'telephone', + width: 150 + }, + { + field: 'work', + title: 'job', + width: 200 + }, + { + field: 'city', + title: 'city', + width: 150 + } + ]; + const option = { + container: document.getElementById(CONTAINER_ID), + records, + columns, + tooltip: { + isShowOverflowTextTooltip: true + }, + pagination: { + perPageCount: 10, + currentPage: 0 + } + // bottomFrozenRowCount: 1 + // autoWrapText: true, + // heightMode: 'autoHeight', + // widthMode: 'adaptive' + }; + const tableInstance = new VTable.ListTable(option); + window.tableInstance = tableInstance; + // tableInstance.on('sort_click', args => { + // tableInstance.updateSortState( + // { + // field: args.field, + // order: Date.now() % 3 === 0 ? 'desc' : Date.now() % 3 === 1 ? 'asc' : 'normal' + // }, + // false + // ); + // return false; //return false代表不执行内部排序逻辑 + // }); +} diff --git a/packages/vtable/examples/menu.ts b/packages/vtable/examples/menu.ts index 56d5465b6..3117ef1fb 100644 --- a/packages/vtable/examples/menu.ts +++ b/packages/vtable/examples/menu.ts @@ -27,6 +27,10 @@ export const menus = [ path: 'list', name: 'list-transpose' }, + { + path: 'list', + name: 'list-add-records' + }, { path: 'list', name: 'list-transpose-autoFillWidth' diff --git a/packages/vtable/examples/pivot-analysis/pivot-analysis.ts b/packages/vtable/examples/pivot-analysis/pivot-analysis.ts index 6092cf086..82ca87e48 100644 --- a/packages/vtable/examples/pivot-analysis/pivot-analysis.ts +++ b/packages/vtable/examples/pivot-analysis/pivot-analysis.ts @@ -11,6 +11,7 @@ export function createTable() { indicatorTitle: '指标名称', indicatorsAsCol: false, corner: { titleOnDimension: 'row' }, + columnResizeType: 'all', records: [ { sales: 891, diff --git a/packages/vtable/package.json b/packages/vtable/package.json index 5ef8b8e79..cf67de91a 100644 --- a/packages/vtable/package.json +++ b/packages/vtable/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/vtable", - "version": "0.15.5", + "version": "0.16.0", "description": "canvas table width high performance", "keywords": [ "grid", @@ -123,4 +123,4 @@ "url": "https://github.com/VisActor/VTable.git", "directory": "packages/vtable" } -} +} \ No newline at end of file diff --git a/packages/vtable/src/ListTable.ts b/packages/vtable/src/ListTable.ts index 84ac5f95b..d642feec6 100644 --- a/packages/vtable/src/ListTable.ts +++ b/packages/vtable/src/ListTable.ts @@ -17,7 +17,7 @@ import type { import { HierarchyState } from './ts-types'; import { SimpleHeaderLayoutMap } from './layout'; import { isValid } from '@visactor/vutils'; -import { _setDataSource, _setRecords } from './core/tableHelper'; +import { _setDataSource, _setRecords, sortRecords } from './core/tableHelper'; import { BaseTable } from './core'; import type { ListTableProtected } from './ts-types/base-table'; import { TABLE_EVENT_TYPE } from './core/TABLE_EVENT_TYPE'; @@ -230,8 +230,8 @@ export class ListTable extends BaseTable implements ListTableAPI { const { field } = table.internalProps.layoutMap.getBody(col, row); return table.getRawFieldData(field, col, row); } - /** @private */ - getRecordIndexByCell(col: number, row: number): number { + /** 获取当前单元格在body部分的展示索引(row / col-headerLevelCount)。注:ListTable特有接口 */ + getRecordShowIndexByCell(col: number, row: number): number { const { layoutMap } = this.internalProps; return layoutMap.getRecordIndexByCell(col, row); } @@ -270,7 +270,7 @@ export class ListTable extends BaseTable implements ListTableAPI { */ getCellOriginRecord(col: number, row: number): MaybePromiseOrUndefined { const table = this; - const index = table.getRecordIndexByCell(col, row); + const index = table.getRecordShowIndexByCell(col, row); if (index > -1) { return table.dataSource.get(index); } @@ -284,7 +284,7 @@ export class ListTable extends BaseTable implements ListTableAPI { */ getCellRawRecord(col: number, row: number): MaybePromiseOrUndefined { const table = this; - const index = table.getRecordIndexByCell(col, row); + const index = table.getRecordShowIndexByCell(col, row); if (index > -1) { return table.dataSource.getRaw(index); } @@ -428,6 +428,9 @@ export class ListTable extends BaseTable implements ListTableAPI { table.frozenRowCount = 0; // table.frozenColCount = layoutMap.headerLevelCount; //这里不要这样写 这个setter会检查扁头宽度 可能将frozenColCount置为0 this.internalProps.frozenColCount = layoutMap.headerLevelCount ?? 0; + if (table.bottomFrozenRowCount !== (this.options.bottomFrozenRowCount ?? 0)) { + table.bottomFrozenRowCount = this.options.bottomFrozenRowCount ?? 0; + } if (table.rightFrozenColCount !== (this.options.rightFrozenColCount ?? 0)) { table.rightFrozenColCount = this.options.rightFrozenColCount ?? 0; } @@ -463,7 +466,7 @@ export class ListTable extends BaseTable implements ListTableAPI { if (table.internalProps.layoutMap.isHeader(col, row)) { return null; } - const index = table.getRecordIndexByCell(col, row); + const index = table.getRecordShowIndexByCell(col, row); return table.internalProps.dataSource.getField(index, field, col, row, this); } /** @@ -481,7 +484,7 @@ export class ListTable extends BaseTable implements ListTableAPI { if (table.internalProps.layoutMap.isHeader(col, row)) { return null; } - const index = table.getRecordIndexByCell(col, row); + const index = table.getRecordShowIndexByCell(col, row); return table.internalProps.dataSource.getRawField(index, field, col, row, this); } /** @@ -617,7 +620,7 @@ export class ListTable extends BaseTable implements ListTableAPI { if (!define.tree) { return HierarchyState.none; } - const index = this.getRecordIndexByCell(col, row); + const index = this.getRecordShowIndexByCell(col, row); return this.dataSource.getHierarchyState(index); } /** @@ -637,6 +640,7 @@ export class ListTable extends BaseTable implements ListTableAPI { } else if (hierarchyState === HierarchyState.collapse) { const record = this.getCellOriginRecord(col, row); if (Array.isArray(record.children)) { + //children 是数组 表示已经有子树节点信息 this._refreshHierarchyState(col, row); } this.fireListeners(TABLE_EVENT_TYPE.TREE_HIERARCHY_STATE_CHANGE, { @@ -649,7 +653,7 @@ export class ListTable extends BaseTable implements ListTableAPI { } /** 刷新当前节点收起展开状态,如手动更改过 */ _refreshHierarchyState(col: number, row: number) { - const index = this.getRecordIndexByCell(col, row); + const index = this.getRecordShowIndexByCell(col, row); const diffDataIndices = this.dataSource.toggleHierarchyState(index); const diffPositions = this.internalProps.layoutMap.toggleHierarchyState(diffDataIndices); //影响行数 @@ -672,7 +676,7 @@ export class ListTable extends BaseTable implements ListTableAPI { }; return result; } - protected _getSortFuncFromHeaderOption( + _getSortFuncFromHeaderOption( columns: ColumnsDefine | undefined, field: FieldDef, fieldKey?: FieldKeyDef @@ -766,7 +770,7 @@ export class ListTable extends BaseTable implements ListTableAPI { const field = define?.field; const cellType = define?.cellType; if (isValid(field) && cellType === 'checkbox') { - const dataIndex = this.dataSource.getIndexKey(this.getRecordIndexByCell(col, row)); + const dataIndex = this.dataSource.getIndexKey(this.getRecordShowIndexByCell(col, row)); return this.stateManager.checkedState[dataIndex as number][field as string | number]; } return undefined; @@ -840,7 +844,7 @@ export class ListTable extends BaseTable implements ListTableAPI { setRecordChildren(records: any[], col: number, row: number) { const record = this.getCellOriginRecord(col, row); record.children = records; - const index = this.getRecordIndexByCell(col, row); + const index = this.getRecordShowIndexByCell(col, row); this.dataSource.setRecord(record, index); this._refreshHierarchyState(col, row); } @@ -881,7 +885,7 @@ export class ListTable extends BaseTable implements ListTableAPI { } /** 更改单元格数据 会触发change_cell_value事件*/ changeCellValue(col: number, row: number, value: string | number | null) { - const recordIndex = this.getRecordIndexByCell(col, row); + const recordIndex = this.getRecordShowIndexByCell(col, row); const { field } = this.internalProps.layoutMap.getBody(col, row); this.dataSource.changeFieldValue(value, recordIndex, field, col, row, this); // const cell_value = this.getCellValue(col, row); @@ -913,4 +917,256 @@ export class ListTable extends BaseTable implements ListTableAPI { }); this.scenegraph.updateNextFrame(); } + /** + * 添加数据 单条数据 + * @param record 数据 + * @param recordIndex 向数据源中要插入的位置,从0开始。不设置recordIndex的话 默认追加到最后。 + * 如果设置了排序规则recordIndex无效,会自动适应排序逻辑确定插入顺序。 + * recordIndex 可以通过接口getRecordShowIndexByCell获取 + */ + addRecord(record: any, recordIndex?: number) { + if (this.sortState) { + this.dataSource.addRecordForSorted(record); + sortRecords(this); + this.refreshRowColCount(); + // 更新整个场景树 + this.scenegraph.clearCells(); + this.scenegraph.createSceneGraph(); + } else { + if (recordIndex === undefined || recordIndex > this.dataSource.sourceLength) { + recordIndex = this.dataSource.sourceLength; + } + const headerCount = this.transpose ? this.rowHeaderLevelCount : this.columnHeaderLevelCount; + this.dataSource.addRecord(record, recordIndex); + const oldRowCount = this.rowCount; + this.refreshRowColCount(); + const newRowCount = this.transpose ? this.colCount : this.rowCount; + if (this.pagination) { + const { perPageCount, currentPage } = this.pagination; + const startIndex = perPageCount * (currentPage || 0); + const endIndex = startIndex + perPageCount; + if (recordIndex < endIndex) { + //插入当前页或者前面的数据才需要更新 如果是插入的是当前页后面的数据不需要更新场景树 + if (recordIndex < endIndex - perPageCount) { + // 如果是当页之前的数据 则整个场景树都更新 + this.scenegraph.clearCells(); + this.scenegraph.createSceneGraph(); + } else { + //如果是插入当前页数据 + const rowNum = recordIndex - (endIndex - perPageCount) + headerCount; + if (oldRowCount - headerCount === this.pagination.perPageCount) { + //如果当页数据是满的 则更新插入的部分行 + const updateRows = []; + for (let row = rowNum; row < newRowCount; row++) { + if (this.transpose) { + updateRows.push({ col: row, row: 0 }); + } else { + updateRows.push({ col: 0, row }); + } + } + this.transpose + ? this.scenegraph.updateCol([], [], updateRows) + : this.scenegraph.updateRow([], [], updateRows); + } else { + //如果当页数据不是满的 则插入新数据 + const addRows = []; + for (let row = rowNum; row < Math.min(newRowCount, rowNum + 1); row++) { + if (this.transpose) { + addRows.push({ col: row, row: 0 }); + } else { + addRows.push({ col: 0, row }); + } + } + this.transpose ? this.scenegraph.updateCol([], addRows, []) : this.scenegraph.updateRow([], addRows, []); + } + } + } + } else { + const addRows = []; + for (let row = recordIndex + headerCount; row < recordIndex + headerCount + 1; row++) { + if (this.transpose) { + addRows.push({ col: row, row: 0 }); + } else { + addRows.push({ col: 0, row }); + } + } + this.transpose ? this.scenegraph.updateCol([], addRows, []) : this.scenegraph.updateRow([], addRows, []); + } + } + // this.fireListeners(TABLE_EVENT_TYPE.ADD_RECORD, { row }); + } + + /** + * 添加数据 支持多条数据 + * @param records 多条数据 + * @param recordIndex 向数据源中要插入的位置,从0开始。不设置recordIndex的话 默认追加到最后。 + * 如果设置了排序规则recordIndex无效,会自动适应排序逻辑确定插入顺序。 + * recordIndex 可以通过接口getRecordShowIndexByCell获取 + */ + addRecords(records: any[], recordIndex?: number) { + if (this.sortState) { + this.dataSource.addRecordsForSorted(records); + sortRecords(this); + this.refreshRowColCount(); + // 更新整个场景树 + this.scenegraph.clearCells(); + this.scenegraph.createSceneGraph(); + } else { + if (recordIndex === undefined || recordIndex > this.dataSource.sourceLength) { + recordIndex = this.dataSource.sourceLength; + } else if (recordIndex < 0) { + recordIndex = 0; + } + const headerCount = this.transpose ? this.rowHeaderLevelCount : this.columnHeaderLevelCount; + this.dataSource.addRecords(records, recordIndex); + const oldRowCount = this.transpose ? this.colCount : this.rowCount; + this.refreshRowColCount(); + const newRowCount = this.transpose ? this.colCount : this.rowCount; + if (this.pagination) { + const { perPageCount, currentPage } = this.pagination; + const startIndex = perPageCount * (currentPage || 0); + const endIndex = startIndex + perPageCount; + if (recordIndex < endIndex) { + //插入当前页或者前面的数据才需要更新 如果是插入的是当前页后面的数据不需要更新场景树 + if (recordIndex < endIndex - perPageCount) { + // 如果是当页之前的数据 则整个场景树都更新 + this.scenegraph.clearCells(); + this.scenegraph.createSceneGraph(); + } else { + //如果是插入当前页数据 + + const rowNum = recordIndex - (endIndex - perPageCount) + headerCount; + if (oldRowCount - headerCount === this.pagination.perPageCount) { + //如果当页数据是满的 则更新插入的部分行 + const updateRows = []; + for (let row = rowNum; row < newRowCount; row++) { + if (this.transpose) { + updateRows.push({ col: row, row: 0 }); + } else { + updateRows.push({ col: 0, row }); + } + } + this.transpose + ? this.scenegraph.updateCol([], [], updateRows) + : this.scenegraph.updateRow([], [], updateRows); + } else { + //如果当页数据不是满的 则插入新数据 + const addRows = []; + for ( + let row = rowNum; + row < Math.min(newRowCount, rowNum + (Array.isArray(records) ? records.length : 1)); + row++ + ) { + if (this.transpose) { + addRows.push({ col: row, row: 0 }); + } else { + addRows.push({ col: 0, row }); + } + } + this.transpose ? this.scenegraph.updateCol([], addRows, []) : this.scenegraph.updateRow([], addRows, []); + } + } + } + } else { + const addRows = []; + for ( + let row = recordIndex + headerCount; + row < recordIndex + headerCount + (Array.isArray(records) ? records.length : 1); + row++ + ) { + if (this.transpose) { + addRows.push({ col: row, row: 0 }); + } else { + addRows.push({ col: 0, row }); + } + } + this.transpose ? this.scenegraph.updateCol([], addRows, []) : this.scenegraph.updateRow([], addRows, []); + } + } + // this.fireListeners(TABLE_EVENT_TYPE.ADD_RECORD, { row }); + } + + /** + * 删除数据 支持多条数据 + * @param recordIndexs 要删除数据的索引(显示到body中的条目索引) + */ + deleteRecords(recordIndexs: number[]) { + if (recordIndexs?.length > 0) { + if (this.sortState) { + this.dataSource.deleteRecordsForSorted(recordIndexs); + sortRecords(this); + this.refreshRowColCount(); + // 更新整个场景树 + this.scenegraph.clearCells(); + this.scenegraph.createSceneGraph(); + } else { + const deletedRecordIndexs = this.dataSource.deleteRecords(recordIndexs); + if (deletedRecordIndexs.length === 0) { + return; + } + const oldRowCount = this.transpose ? this.colCount : this.rowCount; + this.refreshRowColCount(); + const newRowCount = this.transpose ? this.colCount : this.rowCount; + const recordIndexsMinToMax = deletedRecordIndexs.sort((a, b) => a - b); + const minRecordIndex = recordIndexsMinToMax[0]; + if (this.pagination) { + const { perPageCount, currentPage } = this.pagination; + const startIndex = perPageCount * (currentPage || 0); + const endIndex = startIndex + perPageCount; + if (minRecordIndex < endIndex) { + //删除当前页或者前面的数据才需要更新 如果是删除的是当前页后面的数据不需要更新场景树 + if (minRecordIndex < endIndex - perPageCount) { + // 如果删除包含当页之前的数据 则整个场景树都更新 + this.scenegraph.clearCells(); + this.scenegraph.createSceneGraph(); + } else { + //如果是仅删除当前页数据 + const minRowNum = + minRecordIndex - + (endIndex - perPageCount) + + (this.transpose ? this.rowHeaderLevelCount : this.columnHeaderLevelCount); + //如果当页数据是满的 则更新影响的部分行 + const updateRows = []; + const delRows = []; + + for (let row = minRowNum; row < newRowCount; row++) { + if (this.transpose) { + updateRows.push({ col: row, row: 0 }); + } else { + updateRows.push({ col: 0, row }); + } + } + if (newRowCount < oldRowCount) { + //如果如果删除后不满 需要有删除数据 + for (let row = newRowCount; row < oldRowCount; row++) { + if (this.transpose) { + delRows.push({ col: row, row: 0 }); + } else { + delRows.push({ col: 0, row }); + } + } + } + this.transpose + ? this.scenegraph.updateCol(delRows, [], updateRows) + : this.scenegraph.updateRow(delRows, [], updateRows); + } + } + } else { + const delRows = []; + + for (let index = 0; index < recordIndexsMinToMax.length; index++) { + const recordIndex = recordIndexsMinToMax[index]; + const rowNum = recordIndex + (this.transpose ? this.rowHeaderLevelCount : this.columnHeaderLevelCount); + if (this.transpose) { + delRows.push({ col: rowNum, row: 0 }); + } else { + delRows.push({ col: 0, row: rowNum }); + } + } + this.transpose ? this.scenegraph.updateCol(delRows, [], []) : this.scenegraph.updateRow(delRows, [], []); + } + } + // this.fireListeners(TABLE_EVENT_TYPE.ADD_RECORD, { row }); + } + } } diff --git a/packages/vtable/src/PivotChart.ts b/packages/vtable/src/PivotChart.ts index 0c86e22d8..2d417c85d 100644 --- a/packages/vtable/src/PivotChart.ts +++ b/packages/vtable/src/PivotChart.ts @@ -342,7 +342,7 @@ export class PivotChart extends BaseTable implements PivotChartAPI { }); } } - getRecordIndexByCell(col: number, row: number): number { + getRecordShowIndexByCell(col: number, row: number): number { return undefined; } diff --git a/packages/vtable/src/PivotTable.ts b/packages/vtable/src/PivotTable.ts index bd8318030..f663729fd 100644 --- a/packages/vtable/src/PivotTable.ts +++ b/packages/vtable/src/PivotTable.ts @@ -455,7 +455,7 @@ export class PivotTable extends BaseTable implements PivotTableAPI { }); } } - getRecordIndexByCell(col: number, row: number): number { + getRecordShowIndexByCell(col: number, row: number): number { return undefined; } getTableIndexByRecordIndex(recordIndex: number): number { diff --git a/packages/vtable/src/components/menu/dom/logic/MenuElement.ts b/packages/vtable/src/components/menu/dom/logic/MenuElement.ts index 0e84a54a1..6e82511c2 100644 --- a/packages/vtable/src/components/menu/dom/logic/MenuElement.ts +++ b/packages/vtable/src/components/menu/dom/logic/MenuElement.ts @@ -501,7 +501,7 @@ export class MenuElement { // 检测下方能否容纳,不能容纳向上偏移 if (rootElementTop + rootElementHeight > containerHeight) { rootElementTop = containerHeight - rootElementHeight; - rootElementLeft += rootElementWidth - 2; + // rootElementLeft += rootElementWidth - 2; } // 偏移后上方超出canvas范围,居中显示 if (rootElementTop < 0) { diff --git a/packages/vtable/src/core/BaseTable.ts b/packages/vtable/src/core/BaseTable.ts index fc29b380a..73efb4efa 100644 --- a/packages/vtable/src/core/BaseTable.ts +++ b/packages/vtable/src/core/BaseTable.ts @@ -1951,7 +1951,7 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { internalProps.title?.release(); internalProps.layoutMap.release(); this.scenegraph.clearCells(); - this.stateManager.initState(); + this.stateManager.updateOptionSetState(); this._updateSize(); // this.stateManager = new StateManager(this); @@ -2368,7 +2368,7 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { abstract moveHeaderPosition(source: CellAddress, target: CellAddress): boolean; /** @private */ // abstract getFieldData(field: FieldDef | FieldFormat | undefined, col: number, row: number): FieldData; - abstract getRecordIndexByCell(col: number, row: number): number; + abstract getRecordShowIndexByCell(col: number, row: number): number; abstract getCellOriginRecord(col: number, row: number): MaybePromiseOrUndefined; abstract getCellRawRecord(col: number, row: number): MaybePromiseOrUndefined; abstract getCellValue(col: number, row: number): FieldData; @@ -2579,7 +2579,7 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { if (this.internalProps.layoutMap.isHeader(col, row)) { return undefined; } - return this.internalProps.dataSource?.get(this.getRecordIndexByCell(col, row)); + return this.internalProps.dataSource?.get(this.getRecordShowIndexByCell(col, row)); } /** @deprecated 请使用getRecordByCell */ getRecordByRowCol(col: number, row: number) { @@ -2802,7 +2802,7 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI { if (table.internalProps.layoutMap.isHeader(col, row)) { return false; } - const index = table.getRecordIndexByCell(col, row); + const index = table.getRecordShowIndexByCell(col, row); return table.internalProps.dataSource.hasField(index, field); } /** diff --git a/packages/vtable/src/core/tableHelper.ts b/packages/vtable/src/core/tableHelper.ts index fd19bfdad..07ca27bab 100644 --- a/packages/vtable/src/core/tableHelper.ts +++ b/packages/vtable/src/core/tableHelper.ts @@ -5,8 +5,10 @@ import { parseFont } from '../scenegraph/utils/font'; import { getQuadProps } from '../scenegraph/utils/padding'; import { Rect } from '../tools/Rect'; import * as calc from '../tools/calc'; -import type { FullExtendStyle } from '../ts-types'; +import type { FullExtendStyle, SortState } from '../ts-types'; import type { BaseTableAPI } from '../ts-types/base-table'; +import { defaultOrderFn } from '../tools/util'; +import type { ListTable } from '../ListTable'; export function createRootElement(padding: any): HTMLElement { const element = document.createElement('div'); @@ -304,3 +306,31 @@ export function getStyleTheme( hasFunctionPros }; } + +export function sortRecords(table: ListTable) { + if ((table as any).sortState) { + let order: any; + let field: any; + let fieldKey: any; + if (Array.isArray((table as any).sortState)) { + if ((table as any).sortState.length !== 0) { + ({ order, field, fieldKey } = (table as any).sortState?.[0]); + } + } else { + ({ order, field, fieldKey } = (table as any).sortState as SortState); + } + // 根据sort规则进行排序 + if (order && field && order !== 'normal') { + const sortFunc = table._getSortFuncFromHeaderOption(undefined, field, fieldKey); + // 如果sort传入的信息不能生成正确的sortFunc,直接更新表格,避免首次加载无法正常显示内容 + let hd; + if (fieldKey) { + hd = table.internalProps.layoutMap.headerObjects.find((col: any) => col && col.fieldKey === fieldKey); + } else { + hd = table.internalProps.layoutMap.headerObjects.find((col: any) => col && col.field === field); + } + // hd?.define?.sort && //如果这里也判断 那想要利用sortState来排序 但不显示排序图标就实现不了 + table.dataSource.sort(hd.field, order, sortFunc ?? defaultOrderFn); + } + } +} diff --git a/packages/vtable/src/data/DataSource.ts b/packages/vtable/src/data/DataSource.ts index 9eb7de78d..7bd5b5d44 100644 --- a/packages/vtable/src/data/DataSource.ts +++ b/packages/vtable/src/data/DataSource.ts @@ -141,8 +141,11 @@ export class DataSource extends EventTarget implements DataSourceAPI { private lastOrder: SortOrder; private lastOrderFn: (a: any, b: any, order: string) => number; private lastOrderField: FieldDef; + /** 每一行对应源数据的索引 */ protected currentIndexedData: (number | number[])[] | null = []; + protected userPagination: IPagination; protected pagination: IPagination; + /** 当前页每一行对应源数据的索引 */ protected _currentPagerIndexedData: (number | number[])[]; // 当前是否为层级的树形结构 排序时判断该值确实是否继续进行子节点排序 enableHierarchyState = false; @@ -160,6 +163,7 @@ export class DataSource extends EventTarget implements DataSourceAPI { this.sortedIndexMap = new Map(); this._currentPagerIndexedData = []; + this.userPagination = pagination; this.pagination = pagination || { totalCount: this._sourceLength, perPageCount: this._sourceLength, @@ -495,6 +499,143 @@ export class DataSource extends EventTarget implements DataSourceAPI { (p_node as any).children.splice(c_node_index, 1, record); } } + /** + * 将单条数据record 添加到index位置处 + * @param record 被添加的单条数据 + * @param index 代表的数据源中的index + */ + addRecord(record: any, index: number) { + this.source.splice(index, 0, record); + this.currentIndexedData.push(this.currentIndexedData.length); + this._sourceLength += 1; + + if (this.userPagination) { + //如果用户配置了分页 + this.pagination.totalCount = this._sourceLength; + const { perPageCount, currentPage } = this.pagination; + const startIndex = perPageCount * (currentPage || 0); + const endIndex = startIndex + perPageCount; + if (index < endIndex) { + this.updatePagerData(); + } + } else { + this.pagination.perPageCount = this._sourceLength; + this.pagination.totalCount = this._sourceLength; + this.updatePagerData(); + } + } + /** + * 将多条数据recordArr 依次添加到index位置处 + * @param recordArr + * @param index 代表的数据源中的index + */ + addRecords(recordArr: any, index: number) { + if (Array.isArray(recordArr)) { + this.source.splice(index, 0, ...recordArr); + for (let i = 0; i < recordArr.length; i++) { + this.currentIndexedData.push(this.currentIndexedData.length); + } + this._sourceLength += recordArr.length; + } + + if (this.userPagination) { + //如果用户配置了分页 + this.pagination.totalCount = this._sourceLength; + const { perPageCount, currentPage } = this.pagination; + const startIndex = perPageCount * (currentPage || 0); + const endIndex = startIndex + perPageCount; + if (index < endIndex) { + this.updatePagerData(); + } + } else { + this.pagination.perPageCount = this._sourceLength; + this.pagination.totalCount = this._sourceLength; + this.updatePagerData(); + } + } + + /** + * 将单条数据record 添加到index位置处 + * @param record 被添加的单条数据 + * @param index 代表的数据源中的index + */ + addRecordForSorted(record: any) { + this.source.push(record); + this.currentIndexedData.push(this.currentIndexedData.length); + this._sourceLength += 1; + this.sortedIndexMap.clear(); + if (!this.userPagination) { + this.pagination.perPageCount = this._sourceLength; + this.pagination.totalCount = this._sourceLength; + } + } + /** + * 将多条数据recordArr 依次添加到index位置处 + * @param recordArr + * @param index 代表的数据源中的index + */ + addRecordsForSorted(recordArr: any) { + if (Array.isArray(recordArr)) { + this.source.push(...recordArr); + for (let i = 0; i < recordArr.length; i++) { + this.currentIndexedData.push(this.currentIndexedData.length); + } + this._sourceLength += recordArr.length; + this.sortedIndexMap.clear(); + } + if (!this.userPagination) { + this.pagination.perPageCount = this._sourceLength; + this.pagination.totalCount = this._sourceLength; + } + } + /** + * 删除多条数据recordIndexs + */ + deleteRecordsForSorted(recordIndexs: number[]) { + const recordIndexsMaxToMin = recordIndexs.sort((a, b) => b - a); + for (let index = 0; index < recordIndexsMaxToMin.length; index++) { + const recordIndex = recordIndexsMaxToMin[index]; + if (recordIndex >= this._sourceLength || recordIndex < 0) { + continue; + } + const rawIndex = this.currentIndexedData[recordIndex]; + this.source.splice(rawIndex, 1); + this._sourceLength -= 1; + } + this.sortedIndexMap.clear(); + if (!this.userPagination) { + this.pagination.perPageCount = this._sourceLength; + this.pagination.totalCount = this._sourceLength; + } + } + + /** + * 删除多条数据recordIndexs + */ + deleteRecords(recordIndexs: number[]) { + const realDeletedRecordIndexs = []; + const recordIndexsMaxToMin = recordIndexs.sort((a, b) => b - a); + for (let index = 0; index < recordIndexsMaxToMin.length; index++) { + const recordIndex = recordIndexsMaxToMin[index]; + if (recordIndex >= this._sourceLength || recordIndex < 0) { + continue; + } + realDeletedRecordIndexs.push(recordIndex); + this.source.splice(recordIndex, 1); + this.currentIndexedData.pop(); + this._sourceLength -= 1; + } + if (this.userPagination) { + // 如果用户配置了分页 + this.updatePagerData(); + } else { + this.pagination.perPageCount = this._sourceLength; + this.pagination.totalCount = this._sourceLength; + this.updatePagerData(); + } + return realDeletedRecordIndexs; + } + sort( field: FieldDef, order: SortOrder, @@ -577,7 +718,7 @@ export class DataSource extends EventTarget implements DataSourceAPI { }); } } - get sourceLenght(): number { + get sourceLength(): number { return this._sourceLength; } set sourceLength(sourceLen: number) { diff --git a/packages/vtable/src/scenegraph/group-creater/column.ts b/packages/vtable/src/scenegraph/group-creater/column.ts index 0ad6cd944..4e8390a62 100644 --- a/packages/vtable/src/scenegraph/group-creater/column.ts +++ b/packages/vtable/src/scenegraph/group-creater/column.ts @@ -4,98 +4,98 @@ import type { BaseTableAPI } from '../../ts-types/base-table'; import { Group } from '../graphic/group'; import { createComplexColumn } from './column-helper'; -/** - * @description: 处理全部角表头 - * @param {Group} colHeaderGroup 列表头容器Group - * @param {number} xOrigin x起始坐标 - * @param {number} yOrigin y起始坐标 - * @param {BaseTableAPI} table - * @return {*} - */ -export function createCornerHeaderColGroup( - cornerHeaderGroup: Group, - xOrigin: number, - yOrigin: number, - table: BaseTableAPI -) { - createColGroup( - cornerHeaderGroup, - xOrigin, - yOrigin, - 0, // colStart - table.rowHeaderLevelCount - 1, // colEnd - 0, // rowStart - table.columnHeaderLevelCount - 1, // rowEnd - 'cornerHeader', // CellType - table - ); -} +// /** +// * @description: 处理全部角表头 +// * @param {Group} colHeaderGroup 列表头容器Group +// * @param {number} xOrigin x起始坐标 +// * @param {number} yOrigin y起始坐标 +// * @param {BaseTableAPI} table +// * @return {*} +// */ +// export function createCornerHeaderColGroup( +// cornerHeaderGroup: Group, +// xOrigin: number, +// yOrigin: number, +// table: BaseTableAPI +// ) { +// createColGroup( +// cornerHeaderGroup, +// xOrigin, +// yOrigin, +// 0, // colStart +// table.rowHeaderLevelCount - 1, // colEnd +// 0, // rowStart +// table.columnHeaderLevelCount - 1, // rowEnd +// 'cornerHeader', // CellType +// table +// ); +// } -/** - * @description: 处理全部列表头 - * @param {Group} colHeaderGroup 列表头容器Group - * @param {number} xOrigin x起始坐标 - * @param {number} yOrigin y起始坐标 - * @param {BaseTableAPI} table - * @return {*} - */ -export function createColHeaderColGroup(colHeaderGroup: Group, xOrigin: number, yOrigin: number, table: BaseTableAPI) { - createColGroup( - colHeaderGroup, - xOrigin, - yOrigin, - table.rowHeaderLevelCount, // colStart - table.colCount - 1, // colEnd - 0, // rowStart - table.columnHeaderLevelCount - 1, // rowEnd - 'columnHeader', // isHeader - table - ); -} +// /** +// * @description: 处理全部列表头 +// * @param {Group} colHeaderGroup 列表头容器Group +// * @param {number} xOrigin x起始坐标 +// * @param {number} yOrigin y起始坐标 +// * @param {BaseTableAPI} table +// * @return {*} +// */ +// export function createColHeaderColGroup(colHeaderGroup: Group, xOrigin: number, yOrigin: number, table: BaseTableAPI) { +// createColGroup( +// colHeaderGroup, +// xOrigin, +// yOrigin, +// table.rowHeaderLevelCount, // colStart +// table.colCount - 1, // colEnd +// 0, // rowStart +// table.columnHeaderLevelCount - 1, // rowEnd +// 'columnHeader', // isHeader +// table +// ); +// } -/** - * @description: 处理全部行表头 - * @param {Group} rowHeaderGroup 行表头容器Group - * @param {number} xOrigin x起始坐标 - * @param {number} yOrigin y起始坐标 - * @param {BaseTableAPI} table - * @return {*} - */ -export function createRowHeaderColGroup(rowHeaderGroup: Group, xOrigin: number, yOrigin: number, table: BaseTableAPI) { - createColGroup( - rowHeaderGroup, - xOrigin, - yOrigin, - 0, // colStart - table.rowHeaderLevelCount - 1, // colEnd - table.columnHeaderLevelCount, // rowStart - table.rowCount - 1, // rowEnd - 'rowHeader', // isHeader - table - ); -} +// /** +// * @description: 处理全部行表头 +// * @param {Group} rowHeaderGroup 行表头容器Group +// * @param {number} xOrigin x起始坐标 +// * @param {number} yOrigin y起始坐标 +// * @param {BaseTableAPI} table +// * @return {*} +// */ +// export function createRowHeaderColGroup(rowHeaderGroup: Group, xOrigin: number, yOrigin: number, table: BaseTableAPI) { +// createColGroup( +// rowHeaderGroup, +// xOrigin, +// yOrigin, +// 0, // colStart +// table.rowHeaderLevelCount - 1, // colEnd +// table.columnHeaderLevelCount, // rowStart +// table.rowCount - 1, // rowEnd +// 'rowHeader', // isHeader +// table +// ); +// } -/** - * @description: 处理内容单元格 - * @param {Group} bodyGroup 内容容器Group - * @param {number} xOrigin x起始坐标 - * @param {number} yOrigin y起始坐标 - * @param {BaseTableAPI} table - * @return {*} - */ -export function createBodyColGroup(bodyGroup: Group, xOrigin: number, yOrigin: number, table: BaseTableAPI) { - createColGroup( - bodyGroup, - xOrigin, - yOrigin, - table.rowHeaderLevelCount, // colStart - table.colCount - 1, // colEnd - table.columnHeaderLevelCount, // rowStart - table.rowCount - 1, // rowEnd - 'body', // isHeader - table - ); -} +// /** +// * @description: 处理内容单元格 +// * @param {Group} bodyGroup 内容容器Group +// * @param {number} xOrigin x起始坐标 +// * @param {number} yOrigin y起始坐标 +// * @param {BaseTableAPI} table +// * @return {*} +// */ +// export function createBodyColGroup(bodyGroup: Group, xOrigin: number, yOrigin: number, table: BaseTableAPI) { +// createColGroup( +// bodyGroup, +// xOrigin, +// yOrigin, +// table.rowHeaderLevelCount, // colStart +// table.colCount - 1, // colEnd +// table.columnHeaderLevelCount, // rowStart +// table.rowCount - 1, // rowEnd +// 'body', // isHeader +// table +// ); +// } /** * @description: 生成一个列的场景节点 diff --git a/packages/vtable/src/scenegraph/group-creater/progress/proxy.ts b/packages/vtable/src/scenegraph/group-creater/progress/proxy.ts index 73ce89945..675b3a5cc 100644 --- a/packages/vtable/src/scenegraph/group-creater/progress/proxy.ts +++ b/packages/vtable/src/scenegraph/group-creater/progress/proxy.ts @@ -12,6 +12,7 @@ import { dynamicSetY, updateRowContent } from './update-position/dynamic-set-y'; import { updateAutoRow } from './update-position/update-auto-row'; import { sortVertical } from './update-position/sort-vertical'; import { sortHorizontal } from './update-position/sort-horizontal'; +import { updateAutoColumn } from './update-position/update-auto-column'; export class SceneProxy { table: BaseTableAPI; @@ -512,7 +513,61 @@ export class SceneProxy { this.rowUpdatePos = distRow + 1; } + /** 更新底部冻结行的单元格内容 包括两边的角头 */ + updateBottomFrozenCellGroups() { + const startRow = this.table.rowCount - this.table.bottomFrozenRowCount; + const endRow = this.table.rowCount - 1; + if (this.table.heightMode === 'autoHeight') { + computeRowsHeight(this.table, startRow, endRow, false); + } + console.log('updateBottomFrozenCellGroups', startRow, endRow); + updateRowContent(startRow, endRow, this); + + if (this.table.heightMode === 'autoHeight') { + // body group + updateAutoRow( + this.bodyLeftCol, // colStart + this.bodyRightCol, // colEnd + startRow, // rowStart + endRow, // rowEnd + this.table, + this.rowUpdateDirection + ); + // row header group + updateAutoRow( + 0, // colStart + this.table.frozenColCount - 1, // colEnd + startRow, // rowStart + endRow, // rowEnd + this.table, + this.rowUpdateDirection + ); + // right frozen group + updateAutoRow( + this.table.colCount - this.table.rightFrozenColCount, // colStart + this.table.colCount - 1, // colEnd + startRow, // rowStart + endRow, // rowEnd + this.table, + this.rowUpdateDirection + ); + } + } + /** 更新底部冻结行的单元格内容 包括两边的角头 */ + updateRightFrozenCellGroups() { + const startCol = this.table.colCount - this.table.rightFrozenColCount; + const endCol = this.table.colCount - 1; + if (this.table.widthMode === 'autoWidth') { + computeColsWidth(this.table, startCol, endCol, false); + } + console.log('updateRightFrozenCellGroups', startCol, endCol); + updateColContent(startCol, endCol, this); + if (this.table.heightMode === 'autoHeight') { + // body group + updateAutoColumn(startCol, endCol, this.table, this.colUpdateDirection); + } + } async updateColCellGroupsAsync() { this.updateColGroups(this.taskRowCount); } diff --git a/packages/vtable/src/scenegraph/group-creater/progress/update-position/dynamic-set-x.ts b/packages/vtable/src/scenegraph/group-creater/progress/update-position/dynamic-set-x.ts index eb0f5bd5d..5d599c071 100644 --- a/packages/vtable/src/scenegraph/group-creater/progress/update-position/dynamic-set-x.ts +++ b/packages/vtable/src/scenegraph/group-creater/progress/update-position/dynamic-set-x.ts @@ -245,6 +245,12 @@ export function updateColContent(syncLeftCol: number, syncRightCol: number, prox const bottomColGroup = proxy.table.scenegraph.getColGroupInBottom(col); bottomColGroup && updateColGroupContent(bottomColGroup, proxy); + + const rightTopColGroup = proxy.table.scenegraph.getColGroupInRightTopCorner(col); + rightTopColGroup && updateColGroupContent(rightTopColGroup, proxy); + + const rightBottomColGroup = proxy.table.scenegraph.getColGroupInRightBottomCorner(col); + rightBottomColGroup && updateColGroupContent(rightBottomColGroup, proxy); } } diff --git a/packages/vtable/src/scenegraph/layout/auto-height.ts b/packages/vtable/src/scenegraph/layout/auto-height.ts index 547ca70f6..a13e260ec 100644 --- a/packages/vtable/src/scenegraph/layout/auto-height.ts +++ b/packages/vtable/src/scenegraph/layout/auto-height.ts @@ -10,63 +10,63 @@ import { updateCellHeightForColumn } from './update-height'; * 在调整列宽时为true,在场景结点生成后为false * @return {*} */ -export function updateAutoRowHeight(scene: Scenegraph, clearCellSize?: boolean) { - const colHeader = scene.colHeaderGroup; - const rowHeader = scene.rowHeaderGroup; - const cornerHeader = scene.cornerHeaderGroup; - const body = scene.bodyGroup; +// export function updateAutoRowHeight(scene: Scenegraph, clearCellSize?: boolean) { +// const colHeader = scene.colHeaderGroup; +// const rowHeader = scene.rowHeaderGroup; +// const cornerHeader = scene.cornerHeaderGroup; +// const body = scene.bodyGroup; - // 获取行高 - for (let row = 0; row <= scene.bodyRowEnd; row++) { - let maxRowHeight = 0; - for (let col = 0; col < scene.table.colCount; col++) { - const cellGroup = scene.getCell(col, row); - // maxRowHeight = Math.max(maxRowHeight, cellGroup.attribute.height); - const mergeInfo = getCellMergeInfo(scene.table, cellGroup.col, cellGroup.row); - if (mergeInfo) { - const mergeCell = scene.getCell(mergeInfo.start.col, mergeInfo.start.row); - maxRowHeight = Math.max( - maxRowHeight, - mergeCell.attribute.height / (mergeInfo.end.row - mergeInfo.start.row + 1) - ); - } else { - maxRowHeight = Math.max(maxRowHeight, cellGroup.attribute.height); - } - } - scene.table._setRowHeight(row, maxRowHeight, true); - } +// // 获取行高 +// for (let row = 0; row <= scene.bodyRowEnd; row++) { +// let maxRowHeight = 0; +// for (let col = 0; col < scene.table.colCount; col++) { +// const cellGroup = scene.getCell(col, row); +// // maxRowHeight = Math.max(maxRowHeight, cellGroup.attribute.height); +// const mergeInfo = getCellMergeInfo(scene.table, cellGroup.col, cellGroup.row); +// if (mergeInfo) { +// const mergeCell = scene.getCell(mergeInfo.start.col, mergeInfo.start.row); +// maxRowHeight = Math.max( +// maxRowHeight, +// mergeCell.attribute.height / (mergeInfo.end.row - mergeInfo.start.row + 1) +// ); +// } else { +// maxRowHeight = Math.max(maxRowHeight, cellGroup.attribute.height); +// } +// } +// scene.table._setRowHeight(row, maxRowHeight, true); +// } - // 设置行高 - let yTemp = 0; - for (let row = 0; row <= scene.bodyRowEnd; row++) { - const maxRowHeight = scene.table.getRowHeight(row); - if (row === scene.table.columnHeaderLevelCount) { - // 更新行表头行高 - let colHeaderHeight = 0; - colHeader?.firstChild?.forEachChildren((cell: Group) => { - if (cell.role !== 'shadow-cell') { - colHeaderHeight += cell.attribute.height; - } - }); - colHeader.setAttribute('height', colHeaderHeight); - cornerHeader.setAttribute('height', colHeaderHeight); - rowHeader.setAttribute('y', colHeaderHeight); - body.setAttribute('y', colHeaderHeight); +// // 设置行高 +// let yTemp = 0; +// for (let row = 0; row <= scene.bodyRowEnd; row++) { +// const maxRowHeight = scene.table.getRowHeight(row); +// if (row === scene.table.columnHeaderLevelCount) { +// // 更新行表头行高 +// let colHeaderHeight = 0; +// colHeader?.firstChild?.forEachChildren((cell: Group) => { +// if (cell.role !== 'shadow-cell') { +// colHeaderHeight += cell.attribute.height; +// } +// }); +// colHeader.setAttribute('height', colHeaderHeight); +// cornerHeader.setAttribute('height', colHeaderHeight); +// rowHeader.setAttribute('y', colHeaderHeight); +// body.setAttribute('y', colHeaderHeight); - yTemp = 0; - } +// yTemp = 0; +// } - for (let col = 0; col < scene.table.colCount; col++) { - const cellGroup = scene.getCell(col, row); - updateCellHeight(cellGroup, scene, col, row, maxRowHeight, yTemp); - } - yTemp += maxRowHeight; - } +// for (let col = 0; col < scene.table.colCount; col++) { +// const cellGroup = scene.getCell(col, row); +// updateCellHeight(cellGroup, scene, col, row, maxRowHeight, yTemp); +// } +// yTemp += maxRowHeight; +// } - // 更新容器尺寸 - rowHeader.setAttribute('height', yTemp); - body.setAttribute('height', yTemp); -} +// // 更新容器尺寸 +// rowHeader.setAttribute('height', yTemp); +// body.setAttribute('height', yTemp); +// } // 更新单元格高度信息 function updateCellHeight( diff --git a/packages/vtable/src/scenegraph/layout/compute-col-width.ts b/packages/vtable/src/scenegraph/layout/compute-col-width.ts index 00f8be64f..704d715dd 100644 --- a/packages/vtable/src/scenegraph/layout/compute-col-width.ts +++ b/packages/vtable/src/scenegraph/layout/compute-col-width.ts @@ -382,7 +382,7 @@ function computeAutoColWidth( // if (cellHierarchyState === HierarchyState.expand || cellHierarchyState === HierarchyState.collapse) { const define = table.getBodyColumnDefine(col, row); if (define?.tree) { - const indexArr = table.dataSource.getIndexKey(table.getRecordIndexByCell(col, row)); + const indexArr = table.dataSource.getIndexKey(table.getRecordShowIndexByCell(col, row)); cellHierarchyIndent = Array.isArray(indexArr) && table.getHierarchyState(col, row) !== HierarchyState.none ? (indexArr.length - 1) * ((layoutMap as SimpleHeaderLayoutMap).hierarchyIndent ?? 0) diff --git a/packages/vtable/src/scenegraph/layout/update-col.ts b/packages/vtable/src/scenegraph/layout/update-col.ts new file mode 100644 index 000000000..6ed1464b6 --- /dev/null +++ b/packages/vtable/src/scenegraph/layout/update-col.ts @@ -0,0 +1,407 @@ +import { isNumber } from '@visactor/vutils'; +import type { CellAddress } from '../../ts-types'; +import type { BaseTableAPI } from '../../ts-types/base-table'; +import { Group } from '../graphic/group'; +import { updateCell } from '../group-creater/cell-helper'; +import type { Scenegraph } from '../scenegraph'; +import { getCellMergeInfo } from '../utils/get-cell-merge'; +import type { IGroup } from '@visactor/vrender'; + +/** + * add and remove rows in scenegraph + */ +export function updateCol( + removeCells: CellAddress[], + addCells: CellAddress[], + updateCells: CellAddress[], + table: BaseTableAPI +) { + const scene = table.scenegraph; + // deduplication + const removeCols = deduplication(removeCells.map(cell => cell.col)).sort((a, b) => b - a); + const addCols = deduplication(addCells.map(cell => cell.col)).sort((a, b) => a - b); + const updateCols = deduplication(updateCells.map(cell => cell.col)).sort((a, b) => a - b); + + // remove cells + removeCols.forEach(col => { + removeCol(col, scene); + }); + + removeCols.forEach(col => { + scene.table.colWidthsMap.adjustOrder(col + 1, col, scene.table.colWidthsMap.count() - col - 1); + scene.table.colWidthsMap.del(scene.table.colWidthsMap.count() - 1); + }); + + if (removeCols.length) { + resetColNumber(scene); + } + + scene.table._clearColRangeWidthsMap(); + + // add cells + let updateAfter: number; + addCols.forEach(col => { + const needUpdateAfter = addCol(col, scene); + resetColNumber(scene); + updateAfter = updateAfter ?? needUpdateAfter; + scene.table.colWidthsMap.adjustOrder(col, col + 1, scene.table.colWidthsMap.count() - col); + }); + + // reset attribute y and col number in CellGroup + // const newTotalHeight = resetColNumberAndY(scene); + resetColNumberAndX(scene); + // add cells + updateCols.forEach(col => { + for (let row = 0; row < table.rowCount; row++) { + // updateColAttr(col, scene); + const mergeInfo = getCellMergeInfo(scene.table, col, row); + if (mergeInfo) { + for (let col = mergeInfo.start.col; col <= mergeInfo.end.col; col++) { + for (let col = mergeInfo.start.col; col <= mergeInfo.end.col; col++) { + updateCell(col, row, scene.table, false); + } + } + } else { + updateCell(col, row, scene.table, false); + } + } + }); + + if (isNumber(updateAfter)) { + for (let col = updateAfter; col < table.colCount; col++) { + for (let row = 0; row < table.rowCount; row++) { + const cellGroup = scene.highPerformanceGetCell(col, row, true); + cellGroup && (cellGroup.needUpdate = true); + } + } + scene.proxy.colUpdatePos = updateAfter; + } + if (addCols.length) { + if (!isNumber(updateAfter)) { + const minCol = Math.min(...addCols); + scene.proxy.colUpdatePos = minCol; + } + scene.proxy.colUpdateDirection = 'left'; + scene.proxy.updateColGroups(scene.proxy.screenColCount * 2); + updateRightFrozeCellGroups(); + scene.proxy.progress(); + } else if (removeCols.length) { + scene.proxy.updateColGroups(scene.proxy.screenColCount * 2); + updateRightFrozeCellGroups(); + scene.proxy.progress(); + } + + // update table size + const newTotalWidth = table.getColsWidth(table.frozenColCount, table.colCount - 1); + scene.updateContainerWidth(scene.table.frozenColCount, newTotalWidth - scene.bodyGroup.attribute.width); + + function updateRightFrozeCellGroups() { + if ( + addCols?.[addCols?.length - 1] >= table.colCount - table.rightFrozenColCount || + updateCols?.[updateCols?.length - 1] >= table.colCount - table.rightFrozenColCount || + removeCols?.[0] >= table.colCount - table.rightFrozenColCount + ) { + for (let col = table.colCount - table.rightFrozenColCount; col < table.colCount; col++) { + for (let row = 0; row < table.rowCount; row++) { + const cellGroup = scene.highPerformanceGetCell(col, row, true); + cellGroup && (cellGroup.needUpdate = true); + } + } + scene.proxy.updateRightFrozenCellGroups(); + } + } +} + +function removeCol(col: number, scene: Scenegraph) { + const proxy = scene.proxy; + // removeCellGroup(col, scene); + //先考虑非表头部分删除情况 + if (col >= scene.table.rowHeaderLevelCount) { + if (col >= scene.table.colCount - scene.table.rightFrozenColCount) { + // 如果是删除的右侧固定列 这里不做真正的删除,只需要后面将相应列做更新 + // scene.bodyGroup.removeChild(scene.bodyGroup.lastChild as any); + // scene.bottomFrozenGroup.removeChild(scene.bottomFrozenGroup.lastChild as any); + } else { + const colGroup = scene.getColGroup(col, false); + if (colGroup && colGroup.parent === scene.bodyGroup) { + scene.bodyGroup.removeChild(colGroup); + } + const bottomColGroup = scene.getColGroupInBottom(col); + if (bottomColGroup && bottomColGroup.parent === scene.bottomFrozenGroup) { + scene.bottomFrozenGroup.removeChild(bottomColGroup); + } + } + } + + // TODO 需要整体更新proxy的状态 + if (col >= proxy.colStart && col <= proxy.colEnd) { + proxy.colEnd--; + proxy.currentCol--; + } + proxy.bodyRightCol--; + // proxy.totalCol--; + const totalActualBodyColCount = Math.min(proxy.colLimit, proxy.bodyRightCol - proxy.bodyLeftCol + 1); // 渐进加载总col数量 + proxy.totalActualBodyColCount = totalActualBodyColCount; + proxy.totalCol = proxy.colStart + totalActualBodyColCount - 1; // 目标渐进完成的col +} + +function addCol(col: number, scene: Scenegraph) { + const proxy = scene.proxy; + proxy.bodyRightCol++; + // proxy.totalCol++; + const totalActualBodyColCount = Math.min(proxy.colLimit, proxy.bodyRightCol - proxy.bodyLeftCol + 1); // 渐进加载总col数量 + proxy.totalActualBodyColCount = totalActualBodyColCount; + proxy.totalCol = proxy.colStart + totalActualBodyColCount - 1; // 目标渐进完成的col + + if (col < proxy.colStart) { + return undefined; + } else if (col > proxy.colEnd) { + if (proxy.colEnd - proxy.colStart + 1 < proxy.colLimit) { + // can add col + proxy.colEnd++; + proxy.currentCol++; + + addColGroup(col, scene); + return col; + } + return undefined; + } + if (proxy.colEnd - proxy.colStart + 1 < proxy.colLimit) { + // can add col + proxy.colEnd++; + proxy.currentCol++; + + addColGroup(col, scene); + return col; + } + return col; +} + +// array deduplication +function deduplication(array: number[]) { + const result = []; + for (let i = 0; i < array.length; i++) { + if (result.indexOf(array[i]) === -1) { + result.push(array[i]); + } + } + return result; +} + +function resetColNumber(scene: Scenegraph) { + let colIndex = scene.bodyColStart; + scene.bodyGroup.forEachChildren((colGroup: Group) => { + colGroup.col = colIndex; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup); + }); + colIndex++; + }); + + colIndex = scene.bodyColStart; + scene.colHeaderGroup.forEachChildren((colGroup: Group) => { + colGroup.col = colIndex; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup); + }); + colIndex++; + }); + + colIndex = scene.bodyColStart; + scene.bottomFrozenGroup.forEachChildren((colGroup: Group) => { + colGroup.col = colIndex; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup); + }); + colIndex++; + }); + function processCell(cellGroup: Group) { + cellGroup.col = colIndex; + const merge = getCellMergeInfo(scene.table, cellGroup.col, cellGroup.row); + if (merge) { + cellGroup.mergeStartCol = merge.start.col; + cellGroup.mergeStartCol = merge.start.col; + cellGroup.mergeEndCol = merge.end.col; + cellGroup.mergeEndCol = merge.end.col; + } + + if (cellGroup.role !== 'cell') { + return; + } + } +} + +function resetColNumberAndX(scene: Scenegraph) { + let colIndex = scene.bodyColStart; + let x = scene.getCellGroupX(colIndex); + scene.bodyGroup.forEachChildren((colGroup: Group) => { + colGroup.col = colIndex; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup); + }); + colGroup.setAttribute('x', x); + x += colGroup.attribute.width; + colIndex++; + }); + + colIndex = scene.bodyColStart; + x = scene.getCellGroupX(colIndex); + scene.colHeaderGroup.forEachChildren((colGroup: Group) => { + colGroup.col = colIndex; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup); + }); + colGroup.setAttribute('x', x); + x += colGroup.attribute.width; + colIndex++; + }); + + colIndex = scene.bodyColStart; + x = scene.getCellGroupX(colIndex); + scene.bottomFrozenGroup.forEachChildren((colGroup: Group) => { + colGroup.col = colIndex; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup); + }); + colGroup.setAttribute('x', x); + x += colGroup.attribute.width; + colIndex++; + }); + colIndex = scene.table.colCount - scene.table.rightFrozenColCount; + x = 0; + scene.rightFrozenGroup.forEachChildren((colGroup: Group) => { + colGroup.col = colIndex; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup); + }); + colGroup.setAttribute('x', x); + x += colGroup.attribute.width; + colIndex++; + }); + + colIndex = scene.table.colCount - scene.table.rightFrozenColCount; + x = 0; + scene.rightTopCornerGroup.forEachChildren((colGroup: Group) => { + colGroup.col = colIndex; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup); + }); + colGroup.setAttribute('x', x); + x += colGroup.attribute.width; + colIndex++; + }); + + colIndex = scene.table.colCount - scene.table.rightFrozenColCount; + x = 0; + scene.rightBottomCornerGroup.forEachChildren((colGroup: Group) => { + colGroup.col = colIndex; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup); + }); + colGroup.setAttribute('x', x); + x += colGroup.attribute.width; + colIndex++; + }); + function processCell(cellGroup: Group) { + cellGroup.col = colIndex; + const merge = getCellMergeInfo(scene.table, cellGroup.col, cellGroup.row); + if (merge) { + cellGroup.mergeStartCol = merge.start.col; + cellGroup.mergeStartCol = merge.start.col; + cellGroup.mergeEndCol = merge.end.col; + cellGroup.mergeEndCol = merge.end.col; + } + + if (cellGroup.role !== 'cell') { + return; + } + } +} + +function addColGroup(col: number, scene: Scenegraph) { + if (scene.colHeaderGroup && scene.table.columnHeaderLevelCount > 0) { + const columnGroup = new Group({ + x: 0, + y: 0, + width: scene.table.getColWidth(col), + height: 0, + clip: false, + pickable: false + }); + columnGroup.role = 'column'; + columnGroup.col = col; + + const colAfter = scene.getColGroup(col, true); + if (colAfter) { + scene.colHeaderGroup.insertBefore(columnGroup, colAfter); + } else { + scene.colHeaderGroup.appendChild(columnGroup); + } + generateCellGroup(columnGroup, col, 0, scene.table.columnHeaderLevelCount - 1); + } + + if (scene.bodyGroup) { + const columnGroup = new Group({ + x: 0, + y: 0, + width: scene.table.getColWidth(col), + height: 0, + clip: false, + pickable: false + }); + columnGroup.role = 'column'; + columnGroup.col = col; + + const colAfter = scene.getColGroup(col, false); + if (colAfter) { + scene.bodyGroup.insertBefore(columnGroup, colAfter); + } else { + scene.bodyGroup.appendChild(columnGroup); + } + generateCellGroup(columnGroup, col, scene.bodyRowStart, scene.bodyRowEnd); + } + if (scene.bottomFrozenGroup && scene.table.bottomFrozenRowCount > 0) { + const columnGroup = new Group({ + x: 0, + y: 0, + width: scene.table.getColWidth(col), + height: 0, + clip: false, + pickable: false + }); + columnGroup.role = 'column'; + columnGroup.col = col; + + const colAfter = scene.getColGroupInBottom(col); + if (colAfter) { + scene.bottomFrozenGroup.insertBefore(columnGroup, colAfter); + } else { + scene.bottomFrozenGroup.appendChild(columnGroup); + } + + generateCellGroup( + columnGroup, + col, + scene.table.rowCount - scene.table.bottomFrozenRowCount, + scene.table.rowCount - 1 + ); + } + + function generateCellGroup(group: IGroup, col: number, rowStart: number, rowEnd: number) { + for (let row = rowStart; row <= rowEnd; row++) { + // create cellGroup + // const cellGroup = updateCell(col, row, scene.table, true); + const cellGroup = new Group({ + x: 0, + y: 0, + width: scene.table.getColWidth(col), + height: scene.table.getRowHeight(row) + }); + cellGroup.role = 'cell'; + cellGroup.col = col; + cellGroup.row = row; + cellGroup.needUpdate = true; + group.appendChild(cellGroup); + } + } +} diff --git a/packages/vtable/src/scenegraph/layout/update-height.ts b/packages/vtable/src/scenegraph/layout/update-height.ts index 5daf2ba5b..14c3b7ab5 100644 --- a/packages/vtable/src/scenegraph/layout/update-height.ts +++ b/packages/vtable/src/scenegraph/layout/update-height.ts @@ -47,7 +47,7 @@ export function updateRowHeight(scene: Scenegraph, row: number, detaY: number) { } else { rowStart = row + 1; // rowEnd = scene.table.rowCount - 1; - rowEnd = scene.bodyRowEnd - scene.table.bottomFrozenRowCount; + rowEnd = scene.bodyRowEnd; //- scene.table.bottomFrozenRowCount; } // 更新以下行位置 diff --git a/packages/vtable/src/scenegraph/layout/update-row.ts b/packages/vtable/src/scenegraph/layout/update-row.ts index 4fa530def..597636e66 100644 --- a/packages/vtable/src/scenegraph/layout/update-row.ts +++ b/packages/vtable/src/scenegraph/layout/update-row.ts @@ -5,6 +5,7 @@ import { Group } from '../graphic/group'; import { updateCell } from '../group-creater/cell-helper'; import type { Scenegraph } from '../scenegraph'; import { getCellMergeInfo } from '../utils/get-cell-merge'; +import type { IGraphic } from '@visactor/vrender'; /** * add and remove rows in scenegraph @@ -19,7 +20,7 @@ export function updateRow( // deduplication const removeRows = deduplication(removeCells.map(cell => cell.row)).sort((a, b) => b - a); const addRows = deduplication(addCells.map(cell => cell.row)).sort((a, b) => a - b); - // const updateRows = deduplication(updateCells.map(cell => cell.row)).sort((a, b) => a - b); + const updateRows = deduplication(updateCells.map(cell => cell.row)).sort((a, b) => a - b); // remove cells removeRows.forEach(row => { @@ -41,7 +42,7 @@ export function updateRow( let updateAfter: number; addRows.forEach(row => { const needUpdateAfter = addRow(row, scene); - updateAfter = updateAfter || needUpdateAfter; + updateAfter = updateAfter ?? needUpdateAfter; scene.table.rowHeightsMap.adjustOrder(row, row + 1, scene.table.rowHeightsMap.count() - row); }); @@ -49,29 +50,27 @@ export function updateRow( // const newTotalHeight = resetRowNumberAndY(scene); resetRowNumberAndY(scene); - // add cells - updateCells.forEach(cell => { - // updateRowAttr(row, scene); - if (!cell) { - return; - } - const mergeInfo = getCellMergeInfo(scene.table, cell.col, cell.row); - if (mergeInfo) { - for (let col = mergeInfo.start.col; col <= mergeInfo.end.col; col++) { - for (let row = mergeInfo.start.row; row <= mergeInfo.end.row; row++) { - updateCell(col, row, scene.table, false); + for (let col = 0; col < table.colCount; col++) { + // add cells + updateRows.forEach(r => { + // updateRowAttr(row, scene); + const mergeInfo = getCellMergeInfo(scene.table, col, r); + if (mergeInfo) { + for (let col = mergeInfo.start.col; col <= mergeInfo.end.col; col++) { + for (let row = mergeInfo.start.row; row <= mergeInfo.end.row; row++) { + updateCell(col, row, scene.table, false); + } } + } else { + updateCell(col, r, scene.table, false); } - } else { - updateCell(cell.col, cell.row, scene.table, false); - } - }); - + }); + } if (isNumber(updateAfter)) { for (let col = 0; col < table.colCount; col++) { for (let row = updateAfter; row < table.rowCount; row++) { const cellGroup = scene.highPerformanceGetCell(col, row, true); - cellGroup.needUpdate = true; + cellGroup && (cellGroup.needUpdate = true); } } scene.proxy.rowUpdatePos = updateAfter; @@ -84,17 +83,35 @@ export function updateRow( } scene.proxy.rowUpdateDirection = 'up'; scene.proxy.updateCellGroups(scene.proxy.screenRowCount * 2); + updateBottomFrozeCellGroups(); scene.proxy.progress(); } else if (removeRows.length) { scene.proxy.updateCellGroups(scene.proxy.screenRowCount * 2); + + updateBottomFrozeCellGroups(); scene.proxy.progress(); } // update table size const newTotalHeight = table.getRowsHeight(table.frozenRowCount, table.rowCount - 1 - table.bottomFrozenRowCount); scene.updateContainerHeight(scene.table.frozenRowCount, newTotalHeight - scene.bodyGroup.attribute.height); -} + function updateBottomFrozeCellGroups() { + if ( + addRows?.[addRows?.length - 1] >= table.rowCount - table.bottomFrozenRowCount || + updateRows?.[updateRows?.length - 1] >= table.rowCount - table.bottomFrozenRowCount || + removeRows?.[0] >= table.rowCount - table.bottomFrozenRowCount + ) { + for (let col = 0; col < table.colCount; col++) { + for (let row = table.rowCount - table.bottomFrozenRowCount; row < table.rowCount; row++) { + const cellGroup = scene.highPerformanceGetCell(col, row, true); + cellGroup && (cellGroup.needUpdate = true); + } + } + scene.proxy.updateBottomFrozenCellGroups(); + } + } +} function removeRow(row: number, scene: Scenegraph) { removeCellGroup(row, scene); const proxy = scene.proxy; @@ -163,108 +180,255 @@ function deduplication(array: number[]) { return result; } +// function resetRowNumber(scene: Scenegraph) { +// for (let col = 0; col < scene.table.colCount; col++) { +// const headerColGroup = scene.getColGroup(col, true); +// const colGroup = scene.getColGroup(col, false); +// if (!headerColGroup && !colGroup) { +// continue; +// } +// // reset row number +// let rowIndex = 0; //(headerColGroup.firstChild as Group)?.row; +// headerColGroup?.forEachChildren((cellGroup: Group) => { +// // const oldRow = cellGroup.row; +// // if (isNumber(cellGroup.mergeStartRow)) { +// // cellGroup.mergeStartRow = cellGroup.mergeStartRow - oldRow + rowIndex; +// // } +// // if (isNumber(cellGroup.mergeEndRow)) { +// // cellGroup.mergeEndRow = cellGroup.mergeEndRow - oldRow + rowIndex; +// // } +// cellGroup.row = rowIndex; +// const merge = getCellMergeInfo(scene.table, cellGroup.col, cellGroup.row); +// if (merge) { +// cellGroup.mergeStartCol = merge.start.col; +// cellGroup.mergeStartRow = merge.start.row; +// cellGroup.mergeEndCol = merge.end.col; +// cellGroup.mergeEndRow = merge.end.row; +// } +// rowIndex++; +// }); +// // rowIndex = (colGroup.firstChild as Group)?.row; +// // rowIndex = scene.table.columnHeaderLevelCount; +// rowIndex = scene.bodyRowStart; +// colGroup?.forEachChildren((cellGroup: Group) => { +// // const oldRow = cellGroup.row; +// // if (isNumber(cellGroup.mergeStartRow)) { +// // cellGroup.mergeStartRow = cellGroup.mergeStartRow - oldRow + rowIndex; +// // } +// // if (isNumber(cellGroup.mergeEndRow)) { +// // cellGroup.mergeEndRow = cellGroup.mergeEndRow - oldRow + rowIndex; +// // } +// cellGroup.row = rowIndex; +// const merge = getCellMergeInfo(scene.table, cellGroup.col, cellGroup.row); +// if (merge) { +// cellGroup.mergeStartCol = merge.start.col; +// cellGroup.mergeStartRow = merge.start.row; +// cellGroup.mergeEndCol = merge.end.col; +// cellGroup.mergeEndRow = merge.end.row; +// } +// rowIndex++; +// }); +// } +// } + +// function resetRowNumberAndY(scene: Scenegraph) { +// const table = scene.table; +// let newTotalHeight = 0; +// for (let col = 0; col < scene.table.colCount; col++) { +// const headerColGroup = scene.getColGroup(col, true); +// const colGroup = scene.getColGroup(col, false); // body, row header, right frozen +// const bottomGroup = +// scene.getColGroupInBottom(col) || +// scene.getColGroupInLeftBottomCorner(col) || +// scene.getColGroupInRightTopCorner(col); +// if (!headerColGroup && !colGroup && !bottomGroup) { +// continue; +// } +// let y = 0; +// // reset row number +// // let rowIndex = (headerColGroup.firstChild as Group)?.row; +// // headerColGroup.forEachChildren((cellGroup: Group) => { +// // cellGroup.row = rowIndex; +// // rowIndex++; +// // if (cellGroup.role !== 'cell') { +// // return; +// // } +// // cellGroup.setAttribute('y', y); +// // y+= cellGroup.attribute.height; +// // }); +// // let rowIndex = (colGroup.firstChild as Group)?.row; +// let rowIndex = scene.bodyRowStart; +// y = scene.getCellGroupY(rowIndex); +// colGroup?.forEachChildren((cellGroup: Group) => { +// // const oldRow = cellGroup.row; +// // if (isNumber(cellGroup.mergeStartRow)) { +// // cellGroup.mergeStartRow = cellGroup.mergeStartRow - oldRow + rowIndex; +// // } +// // if (isNumber(cellGroup.mergeEndRow)) { +// // cellGroup.mergeEndRow = cellGroup.mergeEndRow - oldRow + rowIndex; +// // } +// cellGroup.row = rowIndex; +// const merge = getCellMergeInfo(scene.table, cellGroup.col, cellGroup.row); +// if (merge) { +// cellGroup.mergeStartCol = merge.start.col; +// cellGroup.mergeStartRow = merge.start.row; +// cellGroup.mergeEndCol = merge.end.col; +// cellGroup.mergeEndRow = merge.end.row; +// } +// rowIndex++; +// if (cellGroup.role !== 'cell') { +// return; +// } +// cellGroup.setAttribute('y', y); +// y += cellGroup.attribute.height; +// }); +// newTotalHeight = y; + +// rowIndex = scene.table.rowCount - scene.table.bottomFrozenRowCount; +// // update bottom frozen cell row index +// bottomGroup?.forEachChildren((cellGroup: Group) => { +// cellGroup.row = rowIndex; +// const merge = getCellMergeInfo(scene.table, cellGroup.col, cellGroup.row); +// if (merge) { +// cellGroup.mergeStartCol = merge.start.col; +// cellGroup.mergeStartRow = merge.start.row; +// cellGroup.mergeEndCol = merge.end.col; +// cellGroup.mergeEndRow = merge.end.row; +// } +// rowIndex++; +// }); +// } +// return newTotalHeight; +// } function resetRowNumber(scene: Scenegraph) { - for (let col = 0; col < scene.table.colCount; col++) { - const headerColGroup = scene.getColGroup(col, true); - const colGroup = scene.getColGroup(col, false); - if (!headerColGroup || !colGroup) { - continue; - } - // reset row number - let rowIndex = (headerColGroup.firstChild as Group)?.row; - headerColGroup.forEachChildren((cellGroup: Group) => { - // const oldRow = cellGroup.row; - // if (isNumber(cellGroup.mergeStartRow)) { - // cellGroup.mergeStartRow = cellGroup.mergeStartRow - oldRow + rowIndex; - // } - // if (isNumber(cellGroup.mergeEndRow)) { - // cellGroup.mergeEndRow = cellGroup.mergeEndRow - oldRow + rowIndex; - // } - cellGroup.row = rowIndex; - const merge = getCellMergeInfo(scene.table, cellGroup.col, cellGroup.row); - if (merge) { - cellGroup.mergeStartCol = merge.start.col; - cellGroup.mergeStartRow = merge.start.row; - cellGroup.mergeEndCol = merge.end.col; - cellGroup.mergeEndRow = merge.end.row; - } + scene.bodyGroup.forEachChildren((colGroup: Group) => { + let rowIndex = scene.bodyRowStart; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup, rowIndex); rowIndex++; }); - rowIndex = (colGroup.firstChild as Group)?.row; - colGroup.forEachChildren((cellGroup: Group) => { - // const oldRow = cellGroup.row; - // if (isNumber(cellGroup.mergeStartRow)) { - // cellGroup.mergeStartRow = cellGroup.mergeStartRow - oldRow + rowIndex; - // } - // if (isNumber(cellGroup.mergeEndRow)) { - // cellGroup.mergeEndRow = cellGroup.mergeEndRow - oldRow + rowIndex; - // } - cellGroup.row = rowIndex; - const merge = getCellMergeInfo(scene.table, cellGroup.col, cellGroup.row); - if (merge) { - cellGroup.mergeStartCol = merge.start.col; - cellGroup.mergeStartRow = merge.start.row; - cellGroup.mergeEndCol = merge.end.col; - cellGroup.mergeEndRow = merge.end.row; - } + }); + + scene.rowHeaderGroup.forEachChildren((colGroup: Group) => { + let rowIndex = scene.bodyRowStart; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup, rowIndex); rowIndex++; }); + }); + + scene.rightFrozenGroup.forEachChildren((colGroup: Group) => { + let rowIndex = scene.bodyRowStart; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup, rowIndex); + rowIndex++; + }); + }); + scene.bottomFrozenGroup.forEachChildren((colGroup: Group) => { + let rowIndex = scene.table.rowCount - scene.table.bottomFrozenRowCount; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup, rowIndex); + rowIndex++; + }); + }); + scene.leftBottomCornerGroup.forEachChildren((colGroup: Group) => { + let rowIndex = scene.table.rowCount - scene.table.bottomFrozenRowCount; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup, rowIndex); + rowIndex++; + }); + }); + scene.rightBottomCornerGroup.forEachChildren((colGroup: Group) => { + let rowIndex = scene.table.rowCount - scene.table.bottomFrozenRowCount; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup, rowIndex); + rowIndex++; + }); + }); + function processCell(cellGroup: Group, rowIndex: number) { + cellGroup.row = rowIndex; + const merge = getCellMergeInfo(scene.table, cellGroup.col, cellGroup.row); + if (merge) { + cellGroup.mergeStartCol = merge.start.col; + cellGroup.mergeStartCol = merge.start.col; + cellGroup.mergeEndCol = merge.end.col; + cellGroup.mergeEndCol = merge.end.col; + } } } function resetRowNumberAndY(scene: Scenegraph) { - const table = scene.table; - let newTotalHeight = 0; - for (let col = 0; col < scene.table.colCount; col++) { - const headerColGroup = scene.getColGroup(col, true); - const colGroup = scene.getColGroup(col, false); // body, row header, right frozen - const bottomGroup = - scene.getColGroupInBottom(col) || - scene.getColGroupInLeftBottomCorner(col) || - scene.getColGroupInRightTopCorner(col); - if (!headerColGroup || !colGroup) { - continue; - } - // reset row number - let rowIndex = (headerColGroup.firstChild as Group)?.row; + scene.bodyGroup.forEachChildren((colGroup: Group) => { + let rowIndex = scene.bodyRowStart; + // let y = (colGroup.firstChild as IGraphic).attribute.y; + let y = scene.getCellGroupY(rowIndex); + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup, rowIndex, y); + rowIndex++; + y += cellGroup.attribute.height; + }); + }); + + scene.rowHeaderGroup.forEachChildren((colGroup: Group) => { + let rowIndex = scene.bodyRowStart; + // let y = (colGroup.firstChild as IGraphic).attribute.y; + let y = scene.getCellGroupY(rowIndex); + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup, rowIndex, y); + rowIndex++; + y += cellGroup.attribute.height; + }); + }); + + scene.rightFrozenGroup.forEachChildren((colGroup: Group) => { + let rowIndex = scene.bodyRowStart; + // let y = (colGroup.firstChild as IGraphic).attribute.y; + let y = scene.getCellGroupY(rowIndex); + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup, rowIndex, y); + rowIndex++; + y += cellGroup.attribute.height; + }); + }); + scene.bottomFrozenGroup.forEachChildren((colGroup: Group) => { + let rowIndex = scene.table.rowCount - scene.table.bottomFrozenRowCount; let y = 0; - rowIndex = (colGroup.firstChild as Group)?.row; - const rowStart = rowIndex; - y = scene.getCellGroupY(rowIndex); - colGroup.forEachChildren((cellGroup: Group) => { - cellGroup.row = rowIndex; - const merge = getCellMergeInfo(scene.table, cellGroup.col, cellGroup.row); - if (merge) { - cellGroup.mergeStartCol = merge.start.col; - cellGroup.mergeStartRow = merge.start.row; - cellGroup.mergeEndCol = merge.end.col; - cellGroup.mergeEndRow = merge.end.row; - } + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup, rowIndex, y); rowIndex++; - if (cellGroup.role !== 'cell') { - return; - } - cellGroup.setAttribute('y', y); y += cellGroup.attribute.height; }); - newTotalHeight = y; - - // update bottom frozen cell row index - bottomGroup?.forEachChildren((cellGroup: Group) => { - cellGroup.row = rowIndex; - const merge = getCellMergeInfo(scene.table, cellGroup.col, cellGroup.row); - if (merge) { - cellGroup.mergeStartCol = merge.start.col; - cellGroup.mergeStartRow = merge.start.row; - cellGroup.mergeEndCol = merge.end.col; - cellGroup.mergeEndRow = merge.end.row; - } + }); + scene.leftBottomCornerGroup.forEachChildren((colGroup: Group) => { + let rowIndex = scene.table.rowCount - scene.table.bottomFrozenRowCount; + let y = 0; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup, rowIndex, y); rowIndex++; + y += cellGroup.attribute.height; }); + }); + scene.rightBottomCornerGroup.forEachChildren((colGroup: Group) => { + let rowIndex = scene.table.rowCount - scene.table.bottomFrozenRowCount; + let y = 0; + colGroup?.forEachChildren((cellGroup: Group) => { + processCell(cellGroup, rowIndex, y); + rowIndex++; + y += cellGroup.attribute.height; + }); + }); + function processCell(cellGroup: Group, rowIndex: number, y: number) { + cellGroup.row = rowIndex; + cellGroup.setAttribute('y', y); + const merge = getCellMergeInfo(scene.table, cellGroup.col, cellGroup.row); + if (merge) { + cellGroup.mergeStartCol = merge.start.col; + cellGroup.mergeStartCol = merge.start.col; + cellGroup.mergeEndCol = merge.end.col; + cellGroup.mergeEndCol = merge.end.col; + } } - return newTotalHeight; } - function addRowCellGroup(row: number, scene: Scenegraph) { for (let col = 0; col < scene.table.colCount; col++) { // create cellGroup diff --git a/packages/vtable/src/scenegraph/scenegraph.ts b/packages/vtable/src/scenegraph/scenegraph.ts index 77a8e8959..18c56247b 100644 --- a/packages/vtable/src/scenegraph/scenegraph.ts +++ b/packages/vtable/src/scenegraph/scenegraph.ts @@ -1,6 +1,6 @@ import type { IStage, IRect, ITextCache, INode, Text } from '@visactor/vrender'; import { createStage, createRect, IContainPointMode, container, vglobal } from '@visactor/vrender'; -import type { CellSubLocation } from '../ts-types'; +import type { CellRange, CellSubLocation } from '../ts-types'; import { type CellAddress, type CellLocation, @@ -58,6 +58,7 @@ import { } from './icon/icon-update'; import { Env } from '../tools/env'; import { createCornerCell } from './style/corner-cell'; +import { updateCol } from './layout/update-col'; // import { contextModule } from './context/module'; // VChart poptip theme @@ -209,17 +210,19 @@ export class Scenegraph { } get bodyRowStart(): number { - if (this.transpose || this.isPivot) { - return this.table.columnHeaderLevelCount; - } return this.proxy.rowStart ?? 0; } get bodyRowEnd(): number { - if (this.transpose || this.isPivot) { - return this.table.rowCount - 1; - } - return this.proxy.rowEnd ?? 0; + return this.proxy.rowEnd ?? this.table.rowCount - 1; + } + + get bodyColStart(): number { + return this.proxy.colStart ?? 0; + } + + get bodyColEnd(): number { + return this.proxy.colEnd ?? this.table.colCount - 1; } /** @@ -664,7 +667,14 @@ export class Scenegraph { updateCellSelectBorder(newStartCol: number, newStartRow: number, newEndCol: number, newEndRow: number) { updateCellSelectBorder(this, newStartCol, newStartRow, newEndCol, newEndRow); } - + /** 根据select状态重新创建选中range节点 目前无调用者 */ + recreateAllSelectRangeComponents() { + deleteAllSelectBorder(this); + this.table.stateManager.select.ranges.forEach((cellRange: CellRange) => { + updateCellSelectBorder(this, cellRange.start.col, cellRange.start.row, cellRange.end.col, cellRange.end.row); + }); + moveSelectingRangeComponentsToSelectedRangeComponents(this); + } /** * @description: 列宽调整结果更新列宽 * @param {number} col @@ -1596,7 +1606,28 @@ export class Scenegraph { // rerender this.updateNextFrame(); } + updateCol(removeCells: CellAddress[], addCells: CellAddress[], updateCells: CellAddress[] = []) { + // add or move rows + updateCol(removeCells, addCells, updateCells, this.table); + + // update column width and row height + this.recalculateColWidths(); + + this.recalculateRowHeights(); + // check frozen status + this.table.stateManager.checkFrozen(); + + // update frozen shadow + if (!this.isPivot && !this.transpose) { + this.component.setFrozenColumnShadow(this.table.frozenColCount - 1); + } + + this.component.updateScrollBar(); + + // rerender + this.updateNextFrame(); + } getColumnGroupX(col: number) { if (col < this.table.rowHeaderLevelCount) { // row header @@ -1624,6 +1655,19 @@ export class Scenegraph { } return 0; } + getCellGroupX(col: number) { + if (col < this.table.rowHeaderLevelCount) { + // column header + return this.table.getColsWidth(0, col - 1); + } else if (col < this.table.colCount - this.table.rightFrozenColCount) { + // body + return this.table.getColsWidth(this.table.rowHeaderLevelCount, col - 1); + } else if (col < this.table.colCount) { + // bottom frozen + return this.table.getColsWidth(this.table.colCount - this.table.rightFrozenColCount, col - 1); + } + return 0; + } // /** 更新场景树某个单元格的值 */ // updateCellValue(col: number, row: number) { // updateCell(col, row, this.table); diff --git a/packages/vtable/src/scenegraph/utils/get-hierarchy-offset.ts b/packages/vtable/src/scenegraph/utils/get-hierarchy-offset.ts index 1ed51a36b..f44b039ed 100644 --- a/packages/vtable/src/scenegraph/utils/get-hierarchy-offset.ts +++ b/packages/vtable/src/scenegraph/utils/get-hierarchy-offset.ts @@ -18,7 +18,7 @@ export function getHierarchyOffset(col: number, row: number, table: BaseTableAPI // const cellHierarchyState = table.getHierarchyState(col, row); const define = table.getBodyColumnDefine(col, row); if (define?.tree) { - const indexArr = table.dataSource.getIndexKey(table.getRecordIndexByCell(col, row)); + const indexArr = table.dataSource.getIndexKey(table.getRecordShowIndexByCell(col, row)); cellHierarchyIndent = Array.isArray(indexArr) && table.getHierarchyState(col, row) !== HierarchyState.none ? (indexArr.length - 1) * ((layoutMap as SimpleHeaderLayoutMap).hierarchyIndent ?? 0) diff --git a/packages/vtable/src/state/resize/update-resize-column.ts b/packages/vtable/src/state/resize/update-resize-column.ts index c69fc0721..3d807ef2a 100644 --- a/packages/vtable/src/state/resize/update-resize-column.ts +++ b/packages/vtable/src/state/resize/update-resize-column.ts @@ -129,11 +129,7 @@ function updateResizeColForColumn(detaX: number, state: StateManager) { function updateResizeColForAll(detaX: number, state: StateManager) { // 全列调整 const layout = state.table.internalProps.layoutMap as PivotHeaderLayoutMap; - for ( - let col = state.table.options.frozenColCount; - col < state.table.colCount - state.table.rightFrozenColCount; - col++ - ) { + for (let col = state.table.frozenColCount; col < state.table.colCount - state.table.rightFrozenColCount; col++) { // 是否禁止调整列宽disableColumnResize 对应canResizeColumn的逻辑判断 if (!(state.table.internalProps.transpose || (state.table.isPivotTable() && !layout.indicatorsAsCol))) { const cellDefine = layout.getBody(col, state.table.columnHeaderLevelCount); diff --git a/packages/vtable/src/state/state.ts b/packages/vtable/src/state/state.ts index 9f26e32b4..e8fedb556 100644 --- a/packages/vtable/src/state/state.ts +++ b/packages/vtable/src/state/state.ts @@ -174,6 +174,85 @@ export class StateManager { this.setSelectState(); this.setFrozenState(); } + /** updateOption更新配置的情况下 调用接口*/ + updateOptionSetState() { + this._updateOptionSetState(); + this.setHoverState(); + this.setSelectState(); + this.setFrozenState(); + } + _updateOptionSetState() { + this.interactionState = InteractionState.default; + // this.select = { + // highlightScope: HighlightScope.single, + // ranges: [], + // cellPos: { + // col: -1, + // row: -1 + // }, + // selecting: false + // }; + // this.hover = { + // highlightScope: HighlightScope.single, + // cellPos: { + // col: -1, + // row: -1 + // } + // }; + this.hoverIcon = { + col: -1, + row: -1, + icon: null + }; + this.columnResize = { + col: -1, + x: 0, + resizing: false + }; + this.columnMove = { + colSource: -1, + colTarget: -1, + rowSource: -1, + rowTarget: -1, + x: 0, + y: 0, + moving: false + }; + this.menu = { + x: -1, + y: -1, + isShow: false, + itemList: [], + bounds: new Bounds(), + highlightIndex: -1, + dropDownMenuHighlight: [] + }; + this.sort = { + col: -1, + row: -1, + order: 'normal' + }; + this.frozen = { + col: -1 + // row: -1, + }; + // this.scroll = { + // horizontalBarPos: 0, + // verticalBarPos: 0 + // }; + this.tablePosition = { + absoluteX: 0, + absoluteY: 0 + }; + this.drill = { + col: -1, + row: -1 + }; + this.sparkLine = { + col: -1, + row: -1 + }; + } _initState() { this.interactionState = InteractionState.default; this.select = { @@ -963,7 +1042,7 @@ export class StateManager { } } setCheckedState(col: number, row: number, field: string | number, checked: boolean) { - const recordIndex = this.table.getRecordIndexByCell(col, row); + const recordIndex = this.table.getRecordShowIndexByCell(col, row); if (recordIndex >= 0) { const dataIndex = this.table.dataSource.getIndexKey(recordIndex) as number; if (this.checkedState[dataIndex]) { @@ -1005,7 +1084,7 @@ export class StateManager { } return this.headerCheckedState[field]; } - const recordIndex = this.table.getRecordIndexByCell(col, row); + const recordIndex = this.table.getRecordShowIndexByCell(col, row); if (recordIndex >= 0) { const dataIndex = this.table.dataSource.getIndexKey(recordIndex) as number; if (isValid(this.checkedState[dataIndex]?.[field])) { diff --git a/packages/vtable/src/themes/DARK.ts b/packages/vtable/src/themes/DARK.ts index a310e3d3b..291fe1c53 100644 --- a/packages/vtable/src/themes/DARK.ts +++ b/packages/vtable/src/themes/DARK.ts @@ -2,9 +2,6 @@ import type { ITableThemeDefine, StylePropertyFunctionArg } from '../ts-types'; function getBackgroundColor(args: StylePropertyFunctionArg): string { const { row, table } = args; - // if (row < table.frozenRowCount) { - // return "#FFF"; - // } const index = row - table.frozenRowCount; if (!(index & 1)) { return '#2d3137'; diff --git a/packages/vtable/src/tools/diff-cell.ts b/packages/vtable/src/tools/diff-cell.ts index ed26129a8..8beca0fd6 100644 --- a/packages/vtable/src/tools/diff-cell.ts +++ b/packages/vtable/src/tools/diff-cell.ts @@ -33,7 +33,7 @@ export function diffCellAddress( let parentId = layout.getParentCellId(col, row); let parentCellAddress = layout.getRowHeaderCellAddressByCellId(parentId); const updateCellPositions = []; - updateCellPositions.push(parentCellAddress); + parentCellAddress && updateCellPositions.push(parentCellAddress); while (parentId) { parentId = layout.getParentCellId(parentCellAddress.col, parentCellAddress.row); if (parentId) { diff --git a/packages/vtable/src/ts-types/base-table.ts b/packages/vtable/src/ts-types/base-table.ts index 1c2039d0f..11a1effca 100644 --- a/packages/vtable/src/ts-types/base-table.ts +++ b/packages/vtable/src/ts-types/base-table.ts @@ -544,7 +544,7 @@ export interface BaseTableAPI { * @returns */ getCellAddrByFieldRecord: (field: FieldDef, recordIndex: number) => CellAddress; - getRecordIndexByCell: (col: number, row: number) => number; + getRecordShowIndexByCell: (col: number, row: number) => number; getRecordStartRowByRecordIndex: (index: number) => number; getHeaderField: (col: number, row: number) => any | undefined; diff --git a/packages/vtable/src/ts-types/table-engine.ts b/packages/vtable/src/ts-types/table-engine.ts index 1cb9f35fa..3d7d7e2d3 100644 --- a/packages/vtable/src/ts-types/table-engine.ts +++ b/packages/vtable/src/ts-types/table-engine.ts @@ -173,6 +173,9 @@ export interface ListTableAPI extends BaseTableAPI { /** 结束编辑 */ completeEditCell: () => void; //#endregion + addRecord: (record: any, recordIndex?: number) => void; + addRecords: (records: any[], recordIndex?: number) => void; + deleteRecords: (recordIndexs: number[]) => void; } export interface PivotTableConstructorOptions extends BaseTableConstructorOptions { /**