Skip to content

Commit dba879a

Browse files
authored
fix(#2651): when scatter data length = 1 and x is cat (#2661)
* fix(#2651): when scatter data length = 1 and x is cat * chore: destroy after test * chore: remove unused code
1 parent 17e8f08 commit dba879a

File tree

5 files changed

+132
-52
lines changed

5 files changed

+132
-52
lines changed

__tests__/bugs/issue-2651-spec.ts

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Scatter } from '../../src';
2+
import { createDiv } from '../utils/dom';
3+
4+
describe('#2651', () => {
5+
it('scatter with 1 record, and x is cat', () => {
6+
const scatter = new Scatter(createDiv(), {
7+
width: 400,
8+
height: 300,
9+
autoFit: false,
10+
data: [
11+
{
12+
x: 'x',
13+
y: 10,
14+
radiusField: 10,
15+
colorField: 'D',
16+
shapeField: 'C',
17+
},
18+
// {
19+
// x: 'y',
20+
// y: 20,
21+
// radiusField: 10,
22+
// colorField: 'D',
23+
// shapeField: 'C'
24+
// },
25+
],
26+
xField: 'x',
27+
yField: 'y',
28+
});
29+
scatter.render();
30+
31+
expect(scatter.chart.getScaleByField('x').min).toEqual(0);
32+
expect(scatter.chart.getScaleByField('x').max).toEqual(1);
33+
expect(scatter.chart.getScaleByField('x').range).toEqual([0.5, 1]);
34+
35+
scatter.destroy();
36+
});
37+
});

__tests__/unit/utils/get-meta-spec.ts

+15
Original file line numberDiff line numberDiff line change
@@ -143,5 +143,20 @@ describe('getMeta', () => {
143143
max: 0,
144144
},
145145
});
146+
147+
// x 分类
148+
expect(
149+
getMeta({
150+
data: [{ gender: 'female', weight: 'a', height: 160 }],
151+
xField: 'weight',
152+
yField: 'height',
153+
})
154+
).toEqual({
155+
weight: {},
156+
height: {
157+
min: 0,
158+
max: 320,
159+
},
160+
});
146161
});
147162
});

src/plots/scatter/adaptor.ts

