Skip to content

Commit

Permalink
feat(venn): 韦恩图交互增强(修复图例激活元素交互 & 增强active、highlight、selected交互) (#2911)
Browse files Browse the repository at this point in the history
  • Loading branch information
visiky authored Oct 15, 2021
1 parent c369496 commit ed5b71e
Show file tree
Hide file tree
Showing 24 changed files with 758 additions and 146 deletions.
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

0 comments on commit ed5b71e

Please sign in to comment.