File size: 1,681 Bytes
3f06a92 7117e78 3f06a92 7117e78 3f06a92 7117e78 3f06a92 7117e78 3f06a92 7117e78 3f06a92 7117e78 3f06a92 7117e78 3f06a92 7117e78 3f06a92 7117e78 3f06a92 7117e78 3f06a92 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
"""
Basic NetworkX helpers for MedGenesis graphs.
Key improvement:
build_nx() now accepts edge dictionaries in either of the two
common formats:
• {'source': 'n1', 'target': 'n2'} (Streamlit-agraph)
• {'from': 'n1', 'to': 'n2'} (PyVis)
This prevents KeyError crashes when nodes / edges come from different
UI toolchains.
"""
from typing import List, Dict, Tuple
import networkx as nx
# ----------------------------------------------------------------------
def _edge_endpoints(e: Dict) -> Tuple[str, str] | None:
"""Return (src, dst) if both ends exist; otherwise None."""
src = e.get("source") or e.get("from")
dst = e.get("target") or e.get("to")
if src and dst:
return src, dst
return None
def build_nx(nodes: List[Dict], edges: List[Dict]) -> nx.Graph:
"""
Convert agraph/PyVis node+edge dicts into a NetworkX Graph.
* Skips malformed edges rather than raising KeyError.
* Node label stored as attribute 'label'.
"""
G = nx.Graph()
# add nodes
for n in nodes:
G.add_node(n["id"], label=n.get("label", n["id"]))
# add edges
for e in edges:
endpoints = _edge_endpoints(e)
if endpoints:
G.add_edge(*endpoints)
return G
# ----------------------------------------------------------------------
def get_top_hubs(G: nx.Graph, k: int = 5) -> List[Tuple[str, float]]:
"""Top-k nodes by degree centrality."""
dc = nx.degree_centrality(G)
return sorted(dc.items(), key=lambda x: x[1], reverse=True)[:k]
def get_density(G: nx.Graph) -> float:
"""Return graph density in [0,1]."""
return nx.density(G)
|