UNPKG

@antv/s2

Version:

effective spreadsheet render core lib

362 lines 15.6 kB
import { find, first, forEach, get, includes, isEmpty, isEqual, map, merge, } from 'lodash'; import { BaseCell } from '../cell/base-cell'; import { CellType, EXTRA_COLUMN_FIELD, EXTRA_FIELD, S2Event, } from '../common/constant'; import { InteractionStateName } from '../common/constant/interaction'; import { GuiIcon } from '../common/icons'; import { includeCell } from '../utils/cell/data-cell'; import { getActionIconConfig, groupIconsByPosition, } from '../utils/cell/header-cell'; import { findFieldCondition } from '../utils/condition/condition'; import { renderIcon } from '../utils/g-renders'; import { getSortTypeIcon } from '../utils/sort-action'; export class HeaderCell extends BaseCell { getHeaderConfig() { return this.headerConfig || {}; } isShallowRender() { return super.isShallowRender() || this.headerConfig.shallowRender; } shouldInit() { return super.shouldInit() && !this.isShallowRender(); } handleRestOptions(...[headerConfig]) { this.headerConfig = Object.assign({}, headerConfig); const { value, query } = this.meta; const sortParams = this.spreadsheet.dataCfg.sortParams || []; // 该单元格是否为需要展示排序 icon 单元格 const isSortCell = this.isSortCell(); const sortParam = find([...sortParams].reverse(), (item) => isSortCell && (item === null || item === void 0 ? void 0 : item.sortByMeasure) === value && isEqual(get(item, 'query'), query)); const type = getSortTypeIcon(sortParam, isSortCell); this.headerConfig.sortParam = Object.assign(Object.assign(Object.assign({}, this.headerConfig.sortParam), (sortParam || { query })), { type }); } initCell() { this.resetTextAndConditionIconShapes(); this.actionIcons = []; this.hasDefaultHiddenIcon = false; this.generateIconConfig(); } generateIconConfig() { var _a, _b; this.conditionIconMappingResult = this.getIconConditionResult(); const { sortParam } = this.getHeaderConfig(); // 为什么有排序参数就不展示 actionIcon 了?背景不清楚,先照旧处理 if (this.showSortIcon()) { this.actionIconConfig = { icons: [ { name: (sortParam === null || sortParam === void 0 ? void 0 : sortParam.type) || 'none', position: 'right', }, ], belongsCell: this .cellType, isSortIcon: true, }; } else { this.actionIconConfig = getActionIconConfig(this.spreadsheet.options.headerActionIcons, this.meta, this.cellType); } this.groupedIcons = groupIconsByPosition((_b = (_a = this.actionIconConfig) === null || _a === void 0 ? void 0 : _a.icons) !== null && _b !== void 0 ? _b : [], this.conditionIconMappingResult); } getFormattedFieldValue() { const { isTotalRoot, isGrandTotals, value } = this.meta; const formatter = this.spreadsheet.dataSet.getFieldFormatter(this.meta.field); /** * 如果是 table mode,列头不需要被格式化 * 树状模式下,小计是父维度本身,需要被格式化,此时只有总计才不需要被格式化 * 平铺模式下,总计/小计 文字单元格,不需要被格式化 * 自定义树模式下,没有总计小计概念,isTotals 均为 false, 所以不受影响 */ let shouldFormat = true; if (this.spreadsheet.isTableMode()) { shouldFormat = false; } else if (this.spreadsheet.isHierarchyTreeType()) { shouldFormat = !(isGrandTotals && isTotalRoot); } else { shouldFormat = !isTotalRoot; } const formattedValue = shouldFormat && formatter ? formatter(value, undefined, this.meta) : value; return { formattedValue, value, }; } showSortIcon() { const { options, dataCfg } = this.spreadsheet; const isEmptyValues = isEmpty(dataCfg.fields.values); if (options.showDefaultHeaderActionIcon && !isEmptyValues) { const { sortParam } = this.getHeaderConfig(); const query = this.meta.query; if (this.isShallowRender()) { return query; } // sortParam 的 query,和 type 本身可能会 undefined return (query && isEqual(sortParam === null || sortParam === void 0 ? void 0 : sortParam.query, query) && (sortParam === null || sortParam === void 0 ? void 0 : sortParam.type) && (sortParam === null || sortParam === void 0 ? void 0 : sortParam.type) !== 'none'); } return false; } getActionIconStyle(options) { const { icon } = this.getStyle(); const conditionStyle = this.getTextConditionMappingResult(); const defaultTextFill = (conditionStyle === null || conditionStyle === void 0 ? void 0 : conditionStyle.fill) || this.getTextStyle().fill; return { width: icon === null || icon === void 0 ? void 0 : icon.size, height: icon === null || icon === void 0 ? void 0 : icon.size, // 优先级: 单个 icon 颜色配置 > 全部 icon 颜色配置 > 主题 icon 颜色配置 > 文本默认颜色 fill: options.fill === null ? undefined : (options === null || options === void 0 ? void 0 : options.fill) || (icon === null || icon === void 0 ? void 0 : icon.fill) || defaultTextFill, cursor: 'pointer', }; } // 是否设置为默认隐藏 action icon,默认隐藏的交互为 hover 后可见 hasDefaultHideActionIcon() { return this.hasDefaultHiddenIcon; } addActionIcon(options) { const { x, y, name, defaultHide, onClick, onHover, isSortIcon } = options; const icon = new GuiIcon(Object.assign(Object.assign({}, this.getActionIconStyle(options)), { name, x, y })); icon.toggleVisibility(!defaultHide); icon.addEventListener('mouseover', (event) => { this.spreadsheet.emit(S2Event.GLOBAL_ACTION_ICON_HOVER, event); onHover === null || onHover === void 0 ? void 0 : onHover({ hovering: true, name, meta: this.meta, event, }); }); icon.addEventListener('mouseleave', (event) => { this.spreadsheet.emit(S2Event.GLOBAL_ACTION_ICON_HOVER_OFF, event); onHover === null || onHover === void 0 ? void 0 : onHover({ hovering: false, name, meta: this.meta, event, }); }); icon.addEventListener('click', (event) => { this.spreadsheet.emit(S2Event.GLOBAL_ACTION_ICON_CLICK, event); if (isSortIcon) { this.spreadsheet.handleGroupSort(event, this.meta); return; } onClick === null || onClick === void 0 ? void 0 : onClick({ name, meta: this.meta, event, }); }); this.actionIcons.push(icon); this.appendChild(icon); } drawActionAndConditionIcons() { if (isEmpty(this.groupedIcons.left) && isEmpty(this.groupedIcons.right)) { return; } if (!this.leftIconPosition || !this.rightIconPosition) { return; } forEach(this.groupedIcons, (icons, position) => { const { size, margin } = this.getStyle().icon; const iconMargin = position === 'left' ? margin.right : margin.right; const iconPosition = position === 'left' ? this.leftIconPosition : this.rightIconPosition; forEach(icons, (icon, i) => { var _a, _b, _c; const x = iconPosition.x + (size + iconMargin) * i; const y = iconPosition.y; if (icon.isConditionIcon) { this.conditionIconShape = renderIcon(this, { x, y, name: icon.name, width: size, height: size, fill: icon.fill, }); this.addConditionIconShape(this.conditionIconShape); return; } const { onClick, onHover, defaultHide, isSortIcon } = this.actionIconConfig; const defaultHideHandler = (_a = icon.defaultHide) !== null && _a !== void 0 ? _a : defaultHide; const iconDefaultHide = typeof defaultHideHandler === 'function' ? defaultHideHandler(this.meta, icon.name) : defaultHideHandler; if (iconDefaultHide) { this.hasDefaultHiddenIcon = true; } this.addActionIcon({ name: icon.name, fill: icon.fill, x, y, defaultHide: iconDefaultHide, onClick: (_b = icon.onClick) !== null && _b !== void 0 ? _b : onClick, onHover: (_c = icon.onHover) !== null && _c !== void 0 ? _c : onHover, isSortIcon, }); }); }); } isSortCell() { var _a, _b, _c; // 数值置于列头, 排序 icon 绘制在列头叶子节点; 置于行头, 排序 icon 绘制在行头叶子节点 const isValueInCols = (_b = (_a = this.spreadsheet) === null || _a === void 0 ? void 0 : _a.isValueInCols) === null || _b === void 0 ? void 0 : _b.call(_a); const isMaxLevel = this.meta.level === ((_c = this.meta.hierarchy) === null || _c === void 0 ? void 0 : _c.maxLevel); if (isValueInCols) { return isMaxLevel && this.cellType === CellType.COL_CELL; } return isMaxLevel && this.cellType === CellType.ROW_CELL; } handleByStateName(cells, stateName) { if (includeCell(cells, this)) { this.updateByState(stateName); } } handleSearchResult(cells) { if (!includeCell(cells, this)) { return; } const targetCell = find(cells, (cell) => cell === null || cell === void 0 ? void 0 : cell['isTarget']); if (targetCell.id === this.getMeta().id) { this.updateByState(InteractionStateName.HIGHLIGHT); } else { this.updateByState(InteractionStateName.SEARCH_RESULT); } } handleHover(cells) { var _a; if (includeCell(cells, this)) { this.updateByState(InteractionStateName.HOVER); if (this.hasDefaultHideActionIcon()) { // hover 只会有一个 cell this.toggleActionIcon((_a = cells === null || cells === void 0 ? void 0 : cells[0]) === null || _a === void 0 ? void 0 : _a.id); } } } handleSelect(cells, nodes = []) { if (includeCell(cells, this)) { this.updateByState(InteractionStateName.SELECTED); } const selectedNodeIds = map(nodes, 'id'); if (includes(selectedNodeIds, this.meta.id)) { this.updateByState(InteractionStateName.SELECTED); } } getTextStyle() { const textOverflowStyle = this.getCellTextWordWrapStyle(); const { text, bolderText, measureText } = this.getStyle(); let style; if (this.isMeasureField()) { style = measureText || text; } else if (this.isBolderText()) { style = bolderText; } else { style = text; } return this.getContainConditionMappingResultTextStyle(Object.assign(Object.assign({}, textOverflowStyle), style)); } getBackgroundColor() { var _a; const { backgroundColor, backgroundColorOpacity } = ((_a = this.getStyle()) === null || _a === void 0 ? void 0 : _a.cell) || {}; return merge({ backgroundColor, backgroundColorOpacity }, this.getBackgroundConditionFill()); } toggleActionIcon(id) { if (this.getMeta().id === id) { const visibleActionIcons = []; forEach(this.actionIcons, (icon) => { // 仅存储当前不可见的 icon if (icon.parsedStyle.visibility !== 'visible') { icon.toggleVisibility(true); visibleActionIcons.push(icon); } }); this.spreadsheet.store.set('visibleActionIcons', visibleActionIcons); } } getIconPosition() { return this.leftIconPosition || this.rightIconPosition; } getInteractedCells() { var _a; return (_a = this.spreadsheet.interaction) === null || _a === void 0 ? void 0 : _a.getCells([ CellType.CORNER_CELL, CellType.COL_CELL, CellType.ROW_CELL, CellType.SERIES_NUMBER_CELL, ]); } update() { const { interaction } = this.spreadsheet; const stateInfo = interaction === null || interaction === void 0 ? void 0 : interaction.getState(); if ((stateInfo === null || stateInfo === void 0 ? void 0 : stateInfo.stateName) === InteractionStateName.ALL_SELECTED) { this.updateByState(InteractionStateName.SELECTED); return; } const cells = this.getInteractedCells(); if (!first(cells)) { return; } switch (stateInfo === null || stateInfo === void 0 ? void 0 : stateInfo.stateName) { case InteractionStateName.SELECTED: case InteractionStateName.ROW_CELL_BRUSH_SELECTED: case InteractionStateName.COL_CELL_BRUSH_SELECTED: this.handleSelect(cells, stateInfo === null || stateInfo === void 0 ? void 0 : stateInfo.nodes); break; case InteractionStateName.HOVER_FOCUS: case InteractionStateName.HOVER: this.handleHover(cells); break; case InteractionStateName.SEARCH_RESULT: this.handleSearchResult(cells); break; default: this.handleByStateName(cells, stateInfo === null || stateInfo === void 0 ? void 0 : stateInfo.stateName); break; } } updateByState(stateName) { super.updateByState(stateName, this); } hideInteractionShape() { super.hideInteractionShape(); } isMeasureField() { return [EXTRA_FIELD, EXTRA_COLUMN_FIELD].includes(this.meta.field); } mappingValue(condition) { var _a; const value = this.getMeta().value; return (_a = condition.mapping) === null || _a === void 0 ? void 0 : _a.call(condition, value, this.meta, this); } findFieldCondition(conditions = []) { return findFieldCondition(conditions, this.meta.field); } getTreeIcon() { return this.treeIcon; } getActionIcons() { return this.actionIcons || []; } getMetaField() { return this.meta.field; } destroy() { this.meta.belongsCell = null; super.destroy(); } } //# sourceMappingURL=header-cell.js.map