Skip to content

Commit

Permalink
fix: fix column update problem #1951
Browse files Browse the repository at this point in the history
  • Loading branch information
Rui-Sun committed Jun 20, 2024
1 parent 3d85980 commit c4fb076
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@visactor/vtable",
"comment": "fix: fix column update problem #1951",
"type": "none"
}
],
"packageName": "@visactor/vtable"
}
80 changes: 80 additions & 0 deletions packages/vtable/examples/debug/scroll.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/* eslint-disable */
import * as VTable from '../../src';
import VChart from '@visactor/vchart';
import { bindDebugTool } from '../../src/scenegraph/debug-tool';

const CONTAINER_ID = 'vTable';
VTable.register.chartModule('vchart', VChart);

function createColumn(col: number) {
const arr: any[] = [];
for (let i = 0; i < col; i++) {
const obj = {
title: i,
field: i
// width: "auto",
};
arr.push(obj);
}
return arr;
}

function createRecords(col: number, row: number) {
const arr: any[] = [];
for (let i = 0; i < row; i++) {
const obj = {};
for (let j = 0; j < col; j++) {
obj[j] = `c${j}r${i}`;
}
arr.push(obj);
}
return arr;
}

export function createTable() {
const records = createRecords(500, 500);
const columns = createColumn(500);

const option = {
records,
columns,
// 表格列宽度的计算模式,可以是 'standard'(标准模式)、'adaptive'(自适应容器宽度模式)或 'autoWidth'(自动宽度模式),默认为 'standard'。
widthMode: 'autoWidth',
heightMode: 'autoHeight',
defaultColWidth: 120
// 冻结列数
// frozenColCount: 3,
};

// document.getElementById(CONTAINER_ID).parentElement.style.display = 'none';
const instance = new VTable.ListTable(document.getElementById(CONTAINER_ID), option);
window.tableInstance = instance;

// tableInstance.onVChartEvent('mouseover', args => {
// console.log('listenChart mouseover', args);
// });

bindDebugTool(tableInstance.scenegraph.stage, {
customGrapicKeys: ['col', 'row']
});

window.update = () => {
(option.rowTree = [
{
dimensionKey: '20001',
value: '销售额'
}
]),
(option.rows = [
{
dimensionKey: '20001',
title: '销售额',
headerStyle: {
color: 'red',
cursor: 'pointer'
}
}
]),
tableInstance.updateOption(option);
};
}
4 changes: 4 additions & 0 deletions packages/vtable/examples/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ export const menus = [
{
path: 'debug',
name: 'animation'
},
{
path: 'debug',
name: 'scroll'
}
]
},
Expand Down
18 changes: 7 additions & 11 deletions packages/vtable/src/core/BaseTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ import type {
TableEventOptions,
WidthAdaptiveModeDef,
HeightAdaptiveModeDef,
ListTableAPI
ListTableAPI,
ColumnInfo,
RowInfo
} from '../ts-types';
import { event, style as utilStyle } from '../tools/helper';

