-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
94 lines (74 loc) · 3.26 KB
/
Copy pathmain.py
File metadata and controls
94 lines (74 loc) · 3.26 KB
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
import streamlit as st
from graph_utils import compute_graph as _compute_graph
st.set_page_config(
page_title="PyGraph",
layout="wide",
menu_items={},
)
st.markdown(
'<meta name="description" content="PyGraph — plot sin, cos and tan functions interactively. Adjust frequency and explore the graph in your browser.">',
unsafe_allow_html=True,
)
# ── Critical CSS ────────────────────────────────────────────────────────────
st.markdown(
"""
<style>
header[data-testid="stHeader"],
#stDecoration,
footer { display: none !important; }
/* Pre-reserve chart height to prevent CLS.
Vega-Lite renders inline — no iframe shift, so only title/slider need locking. */
/* Title row */
.stElementContainer:has([data-testid="stHeading"]),
.stElementContainer:has(.stHeading) { min-height: 96px; }
/* Slider row */
.stElementContainer:has([data-testid="stSlider"]) { min-height: 72px; }
/* st.info() alert box — bounding-rect height 56px; lock it to prevent CLS. */
.stElementContainer:has([data-testid="stAlert"]) { min-height: 60px; }
</style>
""",
unsafe_allow_html=True,
)
# ── Cached computation ──────────────────────────────────────────────────────
@st.cache_data(max_entries=64)
def compute_graph(equation: str, freq: int):
"""Streamlit-cached wrapper around graph_utils.compute_graph."""
return _compute_graph(equation, freq)
# ── UI ──────────────────────────────────────────────────────────────────────
st.title("📈 PyGraph")
# Place the selectbox and Plot button side-by-side.
col_input, col_btn = st.columns([5, 1])
with col_input:
equation = st.selectbox(
"Select Function",
["sin", "cos", "tan"],
index=None,
placeholder="Choose a function to plot…",
)
with col_btn:
# Invisible label keeps the button vertically aligned with the selectbox.
st.markdown('<div style="margin-top:28px"></div>', unsafe_allow_html=True)
plot_clicked = st.button("Plot 📈", use_container_width=True)
# Persist the last successfully plotted equation across reruns.
if plot_clicked:
if equation is not None:
st.session_state["active_equation"] = equation
else:
st.warning("Please select a function before plotting.", icon="⚠️")
active_equation = st.session_state.get("active_equation")
if active_equation is None:
st.info("Select a function and click **Plot** to draw the graph.", icon="📈")
else:
freq = st.slider("Frequency", 1, 10, 1)
# @st.fragment scopes reruns to this block only — slider drags don't
# re-execute the selectbox or any widget above.
@st.fragment
def render_chart(equation: str, freq: int) -> None:
df = compute_graph(equation, freq)
st.line_chart(
df,
height=600,
color=["#1f77b4"],
use_container_width=True,
)
render_chart(active_equation, freq)