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)