diff --git a/examples/advanced/scripts/ExampleGraph.js b/examples/advanced/scripts/ExampleGraph.js index f003479d..0ed88afd 100644 --- a/examples/advanced/scripts/ExampleGraph.js +++ b/examples/advanced/scripts/ExampleGraph.js @@ -1,13 +1,11 @@ import React, { PureComponent } from 'react'; -import Graph, { isEdge, removeElements, getOutgoers, MiniMap, Controls } from '../../../src'; +import Graph, { isEdge, removeElements, addEdge, getOutgoers, MiniMap, Controls } from '../../../src'; import SpecialNode from './SpecialNode'; import InputNode from './InputNode'; const onNodeDragStop = node => console.log('drag stop', node); -let edgeId = 0; -const getEdgeId = () => `edge__${edgeId++}`; class App extends PureComponent { constructor() { @@ -74,9 +72,6 @@ class App extends PureComponent { { id: 'e6-7', source: '6', target: '7', style: { stroke: '#FFCC00' }}, ] }; - - this.onElementClick = this.onElementClick.bind(this); - this.onConnect = this.onConnect.bind(this); } onLoad(graphInstance) { @@ -120,14 +115,13 @@ class App extends PureComponent { onElementsRemove(elementsToRemove) { this.setState(prevState => ({ - elements: removeElements(prevState.elements, elementsToRemove) + elements: removeElements(elementsToRemove, prevState.elements) })); } onConnect(params) { - console.log('connect', params); this.setState(prevState => ({ - elements: prevState.elements.concat({ id: getEdgeId(), ...params }) + elements: addEdge(params, prevState.elements) })); } @@ -135,9 +129,9 @@ class App extends PureComponent { return ( this.onElementClick(element)} onElementsRemove={elements => this.onElementsRemove(elements)} - onConnect={this.onConnect} + onConnect={params => this.onConnect(params)} onNodeDragStop={onNodeDragStop} style={{ width: '100%', height: '100%' }} onLoad={graphInstance => this.onLoad(graphInstance)} diff --git a/examples/basic/scripts/ExampleGraph.js b/examples/basic/scripts/ExampleGraph.js index 9b98b7bd..735bf849 100644 --- a/examples/basic/scripts/ExampleGraph.js +++ b/examples/basic/scripts/ExampleGraph.js @@ -1,12 +1,9 @@ import React, { PureComponent } from 'react'; -import Graph, { removeElements, getOutgoers } from '../../../src'; +import Graph, { removeElements, addEdge, getOutgoers } from '../../../src'; const onNodeDragStop = node => console.log('drag stop', node); -let edgeId = 0; -const getEdgeId = () => `edge__${edgeId++}`; - class App extends PureComponent { constructor() { super(); @@ -22,9 +19,6 @@ class App extends PureComponent { { id: 'e1-3', source: '1', target: '3' }, ] }; - - this.onElementClick = this.onElementClick.bind(this); - this.onConnect = this.onConnect.bind(this); } onLoad(graphInstance) { @@ -43,14 +37,14 @@ class App extends PureComponent { onElementsRemove(elementsToRemove) { this.setState(prevState => ({ - elements: removeElements(prevState.elements, elementsToRemove) + elements: removeElements(elementsToRemove, prevState.elements) })); } onConnect(params) { console.log('connect', params); this.setState(prevState => ({ - elements: prevState.elements.concat({ id: getEdgeId(), ...params }) + elements: addEdge(params, prevState.elements) })); } @@ -59,9 +53,9 @@ class App extends PureComponent { this.onLoad(graphInstance)} - onElementClick={this.onElementClick} + onElementClick={element => this.onElementClick(element)} onElementsRemove={elements => this.onElementsRemove(elements)} - onConnect={this.onConnect} + onConnect={params => this.onConnect(params)} onNodeDragStop={onNodeDragStop} style={{ width: '100%', height: '100%' }} showBackground={false} diff --git a/src/index.js b/src/index.js index 1a71539a..085859da 100644 --- a/src/index.js +++ b/src/index.js @@ -10,5 +10,6 @@ export { isNode, isEdge, removeElements, + addEdge, getOutgoers } from './utils/graph'; diff --git a/src/utils/graph.js b/src/utils/graph.js index a7427099..c6c4cd57 100644 --- a/src/utils/graph.js +++ b/src/utils/graph.js @@ -1,5 +1,7 @@ import { zoomIdentity } from 'd3-zoom'; + import store from '../store'; +import { isDefined } from './index'; export const isEdge = element => element.source && element.target; @@ -14,7 +16,7 @@ export const getOutgoers = (node, elements) => { return elements.filter(e => outgoerIds.includes(e.id)); }; -export const removeElements = (elements, elementsToRemove) => { +export const removeElements = (elementsToRemove, elements) => { const nodeIdsToRemove = elementsToRemove.map(n => n.id); return elements.filter(e => { @@ -26,6 +28,21 @@ export const removeElements = (elements, elementsToRemove) => { }); }; +function getEdgeId(params) { + return `reactflow__edge-${params.source}-${params.target}`; +} + +export const addEdge = (edgeParams, elements) => { + if (!edgeParams.source || !edgeParams.target) { + throw new Error('Can not create edge. An edge needs a source and a target'); + } + + return elements.concat({ + ...edgeParams, + id: isDefined(edgeParams.id) ? edgeParams.id : getEdgeId(edgeParams) + }); +} + const pointToRendererPoint = ({ x, y }, transform) => { const rendererX = (x - transform[0]) * (1 / [transform[2]]); const rendererY = (y - transform[1]) * (1 / [transform[2]]); diff --git a/src/utils/index.js b/src/utils/index.js index db8f54ec..2600fd4e 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1,5 +1,7 @@ export const isFunction = obj => !!(obj && obj.constructor && obj.call && obj.apply); +export const isDefined = obj => typeof obj !== 'undefined'; + export const inInputDOMNode = e => e && e.target && ['INPUT', 'SELECT', 'TEXTAREA'].includes(e.target.nodeName); export const getDimensions = (node = {}) => ({