Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1719,24 +1719,39 @@ with col_insights:
|
|
| 1719 |
st.info("Shift data not available for Shift Pattern Analysis.")
|
| 1720 |
|
| 1721 |
# 4. Operator Risk Profiling
|
| 1722 |
-
|
| 1723 |
-
|
| 1724 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1725 |
|
| 1726 |
-
st.markdown(f"**High-Risk Operator Identification**")
|
| 1727 |
-
for op_name, count in top_risk_operators.items():
|
| 1728 |
-
op_pct = (count / len(df)) * 100
|
| 1729 |
-
# Ganti st.metric dengan HTML custom
|
| 1730 |
-
st.markdown(f"""
|
| 1731 |
-
<div style="font-size: 24px; font-weight: bold;">{count} alerts</div>
|
| 1732 |
-
<div style="color: red; font-size: 14px; margin-top: -5px;">↑ {op_pct:.1f}% of total alerts</div>
|
| 1733 |
-
""", unsafe_allow_html=True)
|
| 1734 |
-
if op_pct > 5:
|
| 1735 |
-
st.warning(f"Operator {op_name} has high fatigue risk ({op_pct:.1f}% of alerts). Consider coaching or rest plan.")
|
| 1736 |
-
else:
|
| 1737 |
-
st.info(f"Operator {op_name} fatigue risk is within acceptable range ({op_pct:.1f}%).")
|
| 1738 |
-
else:
|
| 1739 |
-
st.info("Operator data not available for Operator Risk Profiling.")
|
| 1740 |
|
| 1741 |
|
| 1742 |
# Kolom kanan: AI Recommendations
|
|
|
|
| 1719 |
st.info("Shift data not available for Shift Pattern Analysis.")
|
| 1720 |
|
| 1721 |
# 4. Operator Risk Profiling
|
| 1722 |
+
# 4. Operator Risk Profiling
|
| 1723 |
+
if col_operator and col_operator in df.columns:
|
| 1724 |
+
operator_alerts = df[col_operator].value_counts()
|
| 1725 |
+
top_risk_operators = operator_alerts.head(5) # Top 5 operators by alerts
|
| 1726 |
+
|
| 1727 |
+
st.markdown("**High-Risk Operator Identification**")
|
| 1728 |
+
|
| 1729 |
+
# Warna berdasarkan ranking 1–5
|
| 1730 |
+
colors = ["#d32f2f", "#e57373", "#ef9a9a", "#ffcdd2", "#ffe1e4"]
|
| 1731 |
+
|
| 1732 |
+
for idx, (op_name, count) in enumerate(top_risk_operators.items()):
|
| 1733 |
+
op_pct = (count / len(df)) * 100
|
| 1734 |
+
color = colors[idx] if idx < len(colors) else colors[-1]
|
| 1735 |
+
|
| 1736 |
+
# Teks normal untuk nama dan jumlah alert
|
| 1737 |
+
st.markdown(f"**Operator:** {op_name} \n**Alerts:** {count}")
|
| 1738 |
+
|
| 1739 |
+
# Hanya 'Share' yang berwarna sesuai ranking
|
| 1740 |
+
st.markdown(
|
| 1741 |
+
f"<span style='font-weight:600'>Share:</span> "
|
| 1742 |
+
f"<span style='color:{color}; font-weight:700'>{op_pct:.1f}% of total alerts</span>",
|
| 1743 |
+
unsafe_allow_html=True
|
| 1744 |
+
)
|
| 1745 |
+
|
| 1746 |
+
# Risk message (tetap gunakan component Streamlit agar konsisten)
|
| 1747 |
+
if op_pct > 5:
|
| 1748 |
+
st.warning(f"Operator {op_name} has high fatigue risk ({op_pct:.1f}%). Consider coaching or rest plan.")
|
| 1749 |
+
else:
|
| 1750 |
+
st.info(f"Operator {op_name} fatigue risk is within acceptable range ({op_pct:.1f}%).")
|
| 1751 |
+
|
| 1752 |
+
else:
|
| 1753 |
+
st.info("Operator data not available for Operator Risk Profiling.")
|
| 1754 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1755 |
|
| 1756 |
|
| 1757 |
# Kolom kanan: AI Recommendations
|