tisoap / react-flow-smart-edge Goto Github PK
View Code? Open in Web Editor NEWCustom Edge for React Flow that never intersects with other nodes
Home Page: https://tisoap.github.io/react-flow-smart-edge/
License: MIT License
Custom Edge for React Flow that never intersects with other nodes
Home Page: https://tisoap.github.io/react-flow-smart-edge/
License: MIT License
If you have something like:
{ id: 'e4-5', source: '4', target: '5', arrowHeadType: 'arrowclosed', label: 'label e-4-5', }, { id: 'e5-4', source: '5', target: '4', type: 'smoothstep', label: 'label e-5-4' },
they will look overlapped.
Me and @antipasvasil are collogues and are working on the Beta version. There is a problem when 2 nodes are close to each other - the edge between them goes to a fixed location(at (0, 0) coordinates.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
No matter how close any nodes that are connected are getting close the connection should remain between them and not disappear
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
OS: Windows 10, 11
Browser Chrome, Firefox
Hey @tisoap,
I am going to implement SmartStetpEdge with( importing {SmartStepEdge} from '@tisoap/react-flow-smart-edge') Button but I didn't see any methods like getBezierPath, getSmoothStepPath
Could you please help me on that
Hey,
First of all, thanks for this library!!!! it is huge help for me :).
I'm looking for equivalent for getBezierPath/getSimpleBezierPath hooks of react-flow-renderer when creating custom edges.
https://reactflow.dev/docs/examples/edges/
there is a way to implement the smart edge functionality in this case?
thanks!!!
Is your feature request related to a problem? Please describe.
Hello @tisoap we are having the following situation when using SmartEdge with GridSnapping
we are having custome grid snaping position and when we connect a parent node to three child nodes at some point the connection gets broken and it's not always a straight line.
My question is, is there a way always to be sure to make the connection straight when using StepEdge, can you suggest a fix if you have ever come across such a problem.
The code for what we use is as follows for the gird snapping and smartEdge:
export const snapGridValue: SnapGridValueProps = { snapGrid: [90, 60], snapToGrid: true, backgroundGap: [90, 60], sizeCrossDots: 40, backgroundGridColor: '#e1e1e1', }
const getSmartEdgeResponse = getSmartEdge({ sourcePosition, targetPosition, sourceX, sourceY, targetX, targetY, nodes: updatedNodes, options: { drawEdge: svgDrawStraightLinePath, generatePath: pathfindingJumpPointNoDiagonal, }, })
https://codesandbox.io/s/trusting-rubin-nus8rh
Add three nodes
Connect them to the parent node and spred them one to another
and observe the behavior of the connection line.
Connection line should be straight after the first step edge
No response
We have used this library in our application for connecting two edges. Theres's an issue that we have noticed that the edge labels are getting overlapped one over the other as we have lot of nodes connecting each other.
https://codesandbox.io/s/edge-overlapping-32omg0?file=/src/Flow.js
Go to the code sandbox, we can see the edge labels getting overlapped on each other.
As a user, we would like the edges not getting overlapped and should be drawn in such a way that both the labels should be displayed properly.
Is there any way we can achieve this by providing or customising the props, that also would be much helpful for us.
No response
Nice work!
I was wondering if there was a way to make the edges squared off instead of the non-uniform curves that it currently draws.
smart edge don't show the edge label, thats cool if there is some basic support.
The edge is not updated while dragging the node. It only updates when you release the node.
im facing an issue while using the custom edge example from the docs,
The connection of edges can be made within the sub-flow or in between another group or a node from outside of the group.
here is my custom edge component
`import { useNodes, BezierEdge } from 'reactflow';
import { getSmartEdge, svgDrawStraightLinePath, pathfindingJumpPointNoDiagonal } from '@tisoap/react-flow-smart-edge';
import { AStarFinder, JumpPointFinder, Util, DiagonalMovement } from 'pathfinding';
export function SmartEdgeWithSubFlow(props: any) {
const { id, sourcePosition, targetPosition, sourceX, sourceY, targetX, targetY, style, markerStart, markerEnd } =
props;
const nodes = useNodes();
console.log('nodes :>> ', nodes);
const getSmartEdgeResponse = getSmartEdge({
sourcePosition,
targetPosition,
sourceX,
sourceY,
targetX,
targetY,
nodes,
options: {
drawEdge: svgDrawStraightLinePath,
generatePath: (grid, start, end) => {
try {
// FIXME: The "pathfinding" module doe not have proper typings.
// @ts-ignore
const finder = new JumpPointFinder({
diagonalMovement: DiagonalMovement.Never,
});
console.log('grid :>> ', grid);
console.log('finder :>> ', finder);
console.log('start :>> ', start);
console.log('end :>> ', end);
const fullPath = finder.findPath(start.x, start.y, end.x, end.y, grid);
const smoothedPath = fullPath;
if (fullPath.length === 0 || smoothedPath.length === 0) return null;
console.log('fullPath :>> ', fullPath);
console.log('smoothedPath :>> ', smoothedPath);
return { fullPath, smoothedPath };
} catch {
return null;
}
},
gridRatio: 2,
nodePadding: 20,
},
});
// If the value returned is null, it means "getSmartEdge" was unable to find
// a valid path, and you should do something else instead
// console.log('getSmartEdgeResponse :>> ', getSmartEdgeResponse);
if (getSmartEdgeResponse === null) {
console.log('null :>> ', null);
return <BezierEdge {...props} />;
}
const { edgeCenterX, edgeCenterY, svgPathString } = getSmartEdgeResponse;
return (
<>
<path
style={style}
className="react-flow__edge-path"
d={svgPathString}
markerEnd={markerEnd}
markerStart={markerStart}
/>
</>
);
}
`
My findings and requirements:
It would be great if you can help me out on this one
https://github.com/tisoap/react-flow-smart-edge#custom-smart-edges
Use a reactflow boiler plate
using this component as your edgeType
`import { useNodes, BezierEdge } from 'reactflow';
import { getSmartEdge, svgDrawStraightLinePath, pathfindingJumpPointNoDiagonal } from '@tisoap/react-flow-smart-edge';
import { AStarFinder, JumpPointFinder, Util, DiagonalMovement } from 'pathfinding';
export function SmartEdgeWithSubFlow(props: any) {
const { id, sourcePosition, targetPosition, sourceX, sourceY, targetX, targetY, style, markerStart, markerEnd } =
props;
const nodes = useNodes();
console.log('nodes :>> ', nodes);
const getSmartEdgeResponse = getSmartEdge({
sourcePosition,
targetPosition,
sourceX,
sourceY,
targetX,
targetY,
nodes,
options: {
drawEdge: svgDrawStraightLinePath,
generatePath: (grid, start, end) => {
try {
// FIXME: The "pathfinding" module doe not have proper typings.
// @ts-ignore
const finder = new JumpPointFinder({
diagonalMovement: DiagonalMovement.Never,
});
console.log('grid :>> ', grid);
console.log('finder :>> ', finder);
console.log('start :>> ', start);
console.log('end :>> ', end);
const fullPath = finder.findPath(start.x, start.y, end.x, end.y, grid);
const smoothedPath = fullPath;
if (fullPath.length === 0 || smoothedPath.length === 0) return null;
console.log('fullPath :>> ', fullPath);
console.log('smoothedPath :>> ', smoothedPath);
return { fullPath, smoothedPath };
} catch {
return null;
}
},
gridRatio: 2,
nodePadding: 20,
},
});
// If the value returned is null, it means "getSmartEdge" was unable to find
// a valid path, and you should do something else instead
// console.log('getSmartEdgeResponse :>> ', getSmartEdgeResponse);
if (getSmartEdgeResponse === null) {
console.log('null :>> ', null);
return <BezierEdge {...props} />;
}
const { edgeCenterX, edgeCenterY, svgPathString } = getSmartEdgeResponse;
return (
<>
</>
);
}
`
make connections between sub-flows and stand alone nodes, connections between nodes within the subflows like in the 2 images
No response
No response
Hello @tisoap,
How can I increase the height of SmartStepEdge of Source Point while taking a turn
Please give me suggestions
Thanks
I've been approved for GitHub Sponsors! ๐ฅณ๐
So I need to updates the repository's .github/FUNDING.yml
file to include the GitHub sponsor option, together with a badge on the project's README
First of all, I thank you for your great work.
The issue is drawing edges in subflows is wrong. In the below figures parentNode
of the smaller nodes is the WHILE node.
Expected behaviour:
It should be drawn like this for all positions inside the parent node.
Actual Result:
After moving a little bit on one of the nodes, the edge was drawn wrong.
Maybe something similar to #28 can solve this.
It was mentioned: "This package is only compatible with version 10 or newer of React Flow Edge."
The library react-flow-smart-edge looking for old dependency of react-flow : "react-flow-renderer" but it should be reactflow
So, what can be done about it?
Diagram freezes when using latest version i.e. 2.0.0 with large data of nodes and edges
On previous version of ReactFlow v10 whenever you start dragging new connection (Edge) to connect towards a new node the props that were coming and that were needed for were sourceX sourceY and targetX targetY everything was working as it should be, while as after updating to ReactFlow v11 and SmartEdge v3.0 when you start to create a connection the line is disappearing and you can't see it until you connect it, and the props that are specified are missing you got an error as well because of that.
Minimal Example
Share an URL with a minimal example on CodeSandbox or a minimal GitHub repository where the error happens. Reported bugs without this link will not be worked on!
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The connection should be visible from the begging of the dragging and props shouldn't be missing
Actual behavior
The connection is disappearing and the props are missing
Desktop (please complete the following information):
Screenshots and Videos
React flow v10 SmartEdge v2.0.0
https://user-images.githubusercontent.com/52380770/199692811-140fe4b3-1109-406f-88e1-b3ecb8e4cc76.mp4
React flow v11 SmartEdge v3.0.0 beta
https://user-images.githubusercontent.com/52380770/199693387-30f6b75e-ab72-4b0a-8083-ab9b64134d8e.mp4
@bcakmakoglu @tisoap when I use smart step edge from here:
@tisoap/react-flow-smart-edge
the custom edge markers get misaligned when i try to change the node layouts why is this happening ? do we have any solutions around this.
please see the gif shared below:
Hello @tisoap we are having the following situation when using SmartEdge with GridSnapping
we are having custome grid snaping position and when we connect a parent node to three child nodes at some point the connection gets broken and it's not always a straight line.
My question is, is there a way always to be sure to make the connection straight when using StepEdge, can you suggest a fix if you have ever come across such a problem.
The code for what we use is as follows for the gird snapping and smartEdge:
export const snapGridValue: SnapGridValueProps = { snapGrid: [90, 60], snapToGrid: true, backgroundGap: [90, 60], sizeCrossDots: 40, backgroundGridColor: '#e1e1e1', }
const getSmartEdgeResponse = getSmartEdge({ sourcePosition, targetPosition, sourceX, sourceY, targetX, targetY, nodes: updatedNodes, options: { drawEdge: svgDrawStraightLinePath, generatePath: pathfindingJumpPointNoDiagonal, }, })
We have been thinking that we might need to create a custom function for svgDrawStraightLinePath if there is no other way.
Other way is to have a custom implementation for a position algorithm because in order for the nodes to always stayed at some position that will not allow for the connections to become broken, but there is a lot of different cases and there always might be some discrepancies
Here is an image of the issue that we are tying to solve.
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '@tisoap/[email protected]',
npm WARN EBADENGINE required: { node: '>=16', npm: '^8.0.0' },
npm WARN EBADENGINE current: { node: 'v18.17.1', npm: '9.6.7' }
npm WARN EBADENGINE }
n/a
nvm use "lts/*"
npm install @tisoap/react-flow-smart-edge
should not warn
No response
node v18
deps in main already mention node 18, just need to publish
Please add SmoothStepPath
I want Smooth Step Path edges ๐
No alternative
No response
In NextJS 12.1.0, I used React Flow v10 with SmartEdge v0.5.0, and tried to import like your document
import ReactFlow, {
addEdge,
Background,
useNodesState,
useEdgesState,
MiniMap,
Controls,
Node,
} from "react-flow-renderer";
import { SmartEdge, SmartEdgeProvider } from "@tisoap/react-flow-smart-edge";
//.......................
const edgeTypes = {
smart: SmartEdge,
};
//.......................
const WorkflowContainer = () => {
//..........................
return (
<SmartEdgeProvider options={{ debounceTime: 300 }}>
<ReactFlow
className="react-flow-subflows-example"
nodes={nodes}
edges={edges}
onNodeMouseEnter={(
event: MouseEvent<Element, globalThis.MouseEvent>,
node: Node<any>
) => {
handleNodeMouseEnter(event, node);
}}
// onNodeDragStop
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
nodeTypes={nodeTypes}
edgeTypes={edgeTypes}
// onConnect={onConnect}
fitView
>
<MiniMap />
<Controls />
<Background />
</ReactFlow>
</SmartEdgeProvider>
);
};
export default WorkflowContainer;
But the browser showed the error:
Error: require() of ES Module D:\digi-curriculum\digi-curriculum-frontend\node_modules\react-flow-renderer\dist\esm\index.js from D:\digi-curriculum\digi-curriculum-frontend\node_modules@tisoap\react-flow-smart-edge\dist\react-flow-smart-edge.cjs.development.js not supported.
Instead change the require of index.js in D:\digi-curriculum\digi-curriculum-frontend\node_modules@tisoap\react-flow-smart-edge\dist\react-flow-smart-edge.cjs.development.js to a dynamic import() which is available in all CommonJS modules.
Two edge labels could overlap. It would be even better if we could configure the labels of different edges to not overlap.
First of all, thanks for the great package! It saves me tons of time.
Originally, the package did not seem to be "smart" on my end (still using the BezierEdge
from react-flow
). I then found out that the length of smoothedPath
for me is always smaller or equal to 2, which fallbacks to the edges of react-flow
(see codes here). Then I was thinking it cannot be that smoothedPath
is always that case. It turns out there is a bug in the dependency pathfinding
, where no coordinate will be recorded if coming across a block (start and end coordinate will not be updated either).
function smoothenPath(grid, path) {
....
blocked = false;
....
if (blocked) {
lastValidCoord = path[i - 1]; // THIS IS NOT DEFINED AND CAUSE AN INTERNAL ERROR
newPath.push(lastValidCoord);
sx = lastValidCoord[0];
sy = lastValidCoord[1];
}
}
newPath.push([x1, y1]);
return newPath;
}
The fix is easy but it seems that no one is maintaining pathfinding
anymore (e.g., qiao/PathFinding.js#192).
react-flow-smart-edge
should use a fork of pathfinding
to have known bugs fixed?As the library grows in API size, it becomes more difficult to read about the available options on the repository README. Ideally this library should have a seperate website for documentation, with separate pages for each option and live intractable examples, same as the React Flow docs. They mentioned in their blog post that they're using Docusaurus, will need to check it out.
Ideally the documentation should be all statically build, and I should be able to deploy it using gh-pages
, to save on server and domain costs. The current GitHub page hosts the Storybook examples and tests, but they can be moved to a free tier on Chromatic.
Getting a 404 at https://tisoap.github.io/react-flow-smart-edge/
https://tisoap.github.io/react-flow-smart-edge/
Go to https://tisoap.github.io/react-flow-smart-edge/
Expected Storybook
No response
macOS + Chrome
No response
With the increase in issues reported, this library needs a template for users to create new issues. At least two templates, one for feature suggestions and another for bug reports. The bug report one should make it clear that the user must provide a a minimal example on CodeSandbox or a minimal GitHub repository where the error happens.
Hello dear,
This is pretty awesome feature that you have developed. lots of appreciation for this. i have been using this nice feature with React flow. during the development I got a weird problem. SmartEdgeProvider wrap React flow, whenever i change the SmartEdgeProvider options then smart edge applies for all edges. and this is not fulfilling my requirement. could you tell me please is it possible to control smart edge individually or if this feature is not available could you add this feature please? you can see a video below where i have highlighted smart edges with green color.
There are multiple nodes layouted^TM by elkjs and afterwards painted on the canvas. The nodes are not draggable, so the user can change the position and trigger the recalculation of the edges by PathFinding.js.
The Problem here is, that the user is not able to recognize which edge connects which nodes.
I thought that marking the edge path points via setWalkableAt
as not walkable would force the edges to not overlay each other anymore. What do you think about this?
Hacking on the PathFinding.js implementation.
Hey @tisoap,
Is there a way/hack to make the edges dodge only some specific nodes instead of all nodes?
If not, It'll be nice if we could pass node IDs or a filter function in the factory functions.
Hi. I have multiple types of edges in my setup. I want to make each one of them smart. From the docs, if we give the type as SmartEdge, it doesn't intersect. How can I make my custom edge inherit these properties and on top of them use properties which are unique to them?
First of all thank you @tisoap for this amazing library.
We have a requirement of displaying a button along with the edge label, through which we want to perform some actions. Something similar to what we have as CustomEdge
in react-flow.
Below is the screenshot of what we are actually trying to achieve
The edge seems to have a bend when it origins from the source. After that it's coming as expected (I tried for smooth step edge). Is there any way to avoid that? Please help me out here
Even if you check in the codesandbox example(not mine) given below, you will be able to see the issue
https://codesandbox.io/s/old-rgb-k9buls
Expected to see no bend. If the line is a straight line, from the source itself, it should be straight
No response
No response
Hi, this repo is awesome. I wonder when we can expect support for v10 of react-flow-renderer. Specifically, how do we plan to support new group feature.
For v10 details, here is a link xyflow/xyflow#1555
We'd like to better understand the situations in which getSmartEdge returns null. We get reports through metrics of this occurring in production but have not been able to repro locally.
diff --git a/src/getSmartEdge/index.ts b/src/getSmartEdge/index.ts
index 75e0f7f..3330734 100644
--- a/src/getSmartEdge/index.ts
+++ b/src/getSmartEdge/index.ts
@@ -28,6 +28,7 @@ export type GetSmartEdgeOptions = {
nodePadding?: number
drawEdge?: SVGDrawFunction
generatePath?: PathFindingFunction
+ propagateError?: boolean
}
export type GetSmartEdgeParams<NodeDataType = unknown> = EdgeParams & {
@@ -128,7 +129,10 @@ export const getSmartEdge = <NodeDataType = unknown>({
)
return { svgPathString, edgeCenterX, edgeCenterY }
- } catch {
+ } catch (e) {
+ if (options.propagateError) {
+ throw e;
+ }
return null
}
}
We could also fork the repo if this approach isn't appealing, though would love to stay on the main branch for future updates.
Happy to open up a PR for this if I can get write permissions
I would expect the edges to start and end on the provided XY coordinates, but they don't.
Used props:
const getSmartEdgeReturn = getSmartEdge({
sourceX: (maxX + defaultNodeWidth + minX) / 2,
sourceY: (maxY + defaultNodeHeight + 20),
sourcePosition: Position.Bottom,
targetX: parentNode.position.x + defaultNodeWidth * 0.73,
targetY: parentNode.position.y + defaultNodeHeight / 2,
targetPosition: Position.Right,
nodes: flowInstance.getNodes(),
options: {
nodePadding: defaultNodeWidth / 4,
drawEdge: svgDrawStraightLinePath,
generatePath: pathfindingJumpPointNoDiagonal,
}
});
/
/
Line should start and end on the provided coordinates.
No response
Hello @tisoap,
Thanks for this awesome library.
I noticed that when you use the following code:
const { edgeCenterX, edgeCenterY, svgPathString } = getSmartEdgeResponse;
return (
<>
<BlockEdge {...props} />
<EdgeLabelRenderer>
<div
style={{
position: 'absolute',
transform: `translate(-50%, -50%) translate(${edgeCenterX}px,${edgeCenterY}px)`,
fontSize: 12,
// everything inside EdgeLabelRenderer has no pointer events by default
// if you have an interactive element, set pointer-events: all
pointerEvents: 'all',
}}
className="nodrag nopan"
>
<div className="edgebutton">
<LogicIcon />
</div>
</div>
</EdgeLabelRenderer>
</>
);
This edge button sometime isn't on the path itself when you try dragging the node.
N/A
1- Try to add an edge button
2- Try dragging the nodes
3- You will notice that the edge button isn't always on the path.
The edge button x and y should be always on the path.
Video: https://www.awesomescreenshot.com/video/18125673?key=f23c09850e5998229585d2a49ea8a2f6
OS: [Windows]
No response
Currently introducing an option (such as gridRatio) is appears to be quite burdensome requiring the creation of a whole custom SmartEdge
Would it be possible to introduce a helper function to apply options to edge types?
const edgeTypes :EdgeTypes = {
smartstep: getSmartStepEdgeType(options)
}
...
return (
<ReactFlow edgeTypes={edgeTypes} ... />
Creating a custom smart edge.
No response
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.