Spaces:
Sleeping
Sleeping
File size: 3,131 Bytes
2c59485 5fbc76a 28b188b 5fbc76a 2c59485 5fbc76a 7c75767 9f9b802 2c59485 5fbc76a a07d7fa 5fbc76a 2c59485 28b188b 9f9b802 2c59485 28b188b 5fbc76a 2c59485 9f9b802 2c59485 5fbc76a 28b188b 5fbc76a 28b188b 5fbc76a 2c59485 5fbc76a 2c59485 5fbc76a 2c59485 7c75767 5fbc76a 7c75767 5fbc76a 7c75767 5fbc76a 7c75767 5fbc76a 7c75767 5fbc76a 7c75767 5fbc76a 9f9b802 7c75767 2c59485 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
import streamlit as st
import pandas as pd
import matplotlib.pyplot as plt
def process_data(df):
# Clean and prepare data
df = df[['Project Category', 'Logged']].copy()
df = df.dropna(subset=['Project Category'])
# Consolidate categories
df['Main Category'] = df['Project Category'].apply(
lambda x: 'Billable' if 'Billable' in str(x) else str(x).strip()
)
# Group by main categories
main_categories = df.groupby('Main Category')['Logged'].sum().reset_index()
total_hours = main_categories['Logged'].sum()
main_categories['Percentage'] = (main_categories['Logged'] / total_hours * 100).round(1)
# Prepare non-billable breakdown
non_billable = df[df['Main Category'] == 'Non-Billable']
non_billable_breakdown = non_billable.groupby('Project Category')['Logged'].sum().reset_index()
return main_categories, non_billable_breakdown
def create_pie_chart(data):
fig, ax = plt.subplots(figsize=(6, 6))
wedges, texts, autotexts = ax.pie(
data['Logged'],
labels=data['Main Category'],
autopct='%1.1f%%',
colors=['#4CAF50', '#FFC107', '#9E9E9E'],
startangle=90
)
plt.setp(autotexts, size=10, weight="bold", color='white')
ax.set_title('Overall Utilization Distribution', pad=20)
return fig
def create_bar_chart(data):
fig, ax = plt.subplots(figsize=(10, 5))
data.plot(kind='bar', x='Project Category', y='Logged', ax=ax, legend=False)
ax.set_title('Non-Billable Time Breakdown')
ax.set_ylabel('Hours')
ax.set_xlabel('')
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
return fig
def main():
st.title('QA Team Utilization Dashboard')
uploaded_file = st.file_uploader("Upload Timesheet Excel File", type=['xls', 'xlsx'])
if uploaded_file:
try:
df = pd.read_excel(uploaded_file, sheet_name='Report')
main_cats, non_billable = process_data(df)
# Main utilization section
st.header("Overall Utilization")
col1, col2 = st.columns([2, 1])
with col1:
st.pyplot(create_pie_chart(main_cats))
with col2:
st.dataframe(
main_cats[['Main Category', 'Logged', 'Percentage']],
hide_index=True,
column_config={
'Main Category': 'Category',
'Logged': st.column_config.NumberColumn('Hours', format="%.2f"),
'Percentage': st.column_config.NumberColumn(format="%.1f%%")
}
)
# Non-billable breakdown
st.header("Non-Billable Detailed Breakdown")
st.pyplot(create_bar_chart(non_billable))
# Raw data preview
st.subheader("Raw Data Preview")
st.dataframe(df.head(10), hide_index=True)
except Exception as e:
st.error(f"Error processing file: {str(e)}")
if __name__ == "__main__":
main() |