UNPKG

@antv/s2

Version:

effective spreadsheet render core lib

188 lines 8.29 kB
import { inRange, isEmpty, isNil, range } from 'lodash'; import { DataCell } from '../cell'; import { CellType, InteractionKeyboardKey, InteractionName, InteractionStateName, InterceptType, S2Event, } from '../common/constant'; import { getCellMeta, getRangeIndex, groupSelectedCells, } from '../utils/interaction/select-event'; import { getCellsTooltipData } from '../utils/tooltip'; import { BaseEvent } from './base-interaction'; export class RangeSelection extends BaseEvent { constructor() { super(...arguments); this.isRangeSelection = false; this.handleColClick = (event) => { event.stopPropagation(); const { interaction, facet } = this.spreadsheet; const cell = this.spreadsheet.getCell(event.target); const meta = cell === null || cell === void 0 ? void 0 : cell.getMeta(); if (!isNil(meta === null || meta === void 0 ? void 0 : meta.x)) { interaction.addIntercepts([InterceptType.HOVER]); let selectedCells = [getCellMeta(cell)]; const lastCell = this.spreadsheet.store.get('lastClickedCell'); // 处理shift区间多选 if (this.isRangeSelection && lastCell && lastCell.cellType === cell.cellType && lastCell.getMeta().level === meta.level) { const { rowsHierarchy, colsHierarchy } = facet.getLayoutResult(); const [rowMaxLevel, colMaxLevel] = [ rowsHierarchy.maxLevel, colsHierarchy.maxLevel, ]; const { start, end } = getRangeIndex(lastCell.getMeta(), meta); if (cell instanceof DataCell) { selectedCells = this.handleSeriesNumberRowSelected(start.rowIndex, end.rowIndex, cell); } else if ((cell === null || cell === void 0 ? void 0 : cell.cellType) === CellType.ROW_CELL && meta.level === rowMaxLevel) { selectedCells = this.handleRowSelected(start.rowIndex, end.rowIndex, cell); } else if ((cell === null || cell === void 0 ? void 0 : cell.cellType) === CellType.COL_CELL && meta.level === colMaxLevel) { selectedCells = this.handleColSelected(start.colIndex, end.colIndex, cell); } interaction.changeState({ cells: selectedCells, stateName: InteractionStateName.SELECTED, }); const selectedCellIds = groupSelectedCells(selectedCells); interaction.updateCells(facet.getHeaderCells(selectedCellIds)); interaction.emitSelectEvent({ event, targetCell: cell, interactionName: InteractionName.RANGE_SELECTION, }); } else { if (isEmpty(interaction.getCells())) { interaction.reset(); } this.spreadsheet.store.set('lastClickedCell', cell); } } }; } bindEvents() { this.bindKeyboardDown(); this.bindDataCellClick(); this.bindColCellClick(); this.bindKeyboardUp(); this.bindMouseMove(); } reset() { this.isRangeSelection = false; this.spreadsheet.interaction.removeIntercepts([InterceptType.CLICK]); } bindKeyboardDown() { this.spreadsheet.on(S2Event.GLOBAL_KEYBOARD_DOWN, (event) => { if (event.key === InteractionKeyboardKey.SHIFT) { this.isRangeSelection = true; this.spreadsheet.interaction.addIntercepts([InterceptType.CLICK]); } }); } bindKeyboardUp() { this.spreadsheet.on(S2Event.GLOBAL_KEYBOARD_UP, (event) => { if (event.key === InteractionKeyboardKey.SHIFT) { this.reset(); } }); } bindMouseMove() { // 当快捷键被系统拦截后,按需补充调用一次 reset this.spreadsheet.on(S2Event.GLOBAL_MOUSE_MOVE, (event) => { if (this.isRangeSelection && !event.shiftKey) { this.reset(); } }); } bindColCellClick() { this.spreadsheet.on(S2Event.COL_CELL_CLICK, (event) => { this.handleColClick(event); }); } bindDataCellClick() { this.spreadsheet.on(S2Event.DATA_CELL_CLICK, (event) => { event.stopPropagation(); const cell = this.spreadsheet.getCell(event.target); const meta = cell.getMeta(); const { interaction } = this.spreadsheet; if (!meta) { return; } const lastClickedCell = this.spreadsheet.store.get('lastClickedCell'); const isShiftSelect = this.isRangeSelection && (lastClickedCell === null || lastClickedCell === void 0 ? void 0 : lastClickedCell.cellType) === cell.cellType; if (!isShiftSelect) { this.spreadsheet.store.set('lastClickedCell', cell); return; } const { start, end } = getRangeIndex(lastClickedCell.getMeta(), cell.getMeta()); const cells = range(start.colIndex, end.colIndex + 1).flatMap((col) => { const cellIdSuffix = this.spreadsheet.facet.getColLeafNodes()[col].id; return range(start.rowIndex, end.rowIndex + 1).map((row) => { const cellIdPrefix = this.spreadsheet.facet.getSeriesNumberWidth() || this.spreadsheet.isTableMode() ? String(row) : this.spreadsheet.facet.getRowLeafNodes()[row].id; return { id: `${cellIdPrefix}-${cellIdSuffix}`, colIndex: col, rowIndex: row, type: cell.cellType, }; }); }); interaction.addIntercepts([InterceptType.CLICK, InterceptType.HOVER]); interaction.changeState({ cells, stateName: InteractionStateName.SELECTED, }); this.spreadsheet.showTooltipWithInfo(event, getCellsTooltipData(this.spreadsheet)); interaction.emitSelectEvent({ targetCell: cell, event, interactionName: InteractionName.RANGE_SELECTION, }); }); } handleSeriesNumberRowSelected(startIndex, endIndex, cell) { // table模式下序列号行头 const cellIdSufFix = this.spreadsheet.facet.getColLeafNodes()[0].id; return range(startIndex, endIndex + 1).map((row) => { const cellIdPrefix = String(row); return { id: `${cellIdPrefix}-${cellIdSufFix}`, colIndex: 0, rowIndex: row, type: cell.cellType, }; }); } handleRowSelected(startIndex, endIndex, cell) { // ROW_CELL类型 最后一个Level支持区间选择 return this.spreadsheet.facet .getRowNodes() .filter(({ rowIndex }) => inRange(rowIndex, startIndex, endIndex + 1)) .map((e) => { return { id: e.id, colIndex: e.colIndex, rowIndex: e.rowIndex, type: cell.cellType, }; }); } handleColSelected(startIndex, endIndex, cell) { // COL_CELL类型 最后一个Level支持区间选择 return this.spreadsheet.facet .getColLeafNodes() .filter(({ colIndex }) => inRange(colIndex, startIndex, endIndex + 1)) .map((e) => { return { id: e.id, colIndex: e.colIndex, rowIndex: e.rowIndex, type: cell.cellType, }; }); } } //# sourceMappingURL=range-selection.js.map