@visactor/vtable
Version:
canvas table width high performance
279 lines (263 loc) • 16.3 kB
JavaScript
import { isNumber, isValid } from "@visactor/vutils";
import { Group } from "../graphic/group";
import { updateCell } from "../group-creater/cell-helper";
import { getCellMergeInfo } from "../utils/get-cell-merge";
import { deduplication } from "../../tools/util";
export function updateRow(removeCells, addCells, updateCells, table, skipUpdateProxy) {
var _a, _b;
const scene = table.scenegraph, removeRows = deduplication(removeCells.map((cell => cell.row))).sort(((a, b) => b - a)), addRows = deduplication(addCells.map((cell => cell.row))).sort(((a, b) => a - b)), updateRows = deduplication(updateCells.map((cell => cell.row))).sort(((a, b) => a - b));
let rowUpdatePos;
if (updateRows.length) {
rowUpdatePos = _getUpdateRowIndexUseCellNode(updateRows[0] - 1, updateRows[updateRows.length - 1] + 1, scene);
}
if (addRows.length) {
const pos = _getUpdateRowIndexUseCellNode(addRows[0] - 1, addRows[addRows.length - 1] + 1, scene);
rowUpdatePos = isValid(rowUpdatePos) ? isValid(pos) ? Math.min(rowUpdatePos, pos) : rowUpdatePos : pos;
}
if (removeRows.length) {
const pos = _getUpdateRowIndexUseCellNode(removeRows[0] - 1, removeRows[removeRows.length - 1] + 1, scene);
rowUpdatePos = isValid(rowUpdatePos) ? isValid(pos) ? Math.min(rowUpdatePos, pos) : rowUpdatePos : pos;
}
removeRows.forEach((row => {
removeRow(row, scene, skipUpdateProxy);
}));
const rowHeightsMap = table.rowHeightsMap;
if (removeRows.forEach((row => {
rowHeightsMap.delete(row);
})), removeRows.length) {
resetRowNumber(scene);
const pos = _getUpdateRowIndex(removeRows[removeRows.length - 1] - 1, removeRows[0] - removeRows.length + 1, scene);
rowUpdatePos = isValid(rowUpdatePos) ? isValid(pos) ? Math.min(rowUpdatePos, pos) : rowUpdatePos : pos;
}
let updateAfter;
if (scene.table._clearRowRangeHeightsMap(), addRows.forEach((row => {
const needUpdateAfter = addRow(row, scene, skipUpdateProxy);
updateAfter = null != updateAfter ? updateAfter : needUpdateAfter, rowHeightsMap.insert(row);
})), resetRowNumberAndY(scene), addRows.length) {
const pos = _getUpdateRowIndex(addRows[0] - 1, addRows[addRows.length - 1] + 1, scene);
rowUpdatePos = isValid(rowUpdatePos) ? isValid(pos) ? Math.min(rowUpdatePos, pos) : rowUpdatePos : pos;
}
for (let col = 0; col < table.colCount; col++) updateRows.forEach((row => {
if (row < table.frozenRowCount) {
const mergeInfo = getCellMergeInfo(scene.table, col, 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, !1); else updateCell(col, row, scene.table, !1);
} else if (row > table.rowCount - 1 || row < scene.table.rowCount - scene.table.bottomFrozenRowCount && (row < scene.proxy.rowStart || row > scene.proxy.rowEnd)) removeCellGroup(row, scene); else {
const mergeInfo = getCellMergeInfo(scene.table, col, 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, !1); else updateCell(col, row, scene.table, !1);
}
}));
if (updateRows.length) {
const pos = _getUpdateRowIndex(updateRows[0] - 1, updateRows[updateRows.length - 1] + 1, scene);
rowUpdatePos = isValid(rowUpdatePos) ? isValid(pos) ? Math.min(rowUpdatePos, pos) : rowUpdatePos : pos;
}
if (isNumber(updateAfter)) {
for (let col = 0; col < Math.max(table.colCount, null !== (_a = table.internalProps._oldColCount) && void 0 !== _a ? _a : table.colCount); col++) for (let row = updateAfter; row < Math.max(table.rowCount, null !== (_b = table.internalProps._oldRowCount) && void 0 !== _b ? _b : table.rowCount); row++) {
const cellGroup = scene.highPerformanceGetCell(col, row, !0);
cellGroup && (cellGroup.needUpdate = !0);
}
rowUpdatePos = isValid(rowUpdatePos) ? isValid(updateAfter) ? Math.min(rowUpdatePos, updateAfter) : rowUpdatePos : updateAfter;
}
if (isNumber(rowUpdatePos) && (scene.proxy.rowUpdatePos = Math.min(scene.proxy.rowUpdatePos, rowUpdatePos)),
addRows.length) {
if (!isNumber(updateAfter)) {
const minRow = Math.min(...addRows);
scene.proxy.rowUpdatePos = Math.min(minRow, scene.proxy.rowUpdatePos);
}
scene.proxy.rowUpdateDirection = "up", scene.proxy.updateCellGroups(2 * scene.proxy.screenRowCount),
updateBottomFrozeCellGroups();
} else removeRows.length && (setRowSeriesNumberCellNeedUpdate(removeRows[removeRows.length - 1], scene),
scene.proxy.updateCellGroups(2 * scene.proxy.screenRowCount), updateBottomFrozeCellGroups());
scene.proxy.progress();
const newTotalHeight = table.getRowsHeight(table.frozenRowCount, table.rowCount - 1 - table.bottomFrozenRowCount);
function updateBottomFrozeCellGroups() {
if ((null == addRows ? void 0 : addRows[(null == addRows ? void 0 : addRows.length) - 1]) >= table.rowCount - table.bottomFrozenRowCount || (null == updateRows ? void 0 : updateRows[(null == updateRows ? void 0 : updateRows.length) - 1]) >= table.rowCount - table.bottomFrozenRowCount || (null == removeRows ? void 0 : 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, !0);
cellGroup && (cellGroup.needUpdate = !0);
}
scene.proxy.updateBottomFrozenCellGroups();
}
}
scene.updateContainerHeight(scene.table.frozenRowCount, newTotalHeight - scene.bodyGroup.attribute.height);
}
function removeRow(row, scene, skipUpdateProxy) {
const proxy = scene.proxy;
if (row >= proxy.rowStart && row <= proxy.rowEnd && (removeCellGroup(row, scene),
proxy.rowEnd--, proxy.currentRow--), !skipUpdateProxy) {
proxy.bodyBottomRow--;
const totalActualBodyRowCount = Math.min(proxy.rowLimit, proxy.bodyBottomRow - proxy.bodyTopRow + 1);
proxy.totalActualBodyRowCount = totalActualBodyRowCount, proxy.totalRow = Math.min(proxy.table.rowCount - 1, proxy.rowStart + totalActualBodyRowCount - 1);
}
}
function addRow(row, scene, skipUpdateProxy) {
const proxy = scene.proxy;
if (!skipUpdateProxy) {
proxy.bodyBottomRow++;
const totalActualBodyRowCount = Math.min(proxy.rowLimit, proxy.bodyBottomRow - proxy.bodyTopRow + 1);
proxy.totalActualBodyRowCount = totalActualBodyRowCount, proxy.totalRow = proxy.rowStart + totalActualBodyRowCount - 1;
}
if (!(row < proxy.rowStart)) return row > proxy.rowEnd ? proxy.rowEnd - proxy.rowStart + 1 < proxy.rowLimit ? (proxy.rowEnd++,
proxy.currentRow++, addRowCellGroup(row, scene), row) : void 0 : proxy.rowEnd - proxy.rowStart + 1 < proxy.rowLimit ? (proxy.rowEnd++,
proxy.currentRow++, addRowCellGroup(row, scene), row) : row;
}
function resetRowNumber(scene) {
function processCell(cellGroup, rowIndex) {
cellGroup.row = rowIndex;
const merge = getCellMergeInfo(scene.table, cellGroup.col, cellGroup.row);
merge ? (cellGroup.mergeStartCol = merge.start.col, cellGroup.mergeEndCol = merge.end.col,
cellGroup.mergeStartRow = merge.start.row, cellGroup.mergeEndRow = merge.end.row) : (cellGroup.mergeStartCol = void 0,
cellGroup.mergeEndCol = void 0, cellGroup.mergeStartRow = void 0, cellGroup.mergeEndRow = void 0);
}
scene.bodyGroup.forEachChildren((colGroup => {
let rowIndex = scene.bodyRowStart;
null == colGroup || colGroup.forEachChildren((cellGroup => {
processCell(cellGroup, rowIndex), rowIndex++;
}));
})), scene.rowHeaderGroup.forEachChildren((colGroup => {
let rowIndex = scene.bodyRowStart;
null == colGroup || colGroup.forEachChildren((cellGroup => {
processCell(cellGroup, rowIndex), rowIndex++;
}));
})), scene.rightFrozenGroup.forEachChildren((colGroup => {
let rowIndex = scene.bodyRowStart;
null == colGroup || colGroup.forEachChildren((cellGroup => {
processCell(cellGroup, rowIndex), rowIndex++;
}));
})), scene.bottomFrozenGroup.forEachChildren((colGroup => {
let rowIndex = scene.table.rowCount - scene.table.bottomFrozenRowCount;
null == colGroup || colGroup.forEachChildren((cellGroup => {
processCell(cellGroup, rowIndex), rowIndex++;
}));
})), scene.leftBottomCornerGroup.forEachChildren((colGroup => {
let rowIndex = scene.table.rowCount - scene.table.bottomFrozenRowCount;
null == colGroup || colGroup.forEachChildren((cellGroup => {
processCell(cellGroup, rowIndex), rowIndex++;
}));
})), scene.rightBottomCornerGroup.forEachChildren((colGroup => {
let rowIndex = scene.table.rowCount - scene.table.bottomFrozenRowCount;
null == colGroup || colGroup.forEachChildren((cellGroup => {
processCell(cellGroup, rowIndex), rowIndex++;
}));
}));
}
function resetRowNumberAndY(scene) {
function processCell(cellGroup, rowIndex, y) {
cellGroup.row = rowIndex, cellGroup.setAttribute("y", y);
const merge = getCellMergeInfo(scene.table, cellGroup.col, cellGroup.row);
merge ? (cellGroup.mergeStartCol = merge.start.col, cellGroup.mergeEndCol = merge.end.col,
cellGroup.mergeStartRow = merge.start.row, cellGroup.mergeEndRow = merge.end.row) : (cellGroup.mergeStartCol = void 0,
cellGroup.mergeEndCol = void 0, cellGroup.mergeStartRow = void 0, cellGroup.mergeEndRow = void 0);
}
scene.bodyGroup.forEachChildren((colGroup => {
let rowIndex = scene.bodyRowStart, y = scene.getCellGroupY(rowIndex);
null == colGroup || colGroup.forEachChildren((cellGroup => {
processCell(cellGroup, rowIndex, y), rowIndex++, y += cellGroup.attribute.height;
}));
})), scene.rowHeaderGroup.forEachChildren((colGroup => {
let rowIndex = scene.bodyRowStart, y = scene.getCellGroupY(rowIndex);
null == colGroup || colGroup.forEachChildren((cellGroup => {
processCell(cellGroup, rowIndex, y), rowIndex++, y += cellGroup.attribute.height;
}));
})), scene.rightFrozenGroup.forEachChildren((colGroup => {
let rowIndex = scene.bodyRowStart, y = scene.getCellGroupY(rowIndex);
null == colGroup || colGroup.forEachChildren((cellGroup => {
processCell(cellGroup, rowIndex, y), rowIndex++, y += cellGroup.attribute.height;
}));
})), scene.bottomFrozenGroup.forEachChildren((colGroup => {
let rowIndex = scene.table.rowCount - scene.table.bottomFrozenRowCount, y = 0;
null == colGroup || colGroup.forEachChildren((cellGroup => {
processCell(cellGroup, rowIndex, y), rowIndex++, y += cellGroup.attribute.height;
}));
})), scene.leftBottomCornerGroup.forEachChildren((colGroup => {
let rowIndex = scene.table.rowCount - scene.table.bottomFrozenRowCount, y = 0;
null == colGroup || colGroup.forEachChildren((cellGroup => {
processCell(cellGroup, rowIndex, y), rowIndex++, y += cellGroup.attribute.height;
}));
})), scene.rightBottomCornerGroup.forEachChildren((colGroup => {
let rowIndex = scene.table.rowCount - scene.table.bottomFrozenRowCount, y = 0;
null == colGroup || colGroup.forEachChildren((cellGroup => {
processCell(cellGroup, rowIndex, y), rowIndex++, y += cellGroup.attribute.height;
}));
}));
}
function addRowCellGroup(row, scene) {
for (let col = 0; col < scene.table.colCount; col++) {
const cellGroup = new Group({
x: 0,
y: 0,
width: scene.table.getColWidth(col),
height: scene.table.getRowHeight(row)
});
if (cellGroup.role = "cell", cellGroup.col = col, cellGroup.row = row, cellGroup.needUpdate = !0,
!cellGroup) continue;
const colGroup = scene.getColGroup(col);
if (colGroup) if (colGroup.firstChild && row < colGroup.firstChild.row) colGroup.insertBefore(cellGroup, colGroup.firstChild),
colGroup.firstChild.row = colGroup.firstChild.row + 1; else if (colGroup.lastChild && row > colGroup.lastChild.row) colGroup.appendChild(cellGroup); else {
const cellBefore = scene.highPerformanceGetCell(col, row, !0);
cellBefore !== cellGroup && (colGroup.insertBefore(cellGroup, cellBefore), cellBefore && (cellBefore.row = cellBefore.row + 1),
cellBefore !== colGroup.lastChild && colGroup.lastChild && (colGroup.lastChild.row = colGroup.lastChild.row + 1));
}
}
}
function removeCellGroup(row, scene) {
for (let col = 0; col < scene.table.colCount; col++) {
const colGroup = scene.getColGroup(col, !1);
if (!colGroup) continue;
let cellGroup;
colGroup.forEachChildren((cell => cell.row === row && (cellGroup = cell, !0))),
cellGroup && (colGroup.updateColumnHeight(-cellGroup.attribute.height), colGroup.removeChild(cellGroup));
}
}
function _getUpdateRowIndex(beforeRow, afterRow, scene) {
let updateRow;
for (let col = 0; col < scene.table.colCount; col++) {
const rangeBefore = scene.table.getCellRange(col, beforeRow);
let row;
rangeBefore.start.row <= beforeRow + 1 && rangeBefore.end.row >= beforeRow + 1 && (addNeedUpdateTag(rangeBefore, scene),
row = rangeBefore.start.row);
const rangeAfter = scene.table.getCellRange(col, afterRow);
rangeAfter.start.row <= afterRow + 1 && rangeAfter.end.row >= afterRow + 1 && (addNeedUpdateTag(rangeAfter, scene),
row = rangeAfter.start.row), isValid(row) && (updateRow = isValid(updateRow) ? Math.min(updateRow, row) : row);
}
return updateRow;
}
function _getUpdateRowIndexUseCellNode(beforeRow, afterRow, scene) {
let updateRow;
for (let col = 0; col < scene.table.colCount; col++) {
let row;
const beforeCell = scene.highPerformanceGetCell(col, beforeRow);
beforeCell.mergeStartRow && beforeCell.mergeEndRow && beforeCell.mergeEndRow > beforeRow && (addNeedUpdateTag({
start: {
row: beforeCell.mergeStartRow,
col: scene.table.isAutoRowHeight(afterRow) ? 0 : beforeCell.mergeStartCol
},
end: {
row: beforeCell.mergeEndRow,
col: scene.table.isAutoRowHeight(afterRow) ? scene.table.colCount - 1 : beforeCell.mergeEndCol
}
}, scene), row = beforeCell.mergeStartRow);
const afterCell = scene.highPerformanceGetCell(col, afterRow);
afterCell.mergeStartRow && afterCell.mergeEndRow && afterCell.mergeStartRow < afterRow && (addNeedUpdateTag({
start: {
row: afterCell.mergeStartRow,
col: scene.table.isAutoRowHeight(afterRow) ? 0 : afterCell.mergeStartCol
},
end: {
row: afterCell.mergeEndRow,
col: scene.table.isAutoRowHeight(afterRow) ? scene.table.colCount - 1 : afterCell.mergeEndCol
}
}, scene), row = afterCell.mergeStartRow), isValid(row) && (updateRow = isValid(updateRow) ? Math.min(updateRow, row) : row);
}
return updateRow;
}
function addNeedUpdateTag(range, scene) {
const {start: start, end: end} = range;
for (let col = start.col; col <= end.col; col++) for (let row = start.row; row <= end.row; row++) {
const cellGroup = scene.highPerformanceGetCell(col, row, !0);
cellGroup && (cellGroup.needUpdate = !0);
}
}
function setRowSeriesNumberCellNeedUpdate(startUpdateRow, scene) {
if (scene.table.isHasSeriesNumber()) for (let row = startUpdateRow; row <= scene.table.rowCount - 1; row++) updateCell(0, row, scene.table, !1);
}
//# sourceMappingURL=update-row.js.map