HumanPlusX / src /pages /analysis.py
FajarHidaa's picture
Upload 3 files
ed5d5d7 verified
Raw History Blame Contribute Delete
6.64 kB
"""
Human+ β€” Page 2: AI Analysis
Refactored: loading states & biomarker rows pakai Streamlit native.
"""
import streamlit as st
from ui.components import (
render_loading_steps,
render_progress_bar,
render_section_label,
render_error_state,
render_biomarker_summary_banner,
render_biomarker_row,
render_success_banner,
ANALYSIS_STEPS,
)
from ui.chart_components import (
render_gauge_grid,
render_biomarker_bar_chart,
render_status_donut,
)
def render_analysis_page():
if not st.session_state.get("uploaded_pdf_bytes"):
render_error_state(
title="Tidak ada file PDF",
message="Silakan kembali ke langkah pertama dan upload hasil lab Anda.",
)
if st.button("← Kembali ke Upload", use_container_width=True):
st.session_state.step = 1
st.rerun()
return
if st.session_state.get("extracted_biomarkers") is not None:
_render_biomarker_results()
return
_run_analysis()
# ── Analysis runner ──────────────────────────────────────────────────
def _run_analysis():
render_section_label("MENGANALISIS LAB ANDA", "⚑")
status_ph = st.empty()
progress_ph = st.empty()
steps_ph = st.empty()
def _update(step_idx: int, msg: str):
with status_ph:
st.caption(f"βš™οΈ {msg}...")
with progress_ph:
render_progress_bar((step_idx + 0.5) / len(ANALYSIS_STEPS))
with steps_ph:
render_loading_steps(ANALYSIS_STEPS, step_idx)
# Step 0 β€” warm up vector store
_update(0, ANALYSIS_STEPS[0])
try:
from core.rag_engine import get_vector_store
get_vector_store()
except Exception:
pass
# Step 1 β€” Gemini PDF extraction
_update(1, ANALYSIS_STEPS[1])
try:
from core.pdf_processor import extract_biomarkers
biomarkers = extract_biomarkers(st.session_state.uploaded_pdf_bytes)
except Exception as e:
_clear(steps_ph, status_ph, progress_ph)
render_error_state(
title="Gagal Menganalisis PDF",
message=f"{e}\n\nPastikan PDF berisi hasil lab yang valid dan terbaca.",
show_contact=True,
)
col1, col2 = st.columns(2)
with col1:
if st.button("← Upload Lagi", use_container_width=True):
st.session_state.step = 1
st.session_state.uploaded_pdf_bytes = None
st.rerun()
with col2:
if st.button("πŸ”„ Coba Lagi", type="primary", use_container_width=True):
st.rerun()
return
# Step 2 & 3 β€” finalize
_update(2, ANALYSIS_STEPS[2])
import time; time.sleep(0.3)
_update(3, ANALYSIS_STEPS[3])
import time; time.sleep(0.3)
st.session_state.extracted_biomarkers = biomarkers
with progress_ph:
render_progress_bar(1.0)
with status_ph:
st.caption("βœ… Analisis selesai")
import time; time.sleep(0.4)
st.rerun()
def _clear(*placeholders):
for ph in placeholders:
ph.empty()
# ── Results renderer ─────────────────────────────────────────────────
def _render_biomarker_results():
biomarkers = st.session_state.extracted_biomarkers
if not biomarkers:
render_error_state(
title="Tidak ada biomarker terdeteksi",
message="Coba upload file PDF yang lebih jelas atau format hasil lab standar.",
show_contact=True,
)
if st.button("← Upload Ulang", use_container_width=True):
for k in ["uploaded_pdf_bytes", "extracted_biomarkers", "generated_protocol"]:
st.session_state[k] = None
st.session_state.step = 1
st.rerun()
return
optimal = sum(1 for b in biomarkers if b["status"] == "optimal")
warning = sum(1 for b in biomarkers if b["status"] == "warning")
danger = sum(1 for b in biomarkers if b["status"] == "danger")
render_success_banner(
title=f"{len(biomarkers)} biomarker berhasil dianalisis",
subtitle="Dibandingkan dengan Human+ optimal ranges β€” bukan range lab standar",
)
render_biomarker_summary_banner(optimal, warning, danger)
# ── Charts ────────────────────────────────────────────────────
render_section_label("VISUALISASI BIOMARKER", "πŸ“Š")
col_donut, col_bar = st.columns([1, 2])
with col_donut:
render_status_donut(optimal, warning, danger)
with col_bar:
render_biomarker_bar_chart(biomarkers)
render_section_label("GAUGE β€” MARKER PRIORITAS", "🎯")
render_gauge_grid(biomarkers)
# ── Biomarker rows ─────────────────────────────────────────────
if danger:
render_section_label(f"PERLU PERHATIAN β€” {danger} MARKER", "πŸ”΄")
for b in biomarkers:
if b["status"] == "danger":
render_biomarker_row(b["name"], b["value"], b["unit"], b["status"], b.get("reference", ""))
if warning:
render_section_label(f"SUB-OPTIMAL β€” {warning} MARKER", "🟑")
for b in biomarkers:
if b["status"] == "warning":
render_biomarker_row(b["name"], b["value"], b["unit"], b["status"], b.get("reference", ""))
if optimal:
render_section_label(f"SUDAH OPTIMAL β€” {optimal} MARKER", "🟒")
for b in biomarkers:
if b["status"] == "optimal":
render_biomarker_row(b["name"], b["value"], b["unit"], b["status"], b.get("reference", ""))
neutral = [b for b in biomarkers if b["status"] == "neutral"]
if neutral:
with st.expander(f"πŸ“Š {len(neutral)} marker lainnya"):
for b in neutral:
render_biomarker_row(b["name"], b["value"], b["unit"], "neutral", "")
st.write("")
if st.button("πŸ”¬ Generate Protocol Personal Saya", type="primary", use_container_width=True):
st.session_state.step = 3
st.rerun()
if st.button("← Upload Lab Lain", use_container_width=True):
for k in ["uploaded_pdf_bytes", "extracted_biomarkers", "generated_protocol", "pdf_filename"]:
st.session_state[k] = None
st.session_state.step = 1
st.rerun()