vasturiano / react-force-graph

React component for 2D, 3D, VR and AR force directed graphs

Home Page:https://vasturiano.github.io/react-force-graph/example/large-graph/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

is there a way to keep the gentle floating movement after the initial graph animation?

Jing1524 opened this issue · comments

I'm working on a project using a basic graph visualization example. Implementing it has been straightforward for the most part. However, I'm struggling with a specific aspect: I want the nodes in the graph to continue floating after the initial render, similar to an effect seen in a Three.js example floating

Here are the methods I've tried so far:

  • Adjusting cooldownTime to slow down the node movement, hoping to maintain a floating effect. Unfortunately, this hasn't worked as expected.

  • Attempting to reheat the simulation. This approach causes the graph to re-render and results in the nodes floating off the screen.

  • Using useEffect to monitor and update each node's location. While this gets me closer to the desired effect, I'm still unable to achieve the smoothness of the floating animation, and I can't prevent the nodes from floating off the screen.

Ideally, I'd like a solution that provides an option to toggle between continuous floating and allowing the graph to gradually come to a stop.

Additional context
below is a quick version of what i have for context, the node stops completely towards the end.
codesandbox

@Jing1524 you can try setting the node's velocities (via v* attributes) instead of their positions. This will probably get you closer to what you have in mind. And possibly it helps too to set d3VelocityDecay and d3AlphaDecay to 0.

Take a look at this example.

const nodes = [...Array(N).keys()].map(() => ({
// Initial velocity in random direction
vx: (Math.random() * 2) - 1,
vy: (Math.random() * 2) - 1
}));

@vasturiano thank you so much for the quick response! will try it out! :)

@vasturiano hey sorry to bother you again.
I just spend a few hours working on it again, but having a hard time to get it to work, feels like I'm missing something still,
i did manage to have the node keep moving, but the resulting movement is way too dramatic. I'm attaching my code and sandbox to show you the currently result. wondering if you could help.

here is the current result
Below useEffect is doing the heavy lift for the "floating" movement.

useEffect(() => {
    graphData.nodes.forEach((node) => {
      const initialColor = "#E4CDC6";
      const targetColor = "#a7715f";
      setNodeTransition((prev) => ({ ...prev, [node.id]: initialColor }));
      setTimeout(() => {
        animateColorTransition(node.id, initialColor, targetColor, 500); // Transition over 2 seconds
      }, Math.random() * 5000 + 1000); // Random interval between 3s and 8s
    });
    graphData.nodes.forEach((node) => {
      node.vx = Math.random() * 2 - 1; 
      node.vy = Math.random() * 2 - 1;
      node.vz = Math.random() * 2 - 1;
    });

    const BOUNDING_BOX_SIZE = 10;

    
    const enforceBoundingBox = () => {
      graphData.nodes.forEach((node) => {
        if (Math.abs(node.x) > BOUNDING_BOX_SIZE) node.vx *= -1;
        if (Math.abs(node.y) > BOUNDING_BOX_SIZE) node.vy *= -1;
        if (Math.abs(node.z) > BOUNDING_BOX_SIZE) node.vz *= -1;
      });
    };

    
    const interval = setInterval(enforceBoundingBox, 1000);

    return () => clearInterval(interval);
  }, [graphData.nodes]);

return (
 <ForceGraph3D
      ref={forceGraphRef}
      width={width}
      height={height}
      graphData={graphData}
      backgroundColor="#ffffff"
      showNavInfo={false}
      nodeColor={(node) => nodeTransition[node.id] || "#E4CDC6"}
      nodeOpacity={1}
      linkColor={(d) => (d.type === "OK" ? "#E4CDC6" : "#E4CDC6")}
      linkOpacity={0.75}
      enableNavigationControls={false}
      d3AlphaDecay={0}
      d3VelocityDecay={0}
    />
)