Comments (9)
The code you are referring to is a utility for adding edges. If you don't want to pass the edges array, the useReactFlow
hook also exports an addEdges
utility.
Or am I misunderstanding something?
from xyflow.
I don't want to add an edge to an array of edges. I want to create an edge object that I can manipulate directly, without needing to extract it from an array or reactflow's internally managed state.
Something like this:
import type { Connection, Edge } from 'reactflow';
import { assert } from 'tsafe';
/**
* Gets the edge id for a connection
* Copied from: https://github.com/xyflow/xyflow/blob/v11/packages/core/src/utils/graph.ts#L44-L45
* Requested for this to be exported in: https://github.com/xyflow/xyflow/issues/4290
* @param connection The connection to get the id for
* @returns The edge id
*/
const getEdgeId = (connection: Connection): string => {
const { source, sourceHandle, target, targetHandle } = connection;
return `reactflow__edge-${source}${sourceHandle || ''}-${target}${targetHandle || ''}`;
};
/**
* Converts a connection to an edge
* @param connection The connection to convert to an edge
* @returns The edge
* @throws If the connection is invalid (e.g. missing source, sourcehandle, target, or targetHandle)
*/
export const connectionToEdge = (connection: Connection): Edge => {
const { source, sourceHandle, target, targetHandle } = connection;
assert(source && sourceHandle && target && targetHandle, 'Invalid connection');
return {
source,
sourceHandle,
target,
targetHandle,
id: getEdgeId({ source, sourceHandle, target, targetHandle }),
};
};
This isn't complicated to implement on my own, but I'd prefer to not be concerned with ID format or any other implementation details from reactflow.
from xyflow.
Is this just about the id? There is no id format that React Flow enforces other than it has to be a string and unique. If you want to generate IDs for real world projects, I suggest you simply use UUIDs. You can generate one using the window.crypto
API of browsers.
from xyflow.
No, it's not just about the id. It's about creating an edge from a connection, with the guarantee that it is identical to the edge that would be created by reactflow, given the input edge params or connection object.
The same problem exists for nodes.
To state the problem in a different way: reactflow encourages users to provide their own state management and handle it on a fairly low level, but it is missing some basic utilities to support this. For example, directly creating an edge or node that I may immediately manipulate without needing to add them to state or an array. I have to review the internal implementation addEdge or addNode to be confident my edge and node are created correctly.
from xyflow.
directly creating an edge or node that I may immediately manipulate without needing to add them to state or an array.
What exactly is preventing you from doing this though? You can create an object, type it properly if you're using TypeScript and you're good, or what's missing that a helper would solve?
I have to review the internal implementation addEdge or addNode to be confident my edge and node are created correctly.
What do you mean by "created correctly" exactly?
As long as you fulfill the requirements of the respective element types (nodes need an id and a position, edges need an id, source and target node id) they would be "created correctly".
Maybe there's a misconception that adding a node or edge would somehow create a new object with properties on it that you didn't explicitly pass?
Besides the required (mostly internal) properties, ReactFlow won't add stuff so if you pass an edge like this
const newEdge: Edge = {
id: 'e1->2',
source: '1',
target: '2',
}
It will (mostly) just stay that, there won't be anything else on it.
There are some errors that can happen though, which you can listen to with the onError
prop you can use to listen for these (by default they will be printed as a console warning, but only in dev).
For example if you try to add an edge without a source or target node id..
from xyflow.
Of course nothing is stopping me, and I have been doing that since I started using reactflow some time ago. I shared a small utility in this issue that does this for edges.
I don't mind if this request goes nowhere. But in an effort to clarify the the request...
Besides the required (mostly internal) properties
Yeah, these are the properties I don't want to be responsible for.
It will (mostly) just stay that
Again, I don't want to be responsible for whatever "mostly" doesn't include.
I have a data format that is an abstraction of the reactflow state. I need to translate between this enriched data format and reactflow nodes and edges regularly. Sometimes, when creating a node or edge, I need to manipulate it in some way before adding it to the application state.
The key thing here is that reactflow may or may not have internal implementation details that dictate the shape of edges and nodes. As a library user, I shouldn't need to know about these details, implement them, or keep track of changing upstream types.
For edges, reactflow provides two helpers:
- Creating the edge object and immediately adding it to an array.
- Creating the edge object and adding it to the internally-managed reactflow state.
In both of these cases, if I want the edge object (with whatever additional data reactflow may or may not add to it), I need to extract it from that array or state.
I'm asking for a third helper:
- Create the edge object without adding it to an array or the internal state - just return it.
Finally, I understand the ID format doesn't affect any functionality, but it's rather nice to use a consistent format everywhere, no? Sometimes, I can rely on reactflow's internal handling to add an edge, but other times I need to create it myself. I want these two actions to result in the same state, given the same edge/connection params.
from xyflow.
Yeah, these are the properties I don't want to be responsible for.
Where does the assumption come from that you are responsible for these values? 😄
You don't have to (and shouldn't) pass these values at all.
Is the problem that you don't want to have these properties when translating from one state to another? Otherwise I'm still not quite sure what the issue is.
I need to manipulate it in some way before adding it to the application state.
Again, what is stopping you from doing so? You said yourself there's nothing preventing you from doing this, no?
Is the feature request a function (as you posted above) that throws when you use an invalid element definition?
Or what exactly is this function supposed to do except literally just return the same object you pass into it?
The key thing here is that reactflow may or may not have internal implementation details that dictate the shape of edges and nodes.
Feels like another assumption that there is some shape that you don't know about even though the base requirements are laid out already and you can use TypeScript to properly type the elements so you'd get feedback whether the shape is acceptable or not.
Anything that doesn't belong on a Node
or Edge
object needs to go into it's data
property - that is what it's for. Any additional info etc. you need belongs into that data object.
I am still not quite sure what this feature request is supposed to solve exactly, it still feels very vague to me even with the explanation above as it seems like there are some assumptions being made about how ReactFlow works and handles your nodes/edges.
Maybe it would help if you could showcase a specific example where this helper would be used, why it would fill a gap that currently exists, how these cases wouldn't work as well without the helpers etc. - that might make it more obvious what exactly you are looking for since I might just be slow to understand 😄
from xyflow.
React Flow is a declarative flow graph renderer. You input nodes & edges with a specific format and it renders it for you. There is no logic attached to ids because we don't want to dictate how people manage their data ids. The same thing applies to state management. We don't want to trap anyone in any specific state or data management pattern, which in a way is what declarative systems tend to provide.
The key thing here is that reactflow may or may not have internal implementation details that dictate the shape of edges and nodes. As a library user, I shouldn't need to know about these details, implement them, or keep track of changing upstream types.
The only thing an edge needs to have is a unique id, so it can be identified, and a specific source and target handle. I don't think an edge can be defined by less information and that is also the only thing you have to provide. We don't know what edges you want to connect, you have to concern yourself with these details as a library user. There are no upstream changes to the types, the edges have and will almost certainly be always defined by these information.
from xyflow.
Ok, thanks for the continued discussion and reassurance. I won't worry about upstream changes, will create and use helpers as are suited to my application, and will rely on TS to alert me if anything does change. Thanks for your work on reactflow.
from xyflow.
Related Issues (20)
- [React Flow]: Handle: No node id found. Make sure to only use a Handle inside a custom Node.
- [React Flow]: Handle: No node id found. Make sure to only use a Handle inside a custom Node. HOT 1
- Zoom In, Zoom Out, fitview, and toggle interactivity HOT 4
- Mini Map preview disappeared in 12.0.0-next.18 HOT 1
- Allow drag selection inside nodes HOT 11
- Revert to window level event listeners
- [SvelteFlow] panOnScroll shift+scroll horizontal does not work after clicking canvas HOT 4
- `Edge` should accept a generic `type` argument like `Node` HOT 2
- Node Position Changes Cause All Nodes To Disappear HOT 3
- Large Data React-Window Virtualization HOT 7
- prevent outcoming edge from target handle HOT 3
- Edge marker is not dynamically updated HOT 9
- accept array of classes in noPanClassName HOT 5
- snap guidelines HOT 2
- Extra Objects needed HOT 2
- Node position not matching the nodes list and rendered node HOT 5
- defining a fixed markerEnd (or Start) in custom Edge doesn't work? HOT 2
- I face a bug to align center expand and collapse flow HOT 1
- Export type definitions for individual methods and variables of `useSvelteFlow` functionality HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from xyflow.