If not posible with vis.js, I could do the entire thing on something else. But this functionality is crucial. So, show everything if nothing selected; show only children (with the "from" arrow) of some node if that node is selected. Or to select the node in some list, or type it somewhere. https://codepen.io/andre-fr-silva/pen/ZEBPpqK
var container = document.getElementById("mynetwork");
var data = {
nodes: nodes,
edges: edges,
};
This can be achieved using the select event defined in the documentation here in combination with the hidden property on nodes defined here. You can update the data in the DataSet, the network will then display the updates. In summary the logic I would suggest is to:
The following implements this logic.
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);
});
Please note this could be optimised further, removing or updating items in the nodesToUpdate
array instead of duplicating them.
A similar approach can be used to show all dependents. Using recursion is the easiset way to achieve this, with checks to make sure the code doesn't get caught in am endless loop (if one exists in the network). In the sample code below a new function named addChildNodes
is declared that is called recursively to add each nodes children as the edges are followed.
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);
});