force-graph icon indicating copy to clipboard operation
force-graph copied to clipboard

Adding a higlight on children nodes effect ( inifinite loop bug in forceGraph )

Open Yass525 opened this issue 2 years ago • 0 comments

In the context of working on another project i had to fork this library and add features to it. As a first feature i added a highlight nodes children function wich blur any other nodes wich is not the children of the selected node. The function works as expected, but there's an infinite loop when i call any method related to state.forceGraph. In this copied code where there is console.log(" there is loop here") that means the infinite loop detected there Also, consolo.log(" No loop here") means that no loop found there, jsut to clarify that the function itself does not loop but state.forceGraph does. Any advice or idea willbe appreciated

The method is added in force-graph.js

`highlightNeighbors: async function (state, node) { if (!state.canvas) return null; consolo.log(" No loop here")

  // getting the current canvas
  const ctx = state.canvas.getContext("2d");

  const highlightNodes = new Set();
  const highlightLinks = new Set();

  //filling the two sets with the connected nodes and edges to node
  const addNeighbors = async (highlightNodes, highlightLinks, node) => {
    return new Promise((resolve) => {
      if (node) {
        highlightNodes.add(node);
        node.neighbors.forEach((neighbor) => highlightNodes.add(neighbor));
        node.links.forEach((link) => highlightLinks.add(link));
      }
      resolve();
    });
  };
  await addNeighbors(highlightNodes, highlightLinks, node);

  const getNodeColor = accessorFn(state.nodeColor);

  //! ********************************************************* !\\
  //! we have an optimization problem, kind of infinite loop !\\
  //! ********************************************************** !\\

  const g = state.forceGraph()(ctx).graphData(state.graphData);
  g.linkWidth((link) => {
   console.log(" there is loop here")
    return highlightLinks.has(link) ? 2 : 1;
  });
  g.linkDirectionalParticles((link) => {
    console.log(" there is loop here")
    return highlightLinks.has(link) ? 4 : 0;
  });
  g.nodeVal((node) => {
    console.log(" there is loop here")
    return highlightNodes.has(node) ? 3 : 2;
  });
  g.nodeColor((node) => {
    console.log(" there is loop here")
    if (highlightNodes.size === 0) {
      return getNodeColor(node);
    } else if (!highlightNodes.has(node)) {
      return "rgba(128,128,128,0.2)";
    } else {
      return getNodeColor(node);
    }
  });
},`

And i call it in the html file like this : <script> fetch("../datasets/miserables.json") .then((res) => res.json()) .then((data) => { const elem = document.getElementById("graph"); const Graph = ForceGraph()(elem) .graphData(data) .nodeLabel("id") .nodeAutoColorBy("group") .onNodeHover((node) => { Graph.highlightNeighbors(node); }); }); </script>

Yass525 avatar Jun 30 '23 13:06 Yass525