@antv/s2
Version:
effective spreadsheet render core lib
366 lines • 16.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HeaderCell = void 0;
const lodash_1 = require("lodash");
const base_cell_1 = require("../cell/base-cell");
const constant_1 = require("../common/constant");
const interaction_1 = require("../common/constant/interaction");
const icons_1 = require("../common/icons");
const data_cell_1 = require("../utils/cell/data-cell");
const header_cell_1 = require("../utils/cell/header-cell");
const condition_1 = require("../utils/condition/condition");
const g_renders_1 = require("../utils/g-renders");
const sort_action_1 = require("../utils/sort-action");
class HeaderCell extends base_cell_1.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 = (0, lodash_1.find)([...sortParams].reverse(), (item) => isSortCell &&
(item === null || item === void 0 ? void 0 : item.sortByMeasure) === value &&
(0, lodash_1.isEqual)((0, lodash_1.get)(item, 'query'), query));
const type = (0, sort_action_1.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 = (0, header_cell_1.getActionIconConfig)(this.spreadsheet.options.headerActionIcons, this.meta, this.cellType);
}
this.groupedIcons = (0, header_cell_1.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 = (0, lodash_1.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 &&
(0, lodash_1.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 icons_1.GuiIcon(Object.assign(Object.assign({}, this.getActionIconStyle(options)), { name,
x,
y }));
icon.toggleVisibility(!defaultHide);
icon.addEventListener('mouseover', (event) => {
this.spreadsheet.emit(constant_1.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(constant_1.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(constant_1.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 ((0, lodash_1.isEmpty)(this.groupedIcons.left) && (0, lodash_1.isEmpty)(this.groupedIcons.right)) {
return;
}
if (!this.leftIconPosition || !this.rightIconPosition) {
return;
}
(0, lodash_1.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;
(0, lodash_1.forEach)(icons, (icon, i) => {
var _a, _b, _c;
const x = iconPosition.x + (size + iconMargin) * i;
const y = iconPosition.y;
if (icon.isConditionIcon) {
this.conditionIconShape = (0, g_renders_1.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 === constant_1.CellType.COL_CELL;
}
return isMaxLevel && this.cellType === constant_1.CellType.ROW_CELL;
}
handleByStateName(cells, stateName) {
if ((0, data_cell_1.includeCell)(cells, this)) {
this.updateByState(stateName);
}
}
handleSearchResult(cells) {
if (!(0, data_cell_1.includeCell)(cells, this)) {
return;
}
const targetCell = (0, lodash_1.find)(cells, (cell) => cell === null || cell === void 0 ? void 0 : cell['isTarget']);
if (targetCell.id === this.getMeta().id) {
this.updateByState(interaction_1.InteractionStateName.HIGHLIGHT);
}
else {
this.updateByState(interaction_1.InteractionStateName.SEARCH_RESULT);
}
}
handleHover(cells) {
var _a;
if ((0, data_cell_1.includeCell)(cells, this)) {
this.updateByState(interaction_1.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 ((0, data_cell_1.includeCell)(cells, this)) {
this.updateByState(interaction_1.InteractionStateName.SELECTED);
}
const selectedNodeIds = (0, lodash_1.map)(nodes, 'id');
if ((0, lodash_1.includes)(selectedNodeIds, this.meta.id)) {
this.updateByState(interaction_1.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 (0, lodash_1.merge)({ backgroundColor, backgroundColorOpacity }, this.getBackgroundConditionFill());
}
toggleActionIcon(id) {
if (this.getMeta().id === id) {
const visibleActionIcons = [];
(0, lodash_1.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([
constant_1.CellType.CORNER_CELL,
constant_1.CellType.COL_CELL,
constant_1.CellType.ROW_CELL,
constant_1.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) === interaction_1.InteractionStateName.ALL_SELECTED) {
this.updateByState(interaction_1.InteractionStateName.SELECTED);
return;
}
const cells = this.getInteractedCells();
if (!(0, lodash_1.first)(cells)) {
return;
}
switch (stateInfo === null || stateInfo === void 0 ? void 0 : stateInfo.stateName) {
case interaction_1.InteractionStateName.SELECTED:
case interaction_1.InteractionStateName.ROW_CELL_BRUSH_SELECTED:
case interaction_1.InteractionStateName.COL_CELL_BRUSH_SELECTED:
this.handleSelect(cells, stateInfo === null || stateInfo === void 0 ? void 0 : stateInfo.nodes);
break;
case interaction_1.InteractionStateName.HOVER_FOCUS:
case interaction_1.InteractionStateName.HOVER:
this.handleHover(cells);
break;
case interaction_1.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 [constant_1.EXTRA_FIELD, constant_1.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 (0, condition_1.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();
}
}
exports.HeaderCell = HeaderCell;
//# sourceMappingURL=header-cell.js.map