Skip to content

Commit 5f67f6f

Browse files
lxfu1liufu.lf
and
liufu.lf
authored
fix: 代码走查 (#1539)
* fix: 优化散点图 * fix: 修复散点图 field 相关逻辑 * fix: tests Co-authored-by: liufu.lf <[email protected]>
1 parent 0f02526 commit 5f67f6f

File tree

10 files changed

+134
-35
lines changed

10 files changed

+134
-35
lines changed

__tests__/unit/plots/scatter/color-spec.ts

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ describe('scatter', () => {
3434
data,
3535
xField: 'weight',
3636
yField: 'height',
37+
colorField: 'gender',
3738
color: ['#e764ff', '#2b0033'],
3839
xAxis: {
3940
nice: true,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { Scatter } from '../../../../src';
2+
import { data } from '../../../data/gender';
3+
import { createDiv } from '../../../utils/dom';
4+
5+
describe('scatter', () => {
6+
it('legend: false', () => {
7+
const scatter = new Scatter(createDiv(), {
8+
width: 400,
9+
height: 300,
10+
appendPadding: 10,
11+
data,
12+
xField: 'weight',
13+
yField: 'height',
14+
shapeField: 'gender',
15+
xAxis: {
16+
nice: true,
17+
},
18+
legend: false,
19+
});
20+
21+
scatter.render();
22+
const legendController = scatter.chart.getController('legend');
23+
// @ts-ignore
24+
const { option } = legendController;
25+
expect(option).toBeUndefined();
26+
});
27+
28+
it('legend: true', () => {
29+
const scatter = new Scatter(createDiv(), {
30+
width: 400,
31+
height: 300,
32+
appendPadding: 10,
33+
data,
34+
xField: 'weight',
35+
yField: 'height',
36+
shapeField: 'gender',
37+
shape: ['circle', 'square'],
38+
colorField: 'gender',
39+
xAxis: {
40+
nice: true,
41+
},
42+
legend: true,
43+
});
44+
45+
scatter.render();
46+
47+
const legendController = scatter.chart.getController('legend');
48+
// @ts-ignore
49+
const { option } = legendController;
50+
expect(option).not.toBeUndefined();
51+
expect(legendController.getComponents().length).toBe(1);
52+
expect(legendController.getComponents()[0].id).toBe('legend-gender');
53+
});
54+
it('legend: postion options', () => {
55+
const scatter = new Scatter(createDiv(), {
56+
width: 400,
57+
height: 300,
58+
appendPadding: 10,
59+
data,
60+
xField: 'weight',
61+
yField: 'height',
62+
shapeField: 'gender',
63+
shape: ['circle', 'square'],
64+
colorField: 'gender',
65+
xAxis: {
66+
nice: true,
67+
},
68+
legend: {
69+
position: 'top-right',
70+
},
71+
});
72+
73+
scatter.render();
74+
75+
const legendController = scatter.chart.getController('legend');
76+
// @ts-ignore
77+
const { option } = legendController;
78+
expect(option).not.toBeUndefined();
79+
expect(legendController.getComponents().length).toBe(1);
80+
expect(legendController.getComponents()[0].id).toBe('legend-gender');
81+
expect(legendController.getComponents()[0].direction).toBe('top-right');
82+
});
83+
});

__tests__/unit/plots/scatter/shape-spec.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ describe('scatter', () => {
1111
data,
1212
xField: 'weight',
1313
yField: 'height',
14+
shapeField: 'gender',
1415
shape: 'hollow-diamond',
1516
xAxis: {
1617
nice: true,
@@ -35,6 +36,7 @@ describe('scatter', () => {
3536
data,
3637
xField: 'weight',
3738
yField: 'height',
39+
shapeField: 'gender',
3840
shape: ['circle', 'square'],
3941
xAxis: {
4042
nice: true,
@@ -66,8 +68,8 @@ describe('scatter', () => {
6668
yField: 'height',
6769
shapeField: 'gender',
6870
size: 10,
69-
shape: (gender: string) => {
70-
if (gender === 'female') {
71+
shape: (...args) => {
72+
if (args[args.length - 1] === 'female') {
7173
return 'square';
7274
}
7375
return 'circle';

__tests__/unit/plots/scatter/size-spec.ts

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ describe('scatter', () => {
4141
data,
4242
xField: 'weight',
4343
yField: 'height',
44+
sizeField: 'gender',
4445
size: [5, 10],
4546
xAxis: {
4647
nice: true,

src/plots/heatmap/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export interface HeatmapOptions extends Options {
1515
/** 热力格子中图形的尺寸比例,可选,只有当 shapeType 和 sizeField 至少指定一项后才生效 */
1616
readonly sizeRatio?: number;
1717
/** 热力图形样式 */
18-
readonly heatmapStyle?: ShapeStyle | ((x: any, y: any, color: any) => ShapeStyle);
18+
readonly heatmapStyle?: ShapeStyle | ((x: any, y: any, color?: any, size?: any) => ShapeStyle);
1919
}
2020

2121
export const SHAPE_TYPES = tuple('circle', 'square');

src/plots/histogram/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ export interface HistogramOptions extends Options {
1818
readonly stackField?: string;
1919

2020
/** 柱子样式配置,可选 */
21-
readonly columnStyle?: ShapeStyle | ((x: any, y: any, color?: any) => ShapeStyle);
21+
readonly columnStyle?: ShapeStyle | ((range: any, count?: any) => ShapeStyle);
2222
}

src/plots/pie/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export interface PieOptions extends Options {
4444
readonly innerRadius?: number;
4545

4646
/** 饼图图形样式 */
47-
readonly pieStyle?: ShapeStyle | ((...args: string[]) => ShapeStyle);
47+
readonly pieStyle?: ShapeStyle | ((angle: string, color: string) => ShapeStyle);
4848

4949
/**
5050
* 指标卡组件: 显示在环图中心,可以代替tooltip,显示环图数据的总计值和各项数据

src/plots/scatter/adaptor.ts

+32-24
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isFunction, isNumber, isString, deepMix } from '@antv/util';
1+
import { isFunction, deepMix, isString, isArray } from '@antv/util';
22
import { Params } from '../../core/adaptor';
33
import { flow } from '../../utils';
44
import { tooltip, interaction, animation, theme, scale } from '../../adaptor/common';
@@ -24,30 +24,30 @@ function field(params: Params<ScatterOptions>): Params<ScatterOptions> {
2424
}
2525

2626
// shape
27-
if (shape) {
28-
if (isString(shape)) {
29-
geometry.shape(shape);
30-
} else {
31-
geometry.shape(shapeField || xField, shape);
32-
}
27+
if (isFunction(shape)) {
28+
geometry.shape(`${xField}*${yField}*${colorField}*${sizeField}*${shapeField}`, shape);
29+
} else if (isArray(shape) && shapeField) {
30+
geometry.shape(shapeField, shape);
31+
} else if (isString(shape) || isString(shapeField)) {
32+
geometry.shape((shape || shapeField) as string);
3333
}
3434

3535
// color
36-
if (color) {
37-
if (isString(color)) {
38-
geometry.color(color);
39-
} else {
40-
geometry.color(colorField || xField, color);
41-
}
36+
if (isFunction(color)) {
37+
geometry.color(`${xField}*${yField}*${colorField}*${sizeField}*${shapeField}`, color);
38+
} else if (isArray(color) && colorField) {
39+
geometry.color(colorField, color);
40+
} else if (isString(color) || isString(colorField)) {
41+
geometry.color((color || colorField) as string);
4242
}
4343

4444
// size
45-
if (size) {
46-
if (isNumber(size)) {
47-
geometry.size(size);
48-
} else {
49-
geometry.size(sizeField || xField, size);
50-
}
45+
if (isFunction(size)) {
46+
geometry.size(`${xField}*${yField}*${colorField}*${sizeField}*${shapeField}`, size);
47+
} else if (isArray(size) && sizeField) {
48+
geometry.size(sizeField, size);
49+
} else if (isString(size) || isString(sizeField)) {
50+
geometry.size((size || sizeField) as string);
5151
}
5252

5353
return params;
@@ -89,10 +89,18 @@ function axis(params: Params<ScatterOptions>): Params<ScatterOptions> {
8989
*/
9090
function legend(params: Params<ScatterOptions>): Params<ScatterOptions> {
9191
const { chart, options } = params;
92-
const { legend, colorField } = options;
92+
const { legend, colorField, shapeField, sizeField } = options;
93+
94+
if (legend) {
95+
chart.legend(shapeField || colorField, legend);
96+
} else {
97+
chart.legend(false);
98+
chart.legend(colorField, false);
99+
}
93100

94-
if (legend && colorField) {
95-
chart.legend(colorField, legend);
101+
// 隐藏连续图例
102+
if (sizeField) {
103+
chart.legend(sizeField, false);
96104
}
97105

98106
return params;
@@ -104,13 +112,13 @@ function legend(params: Params<ScatterOptions>): Params<ScatterOptions> {
104112
*/
105113
function style(params: Params<ScatterOptions>): Params<ScatterOptions> {
106114
const { chart, options } = params;
107-
const { xField, yField, pointStyle, colorField } = options;
115+
const { xField, yField, pointStyle, colorField, sizeField, shapeField } = options;
108116

109117
const geometry = chart.geometries[0];
110118

111119
if (pointStyle && geometry) {
112120
if (isFunction(pointStyle)) {
113-
geometry.style(`${xField}*${yField}*${colorField}`, pointStyle);
121+
geometry.style(`${xField}*${yField}*${colorField}*${sizeField}*${shapeField}`, pointStyle);
114122
} else {
115123
geometry.style(pointStyle);
116124
}

src/plots/scatter/index.ts

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { deepMix } from '@antv/util';
1+
import { deepMix, isBoolean } from '@antv/util';
22
import { Plot } from '../../core/plot';
33
import { Adaptor } from '../../core/adaptor';
44
import { ScatterOptions } from './types';
@@ -18,15 +18,19 @@ export class Scatter extends Plot<ScatterOptions> {
1818
return adaptor;
1919
}
2020

21-
protected getDefaultOptions() {
21+
protected getDefaultOptions(options: ScatterOptions) {
22+
const { shapeField, colorField, legend } = options;
2223
return deepMix({}, super.getDefaultOptions(), {
2324
size: 4,
2425
/** pointStyle 跟随主题默认样式 */
2526
tooltip: {
2627
shared: null,
2728
showTitle: false,
2829
},
29-
shape: 'circle',
30+
/**
31+
* legend 没有指定时根据 shapeField 和 colorField 来设置默认值
32+
*/
33+
legend: isBoolean(legend) ? legend : legend || !!(shapeField || colorField),
3034
});
3135
}
3236
}

src/plots/scatter/types.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ export interface ScatterOptions extends Options {
5858
/** 点大小映射对应的数据字段名 */
5959
readonly sizeField?: string;
6060
/** 散点图大小 */
61-
readonly size?: number | [number, number] | ((value: number) => number);
61+
readonly size?: number | [number, number] | ((x: any, y: any, color?: any, size?: any, shape?: any) => number);
6262
/** 点形状映射对应的数据字段名 */
6363
readonly shapeField?: string;
6464
/** 散点图形状 */
65-
readonly shape?: string | string[] | ((shape: string) => string);
65+
readonly shape?: string | string[] | ((x: any, y: any, color?: any, size?: any, shape?: any) => string);
6666
/** 散点图样式 */
67-
readonly pointStyle?: PointStyle | ((x: number, y: number, colorfield?: string) => ShapeStyle);
67+
readonly pointStyle?: PointStyle | ((x: any, y: any, color?: any, size?: any, shape?: any) => ShapeStyle);
6868
/** 点颜色映射对应的数据字段名 */
6969
readonly colorField?: string;
7070
/** 四象限组件 */

0 commit comments

Comments
 (0)