G6.registerBehavior('click-add-node', {
// Set the events and the corresponding responsing function for this behavior
getEvents() {
// The event is canvas:click, the responsing function is onClick
return {
'canvas:click': 'onClick',
};
},
// Click event
onClick(ev) {
const self = this;
const graph = self.graph;
// Add a new node
graph.addItem('node', {
x: ev.canvasX,
y: ev.canvasY,
id: `node-${addedCount}`, // Generate the unique id
});
addedCount++;
},
});
G6.registerBehavior('click-add-edge', {
// Set the events and the corresponding responsing function for this behavior
getEvents() {
return {
'node:click': 'onClick', // The event is canvas:click, the responsing function is onClick
mousemove: 'onMousemove', // The event is mousemove, the responsing function is onMousemove
'edge:click': 'onEdgeClick', // The event is edge:click, the responsing function is onEdgeClick
};
},
// The responsing function for node:click defined in getEvents
onClick(ev) {
const self = this;
const node = ev.item;
const graph = self.graph;
// The position where the mouse clicks
const point = { x: ev.x, y: ev.y };
const model = node.getModel();
if (self.addingEdge && self.edge) {
graph.updateItem(self.edge, {
target: model.id,
});
self.edge = null;
self.addingEdge = false;
} else {
// Add anew edge, the end node is the current node user clicks
self.edge = graph.addItem('edge', {
source: model.id,
target: model.id,
});
self.addingEdge = true;
}
},
// The responsing function for mousemove defined in getEvents
onMousemove(ev) {
const self = this;
// The current position the mouse clicks
const point = { x: ev.x, y: ev.y };
if (self.addingEdge && self.edge) {
// Update the end node to the current node the mouse clicks
self.graph.updateItem(self.edge, {
target: point,
});
}
},
// The responsing function for edge:click defined in getEvents
onEdgeClick(ev) {
const self = this;
const currentEdge = ev.item;
if (self.addingEdge && self.edge === currentEdge) {
self.graph.removeItem(self.edge);
self.edge = null;
self.addingEdge = false;
}
},
});
完整示例:
let addedCount = 0;
// Register a custom behavior: add a node when user click the blank part of canvas
G6.registerBehavior("click-add-node", {
// Set the events and the corresponding responsing function for this behavior
getEvents() {
// The event is canvas:click, the responsing function is onClick
return {
"canvas:click": "onClick",
};
},
// Click event
onClick(ev: IG6GraphEvent) {
const self = this;
const graph = self.graph as Graph;
// Add a new node
graph.addItem("node", {
x: ev.canvasX,
y: ev.canvasY,
id: `node-${addedCount}`, // Generate the unique id
});
addedCount++;
},
});
// Register a custom behavior: click two end nodes to add an edge
G6.registerBehavior("click-add-edge", {
// Set the events and the corresponding responsing function for this behavior
getEvents() {
return {
"node:click": "onClick", // The event is canvas:click, the responsing function is onClick
mousemove: "onMousemove", // The event is mousemove, the responsing function is onMousemove
"edge:click": "onEdgeClick", // The event is edge:click, the responsing function is onEdgeClick
};
},
// The responsing function for node:click defined in getEvents
onClick(ev: IG6GraphEvent) {
const self = this;
const node = ev.item;
const graph = self.graph as Graph;
// The position where the mouse clicks
//const point = { x: ev.x, y: ev.y };
const model = node!.getModel();
if (self.addingEdge && self.edge) {
graph.updateItem(self.edge as IEdge, {
target: model.id,
});
self.edge = null;
self.addingEdge = false;
} else {
// Add anew edge, the end node is the current node user clicks
self.edge = graph.addItem("edge", {
source: model.id,
target: model.id,
});
self.addingEdge = true;
}
},
// The responsing function for mousemove defined in getEvents
onMousemove(ev: IG6GraphEvent) {
const self = this;
// The current position the mouse clicks
const graph = self.graph as Graph;
const point = { x: ev.x, y: ev.y };
if (self.addingEdge && self.edge) {
// Update the end node to the current node the mouse clicks
graph.updateItem(self.edge as IEdge, {
target: point,
});
}
}, // The responsing function for edge:click defined in getEvents
onEdgeClick(ev: IG6GraphEvent) {
const self = this;
const currentEdge = ev.item;
const graph = self.graph as Graph;
if (self.addingEdge && self.edge === currentEdge) {
graph.removeItem(self.edge as IEdge);
self.edge = null;
self.addingEdge = false;
}
},
});
// Initial data
const data = {
nodes: [
{
id: "node1",
x: 100,
y: 200,
},
{
id: "node2",
x: 300,
y: 200,
},
{
id: "node3",
x: 300,
y: 300,
},
],
edges: [
{
id: "edge1",
target: "node2",
source: "node1",
},
],
};
let graph: Graph;
function App() {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
graph = new G6.Graph({
container: ref.current!,
width: 800,
height: 800,
// The sets of behavior modes
modes: {
// Defualt mode
default: ["drag-node", "click-select"],
// Adding node mode
addNode: ["click-add-node", "click-select"],
// Adding edge mode
addEdge: ["click-add-edge", "click-select"],
},
// The node styles in different states
nodeStateStyles: {
// The node styles in selected state
selected: {
stroke: "#666",
lineWidth: 2,
fill: "steelblue",
},
},
});
graph.data(data);
graph.render();
}, []);
return (
<div>
<button onClick={() => graph.setMode("addNode")}>添加节点</button>
<button onClick={() => graph.setMode("addEdge")}>添加边</button>
<button onClick={() => graph.setMode("default")}>默认模式</button>
<div ref={ref}></div>
</div>
);
}
export default App;
onClick(ev: IG6GraphEvent) {
const self = this;
const graph = self.graph as Graph;
// Add a new node
const { x, y } = graph.getPointByClient(ev.clientX, ev.clientY);
graph.addItem("node", {
x: x,
y: y,
id: `node-${addedCount}`, // Generate the unique id
});
addedCount++;
},
import React, { useRef, useEffect } from "react";
import G6, { Graph } from "@antv/g6";
import { IG6GraphEvent } from "@antv/g6/lib/types";
import { IEdge, INode } from "@antv/g6/lib/interface/item";
let addedCount = 0;
// Register a custom behavior: add a node when user click the blank part of canvas
G6.registerBehavior("click-add-node", {
// Set the events and the corresponding responsing function for this behavior
getEvents() {
// The event is canvas:click, the responsing function is onClick
return {
"canvas:click": "onClick",
};
},
// Click event
onClick(ev: IG6GraphEvent) {
const self = this;
const graph = self.graph as Graph;
// Add a new node
const { x, y } = graph.getPointByClient(ev.clientX, ev.clientY);
graph.addItem("node", {
x: x,
y: y,
id: `node-${addedCount}`, // Generate the unique id
});
addedCount++;
},
});
// Register a custom behavior: click two end nodes to add an edge
G6.registerBehavior("click-add-edge", {
// Set the events and the corresponding responsing function for this behavior
getEvents() {
return {
"node:click": "onClick", // The event is canvas:click, the responsing function is onClick
mousemove: "onMousemove", // The event is mousemove, the responsing function is onMousemove
"edge:click": "onEdgeClick", // The event is edge:click, the responsing function is onEdgeClick
};
},
// The responsing function for node:click defined in getEvents
onClick(ev: IG6GraphEvent) {
const self = this;
const node = ev.item;
const graph = self.graph as Graph;
// The position where the mouse clicks
//const point = { x: ev.x, y: ev.y };
const model = node!.getModel();
if (self.addingEdge && self.edge) {
graph.updateItem(self.edge as IEdge, {
target: model.id,
});
self.edge = null;
self.addingEdge = false;
} else {
// Add anew edge, the end node is the current node user clicks
self.edge = graph.addItem("edge", {
source: model.id,
target: model.id,
});
self.addingEdge = true;
}
},
// The responsing function for mousemove defined in getEvents
onMousemove(ev: IG6GraphEvent) {
const self = this;
// The current position the mouse clicks
const graph = self.graph as Graph;
const point = { x: ev.x, y: ev.y };
if (self.addingEdge && self.edge) {
// Update the end node to the current node the mouse clicks
graph.updateItem(self.edge as IEdge, {
target: point,
});
}
}, // The responsing function for edge:click defined in getEvents
onEdgeClick(ev: IG6GraphEvent) {
const self = this;
const currentEdge = ev.item;
const graph = self.graph as Graph;
if (self.addingEdge && self.edge === currentEdge) {
graph.removeItem(self.edge as IEdge);
self.edge = null;
self.addingEdge = false;
}
},
});
G6.registerBehavior("del-node-and-edge", {
// Set the events and the corresponding responsing function for this behavior
getEvents() {
return {
"node:click": "onClick", // The event is canvas:click, the responsing function is onClick
"edge:click": "onEdgeClick", // The event is edge:click, the responsing function is onEdgeClick
};
},
// The responsing function for node:click defined in getEvents
onClick(ev: IG6GraphEvent) {
const self = this;
const node = ev.item;
const graph = self.graph as Graph;
// const itemController = graph.get("itemController");
// itemController.removeItem(node);
graph.removeItem(node as INode);
},
onEdgeClick(ev: IG6GraphEvent) {
const self = this;
const currentEdge = ev.item;
const graph = self.graph as Graph;
graph.removeItem(currentEdge as IEdge);
},
});
// Initial data
const data = {
nodes: [
{
id: "node1",
x: 100,
y: 200,
},
{
id: "node2",
x: 300,
y: 200,
},
{
id: "node3",
x: 300,
y: 300,
},
],
edges: [
{
id: "edge1",
target: "node2",
source: "node1",
},
],
};
let graph: Graph;
function App() {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
graph = new G6.Graph({
container: ref.current!,
width: 800,
height: 800,
// The sets of behavior modes
modes: {
// Defualt mode
default: [
"drag-node",
"click-select",
"drag-canvas",
"zoom-canvas",
],
// Adding node mode
addNode: ["click-add-node", "click-select"],
// Adding edge mode
addEdge: ["click-add-edge", "click-select"],
del: ["del-node-and-edge"],
},
// The node styles in different states
nodeStateStyles: {
// The node styles in selected state
selected: {
stroke: "#666",
lineWidth: 2,
fill: "steelblue",
},
},
});
graph.data(data);
graph.render();
}, []);
return (
<div>
<button onClick={() => graph.setMode("addNode")}>添加节点</button>
<button onClick={() => graph.setMode("addEdge")}>添加边</button>
<button onClick={() => graph.setMode("default")}>默认模式</button>
<button onClick={() => graph.setMode("del")}>删除模式</button>
<div ref={ref}></div>
</div>
);
}
export default App;