问题描述
我有单独的按钮来添加节点和添加边。当我单击添加边缘按钮(名称:流)时,边缘手柄变为活动状态。使用 eh.enable() 函数。当我使用 eh.disable();eh.hide() 函数开始绘制箭头时,我在侧手柄选项中的停止函数中添加了该函数,或者当箭头绘制完成时,它会关闭。
我还想在单击添加节点按钮时停止边缘手柄。我在 stopAddEdge() 函数中包含的 eh.disable();eh.hide() 函数没有提供这个。按下按钮时如何禁用边缘手柄。我应该在哪里以及如何使用 eh.disable() 函数?
我的项目由两个部分组成,
MyParentComponent.jsx;
import React,{ useState,useEffect } from 'react';
import { DownCircleOutlined,SyncOutlined,MinusCircleOutlined,ArrowRightOutlined } from '@ant-design/icons';
import { Button } from 'antd';
import 'antd/dist/antd.css';
import NewComponent from './NewComponent';
const MyParentComponent = () => {
const [nodeType,setNodeType] = useState("");
const [flowModeOn,setFlowModeOn] = useState(false);
useEffect(() => {
},[]);
const handleEvent = (e) => {
console.log(e.currentTarget);
console.log(e.currentTarget.value);
const btnValue = e.currentTarget.value;
setNodeType(btnValue);
setFlowModeOn(false);
};
const stopAddNode = (params) => {
setNodeType(params);
}
const flowModeEvent = () => {
setFlowModeOn(true);
setNodeType("");
};
const ChangeFlowMode = (params) => {
setFlowModeOn(params);
};
return (
<div>
<div style={{ textAlign: "center" }}>
<h1> My Cytoscape App </h1>
<div>
<Button value="startNode" shape="round" icon={<DownCircleOutlined />} size='large' onClick={handleEvent}>Start</Button>
<Button value="activity" shape="round" icon={<SyncOutlined />} size='large' onClick={handleEvent}>Activity</Button>
<Button value="endNode" shape="round" icon={<MinusCircleOutlined />} size='large' onClick={handleEvent}>End</Button>
<Button value="edge" shape="round" icon={<ArrowRightOutlined />} size='large' onClick={() => flowModeEvent()}>Flow</Button>
</div>
<h3>Selected Items: {nodeType}</h3>
</div>
<NewComponent nodeType={nodeType} stopAddNode={stopAddNode} flowModeOn={flowModeOn} ChangeFlowMode={ChangeFlowMode} />
</div>
);
};
export default MyParentComponent;
NewComponent.jsx;
import React,{ useEffect,useState,useRef } from 'react';
import CytoscapeComponent from 'react-cytoscapejs';
import Cytoscape from 'cytoscape';
import edgehandles from 'cytoscape-edgehandles';
import contextMenus from 'cytoscape-context-menus';
import 'cytoscape-context-menus/cytoscape-context-menus.css';
Cytoscape.use(edgehandles);
Cytoscape.use(contextMenus);
const NewComponent = (props) => {
const cyRef = useRef();
const [controlStartState,setControlStartState] = useState(-1);
const [controlEndState,setControlEndState] = useState(-1);
const [nodeArray,setNodeArray] = useState([]);
const [currentNodeArray,setCurrentNodeArray] = useState([]);
const [ehStoped,setEhStoped] = useState(true)
let eh;
useEffect(() => {
eh = cyRef.current.edgehandles(edgehandlesOptions);
eh.disable();
});
useEffect(() => {
cyRef.current.contextMenus(contextMenuOptions);
},[]);
useEffect(() => {
console.log("props.flowModeOn: " + props.flowModeOn);
console.log("ehStoped: " + ehStoped);
if (props.flowModeOn === true && ehStoped ===true) {
if (cyRef.current) {
console.log("add edgein hemen üstü");
addEdge();
}
}
else if (props.flowModeOn === false) {
if (cyRef.current) {
console.log("stopAddEdgein hemen üstü");
stopAddEdge();
}
}
},[props.flowModeOn]);
const edgehandlesOptions = {
preview: true,// whether to show added edges preview before releasing selection
hoverDelay: 150,// time spent hovering over a target node before it is considered selected
handleNodes: 'node',// selector/filter function for whether edges can be made from a given node
snap: false,// when enabled,the edge can be drawn by just moving close to a target node
snapThreshold: 50,// the target node must be less than or equal to this many pixels away from the cursor/finger
snapFrequency: 15,// the number of times per second (Hz) that snap checks done (lower is less expensive)
noEdgeEventsInDraw: false,// set events:no to edges during draws,prevents mouSEOuts on compounds
disablebrowserGestures: true,// during an edge drawing gesture,disable browser gestures such as two-finger trackpad swipe and pinch-to-zoom
handlePosition: function (node) {
return 'middle top'; // sets the position of the handle in the format of "X-AXIS Y-AXIS" such as "left top","middle top"
},handleInDrawMode: false,// whether to show the handle in draw mode
edgeType: function (sourceNode,targetNode) {
// can return 'flat' for flat edges between nodes or 'node' for intermediate node between them
// returning null/undefined means an edge can't be added between the two nodes
return 'flat';
},loopAllowed: function (node) {
// for the specified node,return whether edges from itself to itself are allowed
return false;
},nodeLoopOffset: -50,// offset for edgeType: 'node' loops
nodeParams: function (sourceNode,targetNode) {
// for edges between the specified source and target
// return element object to be passed to cy.add() for intermediary node
return {};
},edgeParams: function (sourceNode,targetNode,i) {
// for edges between the specified source and target
// return element object to be passed to cy.add() for edge
// NB: i indicates edge index in case of edgeType: 'node'
return {};
},ghostEdgeParams: function () {
// return element object to be passed to cy.add() for the ghost edge
// (default classes are always added for you)
return {};
},show: function (sourceNode) {
// fired when handle is shown
},hide: function (sourceNode) {
// fired when the handle is hidden
console.log("options içindeki HİDE fonksiyonu");
},start: function (sourceNode) {
// fired when edgehandles interaction starts (drag on handle)
},complete: function (sourceNode,addedEles) {
// fired when edgehandles is done and elements are added
// console.log("addedEles: ");
// console.log(addedEles);
// cyRef.current.remove(addedEles);
},stop: function (sourceNode) {
// fired when edgehandles interaction is stopped (either complete with added edges or incomplete)
eh.disable();
eh.hide();
console.log("options içindeki stop fonksiyonu");
props.ChangeFlowMode(false);
setEhStoped(true);
console.log("ehStoped: " + ehStoped);
},cancel: function (sourceNode,cancelledTargets) {
// fired when edgehandles are cancelled (incomplete gesture)
console.log("options içindeki cancel fonksiyonu");
},hoverover: function (sourceNode,targetNode) {
// fired when a target is hovered
},hoverout: function (sourceNode,targetNode) {
// fired when a target isn't hovered anymore
},previewon: function (sourceNode,previewEles) {
console.log("previewon qqqqq");
// fired when preview is shown
},previewoff: function (sourceNode,previewEles) {
// fired when preview is hidden
console.log("previewoff");
},drawon: function () {
// fired when draw mode enabled
console.log("drawon");
},drawoff: function () {
// fired when draw mode disabled
console.log("options içindeki drawoff fonksiyonu");
}
};
const addEdge = () => {
console.log("1 addEdge ehStoped: " + ehStoped);
console.log("add adge enable");
// @ts-ignore
eh.enable();
setEhStoped(false);
console.log("2 addEdge ehStoped: " + ehStoped);
}
const stopAddEdge = () => {
console.log("stop Add edge fonksiyonu");
// eh.destroy();
// eh.stop();
// eh.disableDrawMode()
eh.disable();
eh.hide();
// props.ChangeFlowMode(false);
}
const elements = [
{ data: { id: "one",label: "Comp1",type: 'comp' },position: { x: 20,y: 200 } },// { data: { id: "two",label: "Node 2" },position: { x: 120,// { data: { id: "three",label: "Node 3" },position: { x: 220,// { data: { id: "four",label: "Node 4" },position: { x: 320,// { data: { source: "one",target: "two",label: "Edge from Node1 to Node2" } }
];
const styleSheet = [
{
selector: 'node',style: {
// 'background-color': '#000','color': '#1e2829','label': 'data(label)',//opacity: 0.3
'width': '80','height': '80','text-wrap': 'wrap','text-valign': 'center','text-halign': 'center','border-width': '1px','border-color': 'black'
}
},{
selector: 'node[type="comp"]',style: {
'background-color': '#822',}
},{
selector: ".startNode",style: {
backgroundColor: "green",{
selector: ".rectangleNode",style: {
'shape': 'rectangle','width': 250,'height': 150,'content': 'data(label)',{
selector: ".endNode",style: {
backgroundColor: "#aa0000",{
selector: 'edge',style: {
'width': 2,'line-color': '#ccc','target-arrow-color': '#ccc','target-arrow-shape': 'triangle','curve-style': 'bezier',// some style for the Edge Handles !!!
{
selector: '.eh-handle',style: {
// 'background-color': '#1abc9c','background-color': 'red','width': 12,'height': 12,'shape': 'barrel','overlay-opacity': 0,'border-width': 12,// makes the handle easier to hit
'border-opacity': 0
}
},{
selector: '.eh-hover',css: {
'background-color': 'red'
}
},{
selector: '.eh-source',//ok tamamlanmadan önceki kaynak görüntüsü
css: {
'border-width': 2,'border-color': 'red'
}
},{
selector: '.eh-target',//ok tamamlanmadan önceki hedef görüntüsü
css: {
'border-width': 2,{
selector: '.eh-preview,.eh-ghost-edge',css: {
'line-color': 'red','target-arrow-color': 'red','source-arrow-color': 'red'
}
},{
selector: 'node:selected',style:
{
'background-color': '#ffc90e','border-color': '#ffc90e',/*#f1c40f'*/
}
},{
selector: 'edge:selected',style:
{
'width': 3,'line-color': '#ffc90e','target-arrow-color': '#ffc90e'
}
},];
const contextMenuOptions = {
evtType: 'cxttap',menuItems: [
{
id: 'add edge',content: 'add edge',tooltipText: 'add edge',selector: 'node',onClickFunction: function (event) {
console.log("label: " + event.target.data().label);
console.log("id: " + event.target.data().id);
// eh.start(cyRef.current.$('node:selected'));
},hasTrailingDivider: true
},{
id: 'edit',content: 'edit',tooltipText: 'edit with text area content',selector: 'node,edge',onClickFunction: function (event) {
console.log("ID: " + event.target.data().label);
},{
id: 'remove',content: 'remove',tooltipText: 'remove',// image: { src: "assets/remove.svg",width: 12,height: 12,x: 6,y: 4 },onClickFunction: function (event) {
console.log("ID: " + event.target.data().id);
var target = event.target || event.cyTarget;
var removed = target.remove();
console.log(removed);
},hasTrailingDivider: true
}
],submenuIndicator: { src: 'assets/submenu-indicator-default.svg',height: 12 }
};
var tempCurrentNodeArray = [];
var controlStart,controlEnd = null;
const mousedownEvent = () => {
cyRef.current.nodes().unlock();
var typeIds = cyRef.current.elements('node');
for (var i = 0; i < typeIds.length; i++) {
tempCurrentNodeArray.push(typeIds[i].data().label);
}
setCurrentNodeArray(tempCurrentNodeArray);
controlStart = tempCurrentNodeArray.indexOf("startNode");
setControlStartState(controlStart);
controlEnd = tempCurrentNodeArray.indexOf("endNode");
setControlEndState(controlEnd);
}
const addNode = (evt) => {
var evtTarget = evt.target;
if (evtTarget === cyRef.current) {
if (props.nodeType == "startNode") {
if (controlStartState == -1) {
// console.log('tap on background');
cyRef.current.add({
group: 'nodes',data: {
weight: 175,label: props.nodeType,},locked: false,classes: 'startNode',position: {
x: evt.position.x,y: evt.position.y
},style: { 'shape': 'ellipse' }
});
setNodeArray([...nodeArray,props.nodeType])
props.stopAddNode("");
} else {
alert("Start Node exist");
}
} else if (props.nodeType == "endNode") {
if (controlEndState == -1) {
var evtTarget = evt.target;
if (evtTarget === cyRef.current) {
// console.log('tap on background');
cyRef.current.add({
group: 'nodes',data: {
weight: 5,classes: 'endNode',position: {
x: evt.position.x,y: evt.position.y
},style: { 'shape': 'ellipse' }
});
setNodeArray([...nodeArray,props.nodeType])
}
props.stopAddNode("");
} else {
alert("End Node exist");
}
} else if (props.nodeType == "activity") {
var evtTarget = evt.target;
if (evtTarget === cyRef.current) {
// console.log('tap on background');
cyRef.current.add({
group: 'nodes',data: {
weight: 5,classes: 'rectangleNode',style: {
// 'shape': 'barrel',// "width": "80",}
});
setNodeArray([...nodeArray,props.nodeType])
}
props.stopAddNode("");
}
} else {
// console.log('tap on some element');
}
}
return (
<div>
<CytoscapeComponent
elements={elements}
// layout={layout}
cy={cy => {
cyRef.current = cy;
cyRef.current.unbind("tap"); // unbind event to prevent possible mishaps with firing too many events
cyRef.current.unbind('mousedown'); // unbind event to prevent the event to fire
cyRef.current.bind("tap",addNode);
cyRef.current.bind('mousedown',mousedownEvent);
}}
stylesheet={styleSheet}
style={{
width: "100%",height: "83vh",border: '1px solid black'
}}
/>
</div>
);
};
export default NewComponent;
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)