Skip to content

Fix/react component update #3609

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Mar 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@visactor/vtable",
"comment": "fix: fix react component update #3474",
"type": "none"
}
],
"packageName": "@visactor/vtable"
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,28 @@ export const CustomLayout: React.FC<CustomLayoutProps> = (props: PropsWithChildr
// customLayout function for vtable
const createGraphic: ICustomLayoutFuc = useCallback(
args => {
const key = `${args.originCol ?? args.col}-${args.originRow ?? args.row}`;
const key = `${args.originCol ?? args.col}-${args.originRow ?? args.row}${
args.forComputation ? '-forComputation' : ''
}`;
let group;
if (container.current.has(key)) {
const currentContainer = container.current.get(key);
// reconcilor.updateContainer(React.cloneElement(children, { ...args }), currentContainer, null);
reconcilorUpdateContainer(children, currentContainer, args);
group = currentContainer.containerInfo;
// 这里更新group,可能会残留dx dy
} else {
group = new Group({});
const currentContainer = reconcilor.createContainer(group, LegacyRoot, null, null, null, 'custom', null, null);
const currentContainer = reconcilor.createContainer(
group as any,
LegacyRoot,
null,
null,
null,
'custom',
null,
null
);
container.current.set(key, currentContainer);
reconcilorUpdateContainer(children, currentContainer, args);
// const ele = React.cloneElement(children, { ...args });
// reconcilor.updateContainer(ele, currentContainer, null);
}

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ describe('listTable init test', () => {
expect(listTable.stateManager?.select.ranges).toEqual([
{ start: { col: 1, row: 3 }, end: { col: 4, row: 6 }, skipBodyMerge: true },
{ start: { col: 0, row: 4 }, end: { col: 7, row: 4 }, skipBodyMerge: true },
{ start: { col: 4, row: 36 }, end: { col: 7, row: 36 }, skipBodyMerge: true }
{ start: { col: 4, row: 20 }, end: { col: 7, row: 20 }, skipBodyMerge: true }
]);
expect(listTable.getScrollTop()).toBe(scrollTop);
});
Expand Down
2 changes: 1 addition & 1 deletion packages/vtable/__tests__/listTable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ describe('listTable init test', () => {
expect(listTable.stateManager?.select.ranges).toEqual([
{ start: { col: 1, row: 3 }, end: { col: 4, row: 6 }, skipBodyMerge: true },
{ start: { col: 0, row: 4 }, end: { col: 7, row: 4 }, skipBodyMerge: true },
{ start: { col: 4, row: 36 }, end: { col: 7, row: 36 }, skipBodyMerge: true }
{ start: { col: 4, row: 20 }, end: { col: 7, row: 20 }, skipBodyMerge: true }
]);
expect(listTable.getScrollTop()).toBe(scrollTop);
});
Expand Down
14 changes: 8 additions & 6 deletions packages/vtable/examples/interactive/custom-scroll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ class VTablePaddingOperator {
// right
this.x2 = Math.max(this.x2Target - this.padding[1], this.x2 - (e.dx || 1));

console.log('left', this.x2);
// console.log('left', this.x2);
setTimeout(() => {
this.clearCanvas();
this.updateViewBox();
Expand All @@ -562,21 +562,21 @@ class VTablePaddingOperator {
// left
this.x2 = Math.min(this.x2Target, this.x2 - (e.dx ?? 0));

console.log('right', this.x2);
// console.log('right', this.x2);
setTimeout(() => {
this.clearCanvas();
this.updateViewBox();
this.table.scenegraph.setX(-this.table.stateManager.scroll.horizontalBarPos - 1, true);
}, 0);
} else {
console.log('normal', this.x2);
// console.log('normal', this.x2);
}

// vertical scroll
if (e.scrollRatioY === 1 && (e.dy ?? 0) >= 0 && this.y2 > this.y2Target - this.padding[2]) {
// bottom
this.y2 = Math.max(this.y2Target - this.padding[2], this.y2 - (e.dy || 1));
console.log('top', this.y2);
// console.log('top', this.y2);
setTimeout(() => {
this.clearCanvas();
this.updateViewBox();
Expand All @@ -585,14 +585,14 @@ class VTablePaddingOperator {
} else if (this.y2 < this.y2Target && (e.dy ?? 0) < 0) {
// top
this.y2 = Math.min(this.y2Target, this.y2 - (e.dy ?? 0));
console.log('bottom', this.y2);
// console.log('bottom', this.y2);
setTimeout(() => {
this.clearCanvas();
this.updateViewBox();
this.table.scenegraph.setY(-this.table.stateManager.scroll.verticalBarPos - 1, true);
}, 0);
} else {
console.log('normal', this.y2);
// console.log('normal', this.y2);
}
});
}
Expand All @@ -614,6 +614,8 @@ class VTablePaddingOperator {
x2: this.x2,
y2: this.y2
});
this.clearCanvas();
this.table.render();
}

reset() {
Expand Down
4 changes: 2 additions & 2 deletions packages/vtable/src/PivotTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1885,7 +1885,7 @@ export class PivotTable extends BaseTable implements PivotTableAPI {
if (this.internalProps._heightResizedRowMap.size === 0) {
this.scenegraph.recalculateRowHeights();
}
} else if (this.isAutoRowHeight() && !this.internalProps._heightResizedRowMap.has(row)) {
} else if (this.isAutoRowHeight(row) && !this.internalProps._heightResizedRowMap.has(row)) {
const oldHeight = this.getRowHeight(row);
const newHeight = computeRowHeight(row, 0, this.colCount - 1, this);
this.scenegraph.updateRowHeight(row, newHeight - oldHeight);
Expand Down Expand Up @@ -2003,7 +2003,7 @@ export class PivotTable extends BaseTable implements PivotTableAPI {

if (this.heightMode === 'adaptive' || (this.autoFillHeight && this.getAllRowsHeight() <= this.tableNoFrameHeight)) {
this.scenegraph.recalculateRowHeights();
} else if (this.isAutoRowHeight()) {
} else if (this.isAutoRowHeight(startRow)) {
const rows: number[] = [];
const deltaYs: number[] = [];
for (let sRow = startRow; sRow <= range.end.row; sRow++) {
Expand Down
18 changes: 12 additions & 6 deletions packages/vtable/src/components/react/react-custom-layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,17 @@ export class ReactCustomLayout {
// }
// }

if (table.widthMode === 'autoWidth') {
table.scenegraph.recalculateColWidths();
}
if (
table.isAutoRowHeight() ||
(table.internalProps.defaultRowHeight === 'auto' && !isHeaderCustomLayout) ||
(table.internalProps.defaultHeaderRowHeight === 'auto' && isHeaderCustomLayout)
) {
table.scenegraph.recalculateRowHeights();
}

if (table.isPivotTable()) {
const ranges = getUpdateCustomCellRangeInPivotTable(componentId, table, isHeaderCustomLayout);
for (let i = 0; i < ranges.length; i++) {
Expand All @@ -108,12 +119,7 @@ export class ReactCustomLayout {
}
}
}
if (table.widthMode === 'autoWidth') {
table.scenegraph.recalculateColWidths();
}
if (table.isAutoRowHeight()) {
table.scenegraph.recalculateRowHeights();
}

// table.scenegraph.updateNextFrame();
table.scenegraph.renderSceneGraph(); // use sync render for faster update
}
Expand Down
17 changes: 15 additions & 2 deletions packages/vtable/src/core/BaseTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1489,7 +1489,8 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI {
} else if (row >= 0 && row < this.columnHeaderLevelCount) {
return this.getDefaultRowHeight(row) === 'auto';
}
return false;
// return false;
return this.internalProps.defaultRowHeight === 'auto';
}
/**
* 根据列号获取列宽定义
Expand Down Expand Up @@ -3126,7 +3127,19 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI {
customMerge.range &&
(isValid(customMerge.text) || customMerge.customLayout || customMerge.customRender)
) {
return customMerge.range;
// return customMerge.range;
// trim range
const range = {
start: {
col: Math.max(customMerge.range.start.col, 0),
row: Math.max(customMerge.range.start.row, 0)
},
end: {
col: Math.min(customMerge.range.end.col, this.colCount - 1),
row: Math.min(customMerge.range.end.row, this.rowCount - 1)
}
};
return range;
}
}
return this.internalProps.layoutMap?.getCellRange(col, row);
Expand Down
2 changes: 2 additions & 0 deletions packages/vtable/src/core/TABLE_EVENT_TYPE.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export interface TableEvents {
* 滚动表格事件
*/
SCROLL: 'scroll';
CAN_SCROLL: 'can_scroll';
/**
* 横向滚动条滚动到结束位
*/
Expand Down Expand Up @@ -226,6 +227,7 @@ export const TABLE_EVENT_TYPE: TableEvents = {
AFTER_SORT: 'after_sort',
FREEZE_CLICK: 'freeze_click',
SCROLL: 'scroll',
CAN_SCROLL: 'can_scroll',
SCROLL_HORIZONTAL_END: 'scroll_horizontal_end',
SCROLL_VERTICAL_END: 'scroll_vertical_end',
DROPDOWN_MENU_CLICK: 'dropdown_menu_click',
Expand Down
4 changes: 2 additions & 2 deletions packages/vtable/src/core/record-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export function listTableChangeCellValue(
if (table.internalProps._heightResizedRowMap.size === 0) {
table.scenegraph.recalculateRowHeights();
}
} else if (table.isAutoRowHeight() && !table.internalProps._heightResizedRowMap.has(row)) {
} else if (table.isAutoRowHeight(row) && !table.internalProps._heightResizedRowMap.has(row)) {
const oldHeight = table.getRowHeight(row);
const newHeight = computeRowHeight(row, 0, table.colCount - 1, table);
table.scenegraph.updateRowHeight(row, newHeight - oldHeight);
Expand Down Expand Up @@ -283,7 +283,7 @@ export function listTableChangeCellValues(
(table.autoFillHeight && table.getAllRowsHeight() <= table.tableNoFrameHeight)
) {
table.scenegraph.recalculateRowHeights();
} else if (table.isAutoRowHeight()) {
} else if (table.isAutoRowHeight(startRow)) {
const rows: number[] = [];
const deltaYs: number[] = [];
for (let sRow = startRow; sRow <= range.end.row; sRow++) {
Expand Down
5 changes: 5 additions & 0 deletions packages/vtable/src/scenegraph/group-creater/cell-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,11 @@ export function updateCell(
) {
// const oldCellGroup = table.scenegraph.getCell(col, row, true);
const oldCellGroup = table.scenegraph.highPerformanceGetCell(col, row, true);

if (oldCellGroup.role !== 'cell' && !addNew) {
return undefined;
}

const cellLocation = table.getCellLocation(col, row);
let value = table.getCellValue(col, row);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ function createRadio(
const autoWrapText = cellStyle.autoWrapText ?? table.internalProps.autoWrapText;
const { lineClamp } = cellStyle;
const autoColWidth = colWidth === 'auto';
const autoRowHeight = table.isAutoRowHeight();
const autoRowHeight = table.isAutoRowHeight(row);

const attribute = {
// text: text.length === 1 ? text[0] : text,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,19 @@ export function createVideoCellGroup(
const anchorY =
top + (height > image.attribute.height ? image.attribute.y - top + image.attribute.height / 2 : height / 2);

// get dx dy of image graphic for merge cell
const imageGraphic = cellGroup.getChildByName('image', true);
const { dx, dy } = imageGraphic.attribute;

const playIcon: Icon = new Icon({
x: anchorX - iconSize / 2,
y: anchorY - iconSize / 2,
width: iconSize,
height: iconSize,
image: (regedIcons.play as any).svg,
cursor: (regedIcons.play as any).cursor
cursor: (regedIcons.play as any).cursor,
dx,
dy
});
playIcon.name = 'play-icon';
cellGroup.appendChild(playIcon);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ export function createGroupForFirstScreen(
let distRowForCompute;
if (
table.widthMode === 'adaptive' ||
(table.options.autoWrapText && (table.heightMode === 'adaptive' || table.isAutoRowHeight()))
(table.options.autoWrapText &&
(table.heightMode === 'adaptive' || table.isAutoRowHeight(table.columnHeaderLevelCount)))
) {
// distCol = table.colCount - 1;
// proxy.colEnd = distCol;
Expand Down
12 changes: 6 additions & 6 deletions packages/vtable/src/scenegraph/group-creater/progress/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export class SceneProxy {
// this.colLimit = 100;
this.rowLimit = Math.max(100, Math.ceil((table.tableNoFrameHeight * 2) / table.defaultRowHeight));
this.colLimit = Math.max(100, Math.ceil((table.tableNoFrameWidth * 2) / table.defaultColWidth));
} else if (this.table.isAutoRowHeight()) {
} else if (this.table.isAutoRowHeight(table.columnHeaderLevelCount)) {
// this.rowLimit = 100;
this.rowLimit = Math.max(100, Math.ceil((table.tableNoFrameHeight * 2) / table.defaultRowHeight));
} else if (this.table.widthMode === 'autoWidth') {
Expand Down Expand Up @@ -563,13 +563,13 @@ export class SceneProxy {
updateCellGroups(count: number) {
const distRow = Math.min(this.bodyBottomRow, this.rowUpdatePos + count);
// console.log('updateCellGroups', this.rowUpdatePos, distRow);
if (this.table.isAutoRowHeight()) {
if (this.table.isAutoRowHeight(this.rowUpdatePos)) {
computeRowsHeight(this.table, this.rowUpdatePos, distRow, false);
}

updateRowContent(this.rowUpdatePos, distRow, this);

if (this.table.isAutoRowHeight()) {
if (this.table.isAutoRowHeight(this.rowUpdatePos)) {
// body group
updateAutoRow(
this.bodyLeftCol, // colStart
Expand Down Expand Up @@ -608,12 +608,12 @@ export class SceneProxy {
updateBottomFrozenCellGroups() {
const startRow = this.table.rowCount - this.table.bottomFrozenRowCount;
const endRow = this.table.rowCount - 1;
if (this.table.isAutoRowHeight()) {
if (this.table.isAutoRowHeight(startRow)) {
computeRowsHeight(this.table, startRow, endRow, false);
}
updateRowContent(startRow, endRow, this);

if (this.table.isAutoRowHeight()) {
if (this.table.isAutoRowHeight(startRow)) {
// body group
updateAutoRow(
this.bodyLeftCol, // colStart
Expand Down Expand Up @@ -653,7 +653,7 @@ export class SceneProxy {
console.log('updateRightFrozenCellGroups', startCol, endCol);
updateColContent(startCol, endCol, this);

if (this.table.isAutoRowHeight()) {
if (this.table.isAutoRowHeight(this.rowStart)) {
// body group
updateAutoColumn(startCol, endCol, this.table, this.colUpdateDirection);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ async function moveCell(
// 更新同步范围
let syncTopRow;
let syncBottomRow;
if (proxy.table.isAutoRowHeight()) {
if (proxy.table.isAutoRowHeight(startRow)) {
syncTopRow = distStartRow;
syncBottomRow = distEndRow;
} else {
Expand All @@ -115,7 +115,7 @@ async function moveCell(
// 本次行更新是否同步完成,列数超过limit时为false
const sync = updateRowContent(syncTopRow, syncBottomRow, proxy, true);

if (proxy.table.isAutoRowHeight()) {
if (proxy.table.isAutoRowHeight(startRow)) {
// body group
updateAutoRow(
proxy.bodyLeftCol, // colStart
Expand Down Expand Up @@ -177,7 +177,7 @@ 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.isAutoRowHeight() && sync) {
if (proxy.table.isAutoRowHeight(startRow) && sync) {
proxy.rowUpdatePos = Math.min(proxy.rowUpdatePos, proxy.rowEnd + 1);
} else {
proxy.rowUpdatePos = Math.min(proxy.rowUpdatePos, distStartRow);
Expand All @@ -196,7 +196,7 @@ async function moveCell(

let syncTopRow;
let syncBottomRow;
if (proxy.table.isAutoRowHeight()) {
if (proxy.table.isAutoRowHeight(distStartRow)) {
syncTopRow = distStartRow;
syncBottomRow = distEndRow;
} else {
Expand All @@ -214,7 +214,7 @@ async function moveCell(

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

if (proxy.table.isAutoRowHeight()) {
if (proxy.table.isAutoRowHeight(distStartRow)) {
// body group
updateAutoRow(
proxy.bodyLeftCol, // colStart
Expand Down Expand Up @@ -277,7 +277,7 @@ async function moveCell(
);
proxy.referenceRow = proxy.rowStart + Math.floor((proxy.rowEnd - proxy.rowStart) / 2);
// proxy.referenceRow = screenTopRow;
if (proxy.table.isAutoRowHeight() && sync) {
if (proxy.table.isAutoRowHeight(distStartRow) && sync) {
proxy.rowUpdatePos = proxy.rowEnd + 1;
} else {
proxy.rowUpdatePos = proxy.rowStart;
Expand Down
Loading
Loading