Skip to content

Commit 871b3c5

Browse files
authored
refactor: 优化下玉珏图处理 stack 的代码 (#2687)
* refactor: 优化下玉珏图处理 stack 的代码 * fix: 修改 lint 问题 * docs(radial-bar): 增加两个新的玉珏图 demo
1 parent 397d864 commit 871b3c5

File tree

8 files changed

+145
-46
lines changed

8 files changed

+145
-46
lines changed

__tests__/unit/plots/radial-bar/index-spec.ts

+50
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,56 @@ describe('radial-bar', () => {
5656
bar.destroy();
5757
});
5858

59+
it('stacked', () => {
60+
const bar = new RadialBar(createDiv(), {
61+
data: [
62+
{
63+
year: '1991',
64+
value: 10,
65+
type: 'Lon',
66+
},
67+
{
68+
year: '1998',
69+
value: 9,
70+
type: 'Lon',
71+
},
72+
{
73+
year: '1999',
74+
value: 13,
75+
type: 'Lon',
76+
},
77+
{
78+
year: '1991',
79+
value: 3,
80+
type: 'Bor',
81+
},
82+
{
83+
year: '1998',
84+
value: 5,
85+
type: 'Bor',
86+
},
87+
{
88+
year: '1999',
89+
value: 10,
90+
type: 'Bor',
91+
},
92+
],
93+
maxAngle: 270,
94+
isStack: true,
95+
xField: 'year',
96+
yField: 'value',
97+
colorField: 'type',
98+
});
99+
bar.render();
100+
101+
// 270度 在中心位置
102+
expect(bar.chart.geometries[0].elements[bar.options.data.length - 1].shape.getBBox().y).toBeCloseTo(
103+
bar.chart.getCoordinate().getCenter().y
104+
);
105+
106+
bar.destroy();
107+
});
108+
59109
it('xField*yField*type', () => {
60110
const bar = new RadialBar(createDiv(), {
61111
width: 400,
+30-32
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
1-
import { getScaleMax, getScaleIsStackMax } from '../../../../src/plots/radial-bar/utils';
1+
import { getScaleMax, getStackedData } from '../../../../src/plots/radial-bar/utils';
22
import { antvStar } from '../../../data/antv-star';
3-
import { populationMovementData as popData } from '../../../data/chord-population';
43

54
const yField = 'star';
65

7-
const popField = {
8-
yField: 'value',
9-
xField: 'source',
10-
};
11-
126
describe('utils of radial-bar', () => {
137
const starArr = antvStar.map((item) => item[yField]);
148
const maxValue = Math.max(...starArr);
@@ -28,36 +22,40 @@ describe('utils of radial-bar', () => {
2822
expect(getScaleMax(360, yField, [])).toBe(0);
2923
});
3024

31-
const popArr = popData
32-
.reduce((value, item) => {
33-
const valueItem = value.find((v) => v[popField.xField] === item[popField.xField]);
34-
if (valueItem) {
35-
valueItem[popField.yField] += item[popField.yField];
36-
} else {
37-
value.push({ ...item });
38-
}
39-
return value;
40-
}, [])
41-
.map((item) => item[popField.yField]);
42-
43-
const isStackMaxValue = Math.max(...popArr);
44-
45-
it('getScaleIsStackMax: normal', () => {
46-
expect(getScaleIsStackMax(360, popField.yField, popField.xField, popData)).toBe(isStackMaxValue);
47-
expect(getScaleIsStackMax(-300, popField.yField, popField.xField, popData)).toBe((isStackMaxValue * 360) / 300);
48-
expect(getScaleIsStackMax(660, popField.yField, popField.xField, popData)).toBe((isStackMaxValue * 360) / 300);
25+
const data2 = [
26+
{ date: '01-01', value: 10, type: 'type1' },
27+
{ date: '01-02', value: 9, type: 'type1' },
28+
{ date: '01-01', value: 5, type: 'type2' },
29+
{ date: '01-02', value: 7, type: 'type2' },
30+
];
31+
32+
it('getStackedData: normal', () => {
33+
const stackedData = getStackedData(data2, 'date', 'value');
34+
expect(stackedData.length).toBe(2);
35+
expect(stackedData[0].date).toBe(data2[0].date);
36+
expect(stackedData[1].date).toBe(data2[1].date);
37+
expect(stackedData[0].value).toBe(15);
38+
expect(stackedData[1].value).toBe(16);
4939
});
5040

5141
it('getScaleIsStackMax: existed nil value', () => {
52-
expect(
53-
getScaleIsStackMax(-300, popField.yField, popField.xField, [...popData, { source: 'c', value: undefined }])
54-
).toBe((isStackMaxValue * 360) / 300);
55-
expect(getScaleIsStackMax(-300, popField.yField, popField.xField, [...popData, { source: 'c', value: null }])).toBe(
56-
(isStackMaxValue * 360) / 300
57-
);
42+
data2[2].value = null;
43+
let stackedData = getStackedData(data2, 'date', 'value');
44+
45+
expect(stackedData.length).toBe(2);
46+
expect(stackedData[0].date).toBe(data2[0].date);
47+
expect(stackedData[1].date).toBe(data2[1].date);
48+
expect(stackedData[0].value).toBe(10);
49+
expect(stackedData[1].value).toBe(16);
50+
51+
data2[2].value = undefined;
52+
stackedData = getStackedData(data2, 'date', 'value');
53+
54+
expect(stackedData.length).toBe(2);
55+
expect(stackedData[0].value).toBe(10);
5856
});
5957

6058
it('getScaleIsStackMax: empty array', () => {
61-
expect(getScaleIsStackMax(360, popField.yField, popField.xField, [])).toBe(0);
59+
expect(getStackedData([], 'date', 'value').length).toBe(0);
6260
});
6361
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { RadialBar } from '@antv/g2plot';
2+
3+
fetch('https://gw.alipayobjects.com/os/antfincdn/8elHX%26irfq/stack-column-data.json')
4+
.then((data) => data.json())
5+
.then((data) => {
6+
const plot = new RadialBar('container', {
7+
data,
8+
xField: 'year',
9+
yField: 'value',
10+
colorField: 'type',
11+
isGroup: true,
12+
maxAngle: 270,
13+
});
14+
15+
plot.render();
16+
});

examples/more-plots/radial-bar/demo/meta.json

+18
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,24 @@
2828
},
2929
"screenshot": "https://gw.alipayobjects.com/zos/antfincdn/l6uP5%26MiT7/385e3f80-52ec-49e9-9dfe-bd447e63203f.png"
3030
},
31+
{
32+
"filename": "stacked.ts",
33+
"title": {
34+
"zh": "堆叠玉珏图",
35+
"en": "Stacked Radial-Bar plot"
36+
},
37+
"new": true,
38+
"screenshot": "https://gw.alipayobjects.com/zos/antfincdn/tft60hEBvN/594d5cfc-8da0-441b-89dd-81eb4f5657b6.png"
39+
},
40+
{
41+
"filename": "grouped.ts",
42+
"title": {
43+
"zh": "分组玉珏图",
44+
"en": "Grouped Radial-Bar plot"
45+
},
46+
"new": true,
47+
"screenshot": "https://gw.alipayobjects.com/zos/antfincdn/M2EJJVBmHE/8984eee5-da51-4afb-8e81-34a8aaab47c0.png"
48+
},
3149
{
3250
"filename": "background.ts",
3351
"title": {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { RadialBar } from '@antv/g2plot';
2+
3+
fetch('https://gw.alipayobjects.com/os/antfincdn/8elHX%26irfq/stack-column-data.json')
4+
.then((data) => data.json())
5+
.then((data) => {
6+
const plot = new RadialBar('container', {
7+
data,
8+
xField: 'year',
9+
yField: 'value',
10+
colorField: 'type',
11+
isStack: true,
12+
maxAngle: 270,
13+
});
14+
15+
plot.render();
16+
});

src/plots/circle-packing/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ColorAttr, Options, SizeAttr, StyleAttr } from '../../types';
1+
import { ColorAttr, Options, StyleAttr } from '../../types';
22
import { DrillDownCfg } from '../../types/drill-down';
33
import { HierarchyOption } from '../../utils/hierarchy/types';
44

src/plots/radial-bar/adaptor.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { flow, deepAssign, findGeometry, transformLabel } from '../../utils';
44
import { interval, point } from '../../adaptor/geometries';
55
import { processIllegalData } from '../../utils';
66
import { RadialBarOptions } from './types';
7-
import { getScaleMax, getScaleIsStackMax } from './utils';
7+
import { getScaleMax, getStackedData } from './utils';
88

99
/**
1010
* geometry 处理
@@ -50,15 +50,14 @@ function geometry(params: Params<RadialBarOptions>): Params<RadialBarOptions> {
5050
export function meta(params: Params<RadialBarOptions>): Params<RadialBarOptions> {
5151
const { options } = params;
5252
const { yField, xField, data, isStack, isGroup, colorField, maxAngle } = options;
53-
const processData = processIllegalData(data, yField);
53+
54+
const actualData = isStack && !isGroup && colorField ? getStackedData(data, xField, yField) : data;
55+
const processData = processIllegalData(actualData, yField);
5456
return flow(
5557
scale({
5658
[yField]: {
5759
min: 0,
58-
max:
59-
isStack && !isGroup && colorField
60-
? getScaleIsStackMax(maxAngle, yField, xField, processData)
61-
: getScaleMax(maxAngle, yField, processData),
60+
max: getScaleMax(maxAngle, yField, processData),
6261
},
6362
})
6463
)(params);

src/plots/radial-bar/utils.ts

+9-7
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,18 @@ export function getScaleMax(maxAngle: number, yField: string, data: Data): numbe
1010
return (maxValue * 360) / formatRadian;
1111
}
1212

13-
// 获取isStack 下的最大值
14-
export function getScaleIsStackMax(maxAngle: number, yField: string, xField: string, data: Data) {
15-
const newData: Data = [];
13+
/**
14+
* 获取堆叠之后的数据
15+
*/
16+
export function getStackedData(data: Data, xField: string, yField: string) {
17+
const stackedData: Data = [];
1618
data.forEach((item) => {
17-
const valueItem = newData.find((v) => v[xField] === item[xField]);
19+
const valueItem = stackedData.find((v) => v[xField] === item[xField]);
1820
if (valueItem) {
19-
valueItem[yField] += item[yField];
21+
valueItem[yField] += item[yField] || null;
2022
} else {
21-
newData.push({ ...item });
23+
stackedData.push({ ...item });
2224
}
2325
});
24-
return getScaleMax(maxAngle, yField, newData);
26+
return stackedData;
2527
}

0 commit comments

Comments
 (0)