Skip to content

Commit

Permalink
refactor: define and export event (#5627)
Browse files Browse the repository at this point in the history
* feat(utils): add isElement util

* refactor(runtime): override on/once api to provide type

* refactor: define and export event type

* refactor(runtime): carry originalTarget in element event
  • Loading branch information
Aarebecca authored Apr 7, 2024
1 parent 944ccda commit a428667
Show file tree
Hide file tree
Showing 18 changed files with 212 additions and 67 deletions.
13 changes: 10 additions & 3 deletions packages/g6/__tests__/unit/behaviors/collapse-expand.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,22 @@ describe('behavior combo expand collapse', () => {

it('collapse', async () => {
// collapse combo-2
graph.emit(`combo:${CommonEvent.DBLCLICK}`, { target: { id: 'combo-2' } });
// @ts-expect-error private method
const combo2 = graph.context.element?.getElement('combo-2');

graph.emit(`combo:${CommonEvent.DBLCLICK}`, { target: combo2 });
await expect(graph).toMatchSnapshot(__filename, 'collapse-combo-2');
});

it('expand', async () => {
// expand combo-2
graph.emit(`combo:${CommonEvent.DBLCLICK}`, { target: { id: 'combo-2' } });
// @ts-expect-error private method
const combo2 = graph.context.element?.getElement('combo-2');
graph.emit(`combo:${CommonEvent.DBLCLICK}`, { target: combo2 });
// expand combo-1
graph.emit(`combo:${CommonEvent.DBLCLICK}`, { target: { id: 'combo-1' } });
// @ts-expect-error private method
const combo1 = graph.context.element?.getElement('combo-1');
graph.emit(`combo:${CommonEvent.DBLCLICK}`, { target: combo1 });
await expect(graph).toMatchSnapshot(__filename, 'expand-combo-1');
});
});
32 changes: 32 additions & 0 deletions packages/g6/__tests__/unit/runtime/element/event.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { IPointerEvent, NodeEvent } from '@/src';
import { createGraph } from '@@/utils';
import type { DisplayObject } from '@antv/g';
import { CustomEvent } from '@antv/g';

describe('element event', () => {
it('element event target', async () => {
const graph = createGraph({
data: {
nodes: [{ id: 'node-1' }, { id: 'node-2' }],
edges: [{ id: 'edge-1', source: 'node-1', target: 'node-2' }],
},
});

const click = jest.fn();

graph.on<IPointerEvent>(`node:${NodeEvent.CLICK}`, click);

await graph.draw();

// @ts-expect-error context is private
const node1 = graph.context.element!.getElement('node-1')!;
(node1.children[0] as DisplayObject).dispatchEvent(new CustomEvent('click', {}));

expect(click).toHaveBeenCalledTimes(1);
expect(click.mock.calls[0][0].target).toBe(node1);
expect(click.mock.calls[0][0].targetType).toBe('node');
expect(click.mock.calls[0][0].originalTarget).toBe(node1.children[0]);

graph.destroy();
});
});
11 changes: 9 additions & 2 deletions packages/g6/__tests__/unit/utils/element.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
getTrianglePoints,
getTrianglePorts,
isEdge,
isElement,
isNode,
isSameNode,
isSimplePort,
Expand All @@ -38,14 +39,20 @@ describe('element', () => {
const edge = new Polyline({ style: { sourceNode: node1, targetNode: node2 } });

it('isNode', () => {
expect(isNode(new Rect({ style: { width: 10, height: 10 } }))).toBe(false);
const rect = new Rect({ style: { width: 10, height: 10 } });
expect(isNode(rect)).toBe(false);
expect(isElement(rect)).toBe(false);
const node = new Circle({});
expect(isNode(node)).toBe(true);
expect(isElement(node)).toBe(true);
});

it('isEdge', () => {
expect(isEdge(new Line({ style: { x1: 0, y1: 0, x2: 10, y2: 10 } }))).toBe(false);
const line = new Line({ style: { x1: 0, y1: 0, x2: 10, y2: 10 } });
expect(isEdge(line)).toBe(false);
expect(isElement(line)).toBe(false);
expect(isEdge(edge)).toBe(true);
expect(isElement(edge)).toBe(true);
});

it('isSameNode', () => {
Expand Down
5 changes: 2 additions & 3 deletions packages/g6/__tests__/utils/to-match-svg-snapshot.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { Graph } from '@/src';
import type { AnimateEvent } from '@/src/utils/event';
import type { Graph, IAnimateEvent } from '@/src';
import type { Canvas, IAnimation } from '@antv/g';
import * as fs from 'fs';
import * as path from 'path';
Expand Down Expand Up @@ -108,7 +107,7 @@ export async function toMatchAnimation(
options: ToMatchSVGSnapshotOptions = {},
) {
const animationPromise = new Promise<IAnimation>((resolve) => {
graph.once('beforeanimate', (e: AnimateEvent) => {
graph.once<IAnimateEvent>('beforeanimate', (e) => {
resolve(e.animation!);
});
});
Expand Down
5 changes: 4 additions & 1 deletion packages/g6/src/behaviors/collapse-expand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { isFunction } from '@antv/util';
import { CommonEvent } from '../constants';
import type { RuntimeContext } from '../runtime/types';
import type { IPointerEvent } from '../types';
import { isElement } from '../utils/element';
import type { BaseBehaviorOptions } from './base-behavior';
import { BaseBehavior } from './base-behavior';

Expand Down Expand Up @@ -59,8 +60,10 @@ export class CollapseExpand extends BaseBehavior<CollapseExpandOptions> {

private onCollapseExpand = async (event: IPointerEvent) => {
if (!this.validate(event)) return;
const { target } = event;
if (!isElement(target)) return;

const id = event?.target?.id;
const id = target.id;
const { model, graph } = this.context;
const data = model.getComboData([id])[0];
if (!data) return false;
Expand Down
10 changes: 6 additions & 4 deletions packages/g6/src/behaviors/create-edge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CommonEvent } from '../constants';
import type { RuntimeContext } from '../runtime/types';
import type { EdgeData } from '../spec';
import type { EdgeStyle } from '../spec/element/edge';
import type { IPointerEvent } from '../types';
import type { Element, IPointerEvent } from '../types';
import type { BaseBehaviorOptions } from './base-behavior';
import { BaseBehavior } from './base-behavior';

Expand Down Expand Up @@ -85,7 +85,7 @@ export class CreateEdge extends BaseBehavior<CreateEdgeOptions> {
graph.on(CommonEvent.POINTER_MOVE, this.updateAssistEdge);
}

private drop = async (event: IPointerEvent) => {
private drop = async (event: IElementEvent) => {
const { targetType } = event;
if (['combo', 'node'].includes(targetType) && this.source) {
await this.handleCreateEdge(event);
Expand All @@ -94,7 +94,7 @@ export class CreateEdge extends BaseBehavior<CreateEdgeOptions> {
}
};

private handleCreateEdge = async (event: IPointerEvent) => {
private handleCreateEdge = async (event: IElementEvent) => {
if (!this.validate(event)) return;
const { graph, canvas } = this.context;
const { style } = this.options;
Expand Down Expand Up @@ -140,7 +140,7 @@ export class CreateEdge extends BaseBehavior<CreateEdgeOptions> {
await element!.draw({ animation: false, silence: true });
};

private createEdge = (event: IPointerEvent) => {
private createEdge = (event: IElementEvent) => {
const { graph } = this.context;
const { style, onFinish, onCreate } = this.options;
const targetId = event.target?.id;
Expand Down Expand Up @@ -202,3 +202,5 @@ export class CreateEdge extends BaseBehavior<CreateEdgeOptions> {
super.destroy();
}
}

type IElementEvent = IPointerEvent<Element>;
14 changes: 8 additions & 6 deletions packages/g6/src/behaviors/drag-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ID } from '@antv/graphlib';
import { isFunction } from '@antv/util';
import { COMBO_KEY, CommonEvent } from '../constants';
import { RuntimeContext } from '../runtime/types';
import type { EdgeDirection, IDragEvent, Point, PrefixObject } from '../types';
import type { EdgeDirection, Element, IDragEvent, Point, PrefixObject } from '../types';
import { getBBoxSize, getCombinedBBox } from '../utils/bbox';
import { idOf } from '../utils/id';
import { subStyleProps } from '../utils/prefix';
Expand All @@ -24,7 +24,7 @@ export interface DragElementOptions extends BaseBehaviorOptions, PrefixObject<Ba
*
* <en/> Whether to enable the function of dragging the node
*/
enable?: boolean | ((event: IDragEvent) => boolean);
enable?: boolean | ((event: IElementDragEvent) => boolean);
/**
* <zh/> 拖拽操作效果
* - link: 将拖拽元素置入为目标元素的子元素
Expand Down Expand Up @@ -150,7 +150,7 @@ export class DragElement extends BaseBehavior<DragElementOptions> {
);
}

private onDragStart = (event: IDragEvent) => {
private onDragStart = (event: IElementDragEvent) => {
this.enable = this.validate(event);
if (!this.enable) return;

Expand All @@ -160,7 +160,7 @@ export class DragElement extends BaseBehavior<DragElementOptions> {
if (this.options.shadow) this.createShadow(this.target);
};

private onDrag = (event: IDragEvent) => {
private onDrag = (event: IElementDragEvent) => {
if (!this.enable) return;
const zoom = this.context.graph.getZoom();
const { dx, dy } = event;
Expand All @@ -184,7 +184,7 @@ export class DragElement extends BaseBehavior<DragElementOptions> {
this.target = [];
};

private onDrop = async (event: IDragEvent) => {
private onDrop = async (event: IElementDragEvent) => {
if (this.options.dropEffect !== 'link') return;
const { model, element } = this.context;
const modifiedParentId = event.target.id;
Expand All @@ -200,7 +200,7 @@ export class DragElement extends BaseBehavior<DragElementOptions> {
await element?.draw({ animation: true });
};

private validate(event: IDragEvent) {
private validate(event: IElementDragEvent) {
if (this.destroyed) return false;
const { enable } = this.options;
if (isFunction(enable)) return enable(event);
Expand Down Expand Up @@ -294,3 +294,5 @@ export class DragElement extends BaseBehavior<DragElementOptions> {
super.destroy();
}
}

type IElementDragEvent = IDragEvent<Element>;
12 changes: 7 additions & 5 deletions packages/g6/src/behaviors/focus-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { ID } from '@antv/graphlib';
import { isFunction } from '@antv/util';
import { CommonEvent } from '../constants';
import type { RuntimeContext } from '../runtime/types';
import type { IKeyboardEvent, IPointerEvent, ViewportAnimationEffectTiming } from '../types';
import type { Element, IPointerEvent, ViewportAnimationEffectTiming } from '../types';
import type { BaseBehaviorOptions } from './base-behavior';
import { BaseBehavior } from './base-behavior';

Expand All @@ -20,7 +20,7 @@ export interface FocusElementOptions extends BaseBehaviorOptions {
*
* <en/> Whether to enable the function of dragging the node
*/
enable?: boolean | ((event: IPointerEvent | IKeyboardEvent) => boolean);
enable?: boolean | ((event: IElementEvent) => boolean);
}

export class FocusElement extends BaseBehavior<FocusElementOptions> {
Expand Down Expand Up @@ -57,16 +57,16 @@ export class FocusElement extends BaseBehavior<FocusElementOptions> {
);
}

private clickFocusElement = async (event: IPointerEvent) => {
private clickFocusElement = async (event: IElementEvent) => {
if (!this.validate(event)) return;
const { animation } = this.options;
const { graph } = this.context;
const id = this.getSelectedNodeIDs([event.target.id]);
const id = this.getSelectedNodeIDs([(event.target as Element).id]);

await graph.focusElement(id, animation);
};

private validate(event: IPointerEvent) {
private validate(event: IElementEvent) {
if (this.destroyed) return false;
const { enable } = this.options;
if (isFunction(enable)) return enable(event);
Expand All @@ -86,3 +86,5 @@ export class FocusElement extends BaseBehavior<FocusElementOptions> {
super.destroy();
}
}

type IElementEvent = IPointerEvent<Element>;
9 changes: 7 additions & 2 deletions packages/g6/src/behaviors/hover-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { isFunction } from '@antv/util';
import { CommonEvent } from '../constants';
import { ELEMENT_TYPES } from '../constants/element';
import type { RuntimeContext } from '../runtime/types';
import type { ElementType, IPointerEvent, State } from '../types';
import type { Element, ElementType, IPointerEvent, State } from '../types';
import { getIds } from '../utils/id';
import { getElementNthDegreeIds } from '../utils/relation';
import type { BaseBehaviorOptions } from './base-behavior';
Expand Down Expand Up @@ -96,7 +96,12 @@ export class HoverElement extends BaseBehavior<HoverElementOptions> {
const { graph } = this.context;
const { targetType, target } = event;

const activeIds = getElementNthDegreeIds(graph, targetType as ElementType, target.id, this.options.degree);
const activeIds = getElementNthDegreeIds(
graph,
targetType as ElementType,
(target as Element).id,
this.options.degree,
);

const states: Record<ID, State[]> = {};

Expand Down
6 changes: 5 additions & 1 deletion packages/g6/src/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,14 @@ export type {
ViewportOptions,
} from './spec';
export type {
IAnimateEvent,
IDragEvent,
IElementEvent,
IElementLifeCycleEvent,
IEvent,
IGraphLifeCycleEvent,
IKeyboardEvent,
IPointerEvent,
IViewportEvent,
IWheelEvent,
Point,
Vector2,
Expand Down
5 changes: 4 additions & 1 deletion packages/g6/src/plugins/contextmenu.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { RuntimeContext } from '../runtime/types';
import type { IElementEvent } from '../types/event';
import type { Element } from '../types';
import type { IPointerEvent } from '../types/event';
import type { Item } from '../utils/contextmenu';
import { CONTEXTMENU_CSS, getContentFromItems } from '../utils/contextmenu';
import { createPluginContainer, insertDOM } from '../utils/dom';
Expand Down Expand Up @@ -196,3 +197,5 @@ export class Contextmenu extends BasePlugin<ContextmenuOptions> {
}
};
}

type IElementEvent = IPointerEvent<Element>;
9 changes: 5 additions & 4 deletions packages/g6/src/plugins/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { TooltipStyleProps } from '@antv/component';
import { Tooltip as TooltipComponent } from '@antv/component';
import { get } from '@antv/util';
import type { RuntimeContext } from '../runtime/types';
import type { ElementDatum, ElementType, IElementEvent } from '../types';
import type { Element, ElementDatum, ElementType, IPointerEvent } from '../types';
import type { BasePluginOptions } from './base-plugin';
import { BasePlugin } from './base-plugin';

Expand Down Expand Up @@ -39,14 +39,13 @@ export class Tooltip extends BasePlugin<TooltipOptions> {
this.bindEvents();
}

public getEvents(): { [key: string]: Function } {
public getEvents(): { [key: string]: (event: IElementEvent) => void } {
if (this.options.trigger === 'click') {
return {
'node:click': this.onClick,
'edge:click': this.onClick,
'combo:click': this.onClick,
'canvas:click': this.onPointerLeave,
afterremoveitem: this.onPointerLeave,
contextmenu: this.onPointerLeave,
drag: this.onPointerLeave,
};
Expand Down Expand Up @@ -176,7 +175,7 @@ export class Tooltip extends BasePlugin<TooltipOptions> {
const { getContent } = this.options;
const { color, stroke } = attributes;
this.currentTarget = id;
const items: ElementDatum[] = this.getItems(id, targetType);
const items: ElementDatum[] = this.getItems(id, targetType as ElementType);
let x;
let y;
if (client) {
Expand Down Expand Up @@ -266,3 +265,5 @@ export class Tooltip extends BasePlugin<TooltipOptions> {
super.destroy();
}
}

type IElementEvent = IPointerEvent<Element>;
4 changes: 2 additions & 2 deletions packages/g6/src/registry/extension/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type EventEmitter from '@antv/event-emitter';
import { getExtension } from '..';
import type { RuntimeContext } from '../../runtime/types';
import type { Listener } from '../../types';
import type { IEvent } from '../../types';
import { arrayDiff } from '../../utils/diff';
import { parseExtensions } from '../../utils/extension';
import type { ExtensionOptions, LooselyExtensionOption, STDExtensionOption } from './types';
Expand Down Expand Up @@ -88,7 +88,7 @@ export class BaseExtension<T extends LooselyExtensionOption> {

protected options: Required<T>;

protected events: [EventEmitter | HTMLElement, string, Listener][] = [];
protected events: [EventEmitter | HTMLElement, string, (event: IEvent) => void][] = [];

public destroyed = false;

Expand Down
5 changes: 3 additions & 2 deletions packages/g6/src/runtime/behavior.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,13 @@ export class BehaviorController extends ExtensionController<BaseBehavior<CustomB
}

private forwardCanvasEvents = (event: FederatedPointerEvent | FederatedWheelEvent) => {
const target = eventTargetOf(event.target as DisplayObject);
const { target: originalTarget } = event;
const target = eventTargetOf(originalTarget as DisplayObject);
if (!target) return;
const { graph, canvas } = this.context;
const { type: targetType, element: targetElement } = target;
const { type, detail, button } = event;
const stdEvent = { ...event, target: targetElement, targetType };
const stdEvent = { ...event, target: targetElement, targetType, originalTarget };

if (type === CanvasEvent.POINTER_MOVE) {
if (this.currentTarget !== targetElement) {
Expand Down
Loading

0 comments on commit a428667

Please sign in to comment.