diff --git a/README.md b/README.md index 802887c5..f6436671 100644 --- a/README.md +++ b/README.md @@ -581,6 +581,12 @@ Returns all direct child nodes of the passed node. `getOutgoers = (node: Node, elements: Elements): Node[]` +### getIncomers + +Returns all direct incoming nodes of the passed node. + +`getOutgoers = (node: Node, elements: Elements): Node[]` + ### getConnectedEdges Returns all edges that are connected to the passed nodes. diff --git a/cypress/integration/flow/graph-utils.spec.js b/cypress/integration/flow/graph-utils.spec.js index 128f3e6d..00e355a7 100644 --- a/cypress/integration/flow/graph-utils.spec.js +++ b/cypress/integration/flow/graph-utils.spec.js @@ -1,4 +1,4 @@ -import { isNode, isEdge, getOutgoers, removeElements, addEdge } from '../../../src/utils/graph.ts'; +import { isNode, isEdge, getOutgoers, getIncomers, removeElements, addEdge } from '../../../src/utils/graph.ts'; const nodes = [ { id: '1', type: 'input', data: { label: 'Node 1' }, position: { x: 250, y: 5 } }, @@ -10,6 +10,7 @@ const nodes = [ const edges = [ { id: 'e1-2', source: '1', target: '2', animated: true }, { id: 'e1-3', source: '1', target: '3' }, + { id: 'e2-3', source: '2', target: '3' }, ]; const elements = [...nodes, ...edges]; @@ -29,10 +30,18 @@ describe('Graph Utils Testing', () => { const outgoers = getOutgoers(nodes[0], elements); expect(outgoers.length).to.be.equal(2); - const noOutgoers = getOutgoers(nodes[1], elements); + const noOutgoers = getOutgoers(nodes[2], elements); expect(noOutgoers.length).to.be.equal(0); }); + it('tests getIncomers function', () => { + const incomers = getIncomers(nodes[2], elements); + expect(incomers.length).to.be.equal(2); + + const noIncomers = getIncomers(nodes[0], elements); + expect(noIncomers.length).to.be.equal(0); + }); + describe('tests addEdge function', () => { it('adds edge', () => { const newEdge = { source: '2', target: '3' }; diff --git a/src/utils/graph.ts b/src/utils/graph.ts index 1d104749..6f341ac9 100644 --- a/src/utils/graph.ts +++ b/src/utils/graph.ts @@ -1,6 +1,7 @@ +import { Store } from 'easy-peasy'; + import store, { StoreModel } from '../store'; import { ElementId, Node, Edge, Elements, Transform, XYPosition, Rect, FitViewParams, Box, Connection } from '../types'; -import { Store } from 'easy-peasy'; export const isEdge = (element: Node | Connection | Edge): element is Edge => 'id' in element && 'source' in element && 'target' in element; @@ -17,6 +18,15 @@ export const getOutgoers = (node: Node, elements: Elements): Node[] => { return elements.filter((e) => outgoerIds.includes(e.id)) as Node[]; }; +export const getIncomers = (node: Node, elements: Elements): Node[] => { + if (!isNode(node)) { + return []; + } + + const incomersIds = elements.filter((e) => isEdge(e) && e.target === node.id).map((e) => (e as Edge).source); + return elements.filter((e) => incomersIds.includes(e.id)) as Node[]; +}; + export const removeElements = (elementsToRemove: Elements, elements: Elements): Elements => { const nodeIdsToRemove = elementsToRemove.map((n) => n.id);