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(event): add plot events bind #1412

Merged
merged 3 commits into from
Aug 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions __tests__/unit/core/index-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,42 @@ describe('core', () => {

expect(line.chart.getTheme().colors10).toEqual(['green']);
});

it('event', async () => {
const line = new Line(createDiv(), {
width: 400,
height: 300,
appendPadding: 10,
data: partySupport.filter((o) => ['FF', 'Lab'].includes(o.type)),
xField: 'date',
yField: 'value',
seriesField: 'type',
theme: {
colors10: ['red'],
},
});

line.render();

function click(): Promise<Event> {
return new Promise((resolve, reject) => {
line.on('element:click', (e) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

element:click 做个映射?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

映射是改事件名称吗?如果 elemnt:click 改成 line:click 可能但这个图来看更语意了,但是就在 G2 的基础增加新概念了。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感觉 element:click 不够明确。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

考虑用户学习成本,同时学习 G2、G2Plot 概念太多,对于他们后续想要做定制也有理解成本。element 其实很明确了,就是图形元素,这些都可以用一个基础概念教程介绍下就行了

resolve(e);
});

line.chart.emit('element:click', {
_data: 1,
type: 'element:click',
});
});
}

const e = await click();

// 直接接受 G2 透传的事件
expect(e).toEqual({
type: 'element:click',
_data: 1,
});
});
});
27 changes: 23 additions & 4 deletions src/core/plot.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Chart } from '@antv/g2';
import { Chart, Event } from '@antv/g2';
import { deepMix } from '@antv/util';
import EE from '@antv/event-emitter';
import { bind } from 'size-sensor';
import { Adaptor } from './adaptor';
import { ChartOptions, Data } from '../types';

/**
* 所有 plot 的基类
*/
export abstract class Plot<O extends ChartOptions> {
export abstract class Plot<O extends ChartOptions> extends EE {
/** plot 类型名称 */
public abstract readonly type: string = 'base';
/** plot 的 schema 配置 */
Expand All @@ -20,11 +21,14 @@ export abstract class Plot<O extends ChartOptions> {
private unbind: () => void;

constructor(container: string | HTMLElement, options: O) {
super();
this.container = typeof container === 'string' ? document.getElementById(container) : container;
const defaultOptions = this.getDefaultOptions();
this.options = deepMix({}, defaultOptions, options);

this.options = deepMix({}, this.getDefaultOptions(), options);

this.createG2();

this.bindEvents();
}

/**
Expand All @@ -46,6 +50,19 @@ export abstract class Plot<O extends ChartOptions> {
});
}

/**
* 绑定代理所有 G2 的事件
*/
private bindEvents() {
if (this.chart) {
this.chart.on('*', (e: Event) => {
if (e?.type) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (e?.type && contains(keys(this.getEvents()), e?.type)) ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

就是每个图表支持哪些 event 有图表决定吗?这样是在 G2 的事件能力上做了限制了~

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

直接透传就行了

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

是的,取决于图表注册了哪些事件,例如 chart.on('line:click',(e)=> console.log(e));

Copy link
Member Author

@hustcc hustcc Aug 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

然后 line:click 映射到 G2 element:click,但看这一个图表是容易理解了,但是从开发者来看:

  1. G2Plot 提供的是通用图表,对于非通用图表,还是会基于 G2,那么这个时候他们可以对于对事件就有两套命名认知了。这是提升了整体成本的
  2. G2, G2Plot 事件文档两份。
  3. 而且 G2 的事件通过 xx: yy 叉乘出上百种事件,G2Plot 这层维护映射关系太难了,而且后很容易出现变量命名上的困难的争论,导致 break change。

比如 G2 中 lable:click,如果在 G2Plot 2.0.0 没有映射掉,如果后面做映射成 pie-label:click 那么就会产生 breakchange,需要发大版本(3.0.0),或者两种命名都支持,上百个事件都存在这类困扰,维护起来也是麻烦。

this.emit(e.type, e);
}
});
}
}

/**
* 获取默认的 options 配置项
* 每个组件都可以复写
Expand Down Expand Up @@ -116,6 +133,8 @@ export abstract class Plot<O extends ChartOptions> {
this.unbindSizeSensor();
// G2 的销毁
this.chart.destroy();
// 清空已经绑定的事件
this.off();
}

/**
Expand Down