Vis.js 如何只显示 children/descendents 个选中的节点?

Vis.js How to show only children/descendents of selected node?

如果 vis.js 不可行,我可以在其他事情上完成所有事情。但是这个功能是至关重要的。所以,如果没有,就显示所有内容 selected;如果某个节点是 selected,则仅显示该节点的子节点(带有“来自”箭头)。或者 select 某个列表中的节点,或者在某处键入它。 https://codepen.io/andre-fr-silva/pen/ZEBPpqK

var container = document.getElementById("mynetwork");
var data = {
  nodes: nodes,
  edges: edges,
};

直系后裔

这可以使用文档 here in combination with the hidden property on nodes defined here 中定义的 select 事件来实现。您可以更新DataSet 中的数据,然后网络将显示更新。总之,我建议的逻辑是:

  1. 如果没有节点 selected
    1. 取消隐藏所有节点
  2. 如果一个或多个节点被 selected
    1. 隐藏所有节点
    2. 显示 selected 个节点
    3. 显示从 selected 节点
    4. 连接的节点

下面实现了这个逻辑。

network.on('select', function (properties) {
  // Define an array of nodes ot update, this is quicker than
  // updating each node individually
  let nodesToUpdate = [];
  
  // If no nodes are selected, unhide all hidden nodes
  if(properties.nodes.length === 0){
    // Populate array with list of nodes to unhide
    data.nodes.forEach(node => {
      if(node.hidden){ 
        nodesToUpdate.push({id:node.id, hidden: false});
      }
    });
    
    // Update nodes and return
    data.nodes.update(nodesToUpdate);
    return;
  }
    
  // One or more nodes are selected
  // Populate array with list of all nodes, hiding them
  data.nodes.forEach(node => {
    nodesToUpdate.push({id:node.id, hidden: true});
  });

  // Pouplate array with list of selected and connected nodes to unhide
  // Note: Nodes will already exist in the array, but these later updates
  //       will overwrite the earlier ones.
  properties.nodes.forEach(node => {
    // Add selected node
    nodesToUpdate.push({id:node, hidden:false});
    
    // Add connected nodes to the selected node
    data.edges.forEach(edge => {
      // Unhide if connected from selected node and connected node exists
      if(edge.from === node && data.nodes.get(edge.to)){
        nodesToUpdate.push({id:edge.to, hidden: false});
      }
    });
  }); 
  
  // Submit updates to hide/unhide nodes
  data.nodes.update(nodesToUpdate);
});

请注意,这可以进一步优化,删除或更新 nodesToUpdate 数组中的项目而不是复制它们。

所有后代

可以使用类似的方法来显示所有家属。使用递归是实现这一目标的最简单方法,并进行检查以确保代码不会陷入无限循环(如果网络中存在的话)。在下面的示例代码中,声明了一个名为 addChildNodes 的新函数,该函数被递归调用以在跟随边时添加每个节点子节点。

function addChildNodes(nodesToUpdate, node){
  // Add child nodes for the passed node
  // Loop around all edges
  data.edges.forEach(edge => {
    // Check if connected from the passed node and connected node exists
    if(edge.from === node.id && data.nodes.get(edge.to)){
      // Find the child node in the update array
      let childNode = nodesToUpdate.find(node => node.id === edge.to);
    
      // Check if the child node is hidden
      // If the node is not hidden then it's already been processed
      // Don't process it again otherwise could get caught in a loop
      if(childNode.hidden){     
        // Node is currently hidden, therefore hasn't been processed yet
        // Set node to be displayed
        childNode.hidden = false;
        
        // Recursive call to function to process its children
        addChildNodes(nodesToUpdate, childNode);
      }
    }
  });
}

network.on('select', function (properties) {
  // Define an array of nodes ot update, this is quicker than
  // updating each node individually
  let nodesToUpdate = [];
  
  // If no nodes are selected, unhide all hidden nodes
  if(properties.nodes.length === 0){
    // Populate array with list of nodes to unhide
    data.nodes.forEach(node => {
      if(node.hidden){ 
        nodesToUpdate.push({id:node.id, hidden: false});
      }
    });
    
    // Update nodes and return
    data.nodes.update(nodesToUpdate);
    return;
  }
    
  // One or more nodes are selected
  // Populate array with list of all nodes, hiding them
  data.nodes.forEach(node => {
    nodesToUpdate.push({id:node.id, hidden: true});
  });

  // Update the arra setting list of selected and connected nodes to unhide
  properties.nodes.forEach(nodeId => {
    // Find the selected node in the array
    let node = nodesToUpdate.find(node => node.id === nodeId);
    
    // Update selected node to be displayed
    node.hidden = false;
  
    // Call recursive function to add all dependents
    addChildNodes(nodesToUpdate, node);
  }); 
  
  // Submit updates to hide/unhide nodes
  data.nodes.update(nodesToUpdate);
});