Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(venn): 韦恩图交互增强(修复图例激活元素交互 & 增强active、highlight、selected交互) #2911

Merged
merged 13 commits into from
Oct 15, 2021
Merged
51 changes: 51 additions & 0 deletions __tests__/bugs/issue-2908-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Venn } from '../../src';
import { createDiv } from '../utils/dom';

describe('#2908, venn', () => {
const plot = new Venn(createDiv(), {
width: 400,
height: 500,
setsField: 'sets',
sizeField: 'size',
data: [
{ sets: ['A'], size: 10, label: 'A' },
{ sets: ['B'], size: 10, label: 'B' },
],
interactions: [{ type: 'legend-active', enable: true }],
});
plot.render();

it('legend interaction', () => {
let labels = plot.chart.geometries[0].elements[0].shape
.getParent()
.getChildren()
.map((c) => c.get('origin').data.label);

expect(labels[0]).toBe('A');
expect(labels[1]).toBe('B');

const legendComponent = plot.chart.getController('legend').getComponents()[0];
const legendContainer = legendComponent.component.get('container');

const legendTarget = legendContainer.findById('-legend-item-A');
const box = legendTarget.getBBox();
plot.chart.emit('legend-item:mouseenter', {
x: (box.x + box.maxX) / 2,
y: (box.y + box.maxY) / 2,
target: legendTarget,
});

// 图例交互,还是保持原序
labels = plot.chart.geometries[0].elements[0].shape
.getParent()
.getChildren()
.map((c) => c.get('origin').data.label);

expect(labels[0]).toBe('A');
expect(labels[1]).toBe('B');
});

afterAll(() => {
plot.destroy();
});
});
119 changes: 105 additions & 14 deletions __tests__/unit/plots/venn/interaction-spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { IGroup } from '@antv/g-base';
import InteractionContext from '@antv/g2/lib/interaction/context';
import { Venn } from '../../../../src';
import { VennElementActive, VennElementSelected } from '../../../../src/plots/venn/interaction/action';
import { VennElementActive } from '../../../../src/plots/venn/interactions/actions/active';
import { VennElementHighlight } from '../../../../src/plots/venn/interactions/actions/highlight';
import {
VennElementSelected,
VennElementSingleSelected,
} from '../../../../src/plots/venn/interactions/actions/selected';
import { createDiv } from '../../../utils/dom';

