SHELLAPANDIANGANHUNGING commited on
Commit
c86ec86
·
verified ·
1 Parent(s): abea765

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +82 -43
app.py CHANGED
@@ -893,36 +893,57 @@ with col_3b:
893
  if avg_leadtime_nama.empty:
894
  st.warning("No data for division-level executor analysis.")
895
  else:
896
- sort_opt = st.selectbox("Show:", ["Top 10", "Bottom 10"], key='sort_3b')
897
-
898
- full_sorted = avg_leadtime_nama.sort_values('avg_monthly_leadtime', ascending=True) # cepat lambat
899
- if sort_opt == "Fastest 10":
900
- subset = full_sorted.head(10).sort_values('avg_monthly_leadtime', ascending=True) # descending dalam subset (cepat di bawah)
901
- else:
902
- subset = full_sorted.tail(10).sort_values('avg_monthly_leadtime', ascending=False) # lambat di atas
 
903
 
904
- # Warna: 5 terlama → merah
905
- colored = add_color_by_global_rank(avg_leadtime_nama, 'avg_monthly_leadtime', worst_n=5, high_is_good=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
906
  subset = subset.merge(colored[['nama', 'color']], on='nama', how='left').fillna({'color': '#1f77b4'})
907
-
908
- # Reverse agar Slowest 10: tertinggi di atas
909
- if sort_opt == "Slowest 10":
910
- subset = subset.iloc[::-1]
911
-
912
  fig = px.bar(
913
- subset, x='avg_monthly_leadtime', y='nama', orientation='h',
914
- title=f'{sort_opt}',
 
 
 
915
  labels={'avg_monthly_leadtime': 'Avg Lead Time (Days)', 'nama': 'Division'},
916
- color='color', color_discrete_map={c: c for c in subset['color'].unique()},
 
917
  text=subset['avg_monthly_leadtime'].apply(lambda x: f'{x:.1f}')
918
  )
919
- fig.update_layout(height=450, showlegend=False, yaxis={'categoryorder': 'array', 'categoryarray': subset['nama'].tolist()})
 
 
 
 
920
  fig.update_traces(textposition='auto')
921
  st.plotly_chart(fig, use_container_width=True)
922
-
923
  if len(full_sorted) >= 2:
924
- min_lt, max_lt, mean_lt = full_sorted['avg_monthly_leadtime'].min(), full_sorted['avg_monthly_leadtime'].max(), full_sorted['avg_monthly_leadtime'].mean()
925
- fastest, slowest = full_sorted.iloc[0]['nama'], full_sorted.iloc[-1]['nama']
 
 
 
926
  st.markdown(
927
  f"<div class='ai-insight'>"
928
  f"<strong>Insight:</strong> Resolution time ranges from {min_lt:.1f} to {max_lt:.1f} days (avg: {mean_lt:.1f}). "
@@ -935,51 +956,69 @@ with col_3b:
935
 
936
  # ─── 3d: Executor by Individual ──────────────────────────────────────────────
937
  with col_3d:
938
- st.markdown(f"<h5 style='text-align:center;'>3d. Avg Lead Time per Executor ({EXECUTOR_INDIV_COL})</h5>", unsafe_allow_html=True)
 
 
 
939
  if avg_leadtime_per_indiv.empty:
940
  st.warning(f"No data for individual executor analysis (column: '{EXECUTOR_INDIV_COL}').")
941
  else:
942
- sort_opt = st.selectbox("Show:", ["Top 10", "Bottom 10"], key='sort_3d')
943
-
 
 
 
 
944
  full_sorted = avg_leadtime_per_indiv.sort_values('avg_monthly_leadtime', ascending=True)
945
- if sort_opt == "Fastest 10":
946
- subset = full_sorted.head(10).sort_values('avg_monthly_leadtime', ascending=True)
947
- else:
948
- subset = full_sorted.tail(10).sort_values('avg_monthly_leadtime', ascending=False)
949
 
 
 
 
 
950
 
951
-
952
- # Warna: 5 terlama → merah
953
- colored = add_color_by_global_rank(avg_leadtime_per_indiv, 'avg_monthly_leadtime', worst_n=5, high_is_good=False)
 
 
 
 
954
  id_col = EXECUTOR_INDIV_COL
955
  subset = subset.merge(colored[[id_col, 'color']], on=id_col, how='left').fillna({'color': '#1f77b4'})
956
-
957
- if sort_opt == "Slowest 10":
958
- subset = subset.iloc[::-1]
959
-
960
  fig = px.bar(
961
- subset, x='avg_monthly_leadtime', y=id_col, orientation='h',
962
- title=f'{sort_opt}',
 
 
 
963
  labels={'avg_monthly_leadtime': 'Avg Lead Time (Days)', id_col: 'Executor'},
964
- color='color', color_discrete_map={c: c for c in subset['color'].unique()},
 
965
  text=subset['avg_monthly_leadtime'].apply(lambda x: f'{x:.1f}')
966
  )
967
- fig.update_layout(height=450, showlegend=False, yaxis={'categoryorder': 'array', 'categoryarray': subset[id_col].tolist()})
 
 
 
 
968
  fig.update_traces(textposition='auto')
969
  st.plotly_chart(fig, use_container_width=True)
970
-
971
  if len(full_sorted) >= 2:
972
- min_lt, max_lt, mean_lt = full_sorted['avg_monthly_leadtime'].min(), full_sorted['avg_monthly_leadtime'].max(), full_sorted['avg_monthly_leadtime'].mean()
 
 
973
  slowest_exec = full_sorted.iloc[-1][id_col]
 
974
  st.markdown(
975
  f"<div class='ai-insight'>"
976
  f"<strong>Insight:</strong> Executor performance ranges from {min_lt:.1f} to {max_lt:.1f} days (avg: {mean_lt:.1f}). "
977
  f"<strong>{slowest_exec}</strong> requires support to meet SLA. "
978
- f"<strong>Recommendation:</strong> Assign mentor to executors >7 days; document & share best practices from top performers."
979
  f"</div>",
980
  unsafe_allow_html=True
981
  )
982
-
983
  #Objective 4
984
  try:
985
  from wordcloud import WordCloud
 
893
  if avg_leadtime_nama.empty:
894
  st.warning("No data for division-level executor analysis.")
895
  else:
896
+ sort_opt = st.selectbox(
897
+ "Show:",
898
+ ["Top 10 Fastest", "Bottom 10 Slowest"],
899
+ key='sort_3b'
900
+ )
901
+
902
+ # Sort penuh sekali — ascending: tercepat terlambat
903
+ full_sorted = avg_leadtime_nama.sort_values('avg_monthly_leadtime', ascending=True)
904
 
905
+ # Ambil subset sesuai pilihan
906
+ if sort_opt == "Top 10 Fastest":
907
+ # 10 tercepat: ascending (kecil → besar), tetap diurut ascending → tercepat di atas
908
+ subset = full_sorted.head(10).copy()
909
+ else: # "Bottom 10 Slowest"
910
+ # 10 terlambat: descending (besar → kecil), agar terlambat di atas
911
+ subset = full_sorted.tail(10).sort_values('avg_monthly_leadtime', ascending=False)
912
+
913
+ # Warna: 5 terlambat secara global (bukan di subset!) → warna merah
914
+ colored = add_color_by_global_rank(
915
+ avg_leadtime_nama,
916
+ 'avg_monthly_leadtime',
917
+ worst_n=5,
918
+ high_is_good=False # lebih tinggi = buruk
919
+ )
920
  subset = subset.merge(colored[['nama', 'color']], on='nama', how='left').fillna({'color': '#1f77b4'})
921
+
 
 
 
 
922
  fig = px.bar(
923
+ subset,
924
+ x='avg_monthly_leadtime',
925
+ y='nama',
926
+ orientation='h',
927
+ title=sort_opt,
928
  labels={'avg_monthly_leadtime': 'Avg Lead Time (Days)', 'nama': 'Division'},
929
+ color='color',
930
+ color_discrete_map={c: c for c in subset['color'].unique()},
931
  text=subset['avg_monthly_leadtime'].apply(lambda x: f'{x:.1f}')
932
  )
933
+ fig.update_layout(
934
+ height=450,
935
+ showlegend=False,
936
+ yaxis={'categoryorder': 'array', 'categoryarray': subset['nama'].tolist()}
937
+ )
938
  fig.update_traces(textposition='auto')
939
  st.plotly_chart(fig, use_container_width=True)
940
+
941
  if len(full_sorted) >= 2:
942
+ min_lt = full_sorted['avg_monthly_leadtime'].min()
943
+ max_lt = full_sorted['avg_monthly_leadtime'].max()
944
+ mean_lt = full_sorted['avg_monthly_leadtime'].mean()
945
+ fastest = full_sorted.iloc[0]['nama']
946
+ slowest = full_sorted.iloc[-1]['nama']
947
  st.markdown(
948
  f"<div class='ai-insight'>"
949
  f"<strong>Insight:</strong> Resolution time ranges from {min_lt:.1f} to {max_lt:.1f} days (avg: {mean_lt:.1f}). "
 
956
 
957
  # ─── 3d: Executor by Individual ──────────────────────────────────────────────
958
  with col_3d:
959
+ st.markdown(
960
+ f"<h5 style='text-align:center;'>3d. Avg Lead Time per Executor ({EXECUTOR_INDIV_COL})</h5>",
961
+ unsafe_allow_html=True
962
+ )
963
  if avg_leadtime_per_indiv.empty:
964
  st.warning(f"No data for individual executor analysis (column: '{EXECUTOR_INDIV_COL}').")
965
  else:
966
+ sort_opt = st.selectbox(
967
+ "Show:",
968
+ ["Top 10 Fastest", "Bottom 10 Slowest"],
969
+ key='sort_3d'
970
+ )
971
+
972
  full_sorted = avg_leadtime_per_indiv.sort_values('avg_monthly_leadtime', ascending=True)
 
 
 
 
973
 
974
+ if sort_opt == "Top 10 Fastest":
975
+ subset = full_sorted.head(10).copy()
976
+ else: # "Bottom 10 Slowest"
977
+ subset = full_sorted.tail(10).sort_values('avg_monthly_leadtime', ascending=False)
978
 
979
+ # Warna berdasarkan ranking global
980
+ colored = add_color_by_global_rank(
981
+ avg_leadtime_per_indiv,
982
+ 'avg_monthly_leadtime',
983
+ worst_n=5,
984
+ high_is_good=False
985
+ )
986
  id_col = EXECUTOR_INDIV_COL
987
  subset = subset.merge(colored[[id_col, 'color']], on=id_col, how='left').fillna({'color': '#1f77b4'})
988
+
 
 
 
989
  fig = px.bar(
990
+ subset,
991
+ x='avg_monthly_leadtime',
992
+ y=id_col,
993
+ orientation='h',
994
+ title=sort_opt,
995
  labels={'avg_monthly_leadtime': 'Avg Lead Time (Days)', id_col: 'Executor'},
996
+ color='color',
997
+ color_discrete_map={c: c for c in subset['color'].unique()},
998
  text=subset['avg_monthly_leadtime'].apply(lambda x: f'{x:.1f}')
999
  )
1000
+ fig.update_layout(
1001
+ height=450,
1002
+ showlegend=False,
1003
+ yaxis={'categoryorder': 'array', 'categoryarray': subset[id_col].tolist()}
1004
+ )
1005
  fig.update_traces(textposition='auto')
1006
  st.plotly_chart(fig, use_container_width=True)
1007
+
1008
  if len(full_sorted) >= 2:
1009
+ min_lt = full_sorted['avg_monthly_leadtime'].min()
1010
+ max_lt = full_sorted['avg_monthly_leadtime'].max()
1011
+ mean_lt = full_sorted['avg_monthly_leadtime'].mean()
1012
  slowest_exec = full_sorted.iloc[-1][id_col]
1013
+ fastest_exec = full_sorted.iloc[0][id_col]
1014
  st.markdown(
1015
  f"<div class='ai-insight'>"
1016
  f"<strong>Insight:</strong> Executor performance ranges from {min_lt:.1f} to {max_lt:.1f} days (avg: {mean_lt:.1f}). "
1017
  f"<strong>{slowest_exec}</strong> requires support to meet SLA. "
1018
+ f"<strong>Recommendation:</strong> Assign mentor to executors >7 days; document & share best practices from top performers (e.g., {fastest_exec})."
1019
  f"</div>",
1020
  unsafe_allow_html=True
1021
  )
 
1022
  #Objective 4
1023
  try:
1024
  from wordcloud import WordCloud