vasturiano / react-force-graph

React component for 2D, 3D, VR and AR force directed graphs
https://vasturiano.github.io/react-force-graph/example/large-graph/
MIT License
2.26k stars 284 forks source link

Drag on nodes stops working after I change the graph data and use zoomToFit afterwards #545

Open angelzbg opened 1 month ago

angelzbg commented 1 month ago

Describe the bug When I change my graph object with a completely new one, which contains the same nodes with different coords and use zoomToFit afterwards. When I try to drag a node it doesn't work anymore and it just moves the canvas.

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

Additional context This is how I use the component:

<ForceGraph2D
                    ref={popupGraphRef}
                    width={state.popupStructureWidth}
                    height={state.popupStructureHeight}
                    graphData={state.popupShareholderStructureData}
                    dagMode="bu"
                    dagLevelDistance={100}
                    nodeRelSize={8}
                    onEngineTick={() => {}}
                    cooldownTime={0}
                    forceEngine="d3"
                    onEngineStop={() => {
                      if (!state.shareholderPopupEngineStopExecuted) {
                        state.shareholderPopupEngineStopExecuted = true;

                        setTimeout(() => {
                          popupGraphRef?.current?.zoomToFit?.(100, 112);
                        }, 100);
                      }
                    }}
                    linkCanvasObjectMode={() => 'replace'}
                    linkCanvasObject={linkCanvasObject}
                    nodeCanvasObject={nodeCanvasObject}
                    onNodeDrag={(node) => {
                      // Freeze all other nodes in their current position during drag
                      state.popupShareholderStructureData.nodes.forEach((n) => {
                        if (n.id !== node.id) {
                          n.fx = n.x; // Lock position
                          n.fy = n.y; // Lock position
                        }
                      });
                    }}
                    onNodeDragEnd={(node) => {
                      // Lock the dragged node's position to its final coordinates
                      node.fx = node.x; // Set fixed position in x
                      node.fy = node.y; // Set fixed position in y
                      node.fz = node.z; // Set fixed position in z if using 3D graph
                    }}
                  />

This is a video, it is working before changing the grph object.

https://github.com/user-attachments/assets/953e595b-1304-4bdd-9ad1-d23303d6710d

UPDATE: I have used same graph object for rendering two ForceGraph2D. It was working for the most part but with some bugs. Now I have created two copies of the graph data for each ForceGraph2D and onNodeDrag I find the node on the other graph and change it's coordinates. This solves my issue. If this is an expected behavior and not a bug please feel free to close the issue.

vasturiano commented 1 month ago

@angelzbg it is preferrable that you don't use the same node object for more than one graph, because it includes state about the graph that it's in and can cause conflicting behaviour if it's associated with more than one. So it is better to just clone the objects and keep them separate.

In any case, if you're still having any issues, please provide an online example that reproduces the issue on https://codesandbox.io/ so we can have a closer look.

angelzbg commented 1 month ago

@vasturiano this is exactly what I have done. Now by cloning the graph data it is working just fine.