describe('venn', () => {
Expand Down Expand Up @@ -38,13 +43,12 @@ describe('venn', () => {
});

const context = new InteractionContext(plot.chart);
// @ts-ignore
const vennElementActive = new VennElementActive(context);

// 模拟 active
context.event = {
data: {
data: plot.chart.getData()[0],
},
target: plot.chart.getElements()[0].shape,
};
vennElementActive.active();

Expand All @@ -60,9 +64,7 @@ describe('venn', () => {

// 模拟 第二次 active
context.event = {
data: {
data: plot.chart.getData()[1],
},
target: plot.chart.getElements()[1].shape,
};
vennElementActive.active();

Expand All @@ -82,7 +84,7 @@ describe('venn', () => {
vennElementActive.destroy();
});

it('venn: selected', () => {
it('venn-element-selected', () => {
plot.update({
state: {
selected: {
Expand All @@ -98,13 +100,12 @@ describe('venn', () => {
});

const context = new InteractionContext(plot.chart);
// @ts-ignore
const vennElementSelected = new VennElementSelected(context);

// 模拟 selected
context.event = {
data: {
data: plot.chart.getData()[0],
},
target: plot.chart.getElements()[0].shape,
};
vennElementSelected.toggle();

Expand All @@ -124,9 +125,7 @@ describe('venn', () => {

// 模拟第二个元素的 selected
context.event = {
data: {
data: plot.chart.getData()[1],
},
target: plot.chart.getElements()[1].shape,
};
vennElementSelected.toggle();

Expand All @@ -145,6 +144,98 @@ describe('venn', () => {
vennElementSelected.destroy();
});

it('venn-element-single-selected', () => {
plot.update({
state: {
selected: {
style: {
lineWidth: 2,
},
},
},
interactions: [
{ type: 'venn-element-selected', enable: false },
{ type: 'venn-element-single-selected', enable: true },
],
});

const context = new InteractionContext(plot.chart);
// @ts-ignore
const vennElementSelected = new VennElementSingleSelected(context);

// 模拟 selected
context.event = {
target: plot.chart.getElements()[0].shape,
};
vennElementSelected.selected();

const elements = plot.chart.geometries[0].elements;

// 第一个元素 点击 有样式
expect(plot.getStates().length).toBe(1);
expect(plot.getStates()[0].state).toBe('selected');
expect(elements[0].getStates()[0]).toBe('selected');
expect((elements[0].shape as IGroup).getChildren()[0].attr('lineWidth')).toBe(2);

// 模拟 selected
context.event = {
target: plot.chart.getElements()[1].shape,
};
vennElementSelected.selected();
expect(plot.getStates().length).toBe(1);
expect(elements[0].getStates()[0]).toBeUndefined();
expect((elements[0].shape as IGroup).getChildren()[0].attr('lineWidth')).toBe(0);
expect(elements[1].getStates()[0]).toBe('selected');

// 所有元素的 selected state 为 false
vennElementSelected.reset();
vennElementSelected.destroy();
});

it('venn-element-highlight', () => {
plot.update({
state: {
inactive: {
style: {
fillOpacity: 0.3,
},
},
},
interactions: [
{ type: 'venn-element-single-selected', enable: false },
{ type: 'venn-element-active', enable: false },
{ type: 'venn-element-highlight', enable: true },
],
});

const context = new InteractionContext(plot.chart);
// @ts-ignore
const action = new VennElementHighlight(context);

// 模拟 selected
context.event = {
target: plot.chart.getElements()[0].shape,
};
action.highlight();
const elements = plot.chart.geometries[0].elements;
// 第一个元素 点击 有样式
expect(elements[0].getStates()[0]).toBe('active');
expect((elements[0].shape as IGroup).getChildren()[0].attr('fillOpacity')).not.toBe(0.3);
expect(elements[1].getStates()[0]).toBe('inactive');
expect((elements[1].shape as IGroup).getChildren()[0].attr('fillOpacity')).toBe(0.3);
action.toggle();

context.event = {
target: plot.chart.getElements()[1].shape,
};
action.toggle();
expect(elements[0].getStates().includes('inactive')).toBe(true);
expect((elements[0].shape as IGroup).getChildren()[0].attr('fillOpacity')).toBe(0.3);
expect((elements[1].shape as IGroup).getChildren()[0].attr('fillOpacity')).not.toBe(0.3);

action.destroy();
});

afterAll(() => {
plot.destroy();
});
Expand Down
12 changes: 9 additions & 3 deletions docs/api/plots/venn.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ Configure the chart data source. For example:
];
```

```sign
💡 注意:这里的数据是包含交集部分的数据量的。如上数据源,含有两个集合:`A` 和 `B`, 其中:`{ sets: ['A'], size: 5 }` 代表的是含有 A 集合的有 5 个(其实有 2 个是包含 B 集合的)
```

#### setsField

<description>**optional** _string_</description>
Expand Down Expand Up @@ -135,14 +139,16 @@ Default configuration:
`markdown:docs/common/tooltip.en.md`


### Plot Interactions
### Plot Interactions

There are interactions for venn diagrams, listed below:

| interaction | description | configuration method |
| ---|--|--|
| venn-element-active | enable the "mouse-over venn diagram element triggers active" interaction | `interactions:[{ type: 'venn-element-active', enabled: true }]` |
| venn-element-selected | enable the interaction "trigger selected when mouse clicked on venn diagram element", multiple options available | `interactions:[{ type: 'venn-element-selected', enabled: true }]` |
| venn-element-active | enable the "mouse-over venn diagram element triggers active" interaction | `interactions:[{ type: 'venn-element-active'}]` |
| venn-element-selected | enable the interaction "trigger selected when mouse clicked on venn diagram element", multiple options available | `interactions:[{ type: 'venn-element-selected'}]` |
| venn-element-single-selected | enable the interaction "trigger selected when mouse clicked on venn diagram element", single selected | `interactions:[{ type: 'venn-element-single-selected'}]` |
| venn-element-highlight | enable the interaction "trigger highlight when mouse clicked on venn diagram element" | `interactions:[{ type: 'venn-element-highlight'}]` |

`markdown:docs/common/interactions.en.md`

Expand Down
25 changes: 15 additions & 10 deletions docs/api/plots/venn.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@ order: 12

<description>**required** _object_</description>

设置图表数据源。数据源为对象集合例如:
设置图表数据源。数据源为对象集合. 例如:

```ts
const data = [
{ sets: ['A'], size: 5 },
{ sets: ['B'], size: 10 },
{ sets: ['A', 'B'], size: 2 },
...
];
const data = [
{ sets: ['A'], size: 5 },
{ sets: ['B'], size: 10 },
{ sets: ['A', 'B'], size: 2 },
];
```

```sign
💡 注意:这里的数据是包含交集部分的数据量的。如上数据源,含有两个集合:`A` 和 `B`, 其中:`{ sets: ['A'], size: 5 }` 代表的是含有 A 集合的有 5 个(其实有 2 个是包含 B 集合的)
```

#### setsField
Expand Down Expand Up @@ -133,14 +136,16 @@ order: 12

`markdown:docs/common/tooltip.zh.md`

### 图表交互
### 图表交互

内置了针对 venn 图交互,列表如下:

| 交互 | 描述 | 配置方式 |
| ---|---|---|
| venn-element-active | 开启「鼠标移入 venn 图元素时触发 active」的交互 | `interactions:[{ type: 'venn-element-active', enabled: true }]` |
| venn-element-selected | 开启「鼠标点击 venn 图元素时触发 selected」的交互,可多选 | `interactions:[{ type: 'venn-element-selected', enabled: true }]` |
| venn-element-active | 开启「鼠标移入 venn 图元素时触发 active」的交互 | `interactions:[{ type: 'venn-element-active' }]` |
| venn-element-selected | 开启「鼠标点击 venn 图元素时触发 selected」的交互,可多选 | `interactions:[{ type: 'venn-element-selected' }]` |
| venn-element-single-selected | 开启「鼠标点击 venn 图元素时触发 selected」的交互,单选 | `interactions:[{ type: 'venn-element-single-selected' }]` |
| venn-element-highlight | 开启「鼠标点击 venn 图元素时触发 高亮」的交互 | `interactions:[{ type: 'venn-element-highlight' }]` |

`markdown:docs/common/interactions.zh.md`

Expand Down
Loading