@antv/g2
Version:
the Grammar of Graphics in Javascript
111 lines (99 loc) • 3.24 kB
text/typescript
import { each, isNil, get } from '@antv/util';
import { ListItem } from '../../../dependents';
import Element from '../../../geometry/element/';
import {
getCurrentElement,
getDelegationObject,
getElements,
getElementValue,
getScaleByField,
isElementChange,
isList,
} from '../util';
import StateBase from './state-base';
function getItem(shape) {
return get(shape.get('delegateObject'), 'item');
}
/**
* 状态量 Action 的基类,允许多个 Element 同时拥有某个状态
* @class
* @ignore
*/
class ElementState extends StateBase {
protected ignoreListItemStates = ['unchecked'];
// 是否忽略触发的列表项
private isItemIgnore(item: ListItem, list) {
const states = this.ignoreListItemStates;
const filtered = states.filter((state) => {
return list.hasState(item, state);
});
return !!filtered.length;
}
// 设置由组件选项导致的状态变化
private setStateByComponent(component, item: ListItem, enable: boolean) {
const view = this.context.view;
const field = component.get('field');
const elements = getElements(view);
this.setElementsStateByItem(elements, field, item, enable);
}
// 处理触发源由 element 导致的状态变化
protected setStateByElement(element: Element, enable: boolean) {
this.setElementState(element, enable);
}
/** 组件的选项是否同 element 匹配 */
protected isMathItem(element: Element, field: string, item: ListItem) {
const view = this.context.view;
const scale = getScaleByField(view, field);
const value = getElementValue(element, field);
return !isNil(value) && item.name === scale.getText(value);
}
protected setElementsStateByItem(elements: Element[], field: string, item: ListItem, enable: boolean) {
each(elements, (el) => {
if (this.isMathItem(el, field, item)) {
el.setState(this.stateName, enable);
}
});
}
/** 设置状态是否激活 */
protected setStateEnable(enable: boolean) {
const element = getCurrentElement(this.context);
if (element) {
// 触发源由于 element 导致
if (isElementChange(this.context)) {
this.setStateByElement(element, enable);
}
} else {
// 触发源由组件导致
const delegateObject = getDelegationObject(this.context);
// 如果触发源时列表,图例、坐标轴
if (isList(delegateObject)) {
const { item, component } = delegateObject;
if (item && component && !this.isItemIgnore(item, component)) {
const event = this.context.event.gEvent;
// 防止闪烁
if (event && event.fromShape && event.toShape && getItem(event.fromShape) === getItem(event.toShape)) {
return;
}
this.setStateByComponent(component, item, enable);
}
}
}
}
/**
* 切换状态
*/
public toggle() {
const element = getCurrentElement(this.context);
if (element) {
const hasState = element.hasState(this.stateName);
this.setElementState(element, !hasState);
}
}
/**
* 取消当前时间影响的状态
*/
public reset() {
this.setStateEnable(false);
}
}
export default ElementState;