Open moklick opened 4 months ago
They are draggable for me (Mac, safari 17.5), although performance is notably worse than it used to be.
They are only draggable after the simulation stops running, for me.
I have worked through this problem myself with V11. It was quite tricky to get all the interactivity to play ball. I'm about to update v12, so once I've checked that none of my solution breaks I will post a link.
I've copied over the simplest solution I found to get the node dragging to function correctly with d3 force layouting. Here's my fork of the example repo:
https://github.com/buchananwill/quizzical-lamarr-tv8srd.git
The gist of the solution is to use the callbacks for onNodeDragStart/onNodeDrag/onNodeDragStop to assign the currently dragging node to a ref:
const draggingNodeRef = useRef(undefined);
const [initialized, {toggle, isRunning}] = useLayoutedElements(draggingNodeRef);
const onNodeDragStart = useCallback(
(_event, node) => {
draggingNodeRef.current = {...node};
},
[]
);
const onNodeDragStop = useCallback(() => {
draggingNodeRef.current = undefined;
}, []);
const onNodeDrag = useCallback(
(_event, node) => {
draggingNodeRef.current = {...node};
},
[]
);
This ref is passed into the useLayoutedElements hook, so the memoized function can always guarantee to see a non-stale reference. I made a few other minor changes to tidy up some janky behaviour, like copying the xyflow positions back onto the sim nodes before restarting the sim - otherwise the nodes forget where you might have dragged them to and hop back to the last position the sim remembers.
Feel free to copy my change/fork back into the example version for the web docs.
Thanks for sharing your solution @buchananwill ! We will have a look
Some observations on the website example (https://reactflow.dev/learn/layouting/layouting#d3-force):
All above are after starting force simulation, i.e., auto-layout in effect.
I observed all of these behaviours as well, both in the example site, and my own project. The solution I posted is how I fixed it in my own project, and also applies to the example site.
On Sun, 22 Sept 2024, 06:01 Hebi Li, @.***> wrote:
Some observations on the website example ( https://reactflow.dev/learn/layouting/layouting#d3-force):
- the nodes are draggable in Safari
- the nodes are not draggable in Chrome/Firefox
- (very weird) if you open the dev tool on Chrome, the nodes are draggable
All above are after starting force simulation, i.e., auto-layout in effect.
— Reply to this email directly, view it on GitHub https://github.com/xyflow/web/issues/429#issuecomment-2365468410, or unsubscribe https://github.com/notifications/unsubscribe-auth/BBL2M6IAK7J4TROJ3YKTVXTZXZFMPAVCNFSM6AAAAABKUT5ZB6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNRVGQ3DQNBRGA . You are receiving this because you were mentioned.Message ID: @.***>
Thanks @buchananwill , I actually did try the codesandbox link on your repo. The behavior is exactly the same as the website example (all 1,2,3 above). I'm surprised that it works on your side. I'm on MacOS 15.0, Chrome 128.0.6613.138 (Official Build).
Ah, you're right. I checked against my main project I copied from and I'd missed one detail: the current drag position needs to come directly from the ref, not the scoped list of nodes (which is stale).
getNodes().forEach((node, i) => {
const dragging = draggingNodeRef?.current?.id === node.id;
// Setting the fx/fy properties of a node tells the simulation to "fix"
// the node at that position and ignore any forces that would normally
// cause it to move.
if (dragging) {
// These two lines were wrong.
nodes[i].fx = draggingNodeRef?.current?.position.x;
nodes[i].fy = draggingNodeRef?.current?.position.y;
} else {
delete nodes[i].fx;
delete nodes[i].fy;
}
});
Please try the codesandbox again and let me know if it works for you now!
Awesome, it works! Thanks for the quick response and debugging.
:-) you're welcome!
On Mon, 23 Sept 2024, 19:32 Hebi Li, @.***> wrote:
Awesome, it works! Thanks for the quick response and debugging.
— Reply to this email directly, view it on GitHub https://github.com/xyflow/web/issues/429#issuecomment-2369064805, or unsubscribe https://github.com/notifications/unsubscribe-auth/BBL2M6N54CPBHEAXIAWIWSLZYBNFLAVCNFSM6AAAAABKUT5ZB6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGNRZGA3DIOBQGU . You are receiving this because you were mentioned.Message ID: @.***>
Hey @buchananwill thank you so much for investigating! I can confirm that your repo/sandbox works outside of safari: it's so strange that it works at all in safari 🧐
We're in the process of reworking how we host our examples (#501) but I'll make sure these changes are added and we'll shout you out when things go live 💕. Until then I'll leave the issue open in case anyone else needs to find it.
Feel free to tag in me in anything else that is a puzzle. I've got a bit of free time at this week and have been using xyflow quite a bit lately. 🙏
On Tue, 1 Oct 2024, 09:16 Hayleigh Thompson, @.***> wrote:
Hey @buchananwill https://github.com/buchananwill thank you so much for investigating! I can confirm that your repo/sandbox works outside of safari: it's so strange that it works at all in safari 🧐
We're in the process of reworking how we host our examples (#501 https://github.com/xyflow/web/pull/501) but I'll make sure these changes are added and we'll shout you out when things go live 💕. Until then I'll leave the issue open in case anyone else needs to find it.
— Reply to this email directly, view it on GitHub https://github.com/xyflow/web/issues/429#issuecomment-2385098031, or unsubscribe https://github.com/notifications/unsubscribe-auth/BBL2M6PCLRQOWNBM5ZZXFILZZJK7NAVCNFSM6AAAAABKUT5ZB6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGOBVGA4TQMBTGE . You are receiving this because you were mentioned.Message ID: @.***>
I've keep running into this issue even though I have a mostly working graph setup. Today I found that adding the useNodesData()
hook into one of the node component implementations I have, breaks the dragging behaviour again. I worked around it by instead subscribing to the higher up context I am wrapping my xyflow setup in.
const { nodes } = useNodeContext<OrganizationDto>();
This doesn't trigger re-renders from selection/movement updates, because it's the external data, rather than the full UI state. So, it'll re-render if a node is added, or the "business" data on any node changes, but not the UI-level state changes.
Does this give any clues about why the dragging behaviour would break in the first place?
While the simulation is running, the nodes are not draggable https://reactflow.dev/learn/layouting/layouting#d3-force