Skip to content

Commit 942f557

Browse files
visikyxinming
andauthored
fix(pie): 修复饼图数据全为 0 展示 (#1223)
close: #1161 Co-authored-by: xinming <xinming.lxj@antfin.com>
1 parent 5db8197 commit 942f557

File tree

3 files changed

+131
-5
lines changed

3 files changed

+131
-5
lines changed

__tests__/bugs/issue-1161-spec.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import { isFinite } from '@antv/util';
2+
import { Pie } from '../../src';
3+
import { createDiv } from '../utils/dom';
4+
5+
describe('#1161: 饼图数据全空的展示优化处理', () => {
6+
const config = {
7+
data: [
8+
{ type: '分类一', value: 0 },
9+
{ type: '分类二', value: 0 },
10+
{ type: '分类三', value: 0 },
11+
{ type: '分类四', value: 0 },
12+
],
13+
angleField: 'value',
14+
colorField: 'type',
15+
pieStyle: {
16+
// 不描边,避免影响计算
17+
lineWidth: 0,
18+
},
19+
};
20+
21+
it('数据全为 0: element 均分展示', () => {
22+
const div = createDiv();
23+
const pie = new Pie(div, config);
24+
pie.render();
25+
const elements = pie.getLayer().getPlot().geometries[0].elements;
26+
expect(elements.length).toBe(4);
27+
28+
const box1 = elements[0].getBBox();
29+
const box2 = elements[1].getBBox();
30+
const box3 = elements[2].getBBox();
31+
const box4 = elements[3].getBBox();
32+
expect(box1.x).toBeCloseTo(box2.x);
33+
expect(box1.minX).toBeCloseTo(box2.minX);
34+
expect(box1.maxX).toBeCloseTo(box2.maxX);
35+
expect(box1.x).not.toBeCloseTo(box3.x);
36+
37+
expect(box1.y).toBeCloseTo(box4.y);
38+
expect(box1.maxY).toBeCloseTo(box4.maxY);
39+
expect(box1.y).not.toBeCloseTo(box3.y);
40+
41+
expect(box4.x).toBeCloseTo(box3.x);
42+
expect(box4.minX).toBeCloseTo(box3.minX);
43+
expect(box4.maxX).toBeCloseTo(box3.maxX);
44+
45+
expect(box2.y).toBeCloseTo(box3.y);
46+
expect(box2.maxY).toBeCloseTo(box3.maxY);
47+
});
48+
49+
it('数据全为空,部分为 0,部分为 null: 0 值的 element 均分展示', () => {
50+
const div = createDiv();
51+
const pie = new Pie(div, { ...config, data: config.data.concat({ type: '分类五', value: null }) });
52+
pie.render();
53+
const elements = pie.getLayer().getPlot().geometries[0].elements;
54+
expect(elements.length).toBe(5);
55+
const box1 = elements[0].getBBox();
56+
const box2 = elements[1].getBBox();
57+
const box3 = elements[2].getBBox();
58+
const box4 = elements[3].getBBox();
59+
const box5 = elements[4].getBBox();
60+
61+
expect(box1.x).toBeCloseTo(box2.x);
62+
expect(box1.minX).toBeCloseTo(box2.minX);
63+
expect(box1.maxX).toBeCloseTo(box2.maxX);
64+
expect(box1.x).not.toBeCloseTo(box3.x);
65+
66+
expect(box1.y).toBeCloseTo(box4.y);
67+
expect(box1.maxY).toBeCloseTo(box4.maxY);
68+
expect(box1.y).not.toBeCloseTo(box3.y);
69+
70+
expect(box4.x).toBeCloseTo(box3.x);
71+
expect(box4.minX).toBeCloseTo(box3.minX);
72+
expect(box4.maxX).toBeCloseTo(box3.maxX);
73+
74+
expect(box2.y).toBeCloseTo(box3.y);
75+
expect(box2.maxY).toBeCloseTo(box3.maxY);
76+
77+
if (isFinite(box5.width)) {
78+
expect(box5.width).toBeCloseTo(1);
79+
}
80+
});
81+
82+
it('数据全为空,且全部为 null: element 均分展示', () => {
83+
const div = createDiv();
84+
const pie = new Pie(div, { ...config, data: config.data.map((v) => ({ ...v, value: null })) });
85+
pie.render();
86+
const elements = pie.getLayer().getPlot().geometries[0].elements;
87+
expect(elements.length).toBe(4);
88+
const box1 = elements[0].getBBox();
89+
const box2 = elements[1].getBBox();
90+
const box3 = elements[2].getBBox();
91+
const box4 = elements[3].getBBox();
92+
expect(box1.x).toBeCloseTo(box2.x);
93+
expect(box1.minX).toBeCloseTo(box2.minX);
94+
expect(box1.maxX).toBeCloseTo(box2.maxX);
95+
expect(box1.x).not.toBeCloseTo(box3.x);
96+
97+
expect(box1.y).toBeCloseTo(box4.y);
98+
expect(box1.maxY).toBeCloseTo(box4.maxY);
99+
expect(box1.y).not.toBeCloseTo(box3.y);
100+
101+
expect(box4.x).toBeCloseTo(box3.x);
102+
expect(box4.minX).toBeCloseTo(box3.minX);
103+
expect(box4.maxX).toBeCloseTo(box3.maxX);
104+
105+
expect(box2.y).toBeCloseTo(box3.y);
106+
expect(box2.maxY).toBeCloseTo(box3.maxY);
107+
});
108+
});

examples/line/multiple/demo/marker-active.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Line } from '@antv/g2plot';
2-
import * as _ from '@antv/util';
2+
import { uniq, findIndex } from '@antv/util';
33

