phy_dig_twin / ui_components.py
cryogenic22's picture
Create ui_components.py
46922d7 verified
import streamlit as st
def set_custom_css():
"""Set custom CSS for better styling"""
custom_css = """
<style>
.main {
background-color: #f5f7f9;
}
.stTabs [data-baseweb="tab-list"] {
gap: 8px;
}
.stTabs [data-baseweb="tab"] {
height: 50px;
white-space: pre-wrap;
background-color: #f0f2f6;
border-radius: 5px 5px 0px 0px;
padding-left: 20px;
padding-right: 20px;
}
.stTabs [aria-selected="true"] {
background-color: #4e8cff;
color: white;
}
.css-1kyxreq {
justify-content: center;
}
.big-font {
font-size:20px !important;
font-weight: bold;
}
.medium-font {
font-size:16px !important;
}
.highlight {
background-color: #f0f7ff;
padding: 15px;
border-radius: 5px;
border-left: 5px solid #4e8cff;
}
.card {
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
.metric-card {
background-color: white;
padding: 15px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
text-align: center;
}
.metric-value {
font-size: 24px;
font-weight: bold;
color: #0068c9;
}
.metric-label {
font-size: 14px;
color: #555;
}
hr {
margin-top: 30px;
margin-bottom: 30px;
}
</style>
"""
st.markdown(custom_css, unsafe_allow_html=True)
def metric_card(label, value, description=None, color="#0068c9"):
"""Create a custom styled metric card"""
html = f"""
<div class="metric-card">
<div class="metric-label">{label}</div>
<div class="metric-value" style="color: {color};">{value}</div>
{f'<div class="metric-description">{description}</div>' if description else ''}
</div>
"""
return st.markdown(html, unsafe_allow_html=True)
def create_sidebar(brand="XenoGlip (DPP-4 Inhibitor)"):
"""Create a sidebar with controls"""
with st.sidebar:
st.title("PhysicianTwin™")
st.markdown("### Digital Twin Parameters")
# Brand selection
selected_brand = st.selectbox("Select Brand", [brand])
# Therapeutic Area
therapeutic_area = st.selectbox("Therapeutic Area", ["Type 2 Diabetes"])
# Physician segment selection
physician_segments = st.multiselect(
"Physician Segments",
["Primary Care", "Endocrinology", "Cardiology"],
default=["Primary Care", "Endocrinology"]
)
# Time period
time_period = st.select_slider(
"Time Period",
options=["Current Quarter", "6 Months", "1 Year", "2 Years"],
value="6 Months"
)
# Payer mix
st.markdown("### Payer Mix")
commercial = st.slider("Commercial", 0, 100, 65, 5)
medicare = st.slider("Medicare", 0, 100, 25, 5)
medicaid = st.slider("Medicaid", 0, 100, 10, 5)
# Ensure total is 100%
total = commercial + medicare + medicaid
if total != 100:
st.warning(f"Payer mix totals {total}%. Please adjust to total 100%.")
st.markdown("---")
st.markdown("### Analysis Options")
analysis_depth = st.select_slider(
"Analysis Depth",
options=["Basic", "Standard", "Comprehensive"],
value="Standard"
)
confidence_display = st.checkbox("Show Confidence Intervals", value=True)
st.markdown("---")
st.markdown("*Powered by Anthropic Claude*")
return {
"brand": selected_brand,
"therapeutic_area": therapeutic_area,
"physician_segments": physician_segments,
"time_period": time_period,
"payer_mix": {
"commercial": commercial,
"medicare": medicare,
"medicaid": medicaid
},
"analysis_depth": analysis_depth,
"confidence_display": confidence_display
}
def create_tabs():
"""Create tabs for different analyses"""
return st.tabs([
"📊 Market Overview",
"👥 Physician Segments",
"💬 Message Testing",
"🔮 Predictive Scenarios",
"🤖 Interactive Twin"
])
def header_section(brand, therapeutic_area):
"""Create the header section of the app"""
st.title("PhysicianTwin™ Digital Simulation")
st.markdown(f"### Brand: {brand} | Therapeutic Area: {therapeutic_area}")
def patient_profile_card(profile_data):
"""Create a patient profile card"""
html = f"""
<div class="card">
<h3>Patient Profile</h3>
<div class="patient-details">
<p><strong>Age:</strong> {profile_data['age']}</p>
<p><strong>Gender:</strong> {profile_data['gender']}</p>
<p><strong>BMI:</strong> {profile_data['bmi']}</p>
<p><strong>A1C:</strong> {profile_data['a1c']}%</p>
<p><strong>Comorbidities:</strong> {profile_data['comorbidities']}</p>
<p><strong>Current Medications:</strong> {profile_data['medications']}</p>
</div>
</div>
"""
return st.markdown(html, unsafe_allow_html=True)
def create_expandable_sections(sections_data):
"""Create expandable sections with content"""
for title, content in sections_data.items():
with st.expander(title):
st.markdown(content)
def loading_spinner(message="Processing data..."):
"""Create a loading spinner with a message"""
with st.spinner(message):
import time
time.sleep(2) # Simulate processing time
def confidence_indicator(score, label="Confidence", description=None):
"""Create a confidence indicator with a score"""
color = "#5cb85c" if score >= 0.7 else "#f0ad4e" if score >= 0.5 else "#d9534f"
return metric_card(label, f"{score:.0%}", description, color)
def create_metric_row(metrics):
"""Create a row of metrics"""
cols = st.columns(len(metrics))
for i, (label, value, delta) in enumerate(metrics):
with cols[i]:
st.metric(label=label, value=value, delta=delta)
def kpi_dashboard(kpis):
"""Create a KPI dashboard section"""
st.markdown("## Key Performance Indicators")
# Create metrics in rows of 3
metrics = []
for label, value, delta in kpis:
metrics.append((label, value, delta))
if len(metrics) == 3:
create_metric_row(metrics)
metrics = []
# Add any remaining metrics
if metrics:
create_metric_row(metrics)