Open lazarospa opened 4 years ago
Hi @lazarospa, did you find a way to do this? I saw a R counterpart "visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE)", but, as it appears, there is none for Python - I could be wrong.
Hi @boludo00, wondering if you can help.
Do you mean something like in this example?
https://visjs.github.io/vis-network/examples/network/exampleApplications/neighbourhoodHighlight.html
If so, then additional JavaScript would need to be supplied in the template.html that pyvis uses for rendering your graph. Inspecting the above example's source code, something similar would like:
var network;
var allNodes;
var highlightActive = false;
var nodesDataset = new vis.DataSet(nodes); // these come from WorldCup2014.js
var edgesDataset = new vis.DataSet(edges); // these come from WorldCup2014.js
function redrawAll() {
var container = document.getElementById("mynetwork");
var options = {
nodes: {
shape: "dot",
scaling: {
min: 10,
max: 30,
label: {
min: 8,
max: 30,
drawThreshold: 12,
maxVisible: 20,
},
},
font: {
size: 12,
face: "Tahoma",
},
},
edges: {
width: 0.15,
color: { inherit: "from" },
smooth: {
type: "continuous",
},
},
physics: false,
interaction: {
tooltipDelay: 200,
hideEdgesOnDrag: true,
hideEdgesOnZoom: true,
},
};
var data = { nodes: nodesDataset, edges: edgesDataset }; // Note: data is coming from ./datasources/WorldCup2014.js
network = new vis.Network(container, data, options);
// get a JSON object
allNodes = nodesDataset.get({ returnType: "Object" });
network.on("click", neighbourhoodHighlight);
}
function neighbourhoodHighlight(params) {
// if something is selected:
if (params.nodes.length > 0) {
highlightActive = true;
var i, j;
var selectedNode = params.nodes[0];
var degrees = 2;
// mark all nodes as hard to read.
for (var nodeId in allNodes) {
allNodes[nodeId].color = "rgba(200,200,200,0.5)";
if (allNodes[nodeId].hiddenLabel === undefined) {
allNodes[nodeId].hiddenLabel = allNodes[nodeId].label;
allNodes[nodeId].label = undefined;
}
}
var connectedNodes = network.getConnectedNodes(selectedNode);
var allConnectedNodes = [];
// get the second degree nodes
for (i = 1; i < degrees; i++) {
for (j = 0; j < connectedNodes.length; j++) {
allConnectedNodes = allConnectedNodes.concat(
network.getConnectedNodes(connectedNodes[j])
);
}
}
// all second degree nodes get a different color and their label back
for (i = 0; i < allConnectedNodes.length; i++) {
allNodes[allConnectedNodes[i]].color = "rgba(150,150,150,0.75)";
if (allNodes[allConnectedNodes[i]].hiddenLabel !== undefined) {
allNodes[allConnectedNodes[i]].label =
allNodes[allConnectedNodes[i]].hiddenLabel;
allNodes[allConnectedNodes[i]].hiddenLabel = undefined;
}
}
// all first degree nodes get their own color and their label back
for (i = 0; i < connectedNodes.length; i++) {
allNodes[connectedNodes[i]].color = undefined;
if (allNodes[connectedNodes[i]].hiddenLabel !== undefined) {
allNodes[connectedNodes[i]].label =
allNodes[connectedNodes[i]].hiddenLabel;
allNodes[connectedNodes[i]].hiddenLabel = undefined;
}
}
// the main node gets its own color and its label back.
allNodes[selectedNode].color = undefined;
if (allNodes[selectedNode].hiddenLabel !== undefined) {
allNodes[selectedNode].label = allNodes[selectedNode].hiddenLabel;
allNodes[selectedNode].hiddenLabel = undefined;
}
} else if (highlightActive === true) {
// reset all nodes
for (var nodeId in allNodes) {
allNodes[nodeId].color = undefined;
if (allNodes[nodeId].hiddenLabel !== undefined) {
allNodes[nodeId].label = allNodes[nodeId].hiddenLabel;
allNodes[nodeId].hiddenLabel = undefined;
}
}
highlightActive = false;
}
// transform the object into an array
var updateArray = [];
for (nodeId in allNodes) {
if (allNodes.hasOwnProperty(nodeId)) {
updateArray.push(allNodes[nodeId]);
}
}
nodesDataset.update(updateArray);
}
redrawAll();
This is something that can be supplied in the template file, for more info on that, checkout #57
I have always wanted to add custom functionality like this to the default template, but have never gotten around to it.
Thanks @boludo00. This solves the question of @lazarospa
On my part, I'm looking for the Python counterpart as explained in the Select by node id section found in this link: https://cran.r-project.org/web/packages/visNetwork/vignettes/Introduction-to-visNetwork.html
I have a network graph that has about 500 nodes. Looking for a single node can be challenging. This is where a feature like Select by node id can come handy. Another thing that can be really useful is being able to Add legend - also a section in the above mentioned link.
Let me see what I can do about that. I agree that could be helpful when looking for a specific node.
Thanks @boludo00. Very much appreciated.
I have been messing around with some pretty big changes in order to support and maintain custom interactions, check out PR #91 you can see a demonstration of some added features I think you were requesting. If you want to pull that expiremental branch you can mess with it and see if it needs any more attention, but I'm going to work on cleaning and testing some more things before I release this into the wild.
Thank you. The demo looks great! It's exactly the feature I was looking for.
I tried to replicate what you did. After pulling the experimental branch, all I'm presented is the dropdown menu and no graph. Without the pulled branch, and excluding the parameters neighborhood_highlight and select_menu, the graph was generated, but (of course) without the dropdown menu.
Oh I see. There might have been an issue with resolving the dependencies that I didn't catch. Are you working out of a Jupyter Notebook by chance? I would take a look at your browser's debugger and check out the console for any errors.
Here you go. localhost-1619774542138.log
P.S. Actually, I'm using Anaconda distro and PyCharm. I tried Jupyter notebook to completely replicate your demo. Also, if I may add:
Thank you.
Ok, I got the select working with greying out the rest. It is basically the same behavior of neighborhood highlight, except it doesnt fire on click event. Just on selection. Which means, too reset the nodes colors I added a button you can click instead of clicking off the nodes.
I think I know what you mean by this error. I got this error when attempting to do g.add_node(n_id, n_id, color="blue")
because a recent change to add_node
added the color
kwarg inplace of the label. So therefore it was receiving 2 args for color. To avoid this you can either use g.add_node(n_id, color="red")
or g.add_node(n_id, label=n_id, color="red")
I have added a legend before in an internal project so this is definitely doable.
Thanks @boludo00.
Have you seen the console errors?
This feature would be great. I tried using the example with the experimental branch but couldn't get it to work. @boludo00 do you know if this will be on any future update?
Hi @boludo00
I'm trying to change the color of the nodes when it gets clicked on. I've tried using the options dictionary but it didn't work:
network_graph.set_options( """ var options = { "configure": { "enabled": true }, "interaction": { "hover": true }, "nodes":{ "chosen": true, "color": { "highlight": { "border": "#D66A5E", "background": "#C93C2C" }, "hover" : { "border": "#D66A5E", "background": "#C93C2C" } }, "font": { "size": 20 } } } """)
How can I achieve this ?
Thanks!
Is there a way to select a node and visualize only the nodes that are connected with the selected one ?