44
fetch('../data/emissions.json')
55
.then((res) => res.json())
@@ -19,7 +19,7 @@ fetch('../data/emissions.json')
1919

2020
const container = document.getElementById('container');
2121
const containerBox = container.getBoundingClientRect();
22-
const series = _.uniq(data.map((d) => d.category));
22+
const series = uniq(data.map((d) => d.category));
2323
const markerSize = 6;
2424

2525
const linePlot = new Line(container, {
@@ -74,7 +74,7 @@ fetch('../data/emissions.json')
7474
lineWidth,
7575
fill,
7676
r,
77-
stroke: COLOR_PLATE_10[_.findIndex(series, (s) => s === seriesField)] || 'transparent',
77+
stroke: COLOR_PLATE_10[findIndex(series, (s) => s === seriesField)] || 'transparent',
7878
};
7979
},
8080
},

src/plots/pie/layer.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { deepMix } from '@antv/util';
1+
import { deepMix, isNil, map, some, every } from '@antv/util';
22
import * as EventParser from './event';
33
import ViewLayer, { ViewConfig } from '../../base/view-layer';
44
import { DataItem, Label, GraphicStyle } from '../../interface/config';
@@ -126,10 +126,28 @@ export default class PieLayer<T extends PieLayerConfig = PieLayerConfig> extends
126126

127127
protected processData(data?: DataItem[]): DataItem[] | undefined {
128128
const key = this.options.angleField;
129-
return data.map((item) => ({
129+
const originalData = data.map((item) => ({
130130
...item,
131131
[key]: typeof item[key] === 'string' ? Number.parseFloat(item[key] as 'string') : item[key],
132132
}));
133+
const getValue = (d: DataItem) => d[key];
134+
const notEqualZeroOrNil = (v: number) => v !== 0 && !isNil(v);
135+
const allAngleValue = map(originalData, getValue);
136+
const allNil = every(allAngleValue, isNil);
137+
/** 数据全空处理,同时处理 meta */
138+
if (!some(allAngleValue, notEqualZeroOrNil)) {
139+
const meta = this.options.meta || {};
140+
// 数据全为 null
141+
if (allNil) {
142+
this.options.meta = deepMix({}, meta, { [key]: { formatter: () => 'null' } });
143+
return map(originalData, (d) => ({ ...d, [key]: allNil ? 1 : d[key] === 0 ? 1 : d[key] }));
144+
} else {
145+
// 数据不全为 null,部分 0 部分 null(null值不展示)
146+
this.options.meta = deepMix({}, meta, { [key]: { formatter: () => '0' } });
147+
return map(originalData, (d) => ({ ...d, [key]: d[key] === 0 ? 1 : d[key] }));
148+
}
149+
}
150+
return originalData;
133151
}
134152

135153
protected axis() {

0 commit comments

Comments
 (0)