File size: 3,123 Bytes
9670807
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12e9a29
9670807
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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."""
    return f"""
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    oscape-dagre@2.5.0/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>
        const elements = {elements_json};
        const cy = cytoscape({{
            container: document.getElementById('cy'),
            elements: elements,
            style: [
                {{
                    selector: 'node',
                    style: {{
                        'label': 'data(label)',
                        'background-color': '{random_rgb()}',
                        'text-valign': 'center',
                        'color': '#fff',
                        'font-size': 12
                    }}
                }},
                {{
                    selector: 'edge',
                    style: {{
                        'width': 'mapData(weight, 1, 5, 1, 5)',
                        'line-color': '#ccc',
                        'target-arrow-color': '#ccc',
                        'target-arrow-shape': 'triangle'
                    }}
                }}
            ],
            layout: {{ name: 'dagre', directed: true }}
        }});
    </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)