UNPKG

@antv/s2

Version:

effective spreadsheet render core lib

209 lines 10.6 kB
import { __awaiter } from "tslib"; import { compact, get, isEmpty, isEqual, last, sortBy, uniq } from 'lodash'; import { NODE_ID_SEPARATOR, S2Event } from '../common/constant'; import { getLeafColumnsWithKey } from '../facet/utils'; export const getHiddenColumnFieldKey = (field) => { const targetFieldKey = (field.includes(NODE_ID_SEPARATOR) ? 'id' : 'field'); return targetFieldKey; }; /** * @name 获取需要隐藏的 field 转成对应的 Node */ export const getHiddenColumnNodes = (spreadsheet, hiddenColumnFields = []) => { const colNodes = spreadsheet.facet.getInitColIndexLeafNodes(); return compact(hiddenColumnFields.map((field) => { const targetFieldKey = getHiddenColumnFieldKey(field); return colNodes.find((node) => node[targetFieldKey] === field); })); }; /** * @name 获取隐藏列兄弟节点 * @description 获取当前隐藏列(兼容多选) 所对应为未隐藏的兄弟节点 * @param hideColumns 经过分组的连续隐藏列 * [ 1, 2, 3, -, -, -, (7 √), 8, 9 ] * [ 1, 2, 3, (4 √), - ] */ export const getHiddenColumnDisplaySiblingNode = (spreadsheet, hiddenColumnFields = []) => { if (isEmpty(hiddenColumnFields)) { return { prev: null, next: null, }; } const initColLeafNodes = spreadsheet.facet.getInitColIndexLeafNodes(); const hiddenColumnIndexes = getHiddenColumnNodes(spreadsheet, hiddenColumnFields).map((node) => initColLeafNodes.findIndex((item) => item.id === node.id)); const lastHiddenColumnIndex = Math.max(...hiddenColumnIndexes); const firstHiddenColumnIndex = Math.min(...hiddenColumnIndexes); const nextSiblingNode = initColLeafNodes.find((node, index) => index === lastHiddenColumnIndex + 1); const prevSiblingNode = initColLeafNodes.find((node, index) => index === firstHiddenColumnIndex - 1); return { prev: prevSiblingNode || null, next: nextSiblingNode || null, }; }; /** * @name 获取隐藏列组 * @description 如果给定的隐藏列不是连续的, 比如原始列是 [1,2,3,4,5,6,7], 隐藏列是 [2,3,6], 那么其实在表格上需要显示两个展开按钮 * [[2,3],[6]] */ export const getHiddenColumnsThunkGroup = (columns, hiddenColumnFields) => { if (isEmpty(hiddenColumnFields)) { return []; } // 上一个需要隐藏项的序号 let prevHiddenIndex = Number.NEGATIVE_INFINITY; return columns.reduce((result, field, index) => { if (!hiddenColumnFields.includes(field)) { return result; } if (index === prevHiddenIndex + 1) { const lastGroup = last(result); lastGroup === null || lastGroup === void 0 ? void 0 : lastGroup.push(field); } else { const group = [field]; result.push(group); } prevHiddenIndex = index; return result; }, []); }; /** * @name 获取相同隐藏组的索引 * 原始列: [a, b, c, d, e, f, g, i] * 隐藏部分列: [[a, b], c, [d], e, f, [g], i] * 变换列头顺序后: [[a], e, [b], c, f, [d, g], i] * 也就是说,变换列头顺序后重新分组,本轮遍历时和列头变换顺序之前的隐藏组做对比,只要有一项是相同的, 那么就属于同一个隐藏组,需要进行替换,如 [a, b] => [a], 剩下的 b ,在本轮遍历时就不会有相同组了,会重新添加 [b],本轮的[d, g]分组会找到上一次的 [d] 分组,并且替换 */ export const getSameHiddenGroupIndex = (currentHiddenColumnsInfo, lastHiddenColumnDetail) => { return lastHiddenColumnDetail.findIndex((item) => currentHiddenColumnsInfo.hideColumnNodes.some((node) => { var _a; return (_a = item.hideColumnNodes) === null || _a === void 0 ? void 0 : _a.find((hiddenNode) => hiddenNode.id === node.id); })); }; /** * @name 隐藏指定列 * @description 1. 通过分析组件隐藏, 2. 点击列头隐藏 * 存储: 1.隐藏列所对应的兄弟节点 (显示展开按钮), 2.当前隐藏列 (点击展开按钮恢复隐藏) * 重置交互: 比如选中当前列, 显示高亮背景色, 隐藏后需要取消高亮 * 钩子: 提供当前被隐藏的列, 和全量的隐藏组 */ export const hideColumns = (spreadsheet_1, ...args_1) => __awaiter(void 0, [spreadsheet_1, ...args_1], void 0, function* (spreadsheet, selectedColumnFields = [], forceRender = false) { const renderByHiddenColumns = (...args_2) => __awaiter(void 0, [...args_2], void 0, function* (hiddenColumnFields = [], hiddenColumnsDetail = []) { spreadsheet.setOptions({ interaction: { hiddenColumnFields, }, }); spreadsheet.interaction.reset(); spreadsheet.store.set('hiddenColumnsDetail', hiddenColumnsDetail); yield spreadsheet.render({ reloadData: false, rebuildHiddenColumnsDetail: false, }); }); if (isEmpty(selectedColumnFields) && forceRender) { yield renderByHiddenColumns(); return; } const lastHiddenColumnDetail = spreadsheet.store.get('hiddenColumnsDetail', []); const { hiddenColumnFields: lastHiddenColumnFields = [] } = spreadsheet.options.interaction; if (isEqual(selectedColumnFields, lastHiddenColumnFields) && !forceRender) { return; } const hiddenColumnFields = uniq([ ...selectedColumnFields, ...lastHiddenColumnFields, ]); const isAllNearToHiddenColumnNodes = getHiddenColumnNodes(spreadsheet, hiddenColumnFields).every((node, i, nodes) => { const nextNode = nodes[i + 1]; return !nextNode || Math.abs(node.colIndex - nextNode.colIndex) === 1; }); const displaySiblingNode = getHiddenColumnDisplaySiblingNode(spreadsheet, isAllNearToHiddenColumnNodes ? hiddenColumnFields : selectedColumnFields); const currentHiddenColumnsInfo = { hideColumnNodes: getHiddenColumnNodes(spreadsheet, selectedColumnFields), displaySiblingNode, }; const index = getSameHiddenGroupIndex(currentHiddenColumnsInfo, lastHiddenColumnDetail); let hiddenColumnsDetail = []; if (index !== -1) { hiddenColumnsDetail = lastHiddenColumnDetail.map((item, i) => { if (i === index) { return currentHiddenColumnsInfo; } return item; }); } else { hiddenColumnsDetail = [...lastHiddenColumnDetail, currentHiddenColumnsInfo]; } spreadsheet.emit(S2Event.COL_CELL_HIDDEN, currentHiddenColumnsInfo, hiddenColumnsDetail); yield renderByHiddenColumns(hiddenColumnFields, hiddenColumnsDetail); }); /** * @name 获取配置的列头 * @description 明细表: 配置的是 field,直接使用, 透视表: 需要将 field 转成布局之后的唯一id */ export const getColumns = (spreadsheet) => { const { columns = [] } = spreadsheet.dataCfg.fields; if (spreadsheet.isTableMode() && !spreadsheet.isCustomColumnFields()) { return columns; } return spreadsheet.facet.getInitColIndexLeafNodes().map(({ id }) => id); }; /** * @name 根据分组隐藏指定列 * @description 根据配置的隐藏列自动分组, 批量隐藏 * @param spreadsheet * @param hiddenColumnFields 隐藏的列头字段 * @param forceRender 隐藏的列头字段为空时, 是否强制更新 */ export const hideColumnsByThunkGroup = (spreadsheet_2, ...args_3) => __awaiter(void 0, [spreadsheet_2, ...args_3], void 0, function* (spreadsheet, hiddenColumnFields = [], forceRender = false) { // 隐藏列为空时, 有可能是隐藏后又展开 ( [] => ['A'] => []), 所以需要更新一次, 将渲染的展开icon, 隐藏列信息等清空 if (isEmpty(hiddenColumnFields) && forceRender) { yield hideColumns(spreadsheet, hiddenColumnFields, true); } const columns = getColumns(spreadsheet); const leafs = getLeafColumnsWithKey(columns); const hiddenColumnsGroup = getHiddenColumnsThunkGroup(leafs, hiddenColumnFields); yield Promise.all(hiddenColumnsGroup.map((fields) => __awaiter(void 0, void 0, void 0, function* () { yield hideColumns(spreadsheet, fields, forceRender); }))); }); export const isLastColumnAfterHidden = (spreadsheet, columnField) => { const columnLeafNodes = spreadsheet.facet.getColLeafNodes(); const initColLeafNodes = spreadsheet.facet.getInitColIndexLeafNodes(); const fieldKey = getHiddenColumnFieldKey(columnField); return (get(last(columnLeafNodes), fieldKey) === columnField && get(last(initColLeafNodes), fieldKey) !== columnField); }; export const getValidDisplaySiblingNode = (displaySiblingNode, direction) => direction ? displaySiblingNode === null || displaySiblingNode === void 0 ? void 0 : displaySiblingNode[direction] : (displaySiblingNode === null || displaySiblingNode === void 0 ? void 0 : displaySiblingNode.next) || (displaySiblingNode === null || displaySiblingNode === void 0 ? void 0 : displaySiblingNode.prev); export const getValidDisplaySiblingNodeId = (displaySiblingNode, direction) => { const node = getValidDisplaySiblingNode(displaySiblingNode, direction); return node === null || node === void 0 ? void 0 : node.id; }; export const isEqualDisplaySiblingNodeId = (displaySiblingNode, nodeId, direction) => getValidDisplaySiblingNodeId(displaySiblingNode, direction) === nodeId; export const getHiddenColumnContinuousSiblingNodes = (spreadsheet, nodeId, hideDirection) => { var _a; const continuousSiblingNodes = []; const hiddenColumnFields = ((_a = spreadsheet.options.interaction) === null || _a === void 0 ? void 0 : _a.hiddenColumnFields) || []; const hiddenColumnNodes = getHiddenColumnNodes(spreadsheet, hiddenColumnFields); const hiddenColumnNodesMap = new Map(hiddenColumnNodes.map((node) => [node.id, node])); const initColLeafNodes = spreadsheet.facet.getInitColIndexLeafNodes(); const step = hideDirection === 'prev' ? 1 : -1; const nodeIndex = initColLeafNodes.findIndex((node) => node.id === nodeId); const startIndex = nodeIndex + step; for (let i = startIndex; i < initColLeafNodes.length; i += step) { const currentNode = initColLeafNodes[i]; if (!currentNode) { break; } if (hiddenColumnNodesMap.has(currentNode === null || currentNode === void 0 ? void 0 : currentNode.id)) { continuousSiblingNodes.push(currentNode); } else { break; } } return sortBy(continuousSiblingNodes, 'colIndex'); }; //# sourceMappingURL=hide-columns.js.map