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 中的数据,然后网络将显示更新。总之,我建议的逻辑是:
- 如果没有节点 selected
- 取消隐藏所有节点
- 如果一个或多个节点被 selected
- 隐藏所有节点
- 显示 selected 个节点
- 显示从 selected 节点
连接的节点
下面实现了这个逻辑。
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);
});
如果 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 中的数据,然后网络将显示更新。总之,我建议的逻辑是:
- 如果没有节点 selected
- 取消隐藏所有节点
- 如果一个或多个节点被 selected
- 隐藏所有节点
- 显示 selected 个节点
- 显示从 selected 节点 连接的节点
下面实现了这个逻辑。
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);
});