File size: 3,830 Bytes
d8f6f04
 
7aa8120
d8f6f04
7aa8120
d8f6f04
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
015baef
d8f6f04
 
 
 
 
857510a
 
 
d8f6f04
015baef
 
d8f6f04
 
 
 
 
857510a
015baef
857510a
015baef
d8f6f04
015baef
d8f6f04
 
 
015baef
d8f6f04
015baef
d8f6f04
015baef
d8f6f04
 
 
015baef
 
 
d8f6f04
015baef
d8f6f04
857510a
 
 
d8f6f04
015baef
 
857510a
015baef
857510a
015baef
857510a
 
 
d8f6f04
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import json
import random
import streamlit as st
import streamlit.components.v1 as components

# --- CONFIGURATION -------------------------------------------------------------
HEIGHT = 600
DEFAULT_NODES = 10
DEFAULT_EDGES = 12

# --- HELPER FUNCTIONS ----------------------------------------------------------
def random_rgb():
    return "#{:02x}{:02x}{:02x}".format(
        random.randint(50, 200),
        random.randint(50, 200),
        random.randint(50, 200)
    )

def build_cytoscape_elements(n_nodes, n_edges):
    """Return Cytoscape-compatible elements JSON."""
    nodes = [{"data": {"id": str(i), "label": f"Node {i}"}} for i in range(n_nodes)]
    edges = [
        {
            "data": {
                "id": f"{u}-{v}",
                "source": str(u),
                "target": str(v),
                "weight": random.randint(1, 5),
            }
        }
        for u, v in [random.sample(range(n_nodes), 2) for _ in range(n_edges)]
    ]
    return nodes + edges

def build_html(elements_json, height):
    """Return complete HTML/JS string for standalone Cytoscape viewer."""
    background_color = random_rgb()
    return f"""
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cytoscape.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/dagre.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/cytoscape-dagre.js"></script>
    <style>
        html, body {{{{ margin: 0; height: 100%; }}}}
        #cy {{{{ width: 100%; height: {height}px; border: 1px solid #ccc; }}}}
    </style>
</head>
<body>
    <div id="cy"></div>
    <script>
        // Register dagre layout extension
        if (typeof cytoscape !== 'undefined' && typeof cytoscape.use === 'function' && typeof dagre !== 'undefined') {{
          cytoscape.use(cytoscapeDagre);
        }}
        const elements = {elements_json};
        const cy = cytoscape({{
            container: document.getElementById('cy'),
            elements: elements,
            style: [
                {{
                    selector: 'node',
                    style: {{
                        'label': 'data(label)',
                        'background-color': '{background_color}',
                        'text-valign': 'center',
                        'color': '#fff',
                        'font-size': 12
                    }}
                }},
                {{
                    selector: 'edge',
                    style: {{
                        'width': 'mapData(weight, 1, 5, 1, 5)',
                        'line-color': '#bbb',
                        'target-arrow-color': '#bbb',
                        'curve-style': 'bezier',
                        'target-arrow-shape': 'triangle'
                    }}
                }}
            ]
        }});
        // Apply layout after elements are added
        cy.layout({{ name: 'dagre', rankDir: 'LR' }}).run();

        // Resize handling for Streamlit container
        window.addEventListener('resize', () => cy.resize());
    </script>
</body>
</html>
    """

# --- STREAMLIT UI --------------------------------------------------------------
st.set_page_config(page_title="Cytoscape + Streamlit Demo", layout="wide")
st.title("Cytoscape Network Viewer in Streamlit")

with st.sidebar:
    st.header("Controls")
    n_nodes = st.slider("Nodes", 3, 50, DEFAULT_NODES)
    n_edges = st.slider("Edges", max(1, n_nodes - 1), 100, DEFAULT_EDGES)

    if st.button("Regenerate"):
        st.cache_data.clear()

# --- RENDER CYTOSCAPE ----------------------------------------------------------
elements = build_cytoscape_elements(n_nodes, n_edges)
html = build_html(json.dumps(elements), HEIGHT)
components.html(html, height=HEIGHT)