Skip to content

Commit 52de25a

Browse files
authored
Merge pull request #3609 from VisActor/fix/react-component-update
Fix/react component update
2 parents d31c47c + 9145819 commit 52de25a

File tree

24 files changed

+202
-86
lines changed

24 files changed

+202
-86
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@visactor/vtable",
5+
"comment": "fix: fix react component update #3474",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@visactor/vtable"
10+
}

packages/react-vtable/src/table-components/custom/custom-layout.tsx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,28 @@ export const CustomLayout: React.FC<CustomLayoutProps> = (props: PropsWithChildr
3131
// customLayout function for vtable
3232
const createGraphic: ICustomLayoutFuc = useCallback(
3333
args => {
34-
const key = `${args.originCol ?? args.col}-${args.originRow ?? args.row}`;
34+
const key = `${args.originCol ?? args.col}-${args.originRow ?? args.row}${
35+
args.forComputation ? '-forComputation' : ''
36+
}`;
3537
let group;
3638
if (container.current.has(key)) {
3739
const currentContainer = container.current.get(key);
38-
// reconcilor.updateContainer(React.cloneElement(children, { ...args }), currentContainer, null);
3940
reconcilorUpdateContainer(children, currentContainer, args);
4041
group = currentContainer.containerInfo;
41-
// 这里更新group,可能会残留dx dy
4242
} else {
4343
group = new Group({});
44-
const currentContainer = reconcilor.createContainer(group, LegacyRoot, null, null, null, 'custom', null, null);
44+
const currentContainer = reconcilor.createContainer(
45+
group as any,
46+
LegacyRoot,
47+
null,
48+
null,
49+
null,
50+
'custom',
51+
null,
52+
null
53+
);
4554
container.current.set(key, currentContainer);
4655
reconcilorUpdateContainer(children, currentContainer, args);
47-
// const ele = React.cloneElement(children, { ...args });
48-
// reconcilor.updateContainer(ele, currentContainer, null);
4956
}
5057

5158
return {

packages/vtable/__tests__/listTable-highlightInRange.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ describe('listTable init test', () => {
195195
expect(listTable.stateManager?.select.ranges).toEqual([
196196
{ start: { col: 1, row: 3 }, end: { col: 4, row: 6 }, skipBodyMerge: true },
197197
{ start: { col: 0, row: 4 }, end: { col: 7, row: 4 }, skipBodyMerge: true },
198-
{ start: { col: 4, row: 36 }, end: { col: 7, row: 36 }, skipBodyMerge: true }
198+
{ start: { col: 4, row: 20 }, end: { col: 7, row: 20 }, skipBodyMerge: true }
199199
]);
200200
expect(listTable.getScrollTop()).toBe(scrollTop);
201201
});

packages/vtable/__tests__/listTable.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ describe('listTable init test', () => {
192192
expect(listTable.stateManager?.select.ranges).toEqual([
193193
{ start: { col: 1, row: 3 }, end: { col: 4, row: 6 }, skipBodyMerge: true },
194194
{ start: { col: 0, row: 4 }, end: { col: 7, row: 4 }, skipBodyMerge: true },
195-
{ start: { col: 4, row: 36 }, end: { col: 7, row: 36 }, skipBodyMerge: true }
195+
{ start: { col: 4, row: 20 }, end: { col: 7, row: 20 }, skipBodyMerge: true }
196196
]);
197197
expect(listTable.getScrollTop()).toBe(scrollTop);
198198
});

packages/vtable/examples/interactive/custom-scroll.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ class VTablePaddingOperator {
552552
// right
553553
this.x2 = Math.max(this.x2Target - this.padding[1], this.x2 - (e.dx || 1));
554554

555-
console.log('left', this.x2);
555+
// console.log('left', this.x2);
556556
setTimeout(() => {
557557
this.clearCanvas();
558558
this.updateViewBox();
@@ -562,21 +562,21 @@ class VTablePaddingOperator {
562562
// left
563563
this.x2 = Math.min(this.x2Target, this.x2 - (e.dx ?? 0));
564564

565-
console.log('right', this.x2);
565+
// console.log('right', this.x2);
566566
setTimeout(() => {
567567
this.clearCanvas();
568568
this.updateViewBox();
569569
this.table.scenegraph.setX(-this.table.stateManager.scroll.horizontalBarPos - 1, true);
570570
}, 0);
571571
} else {
572-
console.log('normal', this.x2);
572+
// console.log('normal', this.x2);
573573
}
574574

575575
// vertical scroll
576576
if (e.scrollRatioY === 1 && (e.dy ?? 0) >= 0 && this.y2 > this.y2Target - this.padding[2]) {
577577
// bottom
578578
this.y2 = Math.max(this.y2Target - this.padding[2], this.y2 - (e.dy || 1));
579-
console.log('top', this.y2);
579+
// console.log('top', this.y2);
580580
setTimeout(() => {
581581
this.clearCanvas();
582582
this.updateViewBox();
@@ -585,14 +585,14 @@ class VTablePaddingOperator {
585585
} else if (this.y2 < this.y2Target && (e.dy ?? 0) < 0) {
586586
// top
587587
this.y2 = Math.min(this.y2Target, this.y2 - (e.dy ?? 0));
588-
console.log('bottom', this.y2);
588+
// console.log('bottom', this.y2);
589589
setTimeout(() => {
590590
this.clearCanvas();
591591
this.updateViewBox();
592592
this.table.scenegraph.setY(-this.table.stateManager.scroll.verticalBarPos - 1, true);
593593
}, 0);
594594
} else {
595-
console.log('normal', this.y2);
595+
// console.log('normal', this.y2);
596596
}
597597
});
598598
}
@@ -614,6 +614,8 @@ class VTablePaddingOperator {
614614
x2: this.x2,
615615
y2: this.y2
616616
});
617+
this.clearCanvas();
618+
this.table.render();
617619
}
618620

619621
reset() {

packages/vtable/src/PivotTable.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1885,7 +1885,7 @@ export class PivotTable extends BaseTable implements PivotTableAPI {
18851885
if (this.internalProps._heightResizedRowMap.size === 0) {
18861886
this.scenegraph.recalculateRowHeights();
18871887
}
1888-
} else if (this.isAutoRowHeight() && !this.internalProps._heightResizedRowMap.has(row)) {
1888+
} else if (this.isAutoRowHeight(row) && !this.internalProps._heightResizedRowMap.has(row)) {
18891889
const oldHeight = this.getRowHeight(row);
18901890
const newHeight = computeRowHeight(row, 0, this.colCount - 1, this);
18911891
this.scenegraph.updateRowHeight(row, newHeight - oldHeight);
@@ -2003,7 +2003,7 @@ export class PivotTable extends BaseTable implements PivotTableAPI {
20032003

20042004
if (this.heightMode === 'adaptive' || (this.autoFillHeight && this.getAllRowsHeight() <= this.tableNoFrameHeight)) {
20052005
this.scenegraph.recalculateRowHeights();
2006-
} else if (this.isAutoRowHeight()) {
2006+
} else if (this.isAutoRowHeight(startRow)) {
20072007
const rows: number[] = [];
20082008
const deltaYs: number[] = [];
20092009
for (let sRow = startRow; sRow <= range.end.row; sRow++) {

packages/vtable/src/components/react/react-custom-layout.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,17 @@ export class ReactCustomLayout {
9090
// }
9191
// }
9292

93+
if (table.widthMode === 'autoWidth') {
94+
table.scenegraph.recalculateColWidths();
95+
}
96+
if (
97+
table.isAutoRowHeight() ||
98+
(table.internalProps.defaultRowHeight === 'auto' && !isHeaderCustomLayout) ||
99+
(table.internalProps.defaultHeaderRowHeight === 'auto' && isHeaderCustomLayout)
100+
) {
101+
table.scenegraph.recalculateRowHeights();
102+
}
103+
93104
if (table.isPivotTable()) {
94105
const ranges = getUpdateCustomCellRangeInPivotTable(componentId, table, isHeaderCustomLayout);
95106
for (let i = 0; i < ranges.length; i++) {
@@ -108,12 +119,7 @@ export class ReactCustomLayout {
108119
}
109120
}
110121
}
111-
if (table.widthMode === 'autoWidth') {
112-
table.scenegraph.recalculateColWidths();
113-
}
114-
if (table.isAutoRowHeight()) {
115-
table.scenegraph.recalculateRowHeights();
116-
}
122+
117123
// table.scenegraph.updateNextFrame();
118124
table.scenegraph.renderSceneGraph(); // use sync render for faster update
119125
}

packages/vtable/src/core/BaseTable.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,7 +1489,8 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI {
14891489
} else if (row >= 0 && row < this.columnHeaderLevelCount) {
14901490
return this.getDefaultRowHeight(row) === 'auto';
14911491
}
1492-
return false;
1492+
// return false;
1493+
return this.internalProps.defaultRowHeight === 'auto';
14931494
}
14941495
/**
14951496
* 根据列号获取列宽定义
@@ -3126,7 +3127,19 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI {
31263127
customMerge.range &&
31273128
(isValid(customMerge.text) || customMerge.customLayout || customMerge.customRender)
31283129
) {
3129-
return customMerge.range;
3130+
// return customMerge.range;
3131+
// trim range
3132+
const range = {
3133+
start: {
3134+
col: Math.max(customMerge.range.start.col, 0),
3135+
row: Math.max(customMerge.range.start.row, 0)
3136+
},
3137+
end: {
3138+
col: Math.min(customMerge.range.end.col, this.colCount - 1),
3139+
row: Math.min(customMerge.range.end.row, this.rowCount - 1)
3140+
}
3141+
};
3142+
return range;
31303143
}
31313144
}
31323145
return this.internalProps.layoutMap?.getCellRange(col, row);

packages/vtable/src/core/TABLE_EVENT_TYPE.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ export interface TableEvents {
100100
* 滚动表格事件
101101
*/
102102
SCROLL: 'scroll';
103+
CAN_SCROLL: 'can_scroll';
103104
/**
104105
* 横向滚动条滚动到结束位
105106
*/
@@ -226,6 +227,7 @@ export const TABLE_EVENT_TYPE: TableEvents = {
226227
AFTER_SORT: 'after_sort',
227228
FREEZE_CLICK: 'freeze_click',
228229
SCROLL: 'scroll',
230+
CAN_SCROLL: 'can_scroll',
229231
SCROLL_HORIZONTAL_END: 'scroll_horizontal_end',
230232
SCROLL_VERTICAL_END: 'scroll_vertical_end',
231233
DROPDOWN_MENU_CLICK: 'dropdown_menu_click',

packages/vtable/src/core/record-helper.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export function listTableChangeCellValue(
8585
if (table.internalProps._heightResizedRowMap.size === 0) {
8686
table.scenegraph.recalculateRowHeights();
8787
}
88-
} else if (table.isAutoRowHeight() && !table.internalProps._heightResizedRowMap.has(row)) {
88+
} else if (table.isAutoRowHeight(row) && !table.internalProps._heightResizedRowMap.has(row)) {
8989
const oldHeight = table.getRowHeight(row);
9090
const newHeight = computeRowHeight(row, 0, table.colCount - 1, table);
9191
table.scenegraph.updateRowHeight(row, newHeight - oldHeight);
@@ -283,7 +283,7 @@ export function listTableChangeCellValues(
283283
(table.autoFillHeight && table.getAllRowsHeight() <= table.tableNoFrameHeight)
284284
) {
285285
table.scenegraph.recalculateRowHeights();
286-
} else if (table.isAutoRowHeight()) {
286+
} else if (table.isAutoRowHeight(startRow)) {
287287
const rows: number[] = [];
288288
const deltaYs: number[] = [];
289289
for (let sRow = startRow; sRow <= range.end.row; sRow++) {

packages/vtable/src/scenegraph/group-creater/cell-helper.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,11 @@ export function updateCell(
504504
) {
505505
// const oldCellGroup = table.scenegraph.getCell(col, row, true);
506506
const oldCellGroup = table.scenegraph.highPerformanceGetCell(col, row, true);
507+
508+
if (oldCellGroup.role !== 'cell' && !addNew) {
509+
return undefined;
510+
}
511+
507512
const cellLocation = table.getCellLocation(col, row);
508513
let value = table.getCellValue(col, row);
509514

packages/vtable/src/scenegraph/group-creater/cell-type/radio-cell.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ function createRadio(
151151
const autoWrapText = cellStyle.autoWrapText ?? table.internalProps.autoWrapText;
152152
const { lineClamp } = cellStyle;
153153
const autoColWidth = colWidth === 'auto';
154-
const autoRowHeight = table.isAutoRowHeight();
154+
const autoRowHeight = table.isAutoRowHeight(row);
155155

156156
const attribute = {
157157
// text: text.length === 1 ? text[0] : text,

packages/vtable/src/scenegraph/group-creater/cell-type/video-cell.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,13 +226,19 @@ export function createVideoCellGroup(
226226
const anchorY =
227227
top + (height > image.attribute.height ? image.attribute.y - top + image.attribute.height / 2 : height / 2);
228228

229+
// get dx dy of image graphic for merge cell
230+
const imageGraphic = cellGroup.getChildByName('image', true);
231+
const { dx, dy } = imageGraphic.attribute;
232+
229233
const playIcon: Icon = new Icon({
230234
x: anchorX - iconSize / 2,
231235
y: anchorY - iconSize / 2,
232236
width: iconSize,
233237
height: iconSize,
234238
image: (regedIcons.play as any).svg,
235-
cursor: (regedIcons.play as any).cursor
239+
cursor: (regedIcons.play as any).cursor,
240+
dx,
241+
dy
236242
});
237243
playIcon.name = 'play-icon';
238244
cellGroup.appendChild(playIcon);

packages/vtable/src/scenegraph/group-creater/progress/create-group-for-first-screen.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ export function createGroupForFirstScreen(
3030
let distRowForCompute;
3131
if (
3232
table.widthMode === 'adaptive' ||
33-
(table.options.autoWrapText && (table.heightMode === 'adaptive' || table.isAutoRowHeight()))
33+
(table.options.autoWrapText &&
34+
(table.heightMode === 'adaptive' || table.isAutoRowHeight(table.columnHeaderLevelCount)))
3435
) {
3536
// distCol = table.colCount - 1;
3637
// proxy.colEnd = distCol;

packages/vtable/src/scenegraph/group-creater/progress/proxy.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export class SceneProxy {
7373
// this.colLimit = 100;
7474
this.rowLimit = Math.max(100, Math.ceil((table.tableNoFrameHeight * 2) / table.defaultRowHeight));
7575
this.colLimit = Math.max(100, Math.ceil((table.tableNoFrameWidth * 2) / table.defaultColWidth));
76-
} else if (this.table.isAutoRowHeight()) {
76+
} else if (this.table.isAutoRowHeight(table.columnHeaderLevelCount)) {
7777
// this.rowLimit = 100;
7878
this.rowLimit = Math.max(100, Math.ceil((table.tableNoFrameHeight * 2) / table.defaultRowHeight));
7979
} else if (this.table.widthMode === 'autoWidth') {
@@ -563,13 +563,13 @@ export class SceneProxy {
563563
updateCellGroups(count: number) {
564564
const distRow = Math.min(this.bodyBottomRow, this.rowUpdatePos + count);
565565
// console.log('updateCellGroups', this.rowUpdatePos, distRow);
566-
if (this.table.isAutoRowHeight()) {
566+
if (this.table.isAutoRowHeight(this.rowUpdatePos)) {
567567
computeRowsHeight(this.table, this.rowUpdatePos, distRow, false);
568568
}
569569

570570
updateRowContent(this.rowUpdatePos, distRow, this);
571571

572-
if (this.table.isAutoRowHeight()) {
572+
if (this.table.isAutoRowHeight(this.rowUpdatePos)) {
573573
// body group
574574
updateAutoRow(
575575
this.bodyLeftCol, // colStart
@@ -608,12 +608,12 @@ export class SceneProxy {
608608
updateBottomFrozenCellGroups() {
609609
const startRow = this.table.rowCount - this.table.bottomFrozenRowCount;
610610
const endRow = this.table.rowCount - 1;
611-
if (this.table.isAutoRowHeight()) {
611+
if (this.table.isAutoRowHeight(startRow)) {
612612
computeRowsHeight(this.table, startRow, endRow, false);
613613
}
614614
updateRowContent(startRow, endRow, this);
615615

616-
if (this.table.isAutoRowHeight()) {
616+
if (this.table.isAutoRowHeight(startRow)) {
617617
// body group
618618
updateAutoRow(
619619
this.bodyLeftCol, // colStart
@@ -653,7 +653,7 @@ export class SceneProxy {
653653
console.log('updateRightFrozenCellGroups', startCol, endCol);
654654
updateColContent(startCol, endCol, this);
655655

656-
if (this.table.isAutoRowHeight()) {
656+
if (this.table.isAutoRowHeight(this.rowStart)) {
657657
// body group
658658
updateAutoColumn(startCol, endCol, this.table, this.colUpdateDirection);
659659
}

packages/vtable/src/scenegraph/group-creater/progress/update-position/dynamic-set-y.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ async function moveCell(
8888
// 更新同步范围
8989
let syncTopRow;
9090
let syncBottomRow;
91-
if (proxy.table.isAutoRowHeight()) {
91+
if (proxy.table.isAutoRowHeight(startRow)) {
9292
syncTopRow = distStartRow;
9393
syncBottomRow = distEndRow;
9494
} else {
@@ -115,7 +115,7 @@ async function moveCell(
115115
// 本次行更新是否同步完成,列数超过limit时为false
116116
const sync = updateRowContent(syncTopRow, syncBottomRow, proxy, true);
117117

118-
if (proxy.table.isAutoRowHeight()) {
118+
if (proxy.table.isAutoRowHeight(startRow)) {
119119
// body group
120120
updateAutoRow(
121121
proxy.bodyLeftCol, // colStart
@@ -177,7 +177,7 @@ async function moveCell(
177177
proxy.referenceRow = proxy.rowStart + Math.floor((proxy.rowEnd - proxy.rowStart) / 2);
178178
// proxy.referenceRow = screenTopRow;
179179
// proxy.rowUpdatePos = Math.min(proxy.rowUpdatePos, distStartRow);
180-
if (proxy.table.isAutoRowHeight() && sync) {
180+
if (proxy.table.isAutoRowHeight(startRow) && sync) {
181181
proxy.rowUpdatePos = Math.min(proxy.rowUpdatePos, proxy.rowEnd + 1);
182182
} else {
183183
proxy.rowUpdatePos = Math.min(proxy.rowUpdatePos, distStartRow);
@@ -196,7 +196,7 @@ async function moveCell(
196196

197197
let syncTopRow;
198198
let syncBottomRow;
199-
if (proxy.table.isAutoRowHeight()) {
199+
if (proxy.table.isAutoRowHeight(distStartRow)) {
200200
syncTopRow = distStartRow;
201201
syncBottomRow = distEndRow;
202202
} else {
@@ -214,7 +214,7 @@ async function moveCell(
214214

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

217-
if (proxy.table.isAutoRowHeight()) {
217+
if (proxy.table.isAutoRowHeight(distStartRow)) {
218218
// body group
219219
updateAutoRow(
220220
proxy.bodyLeftCol, // colStart
@@ -277,7 +277,7 @@ async function moveCell(
277277
);
278278
proxy.referenceRow = proxy.rowStart + Math.floor((proxy.rowEnd - proxy.rowStart) / 2);
279279
// proxy.referenceRow = screenTopRow;
280-
if (proxy.table.isAutoRowHeight() && sync) {
280+
if (proxy.table.isAutoRowHeight(distStartRow) && sync) {
281281
proxy.rowUpdatePos = proxy.rowEnd + 1;
282282
} else {
283283
proxy.rowUpdatePos = proxy.rowStart;

0 commit comments

Comments
 (0)