diff --git a/src/common/constants/index.ts b/src/common/constants/index.ts index e06e905c..442bfe4d 100644 --- a/src/common/constants/index.ts +++ b/src/common/constants/index.ts @@ -11,6 +11,7 @@ export enum RendererType { export enum ItemType { Node = 'node', Edge = 'edge', + Combo = 'combo', } export enum ItemState { @@ -35,6 +36,7 @@ export enum GraphMode { export enum GraphState { NodeSelected = 'nodeSelected', EdgeSelected = 'edgeSelected', + ComboSelected = 'comboSelected', MultiSelected = 'multiSelected', CanvasSelected = 'canvasSelected', } @@ -194,6 +196,41 @@ export enum GraphEdgeEvent { onEdgeContextMenu = 'edge:contextmenu', } +export enum GraphComboEvent { + /** 鼠标左键单击 Combo 时触发 */ + onComboClick = 'combo:click', + /** 鼠标双击左键 Combo 时触发 */ + onComboDoubleClick = 'combo:dblclick', + /** 鼠标移入 Combo 时触发 */ + onComboMouseEnter = 'combo:mouseenter', + /** 鼠标在 Combo 内部移到时不断触发,不能通过键盘触发 */ + onComboMouseMove = 'combo:mousemove', + /** 鼠标移出 Combo 后触发 */ + onComboMouseOut = 'combo:mouseout', + /** 鼠标移入 Combo 上方时触发 */ + onComboMouseOver = 'combo:mouseover', + /** 鼠标移出 Combo 时触发 */ + onComboMouseLeave = 'combo:mouseleave', + /** 鼠标按钮在 Combo 上按下(左键或者右键)时触发,不能通过键盘触发 */ + onComboMouseDown = 'combo:mousedown', + /** Combo 上按下的鼠标按钮被释放弹起时触发,不能通过键盘触发 */ + onComboMouseUp = 'combo:mouseup', + /** 用户在 Combo 上右击鼠标时触发并打开右键菜单 */ + onComboContextMenu = 'combo:contextmenu', + /** 当 Combo 开始被拖拽的时候触发的事件,此事件作用在被拖曳 Combo 上 */ + onComboDragStart = 'combo:dragstart', + /** 当 Combo 在拖动过程中时触发的事件,此事件作用于被拖拽 Combo 上 */ + onComboDrag = 'combo:drag', + /** 当拖拽完成后触发的事件,此事件作用在被拖曳 Combo 上 */ + onComboDragEnd = 'combo:dragend', + /** 当拖曳 Combo 进入目标元素的时候触发的事件,此事件作用在目标元素上 */ + onComboDragEnter = 'combo:dragenter', + /** 当拖曳 Combo 离开目标元素的时候触发的事件,此事件作用在目标元素上 */ + onComboDragLeave = 'combo:dragleave', + /** 被拖拽的 Combo 在目标元素上同时鼠标放开触发的事件,此事件作用在目标元素上 */ + onComboDrop = 'combo:drop', +} + export enum GraphCanvasEvent { /** 鼠标左键单击画布时触发 */ onCanvasClick = 'canvas:click', diff --git a/src/common/interfaces/index.ts b/src/common/interfaces/index.ts index c69e420c..a76a044d 100644 --- a/src/common/interfaces/index.ts +++ b/src/common/interfaces/index.ts @@ -6,6 +6,7 @@ import { GraphCommonEvent, GraphNodeEvent, GraphEdgeEvent, + GraphComboEvent, GraphCanvasEvent, GraphCustomEvent, } from '@/common/constants'; @@ -20,11 +21,12 @@ import { TreeGraphData as ITreeGraphData, NodeConfig as INodeConfig, EdgeConfig as IEdgeConfig, + ComboConfig as IComboConfig, BehaviorOption as IBehaviorOption, IG6GraphEvent as IGraphEvent, } from '@antv/g6/lib/types'; import { ShapeOptions as IShapeOptions } from '@antv/g6/lib/interface/shape'; -import { INode, IEdge } from '@antv/g6/lib/interface/item'; +import { INode, IEdge, ICombo } from '@antv/g6/lib/interface/item'; export interface GShape extends IGShape {} export interface GGroup extends IGGroup {} @@ -43,16 +45,19 @@ export interface MindData extends ITreeGraphData {} export interface NodeModel extends INodeConfig {} export interface EdgeModel extends IEdgeConfig {} +export interface ComboModel extends IComboConfig {} export interface GraphEvent extends IGraphEvent {} export interface GraphOptions extends IGraphOptions {} export interface CustomShape extends IShapeOptions {} export interface CustomNode extends CustomShape {} export interface CustomEdge extends CustomShape {} +export interface CustomCombo extends CustomShape {} -export type Item = Node | Edge; +export type Item = Node | Edge | Combo; export interface Node extends INode {} export interface Edge extends IEdge {} +export interface Combo extends ICombo {} export interface Behavior extends IBehaviorOption { graph?: Graph; @@ -95,12 +100,19 @@ export interface LabelStateEvent { labelState: LabelState; } -export type GraphNativeEvent = GraphCommonEvent | GraphNodeEvent | GraphEdgeEvent | GraphCanvasEvent | GraphCustomEvent; +export type GraphNativeEvent = + | GraphCommonEvent + | GraphNodeEvent + | GraphEdgeEvent + | GraphComboEvent + | GraphCanvasEvent + | GraphCustomEvent; export type GraphReactEvent = | keyof typeof GraphCommonEvent | keyof typeof GraphNodeEvent | keyof typeof GraphEdgeEvent + | keyof typeof GraphComboEvent | keyof typeof GraphCanvasEvent | keyof typeof GraphCustomEvent; diff --git a/src/components/DetailPanel/index.tsx b/src/components/DetailPanel/index.tsx index 5dcd6f6d..acc87bcd 100644 --- a/src/components/DetailPanel/index.tsx +++ b/src/components/DetailPanel/index.tsx @@ -1,15 +1,16 @@ import React from 'react'; -import { getSelectedNodes, getSelectedEdges } from '@/utils'; +import { getSelectedNodes, getSelectedEdges, getSelectedCombos } from '@/utils'; import { GraphState, EditorEvent } from '@/common/constants'; import { EditorContextProps, withEditorContext } from '@/components/EditorContext'; -import { Node, Edge, GraphStateEvent } from '@/common/interfaces'; +import { Node, Edge, Combo, GraphStateEvent } from '@/common/interfaces'; -type DetailPanelType = 'node' | 'edge' | 'multi' | 'canvas'; +type DetailPanelType = 'node' | 'edge' | 'combo' | 'multi' | 'canvas'; export interface DetailPanelComponentProps { type: DetailPanelType; nodes: Node[]; edges: Edge[]; + combos: Combo[]; } class DetailPanel { @@ -43,8 +44,9 @@ class DetailPanel { const nodes = getSelectedNodes(graph); const edges = getSelectedEdges(graph); + const combos = getSelectedCombos(graph); - return ; + return ; } } diff --git a/src/components/Graph/behavior/clickItem.ts b/src/components/Graph/behavior/clickItem.ts index 6908cbc6..1ba3719e 100644 --- a/src/components/Graph/behavior/clickItem.ts +++ b/src/components/Graph/behavior/clickItem.ts @@ -36,6 +36,7 @@ const clickItemBehavior: ClickItemBehavior & ThisType { ...GraphCommonEvent, ...GraphNodeEvent, ...GraphEdgeEvent, + ...GraphComboEvent, ...GraphCanvasEvent, ...GraphCustomEvent, }; diff --git a/src/components/Register/index.ts b/src/components/Register/index.ts index 63b7d923..7b3cce63 100644 --- a/src/components/Register/index.ts +++ b/src/components/Register/index.ts @@ -36,6 +36,10 @@ class Register extends React.Component { G6.registerEdge(name, config, extend); break; + case 'combo': + G6.registerCombo(name, config, extend); + break; + case 'command': commandManager.register(name, config as Command); break; @@ -56,5 +60,6 @@ class Register extends React.Component { export const RegisterNode = Register.create('node'); export const RegisterEdge = Register.create('edge'); +export const RegisterCombo = Register.create('combo'); export const RegisterCommand = Register.create('command'); export const RegisterBehavior = Register.create('behavior'); diff --git a/src/index.tsx b/src/index.tsx index e0b7821c..b168aeb6 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -10,7 +10,7 @@ import Mind from '@/components/Mind'; import Command from '@/components/Command'; import ItemPanel, { Item } from '@/components/ItemPanel'; import DetailPanel from '@/components/DetailPanel'; -import { RegisterNode, RegisterEdge, RegisterCommand, RegisterBehavior } from '@/components/Register'; +import { RegisterNode, RegisterEdge, RegisterCombo, RegisterCommand, RegisterBehavior } from '@/components/Register'; import { withEditorContext } from '@/components/EditorContext'; import { baseCommand } from '@/components/Graph/command/base'; @@ -36,6 +36,7 @@ export { DetailPanel, RegisterNode, RegisterEdge, + RegisterCombo, RegisterCommand, RegisterBehavior, withEditorContext, diff --git a/src/utils/index.ts b/src/utils/index.ts index 39010639..e2ee269f 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,6 +1,6 @@ import G6 from '@antv/g6'; import { ItemType, ItemState, GraphState, EditorEvent } from '@/common/constants'; -import { Graph, TreeGraph, EdgeModel, Item, Node, Edge } from '@/common/interfaces'; +import { Graph, TreeGraph, EdgeModel, Item, Node, Edge, Combo } from '@/common/interfaces'; /** 生成唯一标识 */ export function guid() { @@ -74,6 +74,30 @@ export function getSelectedEdges(graph: Graph): Edge[] { return graph.findAllByState(ItemType.Edge, ItemState.Selected); } +/** 获取选中边线 */ +export function getSelectedCombos(graph: Graph): Combo[] { + return graph.findAllByState(ItemType.Combo, ItemState.Selected); +} + +/** 获取选中元素 */ +export function getSelectedItems(graph: Graph): Item[] { + const selectedNodes = getSelectedNodes(graph); + const selectedEdges = getSelectedEdges(graph); + const selectedCombos = getSelectedCombos(graph); + return [...selectedNodes, ...selectedEdges, ...selectedCombos]; +} + +/** 清除选中状态 */ +export function clearSelectedState(graph: Graph, shouldUpdate: (item: Item) => boolean = () => true) { + executeBatch(graph, () => { + getSelectedItems(graph).forEach(item => { + if (shouldUpdate(item)) { + graph.setItemState(item, ItemState.Selected, false); + } + }); + }); +} + /** 获取高亮边线 */ export function getHighlightEdges(graph: Graph): Edge[] { return graph.findAllByState(ItemType.Edge, ItemState.HighLight); @@ -83,19 +107,23 @@ export function getHighlightEdges(graph: Graph): Edge[] { export function getGraphState(graph: Graph): GraphState { let graphState: GraphState = GraphState.MultiSelected; - const selectedNodes = getSelectedNodes(graph); - const selectedEdges = getSelectedEdges(graph); - - if (selectedNodes.length === 1 && !selectedEdges.length) { - graphState = GraphState.NodeSelected; - } - - if (selectedEdges.length === 1 && !selectedNodes.length) { - graphState = GraphState.EdgeSelected; - } - - if (!selectedNodes.length && !selectedEdges.length) { - graphState = GraphState.CanvasSelected; + const selectedItems = getSelectedItems(graph); + + if (selectedItems.length <= 1) { + switch (selectedItems[0] ? selectedItems[0].getType() : '') { + case ItemType.Node: + graphState = GraphState.NodeSelected; + break; + case ItemType.Edge: + graphState = GraphState.EdgeSelected; + break; + case ItemType.Combo: + graphState = GraphState.ComboSelected; + break; + default: + graphState = GraphState.CanvasSelected; + break; + } } return graphState; @@ -104,12 +132,7 @@ export function getGraphState(graph: Graph): GraphState { /** 设置选中元素 */ export function setSelectedItems(graph: Graph, items: Item[] | string[]) { executeBatch(graph, () => { - const selectedNodes = getSelectedNodes(graph); - const selectedEdges = getSelectedEdges(graph); - - [...selectedNodes, ...selectedEdges].forEach(node => { - graph.setItemState(node, ItemState.Selected, false); - }); + clearSelectedState(graph); items.forEach(item => { graph.setItemState(item, ItemState.Selected, true); @@ -121,20 +144,6 @@ export function setSelectedItems(graph: Graph, items: Item[] | string[]) { }); } -/** 清除选中状态 */ -export function clearSelectedState(graph: Graph, shouldUpdate: (item: Item) => boolean = () => true) { - const selectedNodes = getSelectedNodes(graph); - const selectedEdges = getSelectedEdges(graph); - - executeBatch(graph, () => { - [...selectedNodes, ...selectedEdges].forEach(item => { - if (shouldUpdate(item)) { - graph.setItemState(item, ItemState.Selected, false); - } - }); - }); -} - /** 获取回溯路径 - Flow */ export function getFlowRecallEdges(graph: Graph, node: Node, targetIds: string[] = [], edges: Edge[] = []) { const inEdges: Edge[] = node.getInEdges();