UNPKG

@antv/s2

Version:

effective spreadsheet render core lib

143 lines 6.67 kB
import { isNil, last, map } from 'lodash'; import { InterceptType, S2Event } from '../../common/constant'; import { InteractionBrushSelectionStage, InteractionName, InteractionStateName, ScrollDirection, } from '../../common/constant/interaction'; import { getCellMeta } from '../../utils/interaction/select-event'; import { BaseBrushSelection } from './base-brush-selection'; export class RowCellBrushSelection extends BaseBrushSelection { constructor() { super(...arguments); this.displayedCells = []; this.brushRangeCells = []; this.isInBrushRange = (meta) => { // start、end 都是相对位置 const { start, end } = this.getBrushRange(); const { scrollY, rowHeaderScrollX } = this.spreadsheet.facet.getScrollOffset(); const { cornerBBox } = this.spreadsheet.facet; // 绝对位置,不随滚动条变化 const { x = 0, y = 0, width = 0, height = 0 } = meta; return this.rectanglesIntersect({ // 行头过长时,可以单独进行滚动,所以需要加上滚动的距离 minX: start.x + rowHeaderScrollX, // 由于刷选的时候,是以行头的左上角为起点,所以需要减去角头的宽度,在滚动后需要加上滚动条的偏移量 minY: start.y - cornerBBox.height + scrollY, maxX: end.x + rowHeaderScrollX, maxY: end.y - cornerBBox.height + scrollY, }, { minX: x, maxX: x + width, minY: y, maxY: y + height, }); }; this.onUpdateCells = (root) => root.updateCells(this.spreadsheet.facet.getRowCells()); this.getSelectedRowNodes = () => { return this.spreadsheet.facet.getRowNodes().filter(this.isInBrushRange); }; /** * 行头的非叶子节点滚动刷选, 以当前节点所对应 [可视范围] 内叶子节点为基准 * 例: 当前刷选 [浙江省] 行头的这一列, 向 🔽 滚动以 [纸张] 为准, 向 🔼滚动以 [桌子] 为准 --------------------------------------- * | | 杭州市 | 家具 | 🔼 [桌子] | * | | | | 沙发 | * | | | 办公用品 | 笔 | * | | | | 纸张 | * | 浙江省 | | | | * | | 绍兴市 | 家具 | 桌子 | * | | | | 沙发 | * | | | 办公用品 | 笔 | * | | | | 🔽 [纸张] | * ------------------------------------- */ this.getVisibleRowLeafCellByScrollDirection = (dir) => { const rowCell = this.spreadsheet.facet.getRowCells(); if (dir === ScrollDirection.SCROLL_DOWN) { return last(rowCell); } return rowCell.find((cell) => { const meta = cell.getMeta(); return meta.isLeaf; }); }; this.getWillScrollToRowIndex = (dir) => { var _a, _b; // 行头叶子节点, 按默认逻辑处理即可 if (!isNil(this.endBrushPoint.rowIndex)) { return this.getDefaultWillScrollToRowIndex(dir); } const visibleCell = this.getVisibleRowLeafCellByScrollDirection(dir); const lastRowIndex = (_b = (_a = visibleCell === null || visibleCell === void 0 ? void 0 : visibleCell.getMeta()) === null || _a === void 0 ? void 0 : _a.rowIndex) !== null && _b !== void 0 ? _b : 0; const nextRowIndex = lastRowIndex + this.getWillScrollRowIndexDiff(dir); return this.validateYIndex(nextRowIndex); }; } bindMouseDown() { this.spreadsheet.on(S2Event.ROW_CELL_MOUSE_DOWN, (event) => { if (!this.spreadsheet.interaction.getBrushSelection().rowCell) { return; } super.mouseDown(event); }); } isPointInCanvas(point) { // 获取行头的区域范围 const { height: maxY } = this.spreadsheet.facet.getCanvasSize(); const { minX, height: minY, maxX } = this.spreadsheet.facet.cornerBBox; return (point.x >= minX && point.x <= maxX && point.y >= minY && point.y <= maxY); } bindMouseMove() { this.spreadsheet.on(S2Event.GLOBAL_MOUSE_MOVE, (event) => { if (this.brushSelectionStage === InteractionBrushSelectionStage.UN_DRAGGED) { return; } this.setBrushSelectionStage(InteractionBrushSelectionStage.DRAGGED); const pointInCanvas = this.spreadsheet.interaction.eventController.getViewportPoint(event); if (this.autoBrushScroll(pointInCanvas, true)) { return; } this.renderPrepareSelected(pointInCanvas); }); } setDisplayedCells() { this.displayedCells = this.spreadsheet.facet.getRowCells(); } // 最终刷选的 cells updateSelectedCells(event) { const selectedRowNodes = this.getSelectedRowNodes(); const scrollBrushRangeCells = this.getScrollBrushRangeCells(selectedRowNodes); const selectedCellMetas = map(scrollBrushRangeCells, getCellMeta); this.spreadsheet.interaction.changeState({ cells: selectedCellMetas, stateName: InteractionStateName.ROW_CELL_BRUSH_SELECTED, onUpdateCells: this.onUpdateCells, }); this.emitBrushSelectionEvent(S2Event.ROW_CELL_BRUSH_SELECTION, scrollBrushRangeCells, { event, targetCell: scrollBrushRangeCells[0], interactionName: InteractionName.ROW_CELL_BRUSH_SELECTION, }); } addBrushIntercepts() { this.spreadsheet.interaction.addIntercepts([ InterceptType.ROW_CELL_BRUSH_SELECTION, ]); } getScrollBrushRangeCells(nodes) { return nodes.map((node) => { const visibleCell = this.getVisibleBrushRangeCells(node.id); if (visibleCell) { return visibleCell; } return this.spreadsheet.facet.rowHeader.getCellInstance(node); }); } getPrepareSelectMaskPosition(brushRange) { const { minY } = this.spreadsheet.facet.panelBBox; const x = brushRange.start.x; const y = Math.max(brushRange.start.y, minY); return { x, y, }; } } //# sourceMappingURL=row-brush-selection.js.map