From 3b80ef1ec5611b287221cbf5221b533b773c962b Mon Sep 17 00:00:00 2001 From: lijinke666 Date: Thu, 12 Oct 2023 16:17:19 +0800 Subject: [PATCH 1/3] =?UTF-8?q?refactor(data-set):=20=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=8D=95=E5=85=83=E6=A0=BC=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=20API=20=E4=BF=9D=E6=8C=81=E9=A3=8E=E6=A0=BC=E7=BB=9F=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data-set/custom-tree-data-set-spec.ts | 2 - .../unit/data-set/pivot-data-set-spec.ts | 59 ++++++------ .../data-set/pivot-data-set-total-spec.ts | 45 +++++---- .../__tests__/unit/facet/pivot-facet-spec.ts | 2 +- packages/s2-core/__tests__/util/helpers.ts | 4 +- .../s2-core/src/common/interface/basic.ts | 27 +++--- .../s2-core/src/data-set/base-data-set.ts | 94 ++++++++++++------- .../data-set/custom-grid-pivot-data-set.ts | 2 +- .../data-set/custom-tree-pivot-data-set.ts | 11 ++- packages/s2-core/src/data-set/interface.ts | 37 +++++++- .../s2-core/src/data-set/pivot-data-set.ts | 32 +++---- .../s2-core/src/data-set/table-data-set.ts | 10 +- packages/s2-core/src/facet/layout/node.ts | 3 +- .../base-interaction/click/row-text-click.ts | 9 +- .../src/utils/dataset/pivot-data-set.ts | 2 +- packages/s2-core/src/utils/sort-action.ts | 4 +- packages/s2-core/src/utils/tooltip.ts | 4 +- packages/s2-react/playground/drill-down.tsx | 5 +- packages/s2-vue/playground/App.vue | 14 +-- .../docs/api/basic-class/base-data-set.en.md | 2 +- .../docs/api/basic-class/base-data-set.zh.md | 68 ++++++++++++-- .../docs/manual/advanced/get-cell-data.en.md | 4 +- .../docs/manual/advanced/get-cell-data.zh.md | 19 ++-- .../manual/basic/analysis/drill-down.en.md | 2 +- .../manual/basic/analysis/drill-down.zh.md | 6 +- .../drill-dwon/demo/for-pivot.tsx | 6 +- 26 files changed, 306 insertions(+), 167 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 a48baba423..d4fc7554d9 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 @@ -101,7 +101,6 @@ describe('Custom Tree Dataset Test', () => { sub_type: '桌子', [EXTRA_FIELD]: 'measure-a', }, - isTotals: true, })! .getOrigin(), ).toContainEntries([['measure-a', 1]]); @@ -114,7 +113,6 @@ describe('Custom Tree Dataset Test', () => { sub_type: '椅子', [EXTRA_FIELD]: 'measure-e', }, - isTotals: true, })! .getOrigin(), ).toContainEntries([['measure-e', 55]]); diff --git a/packages/s2-core/__tests__/unit/data-set/pivot-data-set-spec.ts b/packages/s2-core/__tests__/unit/data-set/pivot-data-set-spec.ts index 9c5ffac5ad..929f98ca26 100644 --- a/packages/s2-core/__tests__/unit/data-set/pivot-data-set-spec.ts +++ b/packages/s2-core/__tests__/unit/data-set/pivot-data-set-spec.ts @@ -191,7 +191,7 @@ describe('Pivot Dataset Test', () => { expect(cell2!.getOrigin()).toContainEntries([['number', 352]]); }); - describe('getMultiData function', () => { + describe('getCellMultiData function', () => { beforeEach(() => { dataSet.setDataCfg(assembleDataCfg()); }); @@ -204,86 +204,91 @@ describe('Pivot Dataset Test', () => { [EXTRA_FIELD]: 'number', }; - expect(dataSet.getMultiData(specialQuery)).toHaveLength(1); + expect(dataSet.getCellMultiData({ query: specialQuery })).toHaveLength( + 1, + ); expect( - dataSet.getMultiData(specialQuery)[0].getOrigin(), + dataSet.getCellMultiData({ query: specialQuery })[0].getOrigin(), ).toContainEntries([['number', 7789]]); }); test('should get all detail data when child dimension is not specified', () => { expect( - dataSet.getMultiData( - { + dataSet.getCellMultiData({ + query: { province: '浙江省', type: '家具', sub_type: '桌子', [EXTRA_FIELD]: 'number', }, - { + totals: { row: { totalDimensions: false }, column: { totalDimensions: false }, }, - ), + }), ).toHaveLength(4); expect( - dataSet.getMultiData( - { + dataSet.getCellMultiData({ + query: { type: '家具', sub_type: '桌子', [EXTRA_FIELD]: 'number', }, - { + totals: { row: { totalDimensions: false }, column: { totalDimensions: false }, }, - ), + }), ).toHaveLength(8); expect( - dataSet.getMultiData( - { + dataSet.getCellMultiData({ + query: { type: '家具', [EXTRA_FIELD]: 'number', }, - { + totals: { row: { totalDimensions: false }, column: { totalDimensions: false }, }, - ), + }), ).toHaveLength(16); expect( - dataSet.getMultiData( - { + dataSet.getCellMultiData({ + query: { [EXTRA_FIELD]: 'number', }, - { + totals: { row: { totalDimensions: false }, column: { totalDimensions: false }, }, - ), + }), ).toHaveLength(32); }); test('should only query grand total data', () => { expect( - dataSet.getMultiData( - { [EXTRA_FIELD]: 'number' }, - { row: { grandTotalOnly: true }, column: { grandTotalOnly: true } }, - ), + dataSet.getCellMultiData({ + query: { [EXTRA_FIELD]: 'number' }, + totals: { + row: { grandTotalOnly: true }, + column: { grandTotalOnly: true }, + }, + }), ).toHaveLength(1); }); test('should query all grand total and sub total data in columns for all cities', () => { expect( - dataSet.getMultiData( - { [EXTRA_FIELD]: 'number' }, - { + dataSet.getCellMultiData({ + query: { [EXTRA_FIELD]: 'number' }, + totals: { row: { totalDimensions: false }, column: { grandTotalOnly: false, subTotalOnly: true }, }, - ), + }), ).toHaveLength(24); }); }); diff --git a/packages/s2-core/__tests__/unit/data-set/pivot-data-set-total-spec.ts b/packages/s2-core/__tests__/unit/data-set/pivot-data-set-total-spec.ts index 5fdb31c0a9..31a3122933 100644 --- a/packages/s2-core/__tests__/unit/data-set/pivot-data-set-total-spec.ts +++ b/packages/s2-core/__tests__/unit/data-set/pivot-data-set-total-spec.ts @@ -5,6 +5,7 @@ import { get, keys } from 'lodash'; import * as multiDataCfg from 'tests/data/simple-data.json'; import * as mockData from 'tests/data/mock-dataset.json'; import { assembleDataCfg, TOTALS_OPTIONS } from '../../util'; +import type { Query } from '../../../src/data-set/interface'; import { EXTRA_FIELD, TOTAL_VALUE, VALUE_FIELD } from '@/common/constant'; import { type S2DataConfig, @@ -552,8 +553,8 @@ describe('Pivot Dataset Total Test', () => { }); }); - test('getMultiData function', () => { - const specialQuery = { + test('getCellMultiData function', () => { + const specialQuery: Query = { province: '浙江省', city: '杭州市', type: '家具', @@ -561,37 +562,45 @@ describe('Pivot Dataset Total Test', () => { [EXTRA_FIELD]: 'number', }; - expect(dataSet.getMultiData(specialQuery)).toHaveLength(1); + expect(dataSet.getCellMultiData({ query: specialQuery })).toHaveLength(1); expect( - dataSet.getMultiData(specialQuery)[0].getOrigin(), + dataSet.getCellMultiData({ query: specialQuery })[0].getOrigin(), ).toContainEntries([['number', 7789]]); expect( - dataSet.getMultiData({ - province: '浙江省', - type: '家具', - sub_type: '桌子', - [EXTRA_FIELD]: 'number', + dataSet.getCellMultiData({ + query: { + province: '浙江省', + type: '家具', + sub_type: '桌子', + [EXTRA_FIELD]: 'number', + }, }), ).toHaveLength(5); expect( - dataSet.getMultiData({ - type: '家具', - sub_type: '桌子', - [EXTRA_FIELD]: 'number', + dataSet.getCellMultiData({ + query: { + type: '家具', + sub_type: '桌子', + [EXTRA_FIELD]: 'number', + }, }), ).toHaveLength(11); expect( - dataSet.getMultiData({ - type: '家具', - [EXTRA_FIELD]: 'number', + dataSet.getCellMultiData({ + query: { + type: '家具', + [EXTRA_FIELD]: 'number', + }, }), ).toHaveLength(33); expect( - dataSet.getMultiData({ - [EXTRA_FIELD]: 'number', + dataSet.getCellMultiData({ + query: { + [EXTRA_FIELD]: 'number', + }, }), ).toHaveLength(77); }); 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 2ac42b2acf..d9358482ef 100644 --- a/packages/s2-core/__tests__/unit/facet/pivot-facet-spec.ts +++ b/packages/s2-core/__tests__/unit/facet/pivot-facet-spec.ts @@ -107,7 +107,7 @@ jest.mock('@/data-set/pivot-data-set', () => { getFieldMeta: (field: string, meta: ViewMeta) => find(meta, { field }), getFieldName: actualPivotDataSet.prototype.getFieldName, getCellData: actualPivotDataSet.prototype.getCellData, - getMultiData: jest.fn(), + getCellMultiData: jest.fn(), getDimensionValues: actualPivotDataSet.prototype.getDimensionValues, }; }), diff --git a/packages/s2-core/__tests__/util/helpers.ts b/packages/s2-core/__tests__/util/helpers.ts index 5ee5a62a96..405215c9c4 100644 --- a/packages/s2-core/__tests__/util/helpers.ts +++ b/packages/s2-core/__tests__/util/helpers.ts @@ -81,7 +81,7 @@ export const createFakeSpreadSheet = () => { }); s2.dataSet = { ...s2.dataCfg, - getMultiData() { + getCellMultiData() { return []; }, } as unknown as any; @@ -128,7 +128,7 @@ export const createFakeSpreadSheet = () => { s2.dataSet = { getFieldDescription: jest.fn(), getCustomFieldDescription: jest.fn(), - getMultiData: jest.fn(() => []), + getCellMultiData: jest.fn(() => []), } as unknown as BaseDataSet; s2.getCellType = jest.fn(); diff --git a/packages/s2-core/src/common/interface/basic.ts b/packages/s2-core/src/common/interface/basic.ts index 4ddf65caec..6a12d46ee4 100644 --- a/packages/s2-core/src/common/interface/basic.ts +++ b/packages/s2-core/src/common/interface/basic.ts @@ -19,7 +19,7 @@ import type { DataItem } from './s2DataConfig'; export type { GetCellMeta, LayoutResult } from './facet'; -/* +/** * 第二个参数在以下情况会传入: * 1. data cell 格式化 * 2. copy/export @@ -154,9 +154,9 @@ export interface Total { /** 当子维度个数 <=1 时,仍然展示小计:默认 true */ always: boolean; }; - // 前端计算总计 + /** 自定义总计 */ calcTotals?: CalcTotals; - // 前端计算小计 + /** 自定义小计 */ calcSubTotals?: CalcTotals; /** 小计的汇总维度 */ @@ -167,25 +167,30 @@ export interface Total { /** 小计布局位置,默认下或者右 */ reverseSubLayout: boolean; - // total's display name default = '总计' + + /** + * 自定义总计展示名 + * @default '总计' + */ label?: string; - // sub label's display name, default = '小计' + + /** + * 自定义小计展示名 + * @default '小计' + */ subLabel?: string; } -/** - * tableau的英文是这个,这里有个绕的概念 - * 如,某行维度需要展示小计,实际上是将对应的一列数据进行聚合,所以文案上显示的应该是“展示列小计” - * 但是内部配置我倾向于仍然按照字段所属维度区,即配置的row,代表的是行维度而不是行小计 - */ export interface Totals { row?: Partial; col?: Partial; } export interface Sort { - /** 字段id,业务中一般是displayId */ + /** 字段id */ sortFieldId: string; + + /** 排序方式 */ sortMethod?: SortMethod; /** 自定义排序 */ diff --git a/packages/s2-core/src/data-set/base-data-set.ts b/packages/s2-core/src/data-set/base-data-set.ts index bed7a04b91..7f78355960 100644 --- a/packages/s2-core/src/data-set/base-data-set.ts +++ b/packages/s2-core/src/data-set/base-data-set.ts @@ -10,60 +10,73 @@ import { memoize, min, } from 'lodash'; +import type { CellMeta, CustomHeaderField, RowData } from '../common'; +import { CellType } from '../common'; import type { - Data, Fields, FilterParam, Formatter, Meta, - S2CellType, - ViewMeta, RawData, + S2CellType, S2DataConfig, SortParams, + ViewMeta, ViewMetaData, } from '../common/interface'; -import type { Node } from '../facet/layout/node'; import type { ValueRange } from '../common/interface/condition'; +import type { Node } from '../facet/layout/node'; import type { SpreadSheet } from '../sheet-type'; import { getValueRangeState, setValueRangeState, } from '../utils/condition/state-controller'; -import { CellType } from '../common'; -import type { CellMeta, RowData, CustomHeaderField } from '../common'; import { generateExtraFieldMeta } from '../utils/dataset/pivot-data-set'; -import type { Query, TotalSelectionsOfMultiData } from './interface'; -import type { CellData } from './cell-data'; -import type { CellDataParams } from './index'; +import type { GetCellDataParams, Query } from './interface'; +import type { GetCellMultiDataParams } from './index'; export abstract class BaseDataSet { - // 字段域信息 + /** + * 字段信息 + */ public fields: Fields; - // 字段元信息,包含有字段名、格式化等 + /** + * 字段元信息,包含有字段名、格式化、描述等 + */ public meta: Meta[]; - // origin data + /** + * 原始数据 + */ public originData: RawData[]; - // multidimensional array to indexes data + /** + * 二维索引数据 + */ public indexesData: RawData[][] | RawData[]; - // 高级排序, 组内排序 + /** + * 高级排序, 组内排序 + */ public sortParams: SortParams | undefined; + /** + * 筛选配置 + */ public filterParams: FilterParam[] | undefined; - // 透视表入口对象实例 + /** + * 表格实例 + */ protected spreadsheet: SpreadSheet; + protected displayData: RawData[]; + public constructor(spreadsheet: SpreadSheet) { this.spreadsheet = spreadsheet; } - protected displayData: RawData[]; - private getField = (field: CustomHeaderField): string => { const realField = isString(field) ? field : field?.field; @@ -179,6 +192,10 @@ export abstract class BaseDataSet { return get(this.getFieldMeta(realField, this.meta), 'description'); } + /** + * 设置数据配置 + * @param dataCfg + */ public setDataCfg(dataCfg: S2DataConfig) { this.getFieldMeta?.cache?.clear?.(); const { fields, meta, data, sortParams, filterParams } = @@ -193,7 +210,13 @@ export abstract class BaseDataSet { this.indexesData = []; } - public processMeta(meta: Meta[] = [], defaultExtraFieldText: string) { + /** + * 添加 (角头/数值虚拟字段) 格式化信息 + */ + public getFieldMetaWithExtraField( + meta: Meta[] = [], + defaultExtraFieldText: string, + ): Meta[] { const newMeta: Meta[] = [ ...meta, generateExtraFieldMeta( @@ -245,6 +268,7 @@ export abstract class BaseDataSet { public abstract processDataCfg(dataCfg: S2DataConfig): S2DataConfig; /** + * 获取指定字段下的维值 * 1、query !== null * province city => field * 辽宁省 @@ -258,38 +282,36 @@ export abstract class BaseDataSet { * query param is not necessary, when just * get some field's all dimension values * - * @param field current dimensions - * @param query dimension value query + * @param field + * @param query */ public abstract getDimensionValues(field: string, query?: Query): string[]; /** - * In most cases, this function to get the specific - * cross data cell data - * @param params + * 获取单个的单元格数据 */ - public abstract getCellData(params: CellDataParams): ViewMetaData | undefined; + public abstract getCellData( + params: GetCellDataParams, + ): ViewMetaData | undefined; /** - * To get a row or column cells data; - * if query is empty, return all data - * @param query - * @param totals @TotalSelectionsOfMultiData - * @param drillDownFields + * 获取批量的单元格数据 + * 如果 query 为空, 则返回全量数据 */ - public abstract getMultiData( - query: Query, - totals?: TotalSelectionsOfMultiData, - drillDownFields?: string[], - ): Data[] | CellData[]; + public abstract getCellMultiData( + params: GetCellMultiDataParams, + ): ViewMetaData[]; + /** + * 是否超过 1 个数值 + */ public moreThanOneValue() { return this.fields?.values?.length! > 1; } /** * get a row cells data including cell - * @param cells + * @param cellMeta */ - public abstract getRowData(cells: CellMeta): RowData; + public abstract getRowData(cellMeta: CellMeta): RowData; } diff --git a/packages/s2-core/src/data-set/custom-grid-pivot-data-set.ts b/packages/s2-core/src/data-set/custom-grid-pivot-data-set.ts index a35feb5445..719b2827ed 100644 --- a/packages/s2-core/src/data-set/custom-grid-pivot-data-set.ts +++ b/packages/s2-core/src/data-set/custom-grid-pivot-data-set.ts @@ -8,7 +8,7 @@ export class CustomGridPivotDataSet extends CustomTreePivotDataSet { const rows = valueInCols ? [EXTRA_FIELD] : [...(dataCfg.fields.rows || []), EXTRA_FIELD]; - const meta = this.processMeta(dataCfg.meta!, i18n('数值')); + const meta = this.getFieldMetaWithExtraField(dataCfg.meta!, i18n('数值')); return { ...dataCfg, 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 bbce3a0193..c5b02d6173 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 @@ -7,11 +7,11 @@ import { transformDimensionsValues, } from '../utils/dataset/pivot-data-set'; import { CellData } from './cell-data'; -import type { CellDataParams } from './interface'; +import type { GetCellMultiDataParams } from './interface'; import { PivotDataSet } from './pivot-data-set'; export class CustomTreePivotDataSet extends PivotDataSet { - getCellData(params: CellDataParams) { + getCellData(params: GetCellMultiDataParams) { const { query } = params; const { columns, rows } = this.fields; const rowDimensionValues = transformDimensionsValues( @@ -37,7 +37,7 @@ export class CustomTreePivotDataSet extends PivotDataSet { } processDataCfg(dataCfg: S2DataConfig): S2DataConfig { - /* + /** * 自定义行头有如下几个特点 * 1、rows配置必须是空,需要额外添加 $$extra$$ 定位数据(标记指标的id) * 2、要有配置 fields.rowCustomTree(行头结构) @@ -45,7 +45,10 @@ export class CustomTreePivotDataSet extends PivotDataSet { */ const updatedDataCfg = super.processDataCfg(dataCfg); - const newMeta: Meta[] = this.processMeta(dataCfg.meta, i18n('指标')); + const newMeta: Meta[] = this.getFieldMetaWithExtraField( + dataCfg.meta, + i18n('指标'), + ); return { ...updatedDataCfg, diff --git a/packages/s2-core/src/data-set/interface.ts b/packages/s2-core/src/data-set/interface.ts index 58c3b55167..3ba7fa5fa1 100644 --- a/packages/s2-core/src/data-set/interface.ts +++ b/packages/s2-core/src/data-set/interface.ts @@ -45,16 +45,45 @@ export type DataPathParams = { export type DataPath = (number | string)[]; -export interface CellDataParams { - // search query +export interface GetCellDataParams { + /** + * 查询条件 + */ query: Query; + + /** + * 是否是汇总节点 + */ isTotals?: boolean; - // use in part drill-down + + /** + * 行头节点, 用于下钻场景 + */ rowNode?: Node; - // mark row's cell + + /** + * 是否是行头 + */ isRow?: boolean; } +export interface GetCellMultiDataParams { + /** + * 查询条件 + */ + query: Query; + + /** + * 汇总 + */ + totals?: TotalSelectionsOfMultiData; + + /** + * 下钻 + */ + drillDownFields?: string[]; +} + export interface SortActionParams { dataSet?: PivotDataSet; sortParam?: SortParam; 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 74c7c2d07b..7d43da9bcd 100644 --- a/packages/s2-core/src/data-set/pivot-data-set.ts +++ b/packages/s2-core/src/data-set/pivot-data-set.ts @@ -18,13 +18,15 @@ import { uniq, unset, } from 'lodash'; +import type { CellMeta } from '../common'; import { EXTRA_FIELD, + MULTI_VALUE, NODE_ID_SEPARATOR, TOTAL_VALUE, - MULTI_VALUE, VALUE_FIELD, } from '../common/constant'; +import { DataSelectType } from '../common/constant/total'; import { DebuggerUtil, DEBUG_TRANSFORM_DATA } from '../common/debug'; import { i18n } from '../common/i18n'; import type { @@ -35,10 +37,10 @@ import type { PartDrillDownDataCache, PartDrillDownFieldInLevel, RawData, + RowData, S2DataConfig, TotalsStatus, ViewMeta, - RowData, } from '../common/interface'; import { Node } from '../facet/layout/node'; import { @@ -59,12 +61,11 @@ import { } from '../utils/dataset/pivot-data-set'; import { calcActionByType } from '../utils/number-calculate'; import { handleSortAction } from '../utils/sort-action'; -import { DataSelectType } from '../common/constant/total'; -import type { CellMeta } from '../common'; -import { CellData } from './cell-data'; import { BaseDataSet } from './base-data-set'; +import { CellData } from './cell-data'; import type { - CellDataParams, + GetCellDataParams, + GetCellMultiDataParams, PivotMeta, Query, SortedDimensionValues, @@ -296,7 +297,7 @@ export class PivotDataSet extends BaseDataSet { : uniq([...rows, EXTRA_FIELD]); } - const newMeta: Meta[] = this.processMeta(meta, i18n('数值')); + const newMeta: Meta[] = this.getFieldMetaWithExtraField(meta, i18n('数值')); return { data, @@ -379,7 +380,7 @@ export class PivotDataSet extends BaseDataSet { // 前端计算汇总值 if (calcAction || !!calcFunc) { - const data = this.getMultiData(query); + const data = this.getCellMultiData({ query }); let totalValue: number | null = null; if (calcFunc) { @@ -395,7 +396,7 @@ export class PivotDataSet extends BaseDataSet { } } - public getCellData(params: CellDataParams) { + public getCellData(params: GetCellDataParams) { const { query = {}, rowNode, isTotals = false } = params || {}; const { rows: originRows, columns } = this.fields; @@ -494,7 +495,7 @@ export class PivotDataSet extends BaseDataSet { protected getQueryExtraFields(query: Query) { const { values } = this.fields; - return query[EXTRA_FIELD] ? [query[EXTRA_FIELD]] : values; + return query?.[EXTRA_FIELD] ? [query[EXTRA_FIELD]] : values; } protected getTotalSelectionByDimensions( @@ -539,11 +540,8 @@ export class PivotDataSet extends BaseDataSet { return rowSelectTypes.concat(columnSelectTypes); } - public getMultiData( - query: Query = {}, - totals?: TotalSelectionsOfMultiData, - drillDownFields?: string[], - ) { + public getCellMultiData(params: GetCellMultiDataParams) { + const { query, totals, drillDownFields } = params; const { path, rows, columns } = this.getMultiDataQueryPath( query, drillDownFields, @@ -646,7 +644,7 @@ export class PivotDataSet extends BaseDataSet { return isNumber(customValueOrder); } - public getRowData(cell: CellMeta): RowData { - return this.getMultiData(cell.rowQuery); + public getRowData(cellMeta: CellMeta): RowData { + return this.getCellMultiData({ query: cellMeta.rowQuery! }); } } diff --git a/packages/s2-core/src/data-set/table-data-set.ts b/packages/s2-core/src/data-set/table-data-set.ts index 9b99a71031..4d35d922a2 100644 --- a/packages/s2-core/src/data-set/table-data-set.ts +++ b/packages/s2-core/src/data-set/table-data-set.ts @@ -3,7 +3,7 @@ import { isAscSort, isDescSort } from '..'; import type { S2DataConfig, RawData, Data } from '../common/interface'; import type { CellMeta } from '../common'; import type { RowData } from '../common/interface/basic'; -import type { CellDataParams, Query } from './interface'; +import type { GetCellMultiDataParams, Query } from './interface'; import { BaseDataSet } from './base-data-set'; export class TableDataSet extends BaseDataSet { @@ -163,7 +163,7 @@ export class TableDataSet extends BaseDataSet { return []; } - public getCellData({ query }: CellDataParams): Data { + public getCellData({ query }: GetCellMultiDataParams): Data { if (this.displayData.length === 0 && query['rowIndex'] === 0) { return; } @@ -177,11 +177,11 @@ export class TableDataSet extends BaseDataSet { return rowData[query['col']] as unknown as Data; } - public getMultiData(): Data[] { + public getCellMultiData(): Data[] { return this.displayData as Data[]; } - public getRowData(cell: CellMeta): RowData { - return this.getCellData({ query: { rowIndex: cell.rowIndex } }); + public getRowData(cellMeta: CellMeta): RowData { + return this.getCellData({ query: { rowIndex: cellMeta.rowIndex } }); } } diff --git a/packages/s2-core/src/facet/layout/node.ts b/packages/s2-core/src/facet/layout/node.ts index 4303becb56..94343bcda0 100644 --- a/packages/s2-core/src/facet/layout/node.ts +++ b/packages/s2-core/src/facet/layout/node.ts @@ -6,6 +6,7 @@ import type { HiddenColumnsInfo, S2CellType, } from '../../common/interface'; +import type { Query } from '../../data-set'; import type { SpreadSheet } from '../../sheet-type'; import type { Hierarchy } from './hierarchy'; @@ -117,7 +118,7 @@ export class Node { public spreadsheet: SpreadSheet; // node self's query condition(represent where node stay) - public query?: Record; + public query?: Query; public belongsCell?: S2CellType | null | undefined; diff --git a/packages/s2-core/src/interaction/base-interaction/click/row-text-click.ts b/packages/s2-core/src/interaction/base-interaction/click/row-text-click.ts index 5424dd4862..68ec6275ec 100644 --- a/packages/s2-core/src/interaction/base-interaction/click/row-text-click.ts +++ b/packages/s2-core/src/interaction/base-interaction/click/row-text-click.ts @@ -39,9 +39,12 @@ export class RowTextClick extends BaseEvent implements BaseEventImplement { private getRowData = (cellData: Node): RawData => { const leafNode = cellData.getHeadLeafChild(); - const data = this.spreadsheet.dataSet.getMultiData(leafNode?.query!, { - row: { - totalDimensions: true, + const data = this.spreadsheet.dataSet.getCellMultiData({ + query: leafNode?.query!, + totals: { + row: { + totalDimensions: true, + }, }, })[0]; 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 c556bc39a5..f81c264476 100644 --- a/packages/s2-core/src/utils/dataset/pivot-data-set.ts +++ b/packages/s2-core/src/utils/dataset/pivot-data-set.ts @@ -163,7 +163,7 @@ export function getDataPath(params: DataPathParams): DataPath { const meta = currentMeta.get(value); - // 只出现在 getMultiData 中, 使用特殊的 value 指明当前复合选择 + // 只出现在 getCellMultiData 中, 使用特殊的 value 指明当前复合选择 if (value === MULTI_VALUE) { path.push(value); } else { diff --git a/packages/s2-core/src/utils/sort-action.ts b/packages/s2-core/src/utils/sort-action.ts index ea655a2b6d..128bd508e3 100644 --- a/packages/s2-core/src/utils/sort-action.ts +++ b/packages/s2-core/src/utils/sort-action.ts @@ -285,7 +285,7 @@ export const getSortByMeasureValues = ( const { fields } = dataSet!; const { sortByMeasure, query, sortFieldId } = sortParam!; // 按 query 查出所有数据 - const dataList = dataSet!.getMultiData(query); + const dataList = dataSet!.getCellMultiData({ query: query! }); const columns = getLeafColumnsWithKey(fields.columns); /** @@ -308,7 +308,7 @@ export const getSortByMeasureValues = ( /** * 按汇总值进行排序 * 需要过滤出符合要求的 “汇总数据” - * 因为 getMultiData 会查询出 query 及其子维度的所有数据 + * 因为 getCellMultiData 会查询出 query 及其子维度的所有数据 * 如 query={ type: 'xx' } 会包含 { type: 'xx', subType: '*' } 的数据 */ const isSortFieldInRow = includes(fields.rows, sortFieldId); diff --git a/packages/s2-core/src/utils/tooltip.ts b/packages/s2-core/src/utils/tooltip.ts index 55750d6fce..a7587f2614 100644 --- a/packages/s2-core/src/utils/tooltip.ts +++ b/packages/s2-core/src/utils/tooltip.ts @@ -485,7 +485,9 @@ export const getSummaries = (params: SummaryParam): TooltipSummaryOptions[] => { const isTableMode = spreadsheet.isTableMode(); if (isTableMode && options?.onlyShowCellText) { - const selectedCellsData = spreadsheet.dataSet.getMultiData({}); + const selectedCellsData = spreadsheet.dataSet.getCellMultiData({ + query: {}, + }); return [{ selectedData: selectedCellsData as Data[], name: '', value: '' }]; } diff --git a/packages/s2-react/playground/drill-down.tsx b/packages/s2-react/playground/drill-down.tsx index db86cb20bb..bcdc8c02ad 100644 --- a/packages/s2-react/playground/drill-down.tsx +++ b/packages/s2-react/playground/drill-down.tsx @@ -35,7 +35,10 @@ export const partDrillDown: PartDrillDown = { const field = drillFields[0]; const rowData = dataSet - .getMultiData(meta.query, {}, [preDrillDownfield]) + .getCellMultiData({ + query: meta.query!, + drillDownFields: [preDrillDownfield], + }) .filter( (item) => item.getValueByField('type') && item.getValueByField('sub_type'), diff --git a/packages/s2-vue/playground/App.vue b/packages/s2-vue/playground/App.vue index 04c8c484db..0c072a9c11 100644 --- a/packages/s2-vue/playground/App.vue +++ b/packages/s2-vue/playground/App.vue @@ -2,19 +2,18 @@ /* eslint-disable no-console */ import { CellType, - type S2DataConfig, - type S2Options, - type Query, type Data, type RawData, + type S2DataConfig, + type S2Options, } from '@antv/s2'; import type { PartDrillDown, PartDrillDownInfo, SheetType, } from '@antv/s2-shared'; -import { defineComponent, reactive, ref, shallowRef } from 'vue'; import { forEach, random } from 'lodash'; +import { defineComponent, reactive, ref, shallowRef } from 'vue'; import { SheetComponent } from '../src'; const dataConfig1: S2DataConfig = { @@ -545,9 +544,10 @@ const partDrillDown: PartDrillDown = { const dataSet = meta.spreadsheet.dataSet; const field = drillFields[0]; const rowData = ( - dataSet.getMultiData(meta?.query as Query, undefined, [ - preDrillDownfield, - ]) as Data[] + dataSet.getCellMultiData({ + query: meta?.query, + drillDownFields: [preDrillDownfield], + }) as Data[] ).filter( (item) => item!.sub_type && item!.type && item![preDrillDownfield], ); diff --git a/s2-site/docs/api/basic-class/base-data-set.en.md b/s2-site/docs/api/basic-class/base-data-set.en.md index f6bdd47fd2..e11b9062e8 100644 --- a/s2-site/docs/api/basic-class/base-data-set.en.md +++ b/s2-site/docs/api/basic-class/base-data-set.en.md @@ -27,7 +27,7 @@ s2.dataSet.getFieldName('type') | getDisplayDataSet | Get the currently displayed dataset | () => [DataType\[\]](#datatype) | | | getDimensionValues | get dimension value | (filed: string, query?: [DataType](#datatype) ) => string\[] | | | getCellData | Get a single cell data | (params: [CellDataParams](#celldataparams) ) => [DataType\[\]](#datatype) | | -| getMultiData | Get bulk cell data | (query: [DataType](#datatype) , isTotals?: boolean, isRow?: boolean, drillDownFields?: string\[]) => [DataType\[\]](#datatype) | | +| getCellMultiData | Get bulk cell data | (query: [DataType](#datatype) , isTotals?: boolean, isRow?: boolean, drillDownFields?: string\[]) => [DataType\[\]](#datatype) | | | moreThanOneValue | Is there more than 1 value | () => [ViewMeta](#viewmeta) | | ### DataType diff --git a/s2-site/docs/api/basic-class/base-data-set.zh.md b/s2-site/docs/api/basic-class/base-data-set.zh.md index 5485bc0221..add7e3c3c0 100644 --- a/s2-site/docs/api/basic-class/base-data-set.zh.md +++ b/s2-site/docs/api/basic-class/base-data-set.zh.md @@ -25,8 +25,8 @@ s2.dataSet.getFieldName('type') | setDataCfg | 设置数据配置 | (dataCfg: [S2DataConfig](/docs/api/general/S2DataConfig), reset?: boolean) => void | `reset` 参数需在 `@antv/s2-v1.34.0`版本使用 | | getDisplayDataSet | 获取当前显示的数据集 | () => [DataType[]](#datatype) | | | getDimensionValues | 获取维值 | (filed: string, query?: [DataType](#datatype) ) => string[] | | -| getCellData | 获取单个的单元格数据 | (params: [CellDataParams](#celldataparams)) => [DataType[]](#datatype) | | -| getMultiData | 获取批量的单元格数据 | (query: [DataType](#datatype), isTotals?: boolean, isRow?: boolean, drillDownFields?: string[]) => [DataType[]](#datatype) | | +| getCellData | 获取单个的单元格数据 | (params: [GetCellDataParams](#getcelldataparams)) => [DataType[]](#datatype) | | +| getCellMultiData | 获取批量的单元格数据 | (params: [GetCellMultiDataParams](#getcellmultidataparams)) => [DataType[]](#datatype) | | | moreThanOneValue | 是否超过 1 个数值 | () => [ViewMeta](#viewmeta) | | ### DataType @@ -35,18 +35,70 @@ s2.dataSet.getFieldName('type') type DataType = Record; ``` -### CellDataParams +### TotalSelection ```ts -interface CellDataParams { - // search query - query: DataType; +type TotalSelection = { + grandTotalOnly?: boolean; + subTotalOnly?: boolean; + totalDimensions?: boolean | string[]; +}; + +``` + +```ts +type TotalSelectionsOfMultiData = { + row?: TotalSelection; + column?: TotalSelection; +}; +``` + +### GetCellDataParams + +```ts +interface GetCellDataParams { + /** + * 查询条件 + */ + query: Query; + + /** + * 是否是汇总节点 + */ isTotals?: boolean; - // use in part drill-down + + /** + * 行头节点,用于下钻场景 + */ rowNode?: Node; - // mark row's cell + + /** + * 是否是行头 + */ isRow?: boolean; } ``` +### GetCellMultiDataParams + +```ts +interface GetCellMultiDataParams { + /** + * 查询条件 + */ + query: Query; + + /** + * 汇总 + */ + totals?: TotalSelectionsOfMultiData; + + /** + * 下钻 + */ + drillDownFields?: string[]; +} + +``` + `markdown:docs/common/custom/customTreeNode.zh.md` diff --git a/s2-site/docs/manual/advanced/get-cell-data.en.md b/s2-site/docs/manual/advanced/get-cell-data.en.md index 91752a1ca8..8810a9b1bf 100644 --- a/s2-site/docs/manual/advanced/get-cell-data.en.md +++ b/s2-site/docs/manual/advanced/get-cell-data.en.md @@ -109,7 +109,7 @@ s2.on(S2Event.ROW_CELL_CLICK, (event) => { const meta = cell.getMeta() // 获取当前行数据 - const rowData = s2.dataSet.getMultiData(meta.query) + const rowData = s2.dataSet.getCellMultiData(meta.query) // 获取当前行头单元格数据: const rowCellData = s2.dataSet.getCellData({ query: meta.query }) // 获取当前行头维值 @@ -158,7 +158,7 @@ const rowCellNode = s2.facet.getRowCellNodes().find((node) => node.id === 'root[ // 找到 "办公用品" 下 "纸张" 对应的 "数量"列头单元格节点 const colCellNode = s2.facet.getColCellNodes().find((node) => node.id === 'root[&]办公用品[&]纸张[&]number') -const data = s2.dataSet.getMultiData({...rowCellNode.query,...colCellNode.query}) +const data = s2.dataSet.getCellMultiData({...rowCellNode.query,...colCellNode.query}) /** [ diff --git a/s2-site/docs/manual/advanced/get-cell-data.zh.md b/s2-site/docs/manual/advanced/get-cell-data.zh.md index 06a52eb973..51c1c65685 100644 --- a/s2-site/docs/manual/advanced/get-cell-data.zh.md +++ b/s2-site/docs/manual/advanced/get-cell-data.zh.md @@ -4,7 +4,7 @@ order: 9 --- :::warning{title='提示'} -阅读本章前,请确保已经阅读过 [基础教程](/manual/basic/base-concept),[数据流处理](/manual/advanced/data-process/pivot),[布局](/manual/advanced/layout/pivot)等章节 +阅读本章前,请确保已经阅读过 [基础教程](/manual/basic/base-concept),[数据流处理](/manual/advanced/data-process/pivot),[布局](/manual/advanced/layout/pivot) 等章节 ::: 在实际的业务场景中,我们往往会遇到一些需要获取**单元格数据**的场景,常见的比如: @@ -121,7 +121,7 @@ s2.on(S2Event.ROW_CELL_CLICK, (event) => { const meta = cell.getMeta() // 获取当前行数据 - const rowData = s2.dataSet.getMultiData(meta.query) + const rowData = s2.dataSet.getCellMultiData({ query: meta.query }) // 获取当前行头单元格数据: const rowCellData = s2.dataSet.getCellData({ query: meta.query }) // 获取当前行头维值 @@ -132,7 +132,6 @@ s2.on(S2Event.ROW_CELL_CLICK, (event) => { console.log('当前行头维值:', dimensionValues) }) - ``` preview @@ -148,9 +147,12 @@ s2.on(S2Event.DATA_CELL_CLICK, (event) => { // 获取当前单元格元数据 const meta = cell.getMeta() // 获取当前行数据 - const rowData = s2.dataSet.getMultiData(meta.query) + const rowData = s2.dataSet.getCellMultiData({ query: meta.rowQuery }) + // 获取当前列数据 + const colData = s2.dataSet.getCellMultiData({ query: meta.colQuery }) console.log('当前行数据', rowData) + console.log('当前行数据', colData) console.log('当前单元格数据', meta.data) /** { @@ -196,9 +198,14 @@ s2.on(S2Event.DATA_CELL_CLICK, (event) => { // 找到 "舟山市" 对应的行头单元格节点 const rowCellNode = s2.facet.getRowCellNodes().find((node) => node.id === 'root[&]浙江省[&]舟山市') // 找到 "办公用品" 下 "纸张" 对应的 "数量"列头单元格节点 -const colCellNode = s2.facet.getColCellNodes().find((node) => node.id === 'root[&]办公用品[&]纸张[&]number') +const colCellNode = s2.facet.getColCellNodes().find((node) => node.id === 'root[&]办公用品[&]纸张Ø[&]number') -const data = s2.dataSet.getMultiData({...rowCellNode.query, ...colCellNode.query}) +const data = s2.dataSet.getCellMultiData({ + query: { + ...rowCellNode.query, + ...colCellNode.query + } +}) /** [ diff --git a/s2-site/docs/manual/basic/analysis/drill-down.en.md b/s2-site/docs/manual/basic/analysis/drill-down.en.md index f2a69b5c6e..fded7be227 100644 --- a/s2-site/docs/manual/basic/analysis/drill-down.en.md +++ b/s2-site/docs/manual/basic/analysis/drill-down.en.md @@ -43,7 +43,7 @@ const&nbsp;PartDrillDown&nbsp;=&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;Promise((resolve)&nbsp;=>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;dataSet&nbsp;=&nbsp;meta.spreadsheet.dataSet; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;field&nbsp;=&nbsp;drillFields[0]; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;rowDatas&nbsp;=&nbsp;dataSet.getMultiData(meta.query,&nbsp;true,&nbsp;true); +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;rowDatas&nbsp;=&nbsp;dataSet.getCellMultiData(meta.query,&nbsp;true,&nbsp;true); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;drillDownData&nbsp;=&nbsp;[]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rowDatas.forEach((data)&nbsp;=>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;{&nbsp;city,&nbsp;number,&nbsp;province,&nbsp;sub_type:&nbsp;subType,&nbsp;type&nbsp;}&nbsp;=&nbsp;data; diff --git a/s2-site/docs/manual/basic/analysis/drill-down.zh.md b/s2-site/docs/manual/basic/analysis/drill-down.zh.md index 20bfafee11..5ee3ec96e4 100644 --- a/s2-site/docs/manual/basic/analysis/drill-down.zh.md +++ b/s2-site/docs/manual/basic/analysis/drill-down.zh.md @@ -3,7 +3,6 @@ title: 维度下钻 order: 13 --- - S2 提供的「维度下钻」的能力,可以为你挖掘不同维度下更详细的数据,让你的数据洞察变得更清晰。 preview @@ -48,9 +47,10 @@ const PartDrillDown = { new Promise((resolve) => { const dataSet = meta.spreadsheet.dataSet; const field = drillFields[0]; - const rowDatas = dataSet.getMultiData(meta.query, true, true); + const rowData = dataSet.getCellMultiData({ query: meta.query }); const drillDownData = []; - rowDatas.forEach((data) => { + + rowData.forEach((data) => { const { city, number, province, sub_type: subType, type } = data; const number0 = Math.ceil(Math.random() * (number - 50)) + 50; const number1 = number - number0; diff --git a/s2-site/examples/react-component/drill-dwon/demo/for-pivot.tsx b/s2-site/examples/react-component/drill-dwon/demo/for-pivot.tsx index 8e6d33a98e..51151fe1d8 100644 --- a/s2-site/examples/react-component/drill-dwon/demo/for-pivot.tsx +++ b/s2-site/examples/react-component/drill-dwon/demo/for-pivot.tsx @@ -41,9 +41,10 @@ fetch( new Promise((resolve) => { const dataSet = meta.spreadsheet.dataSet; const field = drillFields[0]; - const rowDatas = dataSet.getMultiData(meta.query, true, true); + const rowData = dataSet.getCellMultiData({ query: meta.query }); const drillDownData = []; - rowDatas.forEach((data) => { + + rowData.forEach((data) => { const { city, number, province, sub_type: subType, type } = data; const number0 = Math.ceil(Math.random() * (number - 50)) + 50; const number1 = number - number0; @@ -55,6 +56,7 @@ fetch( type, [field]: sex[0], }; + drillDownData.push(dataItem0); const dataItem1 = { city, From 1735ccbed98038d5e1c9d2f6556d2875f6f2355b Mon Sep 17 00:00:00 2001 From: lijinke666 Date: Thu, 12 Oct 2023 16:40:36 +0800 Subject: [PATCH 2/3] chore: update --- packages/s2-react/playground/components/StrategySheet.tsx | 2 +- packages/s2-react/playground/config.ts | 1 - packages/s2-react/playground/index.tsx | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/s2-react/playground/components/StrategySheet.tsx b/packages/s2-react/playground/components/StrategySheet.tsx index 065ea10be6..63d0e485ca 100644 --- a/packages/s2-react/playground/components/StrategySheet.tsx +++ b/packages/s2-react/playground/components/StrategySheet.tsx @@ -23,7 +23,7 @@ export const StrategySheet: React.FC< const [strategyDataCfg, setStrategyDataCfg] = React.useState( StrategySheetDataConfig, ); - const [showConditions, setShowConditions] = React.useState(false); + const [showConditions, setShowConditions] = React.useState(true); const conditions: SheetComponentOptions['conditions'] = { text: [ diff --git a/packages/s2-react/playground/config.ts b/packages/s2-react/playground/config.ts index 658de99b15..0fd155153e 100644 --- a/packages/s2-react/playground/config.ts +++ b/packages/s2-react/playground/config.ts @@ -267,7 +267,6 @@ export const s2Options: SheetComponentOptions = { }, }, - conditions: s2ConditionsOptions, style: { rowCell: { height: 50, diff --git a/packages/s2-react/playground/index.tsx b/packages/s2-react/playground/index.tsx index 6bb5fb2b85..9ea37c34a1 100644 --- a/packages/s2-react/playground/index.tsx +++ b/packages/s2-react/playground/index.tsx @@ -626,7 +626,7 @@ function MainLayout() { { updateOptions({ conditions: checked ? s2ConditionsOptions : null, From 3c73bd19419f176382d12e342c360d46d62ee7a8 Mon Sep 17 00:00:00 2001 From: lijinke666 Date: Tue, 31 Oct 2023 17:45:23 +0800 Subject: [PATCH 3/3] docs: typo --- s2-site/docs/manual/advanced/get-cell-data.zh.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/s2-site/docs/manual/advanced/get-cell-data.zh.md b/s2-site/docs/manual/advanced/get-cell-data.zh.md index 51c1c65685..c55d25d67b 100644 --- a/s2-site/docs/manual/advanced/get-cell-data.zh.md +++ b/s2-site/docs/manual/advanced/get-cell-data.zh.md @@ -198,7 +198,7 @@ s2.on(S2Event.DATA_CELL_CLICK, (event) => { // 找到 "舟山市" 对应的行头单元格节点 const rowCellNode = s2.facet.getRowCellNodes().find((node) => node.id === 'root[&]浙江省[&]舟山市') // 找到 "办公用品" 下 "纸张" 对应的 "数量"列头单元格节点 -const colCellNode = s2.facet.getColCellNodes().find((node) => node.id === 'root[&]办公用品[&]纸张Ø[&]number') +const colCellNode = s2.facet.getColCellNodes().find((node) => node.id === 'root[&]办公用品[&]纸张[&]number') const data = s2.dataSet.getCellMultiData({ query: {