Expand Down Expand Up @@ -2460,7 +2462,7 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI {
* @param absoluteX
* @returns
*/
getTargetColAt(absoluteX: number): { col: number; left: number; right: number; width: number } | null {
getTargetColAt(absoluteX: number): ColumnInfo | null {
if (absoluteX === 0) {
return { left: 0, col: 0, right: 0, width: 0 };
}
Expand Down Expand Up @@ -2529,7 +2531,7 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI {
* @param absoluteX
* @returns
*/
getTargetRowAt(absoluteY: number): { row: number; top: number; bottom: number; height: number } | null {
getTargetRowAt(absoluteY: number): RowInfo | null {
if (absoluteY === 0) {
return { top: 0, row: 0, bottom: 0, height: 0 };
}
Expand Down Expand Up @@ -2604,10 +2606,7 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI {
* @param absoluteX
* @returns
*/
getTargetColAtConsiderRightFrozen(
absoluteX: number,
isConsider: boolean
): { col: number; left: number; right: number; width: number } | null {
getTargetColAtConsiderRightFrozen(absoluteX: number, isConsider: boolean): ColumnInfo | null {
if (absoluteX === 0) {
return { left: 0, col: 0, right: 0, width: 0 };
}
Expand Down Expand Up @@ -2636,10 +2635,7 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI {
* @param absoluteX
* @returns
*/
getTargetRowAtConsiderBottomFrozen(
absoluteY: number,
isConsider: boolean
): { row: number; top: number; bottom: number; height: number } | null {
getTargetRowAtConsiderBottomFrozen(absoluteY: number, isConsider: boolean): RowInfo | null {
if (absoluteY === 0) {
return { top: 0, row: 0, bottom: 0, height: 0 };
}
Expand Down
25 changes: 19 additions & 6 deletions packages/vtable/src/scenegraph/group-creater/progress/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { sortHorizontal } from './update-position/sort-horizontal';
import { updateAutoColumn } from './update-position/update-auto-column';
import { getDefaultHeight, getDefaultWidth } from './default-width-height';
import { handleTextStick } from '../../stick-text';
import type { ColumnInfo, RowInfo } from '../../../ts-types';

export class SceneProxy {
table: BaseTableAPI;
Expand Down Expand Up @@ -453,6 +454,12 @@ export class SceneProxy {
const yLimitTop =
this.table.getRowsHeight(this.bodyTopRow, this.bodyTopRow + (this.rowEnd - this.rowStart + 1)) / 2;
const yLimitBottom = this.table.getAllRowsHeight() - yLimitTop;

const screenTop = this.table.getTargetRowAt(y + this.table.scenegraph.colHeaderGroup.attribute.height);
if (screenTop) {
this.screenTopRow = screenTop.row;
}

if (y < yLimitTop && this.rowStart === this.bodyTopRow) {
// 执行真实body group坐标修改
this.updateDeltaY(y);
Expand All @@ -471,14 +478,20 @@ export class SceneProxy {
this.updateBody(y - this.deltaY);
} else {
// 执行动态更新节点
this.dynamicSetY(y, isEnd);
this.dynamicSetY(y, screenTop, isEnd);
}
}

async setX(x: number, isEnd = false) {
const xLimitLeft =
this.table.getColsWidth(this.bodyLeftCol, this.bodyLeftCol + (this.colEnd - this.colStart + 1)) / 2;
const xLimitRight = this.table.getAllColsWidth() - xLimitLeft;

const screenLeft = this.table.getTargetColAt(x + this.table.scenegraph.rowHeaderGroup.attribute.width);
if (screenLeft) {
this.screenLeftCol = screenLeft.col;
}

if (x < xLimitLeft && this.colStart === this.bodyLeftCol) {
// 执行真实body group坐标修改
this.updateDeltaX(x);
Expand All @@ -496,15 +509,15 @@ export class SceneProxy {
this.table.scenegraph.setBodyAndColHeaderX(-x + this.deltaX);
} else {
// 执行动态更新节点
this.dynamicSetX(x, isEnd);
this.dynamicSetX(x, screenLeft, isEnd);
}
}

async dynamicSetY(y: number, isEnd = false) {
dynamicSetY(y, isEnd, this);
async dynamicSetY(y: number, screenTop: RowInfo | null, isEnd = false) {
dynamicSetY(y, screenTop, isEnd, this);
}
async dynamicSetX(x: number, isEnd = false) {
dynamicSetX(x, isEnd, this);
async dynamicSetX(x: number, screenLeft: ColumnInfo | null, isEnd = false) {
dynamicSetX(x, screenLeft, isEnd, this);
}

updateBody(y: number) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import type { ColumnInfo } from '../../../../ts-types';
import type { BaseTableAPI } from '../../../../ts-types/base-table';
import type { Group } from '../../../graphic/group';
import { computeColsWidth } from '../../../layout/compute-col-width';
import type { SceneProxy } from '../proxy';
import { updateAutoColumn } from './update-auto-column';
import { checkFirstColMerge, getFirstChild, getLastChild } from './util';

export async function dynamicSetX(x: number, isEnd: boolean, proxy: SceneProxy) {
const screenLeft = (proxy.table as BaseTableAPI).getTargetColAt(
x + proxy.table.scenegraph.rowHeaderGroup.attribute.width
);
export async function dynamicSetX(x: number, screenLeft: ColumnInfo | null, isEnd: boolean, proxy: SceneProxy) {
if (!screenLeft) {
return;
}
const screenLeftCol = screenLeft.col;
const screenLeftX = screenLeft.left;
proxy.screenLeftCol = screenLeftCol;

let deltaCol;
if (isEnd) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import type { RowInfo } from '../../../../ts-types';
import type { Group } from '../../../graphic/group';
import { computeRowsHeight } from '../../../layout/compute-row-height';
import type { SceneProxy } from '../proxy';
import { updateAutoRow } from './update-auto-row';

export async function dynamicSetY(y: number, isEnd: boolean, proxy: SceneProxy) {
// 计算变动row range
// const screenTopRow = proxy.table.getRowAt(y).row;
const screenTop = (proxy.table as any).getTargetRowAt(y + proxy.table.scenegraph.colHeaderGroup.attribute.height);
export async function dynamicSetY(y: number, screenTop: RowInfo | null, isEnd: boolean, proxy: SceneProxy) {
if (!screenTop) {
return;
}
const screenTopRow = screenTop.row;
const screenTopY = screenTop.top;
proxy.screenTopRow = screenTopRow;

let deltaRow;
if (isEnd) {
deltaRow = proxy.bodyBottomRow - proxy.rowEnd;
Expand Down Expand Up @@ -108,7 +106,8 @@ async function moveCell(
proxy.rowStart = direction === 'up' ? proxy.rowStart + count : proxy.rowStart - count;
proxy.rowEnd = direction === 'up' ? proxy.rowEnd + count : proxy.rowEnd - count;

updateRowContent(syncTopRow, syncBottomRow, proxy, true);
// 本次行更新是否同步完成,列数超过limit时为false
const sync = updateRowContent(syncTopRow, syncBottomRow, proxy, true);

if (proxy.table.heightMode === 'autoHeight') {
// body group
Expand Down Expand Up @@ -168,17 +167,15 @@ async function moveCell(
proxy.referenceRow = proxy.rowStart + Math.floor((proxy.rowEnd - proxy.rowStart) / 2);
// proxy.referenceRow = screenTopRow;
// proxy.rowUpdatePos = Math.min(proxy.rowUpdatePos, distStartRow);
if (proxy.table.heightMode === 'autoHeight') {
if (proxy.table.heightMode === 'autoHeight' && sync) {
proxy.rowUpdatePos = Math.min(proxy.rowUpdatePos, proxy.rowEnd + 1);
} else {
proxy.rowUpdatePos = Math.min(proxy.rowUpdatePos, distStartRow);
}
proxy.rowUpdateDirection = direction;

proxy.table.scenegraph.updateNextFrame();
if (proxy.table.heightMode !== 'autoHeight') {
await proxy.progress();
}
await proxy.progress();
} else {
const distStartRow = direction === 'up' ? proxy.rowStart + count : proxy.rowStart - count;
const distEndRow = direction === 'up' ? proxy.rowEnd + count : proxy.rowEnd - count;
Expand All @@ -202,7 +199,7 @@ async function moveCell(
proxy.rowStart = distStartRow;
proxy.rowEnd = distEndRow;

updateRowContent(syncTopRow, syncBottomRow, proxy, true);
const sync = updateRowContent(syncTopRow, syncBottomRow, proxy, true);

if (proxy.table.heightMode === 'autoHeight') {
// body group
Expand Down Expand Up @@ -263,17 +260,15 @@ async function moveCell(
);
proxy.referenceRow = proxy.rowStart + Math.floor((proxy.rowEnd - proxy.rowStart) / 2);
// proxy.referenceRow = screenTopRow;
if (proxy.table.heightMode === 'autoHeight') {
if (proxy.table.heightMode === 'autoHeight' && sync) {
proxy.rowUpdatePos = proxy.rowEnd + 1;
} else {
proxy.rowUpdatePos = proxy.rowStart;
}
proxy.rowUpdateDirection = distEndRow > proxy.bodyBottomRow - (proxy.rowEnd - proxy.rowStart + 1) ? 'down' : 'up';

proxy.table.scenegraph.updateNextFrame();
if (proxy.table.heightMode !== 'autoHeight') {
await proxy.progress();
}
await proxy.progress();
}
}

Expand Down Expand Up @@ -396,10 +391,14 @@ export function updateRowContent(syncTopRow: number, syncBottomRow: number, prox
// body group
let leftCol = proxy.bodyLeftCol;
let rightCol = proxy.bodyRightCol;
let sync = true;
if (async) {
const screenLeftCol = proxy.screenLeftCol;
leftCol = Math.max(proxy.bodyLeftCol, screenLeftCol - proxy.screenColCount * 1);
rightCol = Math.min(proxy.bodyRightCol, screenLeftCol + proxy.screenColCount * 2);
if (leftCol !== proxy.bodyLeftCol || rightCol !== proxy.bodyRightCol) {
sync = false;
}
}
for (let col = leftCol; col <= rightCol; col++) {
for (let row = syncTopRow; row <= syncBottomRow; row++) {
Expand All @@ -409,4 +408,6 @@ export function updateRowContent(syncTopRow: number, syncBottomRow: number, prox
}
}
proxy.table.scenegraph.updateNextFrame();

return sync;
}
Loading

0 comments on commit c4fb076

Please sign in to comment.