UNPKG

@antv/s2

Version:

effective spreadsheet render core lib

282 lines 11.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.areAllFieldsEmpty = exports.getLeftLeafNode = exports.getLeafColumnsWithKey = exports.getLeafColumns = exports.getNodeRoot = exports.getCellRange = exports.splitInViewIndexesWithFrozen = exports.calculateFrozenCornerCells = exports.getFrozenGroupTypeByCell = exports.translateGroupY = exports.translateGroupX = exports.translateGroup = exports.optimizeScrollXY = exports.calculateInViewIndexes = exports.isFrozenTrailingRow = exports.isFrozenRow = exports.isFrozenTrailingCol = exports.isFrozenCol = void 0; const lodash_1 = require("lodash"); const frozen_1 = require("../common/constant/frozen"); const pagination_1 = require("../common/constant/pagination"); const isFrozenCol = (colIndex, frozenCount) => frozenCount > 0 && colIndex < frozenCount; exports.isFrozenCol = isFrozenCol; const isFrozenTrailingCol = (colIndex, frozenCount, colLength) => frozenCount > 0 && colIndex >= colLength - frozenCount; exports.isFrozenTrailingCol = isFrozenTrailingCol; const isFrozenRow = (rowIndex, minRowIndex, frozenCount) => frozenCount > 0 && rowIndex < minRowIndex + frozenCount; exports.isFrozenRow = isFrozenRow; const isFrozenTrailingRow = (rowIndex, maxRowIndex, frozenCount) => frozenCount > 0 && rowIndex >= maxRowIndex + 1 - frozenCount; exports.isFrozenTrailingRow = isFrozenTrailingRow; /** * 计算偏移 scrollX、scrollY 的时候,在视窗中的节点索引 */ const calculateInViewIndexes = (options) => { const { scrollX, scrollY, widths, heights, viewport, rowRemainWidth } = options; // 1. 计算 x min、max let xMin = (0, lodash_1.findIndex)(widths, (width, idx) => { const x = scrollX - ((0, lodash_1.isNil)(rowRemainWidth) ? 0 : rowRemainWidth) + viewport.x; return x >= width && x < widths[idx + 1]; }, 0); xMin = Math.max(xMin, 0); let xMax = (0, lodash_1.findIndex)(widths, (width, idx) => { const x = viewport.width + scrollX + viewport.x; return x >= width && x < widths[idx + 1]; }, xMin); xMax = Math.min(xMax === -1 ? Infinity : xMax, widths.length - 2); const { start: yMin, end: yMax } = heights.getIndexRange(scrollY + viewport.y, viewport.height + scrollY + viewport.y); return [xMin, xMax, yMin, yMax]; }; exports.calculateInViewIndexes = calculateInViewIndexes; /** * 优化滚动方向,对于小角度的滚动,固定为一个方向 * @param x * @param y * @param ratio */ const optimizeScrollXY = (x, y, ratio) => { // 调参工程师 const ANGLE = 2; const angle = Math.abs(x / y); // 经过滚动优化之后的 x, y const deltaX = angle <= 1 / ANGLE ? 0 : x; const deltaY = angle > ANGLE ? 0 : y; return [deltaX * ratio.horizontal, deltaY * ratio.vertical]; }; exports.optimizeScrollXY = optimizeScrollXY; const translateGroup = (group, scrollX, scrollY) => { if (group) { const [preX, preY] = group.getPosition(); group.translate(scrollX - preX, scrollY - preY); } }; exports.translateGroup = translateGroup; const translateGroupX = (group, scrollX) => { if (group) { const [preX] = group.getPosition(); group.translate(scrollX - preX, 0); } }; exports.translateGroupX = translateGroupX; const translateGroupY = (group, scrollY) => { if (group) { const [, preY] = group.getPosition(); group === null || group === void 0 ? void 0 : group.translate(0, scrollY - preY); } }; exports.translateGroupY = translateGroupY; /** * frozen frozenTrailing * ColCount ColCount * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * | | frozenRow | | frozenRowCount * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * | fro | | fro | * | zen | panel | zen | * | col | scroll | trailing | * | | | col | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * | | frozenTrailingRow | | frozenTrailingRowCount * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * @description returns which group data cell belongs in frozen mode */ const getFrozenGroupTypeByCell = (meta, frozenOptions, colLength, cellRange) => { const { colCount = 0, rowCount = 0, trailingColCount = 0, trailingRowCount = 0, } = frozenOptions; const { colIndex, rowIndex } = meta; if ((0, exports.isFrozenRow)(rowIndex, cellRange.start, rowCount)) { return frozen_1.FrozenGroupType.Row; } if ((0, exports.isFrozenTrailingRow)(rowIndex, cellRange.end, trailingRowCount)) { return frozen_1.FrozenGroupType.TrailingRow; } if ((0, exports.isFrozenCol)(colIndex, colCount)) { return frozen_1.FrozenGroupType.Col; } if ((0, exports.isFrozenTrailingCol)(colIndex, trailingColCount, colLength)) { return frozen_1.FrozenGroupType.TrailingCol; } return frozen_1.FrozenGroupType.Scroll; }; exports.getFrozenGroupTypeByCell = getFrozenGroupTypeByCell; /** * @description calculate all cells in frozen group's intersection region */ const calculateFrozenCornerCells = (frozenOptions, colLength, cellRange) => { const { colCount: frozenColCount = 0, rowCount: frozenRowCount = 0, trailingColCount: frozenTrailingColCount = 0, trailingRowCount: frozenTrailingRowCount = 0, } = frozenOptions; const result = { [frozen_1.FrozenGroupType.TopLeft]: [], [frozen_1.FrozenGroupType.TopRight]: [], [frozen_1.FrozenGroupType.BottomLeft]: [], [frozen_1.FrozenGroupType.BottomRight]: [], }; // frozenColGroup with frozenRowGroup or frozenTrailingRowGroup. Top left and Bottom left corner. for (let i = 0; i < frozenColCount; i++) { for (let j = cellRange.start; j < cellRange.start + frozenRowCount; j++) { result[frozen_1.FrozenGroupType.TopLeft].push({ x: i, y: j, }); } if (frozenTrailingRowCount > 0) { for (let j = 0; j < frozenTrailingRowCount; j++) { const index = cellRange.end - j; result[frozen_1.FrozenGroupType.BottomLeft].push({ x: i, y: index, }); } } } // frozenTrailingColGroup with frozenRowGroup or frozenTrailingRowGroup. Top right and bottom right corner. for (let i = 0; i < frozenTrailingColCount; i++) { const colIndex = colLength - 1 - i; for (let j = cellRange.start; j < cellRange.start + frozenRowCount; j++) { result[frozen_1.FrozenGroupType.TopRight].push({ x: colIndex, y: j, }); } if (frozenTrailingRowCount > 0) { for (let j = 0; j < frozenTrailingRowCount; j++) { const index = cellRange.end - j; result[frozen_1.FrozenGroupType.BottomRight].push({ x: colIndex, y: index, }); } } } return result; }; exports.calculateFrozenCornerCells = calculateFrozenCornerCells; /** * @description split all cells in current panel with five child group */ const splitInViewIndexesWithFrozen = (indexes, frozenOptions, colLength, cellRange) => { const { colCount = 0, rowCount = 0, trailingColCount = 0, trailingRowCount = 0, } = frozenOptions; const centerIndexes = [...indexes]; // Cut off frozen cells from centerIndexes if ((0, exports.isFrozenCol)(centerIndexes[0], colCount)) { centerIndexes[0] = colCount; } if ((0, exports.isFrozenTrailingCol)(centerIndexes[1], trailingColCount, colLength)) { centerIndexes[1] = colLength - trailingColCount - 1; } if ((0, exports.isFrozenRow)(centerIndexes[2], cellRange.start, rowCount)) { centerIndexes[2] = cellRange.start + rowCount; } if ((0, exports.isFrozenTrailingRow)(centerIndexes[3], cellRange.end, trailingRowCount)) { centerIndexes[3] = cellRange.end - trailingRowCount; } // Calculate indexes for four frozen groups const frozenRowIndexes = [...centerIndexes]; frozenRowIndexes[2] = cellRange.start; frozenRowIndexes[3] = cellRange.start + rowCount - 1; const frozenColIndexes = [...centerIndexes]; frozenColIndexes[0] = 0; frozenColIndexes[1] = colCount - 1; const frozenTrailingRowIndexes = [...centerIndexes]; frozenTrailingRowIndexes[2] = cellRange.end + 1 - trailingRowCount; frozenTrailingRowIndexes[3] = cellRange.end; const frozenTrailingColIndexes = [...centerIndexes]; frozenTrailingColIndexes[0] = colLength - trailingColCount; frozenTrailingColIndexes[1] = colLength - 1; return { center: centerIndexes, frozenRow: frozenRowIndexes, frozenCol: frozenColIndexes, frozenTrailingCol: frozenTrailingColIndexes, frozenTrailingRow: frozenTrailingRowIndexes, }; }; exports.splitInViewIndexesWithFrozen = splitInViewIndexesWithFrozen; const getCellRange = (viewCellHeights, pagination) => { const heights = viewCellHeights; let start = 0; let end = heights.getTotalLength() - 1; if (pagination) { const { current = pagination_1.DEFAULT_PAGE_INDEX, pageSize } = pagination; start = Math.max((current - 1) * pageSize, 0); end = Math.min(current * pageSize - 1, heights.getTotalLength() - 1); } return { start, end, }; }; exports.getCellRange = getCellRange; /** * 明细表多级表头根据一个 node 返回其所属顶层节点 * @param node * @returns {Node} */ const getNodeRoot = (node) => { while (node.level !== 0) { node = node.parent; } return node; }; exports.getNodeRoot = getNodeRoot; /** * 获取 columns 的所有叶子节点 * @param columns 列配置 * @returns {Array} 叶子节点列组成的数组 */ const getLeafColumns = (columns) => { const leafs = []; const recursionFn = (list) => { list.forEach((column) => { if (typeof column === 'string' || !column.children) { leafs.push(column); } else { recursionFn(column.children); } }); }; recursionFn(columns); return leafs; }; exports.getLeafColumns = getLeafColumns; /** * 获取 columns 的所有叶子节点的 key * @param columns 列配置 * @returns {Array<string>} 叶子节点列的key组成的数组 */ const getLeafColumnsWithKey = (columns = []) => { const leafs = (0, exports.getLeafColumns)(columns); return leafs.map((column) => { if (typeof column === 'string') { return column; } return column.field; }); }; exports.getLeafColumnsWithKey = getLeafColumnsWithKey; /** * 获取一个 node 的最左叶子节点,找不到则返回自身 * @param node * @returns {Node} */ const getLeftLeafNode = (node) => { const firstNode = node.children[0]; if (!firstNode) { return node; } return firstNode.isLeaf ? firstNode : (0, exports.getLeftLeafNode)(firstNode); }; exports.getLeftLeafNode = getLeftLeafNode; /** * fields 的 rows、columns、values 值都为空时,返回 true * @param {Fields} fields * @return {boolean} */ const areAllFieldsEmpty = (fields) => { return ((0, lodash_1.isEmpty)(fields.rows) && (0, lodash_1.isEmpty)(fields.columns) && (0, lodash_1.isEmpty)(fields.values)); }; exports.areAllFieldsEmpty = areAllFieldsEmpty; //# sourceMappingURL=utils.js.map