SHELLAPANDIANGANHUNGING commited on
Commit
90cfa07
·
verified ·
1 Parent(s): dd394a0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -28
app.py CHANGED
@@ -1700,36 +1700,86 @@ with col_insights:
1700
  st.info("Speed data not available for High-Speed Fatigue Analysis.")
1701
 
1702
  # 3. Shift Pattern Analysis
1703
- if col_shift and col_shift in df.columns:
1704
- shift_counts = df[col_shift].value_counts()
1705
- # shift_alerts_by_hour = df.groupby([col_shift, 'hour']).size().reset_index(name='alerts') # Tidak digunakan dalam tampilan ini
1706
-
1707
- st.markdown(f"**Shift Pattern Risk**")
1708
- for shift_val in shift_counts.index:
1709
- shift_pct = (shift_counts[shift_val] / len(df)) * 100
1710
- st.metric(f"Shift {shift_val} Alerts", f"{shift_counts[shift_val]}", f"{shift_pct:.1f}% of total alerts")
1711
- if shift_pct > 50: # If one shift has more than 50% of alerts
1712
- st.warning(f"Shift {shift_val} has disproportionately high alerts ({shift_pct:.1f}%). Review shift scheduling and workload.")
1713
- else:
1714
- st.info(f"Shift {shift_val} alert distribution is acceptable ({shift_pct:.1f}%).")
1715
- else:
1716
- st.info("Shift data not available for Shift Pattern Analysis.")
1717
 
1718
- # 4. Operator Risk Profiling
1719
- if col_operator and col_operator in df.columns:
1720
- operator_alerts = df[col_operator].value_counts()
1721
- top_risk_operators = operator_alerts.head(5) # Top 5 operators by alerts
1722
 
1723
- st.markdown(f"**High-Risk Operator Identification**")
1724
- for op_name, count in top_risk_operators.items():
1725
- op_pct = (count / len(df)) * 100
1726
- st.metric(f"Operator: {op_name}", f"{count} alerts", f"{op_pct:.1f}% of total alerts")
1727
- if op_pct > 5: # If an operator has more than 5% of all alerts
1728
- st.warning(f"Operator {op_name} has high fatigue risk ({op_pct:.1f}% of alerts). Consider coaching or rest plan.")
1729
- else:
1730
- st.info(f"Operator {op_name} fatigue risk is within acceptable range ({op_pct:.1f}%).")
1731
- else:
1732
- st.info("Operator data not available for Operator Risk Profiling.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1733
 
1734
 
1735
  # Kolom kanan: AI Recommendations
 
1700
  st.info("Speed data not available for High-Speed Fatigue Analysis.")
1701
 
1702
  # 3. Shift Pattern Analysis
1703
+ if col_shift and col_shift in df.columns:
1704
+ shift_counts = df[col_shift].value_counts()
1705
+
1706
+ st.markdown("**Shift Pattern Risk**")
1707
+
1708
+ shift_color = "#d32f2f" # warna merah gelap
 
 
 
 
 
 
 
 
1709
 
1710
+ for shift_val in shift_counts.index:
1711
+ shift_pct = (shift_counts[shift_val] / len(df)) * 100
 
 
1712
 
1713
+ # Metric-style card
1714
+ st.markdown(
1715
+ f"""
1716
+ <div style="
1717
+ padding: 12px 16px;
1718
+ border-radius: 10px;
1719
+ background-color: #f9f9f9;
1720
+ border: 1px solid #ddd;
1721
+ margin-bottom: 10px;
1722
+ ">
1723
+ <div style="font-size: 16px; font-weight: 600;">
1724
+ Shift {shift_val} Alerts
1725
+ </div>
1726
+
1727
+ <div style="font-size: 28px; font-weight: 700;">
1728
+ {shift_counts[shift_val]}
1729
+ </div>
1730
+
1731
+ <div style="font-size: 14px; font-weight: 700; color:{shift_color};">
1732
+ {shift_pct:.1f}% of total alerts
1733
+ </div>
1734
+ </div>
1735
+ """,
1736
+ unsafe_allow_html=True
1737
+ )
1738
+
1739
+ # Risk Message
1740
+ if shift_pct > 50:
1741
+ st.warning(
1742
+ f"Shift {shift_val} has disproportionately high alerts ({shift_pct:.1f}%). Review shift scheduling and workload."
1743
+ )
1744
+ else:
1745
+ st.info(
1746
+ f"Shift {shift_val} alert distribution is acceptable ({shift_pct:.1f}%)."
1747
+ )
1748
+ else:
1749
+ st.info("Shift data not available for Shift Pattern Analysis.")
1750
+
1751
+ # 4. Operator Risk Profiling
1752
+ if col_operator and col_operator in df.columns:
1753
+ operator_alerts = df[col_operator].value_counts()
1754
+ top_risk_operators = operator_alerts.head(5) # Top 5 operators by alerts
1755
+
1756
+ st.markdown("**High-Risk Operator Identification**")
1757
+
1758
+ # Warna berdasarkan ranking 1–5
1759
+ colors = ["#d32f2f", "#e57373", "#ef9a9a", "#ffcdd2", "#ffe1e4"]
1760
+
1761
+ for idx, (op_name, count) in enumerate(top_risk_operators.items()):
1762
+ op_pct = (count / len(df)) * 100
1763
+ color = colors[idx] if idx < len(colors) else colors[-1]
1764
+
1765
+ # Teks normal untuk nama dan jumlah alert
1766
+ st.markdown(f"**Operator:** {op_name} \n**Alerts:** {count}")
1767
+
1768
+ # Hanya 'Share' yang berwarna sesuai ranking
1769
+ st.markdown(
1770
+ f"<span style='font-weight:600'>Share:</span> "
1771
+ f"<span style='color:{color}; font-weight:700'>{op_pct:.1f}% of total alerts</span>",
1772
+ unsafe_allow_html=True
1773
+ )
1774
+
1775
+ # Risk message (tetap gunakan component Streamlit agar konsisten)
1776
+ if op_pct > 5:
1777
+ st.warning(f"Operator {op_name} has high fatigue risk ({op_pct:.1f}%). Consider coaching or rest plan.")
1778
+ else:
1779
+ st.info(f"Operator {op_name} fatigue risk is within acceptable range ({op_pct:.1f}%).")
1780
+
1781
+ else:
1782
+ st.info("Operator data not available for Operator Risk Profiling.")
1783
 
1784
 
1785
  # Kolom kanan: AI Recommendations