Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: 优化 customTree 包含大量 values 生成结构时性能 #2469

Merged
merged 6 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/s2-core/__tests__/unit/facet/pivot-facet-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ jest.mock('@/data-set/pivot-data-set', () => {
indexesData,
sortedDimensionValues,
moreThanOneValue: jest.fn(),
transformIndexesData: actualPivotDataSet.prototype.transformIndexesData,
getExistValuesByDataItem:
actualPivotDataSet.prototype.getExistValuesByDataItem,
getFieldFormatter: actualDataSet.prototype.getFieldFormatter,
getFieldMeta: (field: string, meta: ViewMeta) => find(meta, { field }),
getFieldName: actualPivotDataSet.prototype.getFieldName,
Expand Down
6 changes: 5 additions & 1 deletion packages/s2-core/__tests__/unit/facet/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { assembleDataCfg } from 'tests/util';
import { transformIndexesData } from '@/utils/dataset/pivot-data-set';
import {
getExistValues,
transformIndexesData,
} from '@/utils/dataset/pivot-data-set';

/**
* 获取 Mock 数据
Expand All @@ -20,5 +23,6 @@ export function getMockPivotMeta() {
rowPivotMeta: rawRowPivotMeta,
colPivotMeta: rawColPivotMeta,
valueInCols: true,
getExistValuesByDataItem: getExistValues,
});
}
57 changes: 30 additions & 27 deletions packages/s2-core/src/data-set/pivot-data-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,13 @@ import {
flattenIndexesData,
getDataPath,
getDataPathPrefix,
getExistValues,
getFlattenDimensionValues,
getSatisfiedPivotMetaValues,
isMultiValue,
transformDimensionsValues,
transformIndexesData,
type TransformResult,
} from '../utils/dataset/pivot-data-set';
import { DataHandler } from '../utils/dataset/proxy-handler';
import { calcActionByType } from '../utils/number-calculate';
Expand All @@ -75,6 +77,10 @@ export class PivotDataSet extends BaseDataSet {
// sorted dimension values
public sortedDimensionValues: SortedDimensionValues;

getExistValuesByDataItem(data: DataType, values: string[]) {
return getExistValues(data, values);
}

/**
* When data related config changed, we need
* 1、re-process config
Expand All @@ -84,26 +90,41 @@ export class PivotDataSet extends BaseDataSet {
*/
public setDataCfg(dataCfg: S2DataConfig) {
super.setDataCfg(dataCfg);
const { rows } = this.fields;
this.sortedDimensionValues = {};
this.rowPivotMeta = new Map();
this.colPivotMeta = new Map();
this.transformIndexesData(this.originData.concat(this.totalData), rows);
this.handleDimensionValuesSort();
}

public transformIndexesData(
data: DataType[],
rows: string[],
): TransformResult {
const { columns, values, valueInCols } = this.fields;

let result: TransformResult;
DebuggerUtil.getInstance().debugCallback(DEBUG_TRANSFORM_DATA, () => {
const { rows, columns, values, valueInCols } = this.fields;
const { indexesData } = transformIndexesData({
result = transformIndexesData({
rows,
columns: columns as string[],
values,
valueInCols,
data: this.originData.concat(this.totalData),
data,
indexesData: this.indexesData,
sortedDimensionValues: this.sortedDimensionValues,
rowPivotMeta: this.rowPivotMeta,
colPivotMeta: this.colPivotMeta,
getExistValuesByDataItem: this.getExistValuesByDataItem,
});
this.indexesData = indexesData;
this.indexesData = result.indexesData;
this.rowPivotMeta = result.rowPivotMeta;
this.colPivotMeta = result.colPivotMeta;
this.sortedDimensionValues = result.sortedDimensionValues;
});

this.handleDimensionValuesSort();
return result;
}

/**
Expand All @@ -117,7 +138,6 @@ export class PivotDataSet extends BaseDataSet {
drillDownData: DataType[],
rowNode: Node,
) {
const { columns, values, valueInCols } = this.fields;
const currentRowFields = Node.getFieldPath(rowNode, true);
const nextRowFields = [...currentRowFields, extraRowField];
const store = this.spreadsheet.store;
Expand All @@ -134,27 +154,10 @@ export class PivotDataSet extends BaseDataSet {
}

// 3、转换数据
const {
paths: drillDownDataPaths,
indexesData,
rowPivotMeta,
colPivotMeta,
sortedDimensionValues,
} = transformIndexesData({
rows: nextRowFields,
columns: columns as string[],
values,
valueInCols,
data: drillDownData,
indexesData: this.indexesData,
sortedDimensionValues: this.sortedDimensionValues,
rowPivotMeta: this.rowPivotMeta,
colPivotMeta: this.colPivotMeta,
});
this.indexesData = indexesData;
this.rowPivotMeta = rowPivotMeta;
this.colPivotMeta = colPivotMeta;
this.sortedDimensionValues = sortedDimensionValues;
const { paths: drillDownDataPaths } = this.transformIndexesData(
drillDownData,
nextRowFields,
);

// 4、record data paths by nodeId
// set new drill-down data path
Expand Down
1 change: 0 additions & 1 deletion packages/s2-core/src/utils/data-set-operate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export const filterOutDetail = (values: string[] = []) => {
(v) => v !== TOTAL_VALUE && v !== EMPTY_EXTRA_FIELD_PLACEHOLDER,
);
};

export const customFlattenDeep = (
data: Record<any, any>[] | Record<any, any>,
) => {
Expand Down
55 changes: 33 additions & 22 deletions packages/s2-core/src/utils/dataset/pivot-data-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export function isMultiValue(pathValue: string | number) {
export function transformDimensionsValues(
record: DataType = {},
dimensions: string[] = [],
placeholder: string = TOTAL_VALUE,
placeholder = TOTAL_VALUE,
): string[] {
return dimensions.reduce((res: string[], dimension: string) => {
const value = record[dimension];
Expand All @@ -70,10 +70,19 @@ export function transformDimensionsValues(
}, []);
}

export function getExistValues(data: DataType, values: string[]) {
const result = values.filter((v) => v in data);
if (isEmpty(result)) {
result.push(EMPTY_EXTRA_FIELD_PLACEHOLDER);
}

return result;
}

export function transformDimensionsValuesWithExtraFields(
record: DataType = {},
dimensions: string[] = [],
values: string[] = [],
values?: string[],
) {
const result = [];

Expand All @@ -93,25 +102,13 @@ export function transformDimensionsValuesWithExtraFields(
}, []);
}

if (isEmpty(values)) {
result.push(transform(record, dimensions));
} else {
if (values) {
values.forEach((value) => {
if (value in record) {
result.push(transform(record, dimensions, value));
}
result.push(transform(record, dimensions, value));
});
} else {
result.push(transform(record, dimensions));
}

/**
* result 为空时,就是命中了数组置于当前维度,但是当前的数据中并没有包含任何 values 配置,给一个默认维度用于占位
* 主要用于处理趋势分析表中只存在日期列头,不存在任何值的情况:
* ref: @see packages/s2-react/__tests__/unit/components/sheets/strategy-sheet/index-spec.tsx
*/
if (isEmpty(result)) {
result.push(transform(record, dimensions, EMPTY_EXTRA_FIELD_PLACEHOLDER));
}

return result;
}

Expand Down Expand Up @@ -277,12 +274,21 @@ interface Param {
sortedDimensionValues: SortedDimensionValues;
rowPivotMeta?: PivotMeta;
colPivotMeta?: PivotMeta;
getExistValuesByDataItem?: (data: DataType, values: string[]) => string[];
}

export interface TransformResult {
paths: (string | number)[];
indexesData: Record<string, DataType[][] | DataType[]>;
rowPivotMeta: PivotMeta;
colPivotMeta: PivotMeta;
sortedDimensionValues: SortedDimensionValues;
}

/**
* 转换原始数据为二维数组数据
*/
export function transformIndexesData(params: Param) {
export function transformIndexesData(params: Param): TransformResult {
const {
rows,
columns,
Expand All @@ -293,6 +299,7 @@ export function transformIndexesData(params: Param) {
sortedDimensionValues,
rowPivotMeta,
colPivotMeta,
getExistValuesByDataItem,
} = params;
const paths = [];

Expand All @@ -319,21 +326,25 @@ export function transformIndexesData(params: Param) {

const prefix = getDataPathPrefix(rows, columns as string[]);

data.forEach((item) => {
data.forEach((item: DataType) => {
// 空数据没有意义,直接跳过
if (!item || isEmpty(item)) {
return;
}

const existValues = getExistValuesByDataItem
? getExistValuesByDataItem(item, values)
: getExistValues(item, values);

const multiRowDimensionValues = transformDimensionsValuesWithExtraFields(
item,
rows,
valueInCols ? undefined : values,
valueInCols ? null : existValues,
);
const multiColDimensionValues = transformDimensionsValuesWithExtraFields(
item,
columns,
valueInCols ? values : undefined,
valueInCols ? existValues : null,
);

for (const rowDimensionValues of multiRowDimensionValues) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
import {
CustomTreePivotDataSet,
EMPTY_EXTRA_FIELD_PLACEHOLDER,
i18n,
type DataType,
type Meta,
type S2DataConfig,
} from '@antv/s2';
import { isEmpty, isObject, keys } from 'lodash';

export class StrategyDataSet extends CustomTreePivotDataSet {
getExistValuesByDataItem(data: DataType, values: string[]) {
const result = keys(data).filter((key) => isObject(data[key]));

if (isEmpty(result)) {
result.push(EMPTY_EXTRA_FIELD_PLACEHOLDER);
}

return result;
}

processDataCfg(dataCfg: S2DataConfig): S2DataConfig {
const { meta } = dataCfg;
const updatedDataCfg = super.processDataCfg(dataCfg);
Expand Down
Loading