import streamlit as st import plotly.graph_objects as go from plotly.subplots import make_subplots import pandas as pd from datetime import datetime, timedelta class DashboardComponents: def __init__(self, colors): self.colors = colors def render_metric_card(self, title, value, subtitle=None, trend=None, trend_value=None): """Render a metric card with optional trend indicator""" trend_html = "" if trend and trend_value: trend_color = self.colors['success'] if trend == 'up' else self.colors['danger'] trend_arrow = '↑' if trend == 'up' else '↓' trend_html = f"""
{trend_arrow} {trend_value}%
""" st.markdown(f"""
{title}
{value}
{f'
{subtitle}
' if subtitle else ''} {trend_html}
""", unsafe_allow_html=True) def create_gauge_chart(self, value, title): """Create a gauge chart for metrics like ATS score""" fig = go.Figure(go.Indicator( mode="gauge+number", value=value, title={'text': title, 'font': {'size': 24, 'color': self.colors['text']}}, gauge={ 'axis': {'range': [0, 100], 'tickwidth': 1, 'tickcolor': self.colors['text']}, 'bar': {'color': self.colors['primary']}, 'bgcolor': "white", 'borderwidth': 2, 'bordercolor': "gray", 'steps': [ {'range': [0, 40], 'color': self.colors['danger']}, {'range': [40, 70], 'color': self.colors['warning']}, {'range': [70, 100], 'color': self.colors['success']} ], } )) fig.update_layout( paper_bgcolor=self.colors['card'], plot_bgcolor=self.colors['card'], font={'color': self.colors['text']}, height=300, margin=dict(l=20, r=20, t=50, b=20) ) return fig def create_trend_chart(self, dates, values, title): """Create a trend line chart""" fig = go.Figure() fig.add_trace(go.Scatter( x=dates, y=values, mode='lines+markers', line=dict(color=self.colors['info'], width=3), marker=dict(size=8, color=self.colors['info']) )) fig.update_layout( title=title, paper_bgcolor=self.colors['card'], plot_bgcolor=self.colors['card'], font={'color': self.colors['text']}, height=300, margin=dict(l=20, r=20, t=50, b=20), xaxis=dict( showgrid=True, gridwidth=1, gridcolor=self.colors['background'] ), yaxis=dict( showgrid=True, gridwidth=1, gridcolor=self.colors['background'] ) ) return fig def create_bar_chart(self, categories, values, title): """Create a bar chart""" fig = go.Figure(go.Bar( x=categories, y=values, marker_color=self.colors['primary'], text=values, textposition='auto', )) fig.update_layout( title=title, paper_bgcolor=self.colors['card'], plot_bgcolor=self.colors['card'], font={'color': self.colors['text']}, height=300, margin=dict(l=20, r=20, t=50, b=20), xaxis=dict( showgrid=False, title_text="Categories", color=self.colors['text'] ), yaxis=dict( showgrid=True, gridwidth=1, gridcolor=self.colors['background'], title_text="Values", color=self.colors['text'] ) ) return fig def create_dual_axis_chart(self, categories, values1, values2, title): """Create a chart with dual y-axes""" fig = make_subplots(specs=[[{"secondary_y": True}]]) fig.add_trace( go.Bar( x=categories, y=values1, name="Count", marker_color=self.colors['secondary'] ), secondary_y=False ) fig.add_trace( go.Scatter( x=categories, y=values2, name="Score", line=dict(color=self.colors['warning'], width=3), mode='lines+markers' ), secondary_y=True ) fig.update_layout( title=title, paper_bgcolor=self.colors['card'], plot_bgcolor=self.colors['card'], font={'color': self.colors['text']}, height=300, margin=dict(l=20, r=20, t=50, b=20), showlegend=True, legend=dict( orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1 ) ) fig.update_xaxes(title_text="Categories", color=self.colors['text']) fig.update_yaxes(title_text="Count", color=self.colors['text'], secondary_y=False) fig.update_yaxes(title_text="Score", color=self.colors['text'], secondary_y=True) return fig