@antv/s2
Version:
effective spreadsheet render core lib
179 lines • 8.31 kB
JavaScript
import { __awaiter } from "tslib";
import { difference, findLast } from 'lodash';
import { SeriesNumberCell } from '../../../cell';
import { CellType, InteractionName, InterceptType, S2Event, getTooltipOperatorHiddenColumnsMenu, } from '../../../common/constant';
import { BaseEvent, } from '../../../interaction/base-event';
import { hideColumnsByThunkGroup, isEqualDisplaySiblingNodeId, } from '../../../utils/hide-columns';
import { isMouseEventWithMeta, isMultiSelectionKey, } from '../../../utils/interaction/select-event';
import { getTooltipOptions, mergeCellInfo } from '../../../utils/tooltip';
export class RowColumnClick extends BaseEvent {
constructor() {
super(...arguments);
this.isMultiSelection = false;
this.handleRowColClick = (event) => {
event.stopPropagation();
if (this.isLinkFieldText(event.target)) {
return;
}
const { interaction, options } = this.spreadsheet;
const cell = this.spreadsheet.getCell(event.target);
if (cell instanceof SeriesNumberCell) {
return;
}
const { multiSelection: enableMultiSelection } = options.interaction;
// 关闭了多选就算按下了 Ctrl/Commend, 行/列也按单选处理
const isMultiSelection = !!(enableMultiSelection && this.isMultiSelection);
const multiSelectionName = cell.cellType === CellType.ROW_CELL
? InteractionName.ROW_CELL_MULTI_SELECTION
: InteractionName.COL_CELL_MULTI_SELECTION;
const defaultSelectionName = cell.cellType === CellType.ROW_CELL
? InteractionName.ROW_CELL_CLICK
: InteractionName.COL_CELL_CLICK;
const success = interaction.changeCell({
event,
cell,
isMultiSelection,
interactionName: isMultiSelection
? multiSelectionName
: defaultSelectionName,
// 能主动触发点击一定是在可视范围内, 无需额外触发滚动
scrollIntoView: false,
});
if (success) {
this.showTooltip(event);
}
};
this.getHideColumnField = (node) => {
var _a;
if ((_a = node.extra) === null || _a === void 0 ? void 0 : _a.isCustomNode) {
return node.id;
}
return this.spreadsheet.isTableMode() ? node.field : node.id;
};
}
bindEvents() {
this.bindKeyboardDown();
this.bindKeyboardUp();
this.bindColCellClick();
this.bindRowCellClick();
this.bindTableColExpand();
this.bindMouseMove();
}
reset() {
this.isMultiSelection = false;
this.spreadsheet.interaction.removeIntercepts([InterceptType.CLICK]);
}
bindKeyboardDown() {
this.spreadsheet.on(S2Event.GLOBAL_KEYBOARD_DOWN, (event) => {
if (isMultiSelectionKey(event)) {
this.isMultiSelection = true;
}
});
}
bindKeyboardUp() {
this.spreadsheet.on(S2Event.GLOBAL_KEYBOARD_UP, (event) => {
if (isMultiSelectionKey(event)) {
this.reset();
}
});
}
bindMouseMove() {
this.spreadsheet.on(S2Event.GLOBAL_MOUSE_MOVE, (event) => {
// 当快捷键被系统拦截后,按需补充调用一次 reset
if (this.isMultiSelection && !isMouseEventWithMeta(event)) {
this.reset();
}
});
}
bindRowCellClick() {
this.spreadsheet.on(S2Event.ROW_CELL_CLICK, (event) => {
this.handleRowColClick(event);
});
}
bindColCellClick() {
this.spreadsheet.on(S2Event.COL_CELL_CLICK, (event) => {
this.handleRowColClick(event);
});
}
showTooltip(event) {
const { operation, enable: showTooltip } = getTooltipOptions(this.spreadsheet, event);
if (!showTooltip) {
return;
}
const { interaction } = this.spreadsheet;
const cellInfos = interaction.isSelectedState()
? mergeCellInfo(interaction.getActiveCells())
: [];
const operator = this.getHeaderTooltipOperator(event, operation);
this.spreadsheet.showTooltipWithInfo(event, cellInfos, {
onlyShowCellText: true,
operator,
});
}
getHeaderTooltipOperator(event, operation) {
const cell = this.spreadsheet.getCell(event.target);
const cellMeta = cell.getMeta();
const isColCell = cell.cellType === CellType.COL_CELL;
// 只有一个叶子节点时, 不显示隐藏按钮
const isOnlyOneLeafColumn = this.spreadsheet.facet.getColLeafNodes().length === 1;
const TOOLTIP_OPERATOR_HIDDEN_COLUMNS_MENU = getTooltipOperatorHiddenColumnsMenu();
const enableHiddenColumnOperator = isColCell &&
!isOnlyOneLeafColumn &&
cellMeta.isLeaf &&
operation.hiddenColumns;
const hiddenColumnsMenu = Object.assign(Object.assign({}, TOOLTIP_OPERATOR_HIDDEN_COLUMNS_MENU), { onClick: () => {
this.hideSelectedColumns();
} });
const menus = enableHiddenColumnOperator ? [hiddenColumnsMenu] : [];
return this.getTooltipOperator(event, menus);
}
bindTableColExpand() {
this.spreadsheet.on(S2Event.COL_CELL_EXPANDED, (node, hideDirection) => {
this.handleExpandIconClick(node, hideDirection);
});
}
/**
* 隐藏选中的列
* 每次点击存储两个信息
* 1. [hiddenColumnFields]: 当前选中 (单/多选) 的 field, 对应 dataCfg 里面的 column
* 用于点击展开按钮后还原, 区别于 options.hiddenColumnFields, 这里需要分段存储, 比如现在有两个隐藏的列
* [1,2, (3隐藏), 4, 5, (6隐藏), 7]
* 展开按钮在 4, 7, 点击任意按钮, 应该只展开所对应的那组 : 4 => [3], 7 => [6]
* 2. [displaySiblingNode]: 当前这一组的列隐藏后, 需要将展开按钮显示到对应的兄弟节点
* 这样不用每次 render 的时候实时计算, 渲染列头单元格 直接取数据即可
*/
hideSelectedColumns() {
return __awaiter(this, void 0, void 0, function* () {
const { interaction } = this.spreadsheet;
const selectedColumnNodes = interaction
.getActiveCells()
.map((cell) => cell.getMeta());
const selectedColumnFields = selectedColumnNodes.map(this.getHideColumnField);
// 兼容多选
yield hideColumnsByThunkGroup(this.spreadsheet, selectedColumnFields, true);
});
}
handleExpandIconClick(node, hideDirection) {
return __awaiter(this, void 0, void 0, function* () {
const lastHiddenColumnsDetail = this.spreadsheet.store.get('hiddenColumnsDetail', []);
// 当前单元格的前/后节点都被隐藏时, 会出现两个展开按钮, 优先展开靠右的
const { hideColumnNodes = [] } = findLast(lastHiddenColumnsDetail, ({ displaySiblingNode }) => isEqualDisplaySiblingNodeId(displaySiblingNode, node.id, hideDirection)) || {};
const { hiddenColumnFields: lastHideColumnFields } = this.spreadsheet.options.interaction;
const willDisplayColumnFields = hideColumnNodes.map(this.getHideColumnField);
const hiddenColumnFields = difference(lastHideColumnFields, willDisplayColumnFields);
const hiddenColumnsDetail = lastHiddenColumnsDetail.filter(({ displaySiblingNode }) => !isEqualDisplaySiblingNodeId(displaySiblingNode, node.id, hideDirection));
this.spreadsheet.setOptions({
interaction: {
hiddenColumnFields,
},
});
this.spreadsheet.store.set('hiddenColumnsDetail', hiddenColumnsDetail);
this.spreadsheet.interaction.reset();
yield this.spreadsheet.render({
reloadData: false,
rebuildHiddenColumnsDetail: false,
});
});
}
}
//# sourceMappingURL=row-column-click.js.map