@antv/s2
Version:
effective spreadsheet render core lib
259 lines • 12 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildGridTreeHierarchy = void 0;
const lodash_1 = require("lodash");
const constant_1 = require("../../common/constant");
const i18n_1 = require("../../common/i18n");
const data_set_operate_1 = require("../../utils/data-set-operate");
const add_totals_1 = require("../../utils/layout/add-totals");
const generate_id_1 = require("../../utils/layout/generate-id");
const get_dims_condition_by_node_1 = require("../../utils/layout/get-dims-condition-by-node");
const whether_leaf_by_level_1 = require("../../utils/layout/whether-leaf-by-level");
const layout_hooks_1 = require("../layout/layout-hooks");
const node_1 = require("../layout/node");
const total_class_1 = require("../layout/total-class");
const total_measure_1 = require("../layout/total-measure");
/**
* 计算节点是否折叠
* 注意:真正的叶子节点(没有子节点)不应该有折叠状态
*/
const calculateCollapsedState = (options) => {
var _a, _b, _c, _d, _e;
const { spreadsheet, nodeId, currentField, level, isTotals, isTotalMeasure, isLeaf, } = options;
// 真正的叶子节点没有子节点,不应有折叠状态
if (isLeaf) {
return false;
}
const { collapseFields, collapseAll, expandDepth } = (_b = (_a = spreadsheet.options.style) === null || _a === void 0 ? void 0 : _a.rowCell) !== null && _b !== void 0 ? _b : {};
const isDefaultCollapsed = (_c = collapseFields === null || collapseFields === void 0 ? void 0 : collapseFields[nodeId]) !== null && _c !== void 0 ? _c : collapseFields === null || collapseFields === void 0 ? void 0 : collapseFields[currentField];
const isLevelCollapsed = (0, lodash_1.isNumber)(expandDepth) ? level >= expandDepth : null;
return isTotals || isTotalMeasure
? false
: (_e = (_d = isDefaultCollapsed !== null && isDefaultCollapsed !== void 0 ? isDefaultCollapsed : isLevelCollapsed) !== null && _d !== void 0 ? _d : collapseAll) !== null && _e !== void 0 ? _e : false;
};
/**
* 处理字段值,返回节点的值、查询条件和各种标志
*/
const processFieldValue = (options) => {
var _a;
const { fieldValue, currentField, query, parentNode, spreadsheet, level, fields, addMeasureInTotalQuery, } = options;
const isTotals = total_class_1.TotalClass.isTotalClassInstance(fieldValue);
const isTotalMeasure = total_measure_1.TotalMeasure.isTotalMeasureInstance(fieldValue);
let value;
let nodeQuery;
let isLeaf = false;
let isGrandTotals = false;
let isSubTotals = false;
let isTotalRoot = false;
if (isTotals) {
isGrandTotals = fieldValue.isGrandTotals;
isSubTotals = fieldValue.isSubTotals;
isTotalRoot = fieldValue.isTotalRoot;
value = (0, i18n_1.i18n)(fieldValue.label);
nodeQuery = isTotalRoot
? Object.assign({}, query) : Object.assign(Object.assign({}, query), { [currentField]: value });
if (addMeasureInTotalQuery) {
nodeQuery[constant_1.EXTRA_FIELD] = (_a = spreadsheet === null || spreadsheet === void 0 ? void 0 : spreadsheet.dataSet) === null || _a === void 0 ? void 0 : _a.fields.values[0];
}
isLeaf = (0, whether_leaf_by_level_1.whetherLeafByLevel)({ spreadsheet, level, fields });
}
else if (isTotalMeasure) {
value = (0, i18n_1.i18n)(fieldValue.label);
nodeQuery = Object.assign(Object.assign({}, query), { [constant_1.EXTRA_FIELD]: value });
isGrandTotals = parentNode.isGrandTotals;
isSubTotals = parentNode.isSubTotals;
isLeaf = (0, whether_leaf_by_level_1.whetherLeafByLevel)({ spreadsheet, level, fields });
}
else {
value = fieldValue;
nodeQuery =
value === constant_1.EMPTY_FIELD_VALUE
? Object.assign({}, query) : Object.assign(Object.assign({}, query), { [currentField]: value });
isLeaf = (0, whether_leaf_by_level_1.whetherLeafByLevel)({ spreadsheet, level, fields });
}
return {
value,
nodeQuery,
isLeaf,
isGrandTotals,
isSubTotals,
isTotalRoot,
isTotals,
isTotalMeasure,
};
};
/**
* 生成 grid-tree 模式的行头节点
* 与 generateHeaderNodes 类似,但支持折叠状态
*/
const generateGridTreeHeaderNodes = (params) => {
var _a;
const { currentField, fields, fieldValues, hierarchy, parentNode, level, query, addMeasureInTotalQuery, addTotalMeasureInTotal, spreadsheet, handler, } = params;
for (const originalFieldValue of fieldValues) {
const fieldValue = (0, generate_id_1.resolveNillString)(originalFieldValue);
const adjustedField = currentField;
const processed = processFieldValue({
fieldValue,
currentField,
query,
parentNode,
spreadsheet,
level,
fields,
addMeasureInTotalQuery,
});
const nodeId = (0, generate_id_1.generateId)(parentNode.id, processed.value);
if (nodeId) {
const isCollapsed = calculateCollapsedState({
spreadsheet,
nodeId,
currentField,
level,
isTotals: processed.isTotals,
isTotalMeasure: processed.isTotalMeasure,
isLeaf: processed.isLeaf,
});
const node = new node_1.Node({
id: nodeId,
value: processed.value,
level,
field: adjustedField,
parent: parentNode,
isTotals: processed.isTotals || processed.isTotalMeasure,
isGrandTotals: processed.isGrandTotals,
isSubTotals: processed.isSubTotals,
isTotalMeasure: processed.isTotalMeasure,
isCollapsed,
isTotalRoot: processed.isTotalRoot,
hierarchy,
query: processed.nodeQuery,
spreadsheet,
isLeaf: processed.isLeaf || isCollapsed,
});
const expandCurrentNode = (0, layout_hooks_1.layoutHierarchy)(spreadsheet, parentNode, node, hierarchy);
const hiddenColumnsInfo = (_a = spreadsheet === null || spreadsheet === void 0 ? void 0 : spreadsheet.facet) === null || _a === void 0 ? void 0 : _a.getHiddenColumnsInfo(node);
if (level > hierarchy.maxLevel &&
!processed.isGrandTotals &&
!parentNode.isGrandTotals &&
!parentNode.isSubTotals &&
!node.isSubTotals &&
!hiddenColumnsInfo) {
hierarchy.sampleNodesForAllLevels.push(node);
hierarchy.maxLevel = level;
hierarchy.sampleNodeForLastLevel = node;
}
// grid-tree 模式下,折叠的节点也是叶子节点
const isLeafNode = processed.isLeaf || isCollapsed || !expandCurrentNode;
if (isLeafNode) {
node.isLeaf = true;
hierarchy.pushIndexNode(node);
node.rowIndex = hierarchy.getIndexNodes().length - 1;
}
else {
handler === null || handler === void 0 ? void 0 : handler({
addTotalMeasureInTotal,
addMeasureInTotalQuery,
parentNode: node,
currentField: fields[level + 1],
fields,
hierarchy,
spreadsheet,
});
}
}
}
};
const buildNormalGridTreeHierarchy = (params) => {
const { parentNode, currentField, fields, spreadsheet } = params;
const dataSet = spreadsheet.dataSet;
const { values = [] } = dataSet.fields;
const index = fields.indexOf(currentField);
const fieldValues = [];
let query = {};
query = (0, get_dims_condition_by_node_1.getDimsCondition)(parentNode, true);
const dimValues = dataSet.getDimensionValues(currentField, query);
const arrangedValues = (0, layout_hooks_1.layoutArrange)(spreadsheet, dimValues, parentNode, currentField);
fieldValues.push(...(arrangedValues || []));
if ((0, lodash_1.isEmpty)(fieldValues) && currentField) {
if (currentField === constant_1.EXTRA_FIELD) {
fieldValues.push(...values);
}
else {
fieldValues.push(constant_1.EMPTY_FIELD_VALUE);
}
}
(0, add_totals_1.addTotals)({
currentField,
lastField: fields[index - 1],
isFirstField: index === 0,
fieldValues,
spreadsheet,
});
const displayFieldValues = (0, data_set_operate_1.filterOutDetail)(fieldValues);
generateGridTreeHeaderNodes(Object.assign(Object.assign({}, params), { fieldValues: displayFieldValues, level: index, parentNode,
query,
// eslint-disable-next-line @typescript-eslint/no-use-before-define
handler: buildGridTreeHierarchy }));
};
const buildTotalGridTreeHierarchy = (params) => {
const { addTotalMeasureInTotal, parentNode, currentField, fields, hierarchy, spreadsheet, } = params;
const index = fields.indexOf(currentField);
const dataSet = spreadsheet.dataSet;
const { values = [] } = dataSet.fields;
const fieldValues = [];
let query = {};
const totalsConfig = spreadsheet.getTotalsConfig(currentField);
const defaultDimensionGroup = parentNode.isGrandTotals
? totalsConfig.grandTotalsGroupDimensions || []
: totalsConfig.subTotalsGroupDimensions || [];
const dimensionGroup = !dataSet.isEmpty() ? defaultDimensionGroup : [];
if (dimensionGroup === null || dimensionGroup === void 0 ? void 0 : dimensionGroup.includes(currentField)) {
query = (0, get_dims_condition_by_node_1.getDimsCondition)(parentNode);
const dimValues = dataSet.getDimensionValues(currentField, query);
fieldValues.push(...(dimValues || []).map((value) => new total_class_1.TotalClass({
label: value,
isSubTotals: parentNode.isSubTotals,
isGrandTotals: parentNode.isGrandTotals,
isTotalRoot: false,
})));
if ((0, lodash_1.isEmpty)(fieldValues) && currentField) {
fieldValues.push(constant_1.EMPTY_FIELD_VALUE);
}
}
else if (addTotalMeasureInTotal && currentField === constant_1.EXTRA_FIELD) {
query = (0, get_dims_condition_by_node_1.getDimsCondition)(parentNode);
fieldValues.push(...values.map((v) => new total_measure_1.TotalMeasure(v)));
}
else if ((0, whether_leaf_by_level_1.whetherLeafByLevel)({ spreadsheet, level: index, fields })) {
parentNode.isLeaf = true;
hierarchy.pushIndexNode(parentNode);
parentNode.rowIndex = hierarchy.getIndexNodes().length - 1;
return;
}
else {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
buildTotalGridTreeHierarchy(Object.assign(Object.assign({}, params), { currentField: fields[index + 1] }));
return;
}
const displayFieldValues = (0, data_set_operate_1.filterOutDetail)(fieldValues);
generateGridTreeHeaderNodes(Object.assign(Object.assign({}, params), { fieldValues: displayFieldValues, level: index, parentNode,
query,
// eslint-disable-next-line @typescript-eslint/no-use-before-define
handler: buildGridTreeHierarchy }));
};
/**
* 构建 grid-tree 模式的行头层级结构
* grid-tree 模式特点:
* 1. 每个维度占据独立的列(与 grid 模式相同)
* 2. 支持展开/折叠子节点(与 tree 模式相同)
*/
function buildGridTreeHierarchy(params) {
if (params.parentNode.isTotals) {
buildTotalGridTreeHierarchy(params);
}
else {
buildNormalGridTreeHierarchy(params);
}
}
exports.buildGridTreeHierarchy = buildGridTreeHierarchy;
//# sourceMappingURL=build-grid-tree-hierarchy.js.map