Skip to content

Commit

Permalink
fix: 修复树状模式当一组数据只有一条数据时, 叶子节点判断错误, 也渲染了展开/收起图标 close #2804 (#2806)
Browse files Browse the repository at this point in the history
fix: 修复树状模式下一组数据只有一条数据时, 叶子节点判断错误, 也渲染了展开/收起图标 close #2804
  • Loading branch information
lijinke666 committed Jul 5, 2024
1 parent 84253cb commit 76a7a59
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 27 deletions.
33 changes: 33 additions & 0 deletions packages/s2-core/__tests__/bugs/issue-2804-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
/**
* 透视表树状模式当某一组数据只有一条数据时, 叶子节点判断错误, 也渲染了展开/收起图标.
* @description spec for issue #2804
* https://github.com/antvis/S2/issues/2804
*/
import { PivotSheet } from '@/sheet-type';
import { S2Options } from '../../src';
import * as mockDataConfig from '../data/data-issue-2804.json';
import { getContainer } from '../util/helpers';

const s2Options: S2Options = {
width: 800,
height: 600,
hierarchyType: 'tree',
};

describe('Tree Leaf Node Status Tests', () => {
test('should get correctly tree icon and leaf node status', () => {
const s2 = new PivotSheet(getContainer(), mockDataConfig, s2Options);

s2.render();

const [a1, a2] = s2.getRowNodes();

expect(a1.isLeaf).toBeTruthy();
expect(a1.isTotals).toBeFalsy();
expect(a2.isLeaf).toBeFalsy();
expect(a2.isTotals).toBeTruthy();
expect(a1.belongsCell.treeIcon).not.toBeDefined();
expect(a2.belongsCell.treeIcon).toBeDefined();
});
});
21 changes: 21 additions & 0 deletions packages/s2-core/__tests__/data/data-issue-2804.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"fields": {
"rows": ["row0", "row1"],
"columns": ["col0"],
"values": ["cost"],
"valueInCols": true
},
"data": [
{
"row0": "a-1",
"col0": "b-1",
"cost": 2
},
{
"row0": "a-2",
"row1": "a-2-1",
"col0": "b-2",
"cost": 3
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,15 @@ import {
TOTAL_VALUE,
VALUE_FIELD,
} from '@/common/constant';
import {
Aggregation,
type CalcTotals,
type S2DataConfig,
} from '@/common/interface';
import { Aggregation, type S2DataConfig } from '@/common/interface';
import { Store } from '@/common/store';
import { PivotDataSet } from '@/data-set/pivot-data-set';
import { PivotSheet } from '@/sheet-type';
import { getDimensionsWithoutPathPre } from '@/utils/dataset/pivot-data-set';
import { get, keys } from 'lodash';
import * as mockData from 'tests/data/mock-dataset.json';
import * as multiDataCfg from 'tests/data/simple-data.json';
import { CalcTotals, SpreadSheet } from '../../../src';
import type { Query } from '../../../src/data-set/interface';
import { TOTALS_OPTIONS, assembleDataCfg } from '../../util';

Expand Down Expand Up @@ -425,14 +422,17 @@ describe('Pivot Dataset Total Test', () => {
});

describe('getCellData function when totals calculated by calcFunc', () => {
let s2: SpreadSheet | undefined;

beforeEach(() => {
MockPivotSheet.mockClear();
const mockSheet = new MockPivotSheet();

mockSheet.store = new Store();
mockSheet.isValueInCols = () => true;

const calcFunc1: CalcTotals['calcFunc'] = (_, data) => {
const calcFunc1: CalcTotals['calcFunc'] = (_, data, spreadsheet) => {
s2 = spreadsheet;
const sum = data.reduce(
(pre, next) => pre + (next[VALUE_FIELD] as number),
0,
Expand All @@ -441,7 +441,8 @@ describe('Pivot Dataset Total Test', () => {
return sum * 2;
};

const calcFunc2: CalcTotals['calcFunc'] = (_, data) => {
const calcFunc2: CalcTotals['calcFunc'] = (_, data, spreadsheet) => {
s2 = spreadsheet;
const sum = data.reduce(
(pre, next) => pre + (next[VALUE_FIELD] as number),
0,
Expand Down Expand Up @@ -482,6 +483,10 @@ describe('Pivot Dataset Total Test', () => {
dataSet.setDataCfg(dataCfg);
});

afterEach(() => {
s2 = undefined;
});

test('should get correct total cell data when totals calculated by calcFunc and Existential dimension grouping', () => {
const totalStatus = {
isRowGrandTotal: true,
Expand Down Expand Up @@ -535,6 +540,8 @@ describe('Pivot Dataset Total Test', () => {
totalStatus,
})?.[VALUE_FIELD],
).toEqual(32418);

expect(s2).toBeDefined();
});

test('should get correct total cell data when totals calculated by calcFunc', () => {
Expand Down Expand Up @@ -602,6 +609,8 @@ describe('Pivot Dataset Total Test', () => {
isTotals: true,
})?.[ORIGIN_FIELD],
).toContainEntries([['number', 78868]]);

expect(s2).toBeDefined();
});
});

Expand Down
10 changes: 8 additions & 2 deletions packages/s2-core/src/common/interface/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,20 @@ export enum Aggregation {
}

export interface CalcTotals {
/** 聚合方式 */
/**
* 聚合方式
*/
aggregation?: `${Aggregation}`;

/**
* 自定义计算汇总
* @see https://s2.antv.antgroup.com/examples/analysis/totals/#custom
*/
calcFunc?: (query: Query, data: CellData[]) => number;
calcFunc?: (
query: Query,
data: CellData[],
spreadsheet: SpreadSheet,
) => number;
}

export interface Total {
Expand Down
2 changes: 1 addition & 1 deletion packages/s2-core/src/data-set/pivot-data-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ export class PivotDataSet extends BaseDataSet {
let totalValue: number | null = null;

if (calcFunc) {
totalValue = calcFunc(query, data);
totalValue = calcFunc(query, data, this.spreadsheet);
} else if (calcAction) {
totalValue = calcAction(data, VALUE_FIELD)!;
}
Expand Down
23 changes: 15 additions & 8 deletions packages/s2-core/src/facet/layout/build-row-tree-hierarchy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { isNumber } from 'lodash';
import { i18n } from '../../common';
import { isEmpty, isNumber } from 'lodash';
import { TOTAL_VALUE, i18n } from '../../common';
import type { SpreadSheet } from '../../sheet-type';
import { filterOutDetail } from '../../utils/data-set-operate';
import { generateId } from '../../utils/layout/generate-id';
Expand Down Expand Up @@ -126,13 +126,20 @@ export const buildRowTreeHierarchy = (params: TreeHeaderParams) => {
hierarchy.maxLevel = level;
}

const emptyChildren = !pivotMetaValue?.children?.size;
/**
* 除了虚拟行小计节点外, 如果为空, 说明当前分组只有一条数据, 应该标记为叶子节点.
* https://github.com/antvis/S2/issues/2804
*/
const children = [...(pivotMetaValue?.children?.keys() || [])].filter(
(child) => child !== TOTAL_VALUE,
);
const isEmptyChildren = isEmpty(children);

if (emptyChildren || isTotals) {
if (isEmptyChildren || isTotals) {
node.isLeaf = true;
}

if (!emptyChildren) {
if (!isEmptyChildren) {
node.isTotals = true;
}

Expand All @@ -143,11 +150,11 @@ export const buildRowTreeHierarchy = (params: TreeHeaderParams) => {
hierarchy,
);

if (!emptyChildren && !isCollapsed && !isTotals && expandCurrentNode) {
if (!isEmptyChildren && !isCollapsed && !isTotals && expandCurrentNode) {
buildRowTreeHierarchy({
level: level + 1,
currentField: pivotMetaValue.childField!,
pivotMeta: pivotMetaValue.children,
currentField: pivotMetaValue!.childField!,
pivotMeta: pivotMetaValue!.children,
parentNode: node,
hierarchy,
spreadsheet,
Expand Down
2 changes: 1 addition & 1 deletion s2-site/docs/common/totals.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ order: 3
| 参数 | 说明 | 类型 | 必选 | 默认值 |
| ----------- | ---------- | -------------------------------------------------------------------- | --- | ------ |
| aggregation | 聚合方式 | `SUM \| MIN \| MAX \| AVG` | | |
| calcFunc | 自定义方法 | `(query: Record<string, any>, arr: Record<string, any>[]) => number` | | |
| calcFunc | 自定义方法 | `(query: Record<string, any>, data: Record<string, any>[], spreadsheet: SpreadSheet) => number` | | |
32 changes: 27 additions & 5 deletions s2-site/docs/manual/basic/totals.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ const s2Options = {

<br/>

##### 2.2. 配置自定义方法
##### 2.2. 配置自定义计算方法

```ts
const s2Options = {
Expand All @@ -242,10 +242,10 @@ const s2Options = {
reverseSubTotalsLayout: true,
subTotalsDimensions: ['province'],
calcGrandTotals: {
calcFunc: (query, data) => {},
calcFunc: (query, data, spreadsheet) => {},
},
calcSubTotals: {
calcFunc: (query, data) => {},
calcFunc: (query, data, spreadsheet) => {},
},
},
col: {
Expand All @@ -255,16 +255,38 @@ const s2Options = {
reverseSubTotalsLayout: true,
subTotalsDimensions: ['type'],
calcGrandTotals: {
calcFunc: (query, data) => {},
calcFunc: (query, data, spreadsheet) => {},
},
calcSubTotals: {
calcFunc: (query, data) => {},
calcFunc: (query, data, spreadsheet) => {},
},
},
},
};
```

通过配置 `calcFunc: (query: Record<string, any>, data: Record<string, any>[], spreadsheet: SpreadSheet) => number` 来实现。[查看示例](https://s2.antv.antgroup.com/zh/examples/analysis/totals/#custom)

注意:`data` 为明细数据,如需获取包含汇总的数据

```ts
import { QueryDataType } from '@antv/s2';

const calcFunc = (query, data, spreadsheet) => {
const allData = spreadsheet.dataSet.getMultiData(query, {
queryType: QueryDataType.All,
});

console.log('data(明细数据):', data);
console.log('data(全部数据,含汇总):', allData);
};

```

<Playground path='analysis/totals/demo/custom.ts' rid='pivot-total-custom' height='400'></playground>

<br/>

### 优先级

1. 数据传入优先级高于计算数据
Expand Down
18 changes: 16 additions & 2 deletions s2-site/examples/analysis/totals/demo/custom.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { PivotSheet, VALUE_FIELD, S2DataConfig, S2Options } from '@antv/s2';
import {
PivotSheet,
QueryDataType,
S2DataConfig,
S2Options,
VALUE_FIELD,
type CalcTotals,
} from '@antv/s2';

fetch('https://render.alipay.com/p/yuyan/180020010001215413/s2/basic.json')
.then((res) => res.json())
Expand Down Expand Up @@ -31,7 +38,14 @@ fetch('https://render.alipay.com/p/yuyan/180020010001215413/s2/basic.json')
data,
};

const calcFunc = (query, data) => {
const calcFunc: CalcTotals['calcFunc'] = (query, data, spreadsheet) => {
const allData = spreadsheet.dataSet.getMultiData(query, {
queryType: QueryDataType.All,
});

console.log('data (明细数据):', data);
console.log('data (全部数据, 含汇总):', allData);

const sum = data.reduce((pre, next) => {
return pre + next[VALUE_FIELD];
}, 0);
Expand Down
2 changes: 1 addition & 1 deletion s2-site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
},
"dependencies": {
"@ant-design/icons": "^5.3.7",
"@antv/dumi-theme-antv": "^0.5.0",
"@antv/dumi-theme-antv": "^0.5.2",
"@antv/g": "^6.0.4",
"@antv/g-canvas": "^2.0.3",
"@antv/g-plugin-a11y": "^1.0.4",
Expand Down

0 comments on commit 76a7a59

Please sign in to comment.