+34-20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { isNumber, min, max } from '@antv/util';
1+
import { isNumber } from '@antv/util';
22
import { Params } from '../../core/adaptor';
3-
import { flow, deepAssign } from '../../utils';
3+
import { flow, deepAssign, pick } from '../../utils';
44
import { point } from '../../adaptor/geometries';
55
import { interaction, animation, theme, scale, annotation } from '../../adaptor/common';
66
import { findGeometry, transformLabel } from '../../utils';
@@ -17,25 +17,39 @@ export function transformOptions(options: ScatterOptions): ScatterOptions {
1717
const { data = [], xField, yField } = options;
1818

1919
if (data.length) {
20-
const xValues = data.map((d) => d[xField]);
21-
const minX = min(xValues);
22-
const maxX = max(xValues);
23-
const yValues = data.map((d) => d[yField]);
24-
const minY = min(yValues);
25-
const maxY = max(yValues);
26-
if (minX === maxX && minY === maxY) {
27-
return deepAssign({}, options, {
28-
meta: getMeta(options, ['x', 'y']),
29-
});
30-
} else if (minX === maxX) {
31-
return deepAssign({}, options, {
32-
meta: getMeta(options, ['x']),
33-
});
34-
} else if (minY === maxY) {
35-
return deepAssign({}, options, {
36-
meta: getMeta(options, ['y']),
37-
});
20+
// x y 字段知否只有一个值,如果只有一个值,则进行优化
21+
let isOneX = true;
22+
let isOneY = true;
23+
24+
let prev = data[0];
25+
let curr;
26+
27+
for (let i = 1; i < data.length; i++) {
28+
curr = data[i];
29+
30+
if (prev[xField] !== curr[xField]) {
31+
isOneX = false;
32+
}
33+
34+
if (prev[yField] !== curr[yField]) {
35+
isOneY = false;
36+
}
37+
38+
// 如果都不是 oneValue,那么可提前跳出循环
39+
if (!isOneX && !isOneY) {
40+
break;
41+
}
42+
43+
prev = curr;
3844
}
45+
46+
const keys = [];
47+
isOneX && keys.push(xField);
48+
isOneY && keys.push(yField);
49+
50+
const meta = pick(getMeta(options), keys);
51+
52+
return deepAssign({}, options, { meta });
3953
}
4054

4155
return options;

src/plots/scatter/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class Scatter extends Plot<ScatterOptions> {
1919
}
2020

2121
/** 图表类型 */
22-
public type: string = 'point';
22+
public type: string = 'scatter';
2323

2424
constructor(container: string | HTMLElement, options: ScatterOptions) {
2525
super(container, options);

src/plots/scatter/util.ts

+45-31
Original file line numberDiff line numberDiff line change
@@ -168,48 +168,62 @@ export const getPath = (config: RenderOptions) => {
168168
* @returns
169169
*/
170170
export const getMeta = (
171-
options: Pick<ScatterOptions, 'meta' | 'xField' | 'yField' | 'data'>,
172-
dims: string[] = ['x', 'y']
171+
options: Pick<ScatterOptions, 'meta' | 'xField' | 'yField' | 'data'>
173172
): ScatterOptions['meta'] => {
174173
const { meta = {}, xField, yField, data } = options;
175174
const xFieldValue = data[0][xField];
176175
const yFieldValue = data[0][yField];
177176
const xIsPositiveNumber = xFieldValue > 0;
178177
const yIsPositiveNumber = yFieldValue > 0;
179178

180-
const getValue = (field: string, type: 'min' | 'max', axis: 'x' | 'y') => {
181-
const customValue = get(meta, [field, type]);
182-
if (isNumber(customValue)) {
183-
return customValue;
179+
/**
180+
* 获得对应字段的 min max scale 配置
181+
*/
182+
function getMetaMinMax(field: string, axis: 'x' | 'y') {
183+
const fieldMeta = get(meta, [field]);
184+
185+
function getCustomValue(type: 'min' | 'max') {
186+
return get(fieldMeta, type);
184187
}
188+
189+
const range = {};
190+
185191
if (axis === 'x') {
186-
const rangeX = {
187-
min: xIsPositiveNumber ? 0 : xFieldValue * 2,
188-
max: xIsPositiveNumber ? xFieldValue * 2 : 0,
189-
};
190-
return rangeX[type];
192+
if (isNumber(xFieldValue)) {
193+
if (!isNumber(getCustomValue('min'))) {
194+
range['min'] = xIsPositiveNumber ? 0 : xFieldValue * 2;
195+
}
196+
197+
if (!isNumber(getCustomValue('max'))) {
198+
range['max'] = xIsPositiveNumber ? xFieldValue * 2 : 0;
199+
}
200+
}
201+
202+
return range;
191203
}
192-
const rangeY = {
193-
min: yIsPositiveNumber ? 0 : yFieldValue * 2,
194-
max: yIsPositiveNumber ? yFieldValue * 2 : 0,
195-
};
196-
return rangeY[type];
197-
};
204+
205+
if (isNumber(yFieldValue)) {
206+
if (!isNumber(getCustomValue('min'))) {
207+
range['min'] = yIsPositiveNumber ? 0 : yFieldValue * 2;
208+
}
209+
210+
if (!isNumber(getCustomValue('max'))) {
211+
range['max'] = yIsPositiveNumber ? yFieldValue * 2 : 0;
212+
}
213+
}
214+
215+
return range;
216+
}
217+
198218
return {
199219
...meta,
200-
[xField]: dims.includes('x')
201-
? {
202-
...meta[xField],
203-
min: getValue(xField, 'min', 'x'),
204-
max: getValue(xField, 'max', 'x'),
205-
}
206-
: {},
207-
[yField]: dims.includes('y')
208-
? {
209-
...meta[yField],
210-
min: getValue(yField, 'min', 'y'),
211-
max: getValue(yField, 'max', 'y'),
212-
}
213-
: {},
220+
[xField]: {
221+
...meta[xField],
222+
...getMetaMinMax(xField, 'x'),
223+
},
224+
[yField]: {
225+
...meta[yField],
226+
...getMetaMinMax(yField, 'y'),
227+
},
214228
};
215229
};

0 commit comments

Comments
 (0)