@antv/g2plot
Version:
An interactive and responsive charting library
162 lines (145 loc) • 3.62 kB
text/typescript
import { Action, IGroup, Util } from '@antv/g2';
import { get } from '@antv/util';
import { BBox, ButtonCfg } from '../../types';
import { deepAssign, normalPadding } from '../../utils';
const PADDING_RIGHT = 10;
const PADDING_TOP = 5;
/**
* Action 中的 Button 按钮配置
*
* 可能的使用场景:brush filter
*/
export const BUTTON_ACTION_CONFIG: ButtonCfg = {
padding: [8, 10],
text: 'reset',
textStyle: {
default: {
x: 0,
y: 0,
fontSize: 12,
fill: '#333333',
cursor: 'pointer',
},
},
buttonStyle: {
default: {
fill: '#f7f7f7',
stroke: '#cccccc',
cursor: 'pointer',
},
active: {
fill: '#e6e6e6',
},
},
};
/**
* @override 复写 G2 Button Action, 后续直接使用 GUI
*/
class ButtonAction extends Action {
private buttonGroup: IGroup = null;
private buttonCfg = {
name: 'button',
...BUTTON_ACTION_CONFIG,
};
/**
* 获取 mix 默认的配置和用户配置
*/
private getButtonCfg(): ButtonCfg & { name: string } {
const { view } = this.context;
const buttonCfg: ButtonCfg = get(view, ['interactions', 'filter-action', 'cfg', 'buttonConfig']);
return deepAssign(this.buttonCfg, buttonCfg, this.cfg);
}
/**
* 绘制 Button 和 文本
*/
private drawButton() {
const config = this.getButtonCfg();
const group = this.context.view.foregroundGroup.addGroup({
name: config.name,
});
const textShape = this.drawText(group);
this.drawBackground(group, textShape.getBBox());
this.buttonGroup = group;
}
/**
* 绘制文本
*/
private drawText(group: IGroup) {
const config = this.getButtonCfg();
// 添加文本
return group.addShape({
type: 'text',
name: 'button-text',
attrs: {
text: config.text,
...config.textStyle?.default,
},
});
}
private drawBackground(group: IGroup, bbox: BBox) {
const config = this.getButtonCfg();
const padding = normalPadding(config.padding);
// 添加背景按钮
const buttonShape = group.addShape({
type: 'rect',
name: 'button-rect',
attrs: {
x: bbox.x - padding[3],
y: bbox.y - padding[0],
width: bbox.width + padding[1] + padding[3],
height: bbox.height + padding[0] + padding[2],
...config.buttonStyle?.default,
},
});
buttonShape.toBack(); // 在后面
// active 效果内置
group.on('mouseenter', () => {
buttonShape.attr(config.buttonStyle?.active);
});
group.on('mouseleave', () => {
buttonShape.attr(config.buttonStyle?.default);
});
return buttonShape;
}
// 重置位置
private resetPosition() {
const view = this.context.view;
const coord = view.getCoordinate();
const point = coord.convert({ x: 1, y: 1 }); // 后面直接改成左上角
const buttonGroup = this.buttonGroup;
const bbox = buttonGroup.getBBox();
const matrix = Util.transform(null, [
['t', point.x - bbox.width - PADDING_RIGHT, point.y + bbox.height + PADDING_TOP],
]);
buttonGroup.setMatrix(matrix);
}
/**
* 显示
*/
public show() {
if (!this.buttonGroup) {
this.drawButton();
}
this.resetPosition();
this.buttonGroup.show();
}
/**
* 隐藏
*/
public hide() {
if (this.buttonGroup) {
this.buttonGroup.hide();
}
}
/**
* 销毁
*/
public destroy() {
const buttonGroup = this.buttonGroup;
if (buttonGroup) {
buttonGroup.remove();
}
super.destroy();
}
}
export { ButtonAction };