import pandas as pd import streamlit as st from config.config import CRRA_COLORS, CRRA_FONT, PLOTLY_TEMPLATE def render_resource_input(name_clean, r, tooltip=None): """Render a number_input widget for a single resource availability cap. Writes the entered value into st.session_state.resource_caps[r]. Args: name_clean (str): display label (resource name without unit suffix). r (str): canonical resource name used as the session state key. tooltip (str | None): optional help text shown on hover. Returns: None """ widget_key = f"cap_{r}" if widget_key not in st.session_state: existing = st.session_state.resource_caps.get(r, 0.0) st.session_state[widget_key] = existing if existing else None cap = st.number_input( label=name_clean, min_value=0.0, format="%.10g", value=None, placeholder="0.0", key=widget_key, help=tooltip, ) st.session_state.resource_caps[r] = cap if cap is not None else 0.0 def apply_chart_style(fig, height=None): """Apply the standard CRRA theme (font, colours, margins) to a Plotly figure. Args: fig: Plotly figure object. height (int | None): optional fixed height in pixels. Returns: fig: the same figure with updated layout. """ fig.update_layout( template=PLOTLY_TEMPLATE, font=dict(family=CRRA_FONT, size=12, color=CRRA_COLORS["black"]), margin=dict(t=40, b=40, l=40, r=20), legend=dict( orientation="v", yanchor="middle", y=0.5, xanchor="left", x=1.02, ), ) if height: fig.update_layout(height=height) return fig def register_chart_data(name: str, df: pd.DataFrame): """Store a chart's underlying DataFrame in the session-level registry for bulk export. Args: name (str): unique chart label used as the dict key and export sheet name. df (pd.DataFrame): data behind the chart. Returns: None """ st.session_state.setdefault("chart_data_registry", {}) st.session_state["chart_data_registry"][name] = df.copy() def show_bar(): """Render the CRRA four-colour decorative bar below page headings. Returns: None """ st.markdown( """