From 954382273438c1ba5e2042c3532afa941855787c Mon Sep 17 00:00:00 2001 From: wjgogogo <906626481@qq.com> Date: Tue, 12 Dec 2023 14:14:41 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=20=E4=BC=98=E5=8C=96=E8=B6=8B?= =?UTF-8?q?=E5=8A=BF=E8=A1=A8=E7=9A=84=E6=95=B0=E6=8D=AE=E8=BD=AC=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data-set/custom-tree-data-set-spec.ts | 6 +- .../__tests__/unit/facet/pivot-facet-spec.ts | 4 +- packages/s2-core/src/common/constant/field.ts | 1 + .../data-set/custom-tree-pivot-data-set.ts | 44 +--------- .../s2-core/src/data-set/pivot-data-set.ts | 32 +++----- .../s2-core/src/utils/data-set-operate.ts | 10 ++- .../src/utils/dataset/pivot-data-set.ts | 82 ++++++------------- .../sheets/strategy-sheet/custom-data-set.ts | 13 +++ 8 files changed, 68 insertions(+), 124 deletions(-) diff --git a/packages/s2-core/__tests__/unit/data-set/custom-tree-data-set-spec.ts b/packages/s2-core/__tests__/unit/data-set/custom-tree-data-set-spec.ts index 99e6b7e8da..11faa4c7a3 100644 --- a/packages/s2-core/__tests__/unit/data-set/custom-tree-data-set-spec.ts +++ b/packages/s2-core/__tests__/unit/data-set/custom-tree-data-set-spec.ts @@ -51,7 +51,7 @@ describe('Custom Tree Dataset Test', () => { test('should get empty row pivot meta', () => { const rowPivotMeta = dataSet.rowPivotMeta; - expect([...rowPivotMeta.keys()]).toEqual([]); + expect([...rowPivotMeta.keys()]).toEqual(values); }); test('should get correct col pivot meta', () => { @@ -68,7 +68,7 @@ describe('Custom Tree Dataset Test', () => { test('should get correct indexesData', () => { const prefix = 'type[&]sub_type'; const indexesData = dataSet.indexesData; - expect(get(indexesData, [prefix, 1, 1])).toEqual({ + expect(get(indexesData, [prefix, 1, 1, 1])).toEqual({ type: '家具', sub_type: '桌子', 'measure-a': 1, @@ -78,7 +78,7 @@ describe('Custom Tree Dataset Test', () => { 'measure-e': 5, 'measure-f': 6, }); - expect(get(indexesData, [prefix, 1, 2])).toEqual({ + expect(get(indexesData, [prefix, 1, 1, 2])).toEqual({ type: '家具', sub_type: '椅子', 'measure-a': 11, diff --git a/packages/s2-core/__tests__/unit/facet/pivot-facet-spec.ts b/packages/s2-core/__tests__/unit/facet/pivot-facet-spec.ts index 393b87c5e0..aec63f6c98 100644 --- a/packages/s2-core/__tests__/unit/facet/pivot-facet-spec.ts +++ b/packages/s2-core/__tests__/unit/facet/pivot-facet-spec.ts @@ -96,8 +96,8 @@ jest.mock('@/data-set/pivot-data-set', () => { sortedDimensionValues, moreThanOneValue: jest.fn(), transformIndexesData: actualPivotDataSet.prototype.transformIndexesData, - transformDimensionsValues: - actualPivotDataSet.prototype.transformDimensionsValues, + getExistValuesByDataItem: + actualPivotDataSet.prototype.getExistValuesByDataItem, getFieldFormatter: actualDataSet.prototype.getFieldFormatter, getFieldMeta: (field: string, meta: ViewMeta) => find(meta, { field }), getFieldName: actualPivotDataSet.prototype.getFieldName, diff --git a/packages/s2-core/src/common/constant/field.ts b/packages/s2-core/src/common/constant/field.ts index 23b607eae0..f9a62a6cfa 100644 --- a/packages/s2-core/src/common/constant/field.ts +++ b/packages/s2-core/src/common/constant/field.ts @@ -7,3 +7,4 @@ export const TOTAL_VALUE = '$$total$$'; export const MULTI_VALUE = '$$multi$$'; export const SERIES_NUMBER_FIELD = '$$series_number$$'; export const EMPTY_FIELD_VALUE = '$$empty_field_value$$'; +export const EMPTY_EXTRA_FIELD_PLACEHOLDER = '$$empty_extra_placeholder$$'; diff --git a/packages/s2-core/src/data-set/custom-tree-pivot-data-set.ts b/packages/s2-core/src/data-set/custom-tree-pivot-data-set.ts index fddefe23d8..8215d774d5 100644 --- a/packages/s2-core/src/data-set/custom-tree-pivot-data-set.ts +++ b/packages/s2-core/src/data-set/custom-tree-pivot-data-set.ts @@ -1,61 +1,23 @@ import { get } from 'lodash'; -import { DebuggerUtil, DEBUG_TRANSFORM_DATA } from '../common/debug'; -import { EXTRA_FIELD, TOTAL_VALUE } from '../common/constant'; +import { EXTRA_FIELD } from '../common/constant'; import { i18n } from '../common/i18n'; import type { Meta, S2DataConfig } from '../common/interface'; import { getDataPath, getDataPathPrefix, transformDimensionsValues, - transformIndexesData, } from '../utils/dataset/pivot-data-set'; import { DataHandler } from '../utils/dataset/proxy-handler'; import type { CellDataParams, DataType } from './interface'; import { PivotDataSet } from './pivot-data-set'; export class CustomTreePivotDataSet extends PivotDataSet { - transformDimensionsValues( - record: DataType = {}, - dimensions: string[] = [], - placeholder = TOTAL_VALUE, - ) { - return transformDimensionsValues(record, dimensions, { - placeholder, - excludeExtra: true, - }); - } - - transformIndexesData(data: DataType[], rows: string[]) { - const { columns, valueInCols } = this.fields; - - let result; - DebuggerUtil.getInstance().debugCallback(DEBUG_TRANSFORM_DATA, () => { - result = transformIndexesData({ - rows, - columns: columns as string[], - values: [], - valueInCols, - data, - indexesData: this.indexesData, - sortedDimensionValues: this.sortedDimensionValues, - rowPivotMeta: this.rowPivotMeta, - colPivotMeta: this.colPivotMeta, - shouldFlatten: false, - }); - this.indexesData = result.indexesData; - this.rowPivotMeta = result.rowPivotMeta; - this.colPivotMeta = result.colPivotMeta; - this.sortedDimensionValues = result.sortedDimensionValues; - }); - return result; - } - getCellData(params: CellDataParams): DataType { const { query } = params; const { rows, columns } = this.fields; - const rowDimensionValues = this.transformDimensionsValues(query, rows); + const rowDimensionValues = transformDimensionsValues(query, rows); // 透视表下columns只支持简单结构 - const colDimensionValues = this.transformDimensionsValues( + const colDimensionValues = transformDimensionsValues( query, columns as string[], ); diff --git a/packages/s2-core/src/data-set/pivot-data-set.ts b/packages/s2-core/src/data-set/pivot-data-set.ts index 9eb6de14af..db992abf3c 100644 --- a/packages/s2-core/src/data-set/pivot-data-set.ts +++ b/packages/s2-core/src/data-set/pivot-data-set.ts @@ -44,6 +44,7 @@ import { flattenIndexesData, getDataPath, getDataPathPrefix, + getExistValues, getFlattenDimensionValues, getSatisfiedPivotMetaValues, isMultiValue, @@ -75,6 +76,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 @@ -92,16 +97,6 @@ export class PivotDataSet extends BaseDataSet { this.handleDimensionValuesSort(); } - public transformDimensionsValues( - record: DataType = {}, - dimensions: string[] = [], - placeholder = TOTAL_VALUE, - ) { - return transformDimensionsValues(record, dimensions, { - placeholder, - }); - } - public transformIndexesData(data: DataType[], rows: string[]) { const { columns, values, valueInCols } = this.fields; @@ -117,18 +112,15 @@ export class PivotDataSet extends BaseDataSet { sortedDimensionValues: this.sortedDimensionValues, rowPivotMeta: this.rowPivotMeta, colPivotMeta: this.colPivotMeta, + getExistValuesByDataItem: this.getExistValuesByDataItem, }); this.indexesData = result.indexesData; this.rowPivotMeta = result.rowPivotMeta; this.colPivotMeta = result.colPivotMeta; this.sortedDimensionValues = result.sortedDimensionValues; }); - return result; - } - getValues() { - const { values } = this.fields; - return values; + return result; } /** @@ -340,7 +332,7 @@ export class PivotDataSet extends BaseDataSet { return []; } - const dimensionValues = this.transformDimensionsValues( + const dimensionValues = transformDimensionsValues( query, dimensions, MULTI_VALUE, @@ -407,8 +399,8 @@ export class PivotDataSet extends BaseDataSet { rows = Node.getFieldPath(rowNode, isDrillDown) ?? originRows; } - const rowDimensionValues = this.transformDimensionsValues(query, rows); - const colDimensionValues = this.transformDimensionsValues( + const rowDimensionValues = transformDimensionsValues(query, rows); + const colDimensionValues = transformDimensionsValues( query, columns as string[], ); @@ -526,12 +518,12 @@ export class PivotDataSet extends BaseDataSet { ? rows.concat(actualDrillDownFields) : rows; - const rowDimensionValues = this.transformDimensionsValues( + const rowDimensionValues = transformDimensionsValues( query, totalRows, MULTI_VALUE, ); - const colDimensionValues = this.transformDimensionsValues( + const colDimensionValues = transformDimensionsValues( query, columns as string[], MULTI_VALUE, diff --git a/packages/s2-core/src/utils/data-set-operate.ts b/packages/s2-core/src/utils/data-set-operate.ts index e597f1b587..498509291e 100644 --- a/packages/s2-core/src/utils/data-set-operate.ts +++ b/packages/s2-core/src/utils/data-set-operate.ts @@ -1,5 +1,8 @@ import { isArray, flattenDeep } from 'lodash'; -import { TOTAL_VALUE } from '../common/constant/field'; +import { + EMPTY_EXTRA_FIELD_PLACEHOLDER, + TOTAL_VALUE, +} from '../common/constant/field'; import type { Totals, TotalsStatus } from '../common/interface'; export const getListBySorted = ( @@ -29,9 +32,10 @@ export const getListBySorted = ( }; export const filterOutDetail = (values: string[] = []) => { - return values.filter((v) => v !== TOTAL_VALUE); + return values.filter( + (v) => v !== TOTAL_VALUE && v !== EMPTY_EXTRA_FIELD_PLACEHOLDER, + ); }; - export const customFlattenDeep = ( data: Record[] | Record, ) => { diff --git a/packages/s2-core/src/utils/dataset/pivot-data-set.ts b/packages/s2-core/src/utils/dataset/pivot-data-set.ts index 55472156ec..00ac0b516b 100644 --- a/packages/s2-core/src/utils/dataset/pivot-data-set.ts +++ b/packages/s2-core/src/utils/dataset/pivot-data-set.ts @@ -14,6 +14,7 @@ import { } from 'lodash'; import type { PickEssential } from '../../common/interface/utils'; import { + EMPTY_EXTRA_FIELD_PLACEHOLDER, EXTRA_FIELD, ID_SEPARATOR, MULTI_VALUE, @@ -56,18 +57,9 @@ export function isMultiValue(pathValue: string | number) { export function transformDimensionsValues( record: DataType = {}, dimensions: string[] = [], - { - placeholder = TOTAL_VALUE, - excludeExtra = false, - }: { - placeholder?: string; - excludeExtra?: boolean; - } = {}, + placeholder = TOTAL_VALUE, ): string[] { return dimensions.reduce((res: string[], dimension: string) => { - if (dimension === EXTRA_FIELD && excludeExtra) { - return res; - } const value = record[dimension]; if (!(dimension in record)) { res.push(placeholder); @@ -78,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 = []; @@ -101,16 +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)); } - return result; } @@ -269,14 +267,14 @@ export function getDataPath(params: DataPathParams) { interface Param { rows: string[]; columns: string[]; - values?: string[]; + values: string[]; valueInCols: boolean; data: DataType[]; indexesData: Record; sortedDimensionValues: SortedDimensionValues; rowPivotMeta?: PivotMeta; colPivotMeta?: PivotMeta; - shouldFlatten?: boolean; + getExistValuesByDataItem: (data: DataType, values: string[]) => string[]; } /** @@ -293,7 +291,7 @@ export function transformIndexesData(params: Param) { sortedDimensionValues, rowPivotMeta, colPivotMeta, - shouldFlatten = true, + getExistValuesByDataItem, } = params; const paths = []; @@ -320,21 +318,25 @@ export function transformIndexesData(params: Param) { const prefix = getDataPathPrefix(rows, columns as string[]); - const flattenData = (item: DataType) => { + 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) { @@ -354,37 +356,7 @@ export function transformIndexesData(params: Param) { set(indexesData, path, item); } } - }; - - const handleData = (item: DataType) => { - // 空数据没有意义,直接跳过 - if (!item || isEmpty(item)) { - return; - } - - const rowDimensionValues = transformDimensionsValues(item, rows, { - excludeExtra: true, - }); - const colDimensionValues = transformDimensionsValues(item, columns, { - excludeExtra: true, - }); - const path = getDataPath({ - rowDimensionValues, - colDimensionValues, - rowPivotMeta, - colPivotMeta, - rowFields: rows, - colFields: columns, - isFirstCreate: true, - onFirstCreate, - prefix, - }); - paths.push(path); - set(indexesData, path, item); - paths.push(path); - }; - - data.forEach(shouldFlatten ? flattenData : handleData); + }); return { paths, diff --git a/packages/s2-react/src/components/sheets/strategy-sheet/custom-data-set.ts b/packages/s2-react/src/components/sheets/strategy-sheet/custom-data-set.ts index 05a6729212..c62fc33710 100644 --- a/packages/s2-react/src/components/sheets/strategy-sheet/custom-data-set.ts +++ b/packages/s2-react/src/components/sheets/strategy-sheet/custom-data-set.ts @@ -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);