Skip to content

Commit a4618c0

Browse files
lxfu1liufu.lf
and
liufu.lf
authored
feat: interaction (#1349)
* fix: 新增 type 类型和修复shpeField * feat: register interaction drag-move * fix: review modify * fix: 统一 log 英文 Co-authored-by: liufu.lf <[email protected]>
1 parent 7dd94e4 commit a4618c0

File tree

7 files changed

+121
-13
lines changed

7 files changed

+121
-13
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { getInteraction } from '@antv/g2';
2+
import { Scatter } from '../../../../src';
3+
import { createDiv } from '../../../utils/dom';
4+
import { data } from '../../../data/gender';
5+
6+
describe('scatter: register interaction', () => {
7+
const scatter = new Scatter(createDiv(), {
8+
width: 400,
9+
height: 300,
10+
appendPadding: 10,
11+
data,
12+
xField: 'weight',
13+
yField: 'height',
14+
sizeField: 'weight',
15+
size: [5, 10],
16+
colorField: 'gender',
17+
xAxis: {
18+
nice: true,
19+
},
20+
interactions: [
21+
{
22+
name: 'drag-move',
23+
},
24+
],
25+
});
26+
27+
scatter.render();
28+
29+
it('define: drag-move', () => {
30+
const statisticInteraction = getInteraction('drag-move');
31+
expect(statisticInteraction).toBeDefined();
32+
});
33+
});

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

+37
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,41 @@ describe('scatter', () => {
7777
expect(elements[0].shape.attr('stroke')).toBe('yellow');
7878
expect(elements[0].shape.attr('opacity')).toBe(0.8);
7979
});
80+
it('style: all options', () => {
81+
const scatter = new Scatter(createDiv(), {
82+
width: 400,
83+
height: 300,
84+
appendPadding: 10,
85+
data,
86+
xField: 'weight',
87+
yField: 'height',
88+
sizeField: 'weight',
89+
size: [5, 10],
90+
xAxis: {
91+
nice: true,
92+
},
93+
pointStyle: {
94+
fill: 'red',
95+
stroke: 'yellow',
96+
lineWidth: 4,
97+
lineDash: [2, 2],
98+
opacity: 0.5,
99+
fillOpacity: 0.5,
100+
strokeOpacity: 0.5,
101+
},
102+
});
103+
104+
scatter.render();
105+
106+
const geometry = scatter.chart.geometries[0];
107+
const elements = geometry.elements;
108+
109+
expect(elements[0].shape.attr('fill')).toBe('red');
110+
expect(elements[0].shape.attr('stroke')).toBe('yellow');
111+
expect(elements[0].shape.attr('lineWidth')).toBe(4);
112+
expect(elements[0].shape.attr('lineDash')).toEqual([2, 2]);
113+
expect(elements[0].shape.attr('opacity')).toBe(0.5);
114+
expect(elements[0].shape.attr('fillOpacity')).toBe(0.5);
115+
expect(elements[0].shape.attr('strokeOpacity')).toBe(0.5);
116+
});
80117
});

docs/demos/scatter.md

