import streamlit as st
import streamlit.components.v1 as components
import json
import networkx as nx
from pyvis.network import Network
st.set_page_config(page_title="Education Network Explorer", layout="wide")
st.title("đ Education Network Explorer")
# ---------- Load graph from JSON ----------
@st.cache_data
def load_graph_from_json(path: str):
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
G = nx.Graph()
for node in data.get("nodes", []):
G.add_node(
node["id"],
label=node.get("label", node["id"]),
influencer_count=node.get("influencer_count", 0),
top_influencers=node.get("top_influencers", []),
)
for edge in data.get("edges", []):
G.add_edge(edge["source"], edge["target"], weight=edge.get("weight", 1))
return G
nx_graph = load_graph_from_json("education_graph.json")
# ---------- Intro ----------
st.markdown("""
Welcome to the **Education Network Explorer** â an interactive dashboard for exploring relationships between education topics on Twitter.
â Nodes are topics
â Edges connect topics that share influencers
â Hover a node to see influencer count and top users
""")
st.markdown("---")
# ---------- Main preview (static HTML you generated in Colab) ----------
st.subheader("đ Interactive Network Graph")
try:
with open("education_graph_preview.html", "r", encoding="utf-8") as f:
graph_html = f.read()
components.html(graph_html, height=750, scrolling=True)
except FileNotFoundError:
st.warning("`education_graph_preview.html` not found. Upload it to the Space or regenerate it.")
st.markdown("---")
# ---------- Subgraph explorer ----------
st.subheader("đ¯ Explore by Topic")
# Show labels in the dropdown, map back to node ids
all_nodes = sorted(nx_graph.nodes())
label_by_id = {n: nx_graph.nodes[n].get("label", n) for n in all_nodes}
id_by_label = {v: k for k, v in label_by_id.items()}
selected_label = st.selectbox("Select a topic", [label_by_id[n] for n in all_nodes])
selected_topic = id_by_label[selected_label]
# Build neighborhood subgraph
sub_nodes = [selected_topic] + list(nx_graph.neighbors(selected_topic))
subgraph = nx_graph.subgraph(sub_nodes)
# PyVis render of the subgraph
net = Network(height="750px", width="100%", notebook=False, bgcolor="#ffffff", font_color="black")
net.barnes_hut()
net.from_nx(subgraph)
# Enrich tooltips/labels
for node in net.nodes:
nid = node["id"]
tdata = nx_graph.nodes[nid]
label = tdata.get("label", nid)
count = tdata.get("influencer_count", 0)
top_users = tdata.get("top_influencers", [])
node["title"] = f"{label}
Influencers: {count}
Top: {', '.join(top_users)}"
node["label"] = label
net.save_graph("education_graph_filtered.html")
with open("education_graph_filtered.html", "r", encoding="utf-8") as f:
components.html(f.read(), height=750, scrolling=True)
st.markdown("---")
st.markdown("âšī¸ *Click a node to view influencer data in the tooltip.*")