Got it! You want to create a well-structured discussion post for a forum (like the Streamlit Community forum or Stack Overflow) to get help with your PyVis + Streamlit integration. Here’s a template you can use. I’ve tailored it to your case, including all the necessary details the forum recommends. You just need to fill in a few placeholders:
Title:
PyVis Graph in Streamlit: Highlight Nodes and Send Clicked Node ID to Backend
Body:
Hi everyone,
I’m trying to integrate an interactive PyVis network graph into Streamlit. I want the following behavior:
-
Clicking a node should highlight connected nodes (incoming/outgoing).
-
Clicking a node should also send the node ID back to Streamlit .
Right now, my setup highlights nodes correctly, but I cannot retrieve the clicked node ID in Streamlit. I’ve tried components.html, st_javascript, and streamlit_js_eval, but I’m either getting DeltaGenerator objects or 0, and the value never updates.
Environment:
-
Streamlit version: 1.29.0
-
Python version: 3.10.12
-
OS: Linux
Code snippet:
import streamlit as st
import streamlit.components.v1 as components
from streamlit_javascript import st_javascript
# Load PyVis HTML
with open("claims_dependency.html", "r", encoding="utf-8") as f:
html_content = f.read()
highlight_js = """
function highlightNode(params) {
nodes.update(nodes.get().map(n => ({id: n.id, color: n.originalColor})));
if (params.nodes.length === 0) return;
var selectedNode = params.nodes[0];
var incoming = network.getConnectedNodes(selectedNode, 'from');
incoming.forEach(nid => nodes.update({id: nid, color: 'rgba(205,175,140)'}));
var outgoing = network.getConnectedNodes(selectedNode, 'to');
outgoing.forEach(nid => nodes.update({id: nid, color: 'rgba(204,255,153)'}));
window.lastClickedNode = selectedNode;
}
nodes.get().forEach(n => n.originalColor = n.color);
network.on("click", highlightNode);
"""
html_content = html_content.replace("</body>", f"<script>{highlight_js}</script></body>")
col1, col2 = st.columns([2,1])
with col1:
st.subheader("Claims Dependency Graph")
components.html(html_content, height=900, width=1200)
with col2:
st.subheader("📄 Claim Metadata")
clicked_node = st_javascript("window.lastClickedNode")
if clicked_node:
st.session_state["clicked_node"] = clicked_node
if "clicked_node" in st.session_state:
st.write("Clicked node:", st.session_state["clicked_node"])
else:
st.info("Click a node in the graph to see metadata")
Issue / Error Messages:
-
clicked_nodealways returns 0 or aDeltaGeneratorobject. -
Using
returnin JS does not propagate the value to Streamlit. -
I’ve tried multiple approaches, including
streamlit_js_evalandst_javascript, but cannot get the value reliably. -
Node highlighting works correctly.
What I’ve tried:
-
Returning the clicked node from JS via
return→ does not work withcomponents.html. -
Using
st_javascript("window.lastClickedNode")→ returns0orDeltaGenerator. -
Using
streamlit_js_eval→ also doesn’t update dynamically.
Question:
How can I capture the clicked node ID in Streamlit while keeping PyVis node highlighting intact?
Additional notes:
-
App is running locally (or deployed)
-
Only need single node ID per click