@antv/g2
Version:
the Grammar of Graphics in Javascript
151 lines (137 loc) • 3.46 kB
text/typescript
import { each, get } from '@antv/util';
import { View } from '../chart';
import { BBox, IShape, Point } from '../dependents';
import { IAction, IInteractionContext, LooseObject } from '../interface';
import { getComponents, isInBox } from './action/util';
/**
* 交互的上下文
*/
export default class Context implements IInteractionContext {
/** 当前所有的 Action */
public actions: IAction[] = [];
/** 当前 View 实例 */
public view: View;
/** 当前事件对象 */
public event: LooseObject = null;
private cacheMap: LooseObject = {};
constructor(view: View) {
this.view = view;
}
/**
* 缓存信息
* @param params 缓存的字段
* - 如果一个字段则获取缓存
* - 两个字段则设置缓存
*/
public cache(...params) {
if (params.length === 1) {
return this.cacheMap[params[0]];
} else if (params.length === 2) {
this.cacheMap[params[0]] = params[1];
}
}
/**
* 获取 Action
* @param name Action 的名称
*/
public getAction(name: string): IAction {
return this.actions.find((action) => action.name === name);
}
/**
* 获取 Action
* @param action Action 对象
*/
public addAction(action: IAction) {
this.actions.push(action);
}
/**
* 移除 Action
* @param action Action 对象
*/
public removeAction(action: IAction) {
const actions = this.actions;
const index = this.actions.indexOf(action);
if (index >= 0) {
actions.splice(index, 1);
}
}
/**
* 获取当前的点
*/
public getCurrentPoint(): Point {
const event = this.event;
if (event) {
if (event.target instanceof HTMLElement) {
const canvas = this.view.getCanvas();
const point = canvas.getPointByClient(event.clientX, event.clientY);
return point;
} else {
return {
x: event.x,
y: event.y,
};
}
}
return null;
}
/**
* 获取当前 shape
* @returns current shape
*/
public getCurrentShape(): IShape {
return get(this.event, ['gEvent', 'shape']);
}
/**
* 当前的触发是否在 View 内
*/
public isInPlot() {
const point = this.getCurrentPoint();
if (point) {
return this.view.isPointInPlot(point);
}
return false;
}
/**
* 是否在指定的图形内
* @param name shape 的 name
*/
public isInShape(name) {
const shape = this.getCurrentShape(); // 不再考虑在 shape 的 parent 内的情况
if (shape) {
return shape.get('name') === name;
}
return false;
}
/**
* 当前的触发是组件内部
* @param name 组件名,可以为空
*/
public isInComponent(name?: string) {
const components = getComponents(this.view);
const point = this.getCurrentPoint();
if (point) {
return !!components.find((component) => {
const bbox = component.getBBox() as BBox;
if (name) {
return component.get('name') === name && isInBox(bbox, point);
} else {
return isInBox(bbox, point);
}
});
}
return false;
}
/**
* 销毁
*/
public destroy() {
// 先销毁 action 再清空,一边遍历,一边删除,所以数组需要更新引用
each(this.actions.slice(), (action) => {
action.destroy();
});
this.view = null;
this.event = null;
this.actions = null;
this.cacheMap = null;
}
}