+17-1
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,25 @@ const Page: React.FC = () => {
3131
data: data.slice(0, 50),
3232
xField: 'weight',
3333
yField: 'height',
34+
shapeField: 'gender',
3435
shape: ['circle', 'square'],
36+
colorField: 'gender',
3537
color: ['green', 'red'],
36-
size: 'weight',
38+
sizeField: 'weight',
39+
interactions: [
40+
{
41+
name: 'drag-move',
42+
},
43+
],
44+
label: {
45+
offsetX: 6,
46+
offsetY: 6,
47+
style: {
48+
fill: 'rgba(0, 0, 0, 0.65)',
49+
stroke: '#ffffff',
50+
lineWidth: 2,
51+
},
52+
},
3753
tooltip: {
3854
showCrosshairs: true,
3955
crosshairs: {

src/plots/scatter/adaptor.ts

+18-10
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { deepMix, isFunction } from '@antv/util';
22
import { Params } from '../../core/adaptor';
3-
import { flow, pick } from '../../utils';
3+
import { flow, pick, log, LEVEL } from '../../utils';
44
import { ScatterOptions } from './types';
5-
import { tooltip } from '../../common/adaptor';
5+
import { tooltip, interaction, animation, theme } from '../../common/adaptor';
66
import { findGeometry } from '../../common/helper';
77
import { AXIS_META_CONFIG_KEYS } from '../../constant';
88
import { REFLECTS } from './reflect';
@@ -13,16 +13,21 @@ import { REFLECTS } from './reflect';
1313
*/
1414
function field(params: Params<ScatterOptions>): Params<ScatterOptions> {
1515
const { chart, options } = params;
16-
const { data, xField, yField, seriesField } = options;
16+
const { data, xField, yField, type } = options;
1717

1818
// 散点图操作逻辑
1919
chart.data(data);
2020
const geometry = chart.point().position(`${xField}*${yField}`);
2121

22+
// 数据调整
23+
if (type) {
24+
geometry.adjust(type);
25+
}
26+
2227
// 统一处理 color、 size、 shape
2328
const reflectKeys = Object.keys(REFLECTS);
2429
reflectKeys.forEach((key: string) => {
25-
if (options[key]) {
30+
if (options[key] || options[REFLECTS[key].field]) {
2631
let validateRules = false;
2732
(REFLECTS[key].rules || []).forEach((fn: (arg: any) => boolean) => {
2833
// 满足任一规则即可
@@ -31,9 +36,12 @@ function field(params: Params<ScatterOptions>): Params<ScatterOptions> {
3136
}
3237
});
3338
if (validateRules) {
34-
geometry[REFLECTS[key].action](options[REFLECTS[key].field] || seriesField || xField, options[key]);
39+
if (!options[REFLECTS[key].field]) {
40+
log(LEVEL.WARN, false, '*** For accurate mapping, specify %s please. ***', REFLECTS[key].field);
41+
}
42+
geometry[REFLECTS[key].action](options[REFLECTS[key].field] || xField, options[key]);
3543
} else {
36-
geometry[REFLECTS[key].action](options[key]);
44+
geometry[REFLECTS[key].action](options[key] || options[REFLECTS[key].field]);
3745
}
3846
}
3947
});
@@ -80,10 +88,10 @@ function axis(params: Params<ScatterOptions>): Params<ScatterOptions> {
8088
*/
8189
function legend(params: Params<ScatterOptions>): Params<ScatterOptions> {
8290
const { chart, options } = params;
83-
const { legend, seriesField } = options;
91+
const { legend, colorField } = options;
8492

85-
if (legend && seriesField) {
86-
chart.legend(seriesField, legend);
93+
if (legend && colorField) {
94+
chart.legend(colorField, legend);
8795
}
8896

8997
return params;
@@ -142,5 +150,5 @@ function label(params: Params<ScatterOptions>): Params<ScatterOptions> {
142150
*/
143151
export function adaptor(params: Params<ScatterOptions>) {
144152
// flow 的方式处理所有的配置到 G2 API
145-
flow(field, meta, axis, legend, tooltip, style, label)(params);
153+
flow(field, meta, axis, legend, tooltip, style, label, interaction, animation, theme)(params);
146154
}

src/plots/scatter/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Plot } from '../../core/plot';
22
import { ScatterOptions } from './types';
33
import { adaptor } from './adaptor';
44
import { Adaptor } from '../../core/adaptor';
5+
import './interaction';
56

67
export { ScatterOptions };
78

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { registerInteraction } from '@antv/g2';
2+
3+
registerInteraction('drag-move', {
4+
start: [{ trigger: 'plot:mousedown', action: 'scale-translate:start' }],
5+
processing: [
6+
{
7+
trigger: 'plot:mousemove',
8+
action: 'scale-translate:translate',
9+
throttle: { wait: 100, leading: true, trailing: false },
10+
},
11+
],
12+
end: [{ trigger: 'plot:mouseup', action: 'scale-translate:end' }],
13+
});

src/plots/scatter/types.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ export interface ScatterOptions extends Options {
5959
readonly xField: string;
6060
/** y 轴字段 */
6161
readonly yField: string;
62-
/** 分组字段 */
63-
readonly seriesField?: string;
62+
/** 数据调整类型 */
63+
readonly type?: 'jitter' | 'stack' | 'symmetric' | 'dodge';
6464
/** 点大小映射对应的数据字段名 */
6565
readonly sizeField?: string;
6666
/** 散点图大小 */

0 commit comments

Comments
 (0)