|
|
import streamlit as st |
|
|
import pandas as pd |
|
|
import plotly.express as px |
|
|
import plotly.graph_objects as go |
|
|
from datetime import datetime, timedelta |
|
|
import numpy as np |
|
|
|
|
|
|
|
|
from utils.storage import load_data, save_data |
|
|
from utils.error_handling import show_error, show_success, show_warning |
|
|
from utils.logging import get_logger |
|
|
|
|
|
logger = get_logger(__name__) |
|
|
|
|
|
def create_dashboard_page(): |
|
|
""" |
|
|
Create the main dashboard page for MONA |
|
|
""" |
|
|
st.title("π€ MONA - Monitoring & Analytics Dashboard") |
|
|
|
|
|
|
|
|
with st.sidebar: |
|
|
st.header("π Dashboard Controls") |
|
|
|
|
|
|
|
|
data_source = st.selectbox( |
|
|
"Select Data Source", |
|
|
["Sample Data", "Upload File", "Real-time Feed"] |
|
|
) |
|
|
|
|
|
|
|
|
st.subheader("Time Range") |
|
|
time_range = st.selectbox( |
|
|
"Select Time Range", |
|
|
["Last 24 Hours", "Last 7 Days", "Last 30 Days", "Custom"] |
|
|
) |
|
|
|
|
|
if time_range == "Custom": |
|
|
start_date = st.date_input("Start Date", datetime.now() - timedelta(days=7)) |
|
|
end_date = st.date_input("End Date", datetime.now()) |
|
|
|
|
|
|
|
|
if st.button("π Refresh Data"): |
|
|
st.rerun() |
|
|
|
|
|
|
|
|
col1, col2, col3, col4 = st.columns(4) |
|
|
|
|
|
|
|
|
with col1: |
|
|
st.metric( |
|
|
label="System Status", |
|
|
value="Online", |
|
|
delta="β
" |
|
|
) |
|
|
|
|
|
with col2: |
|
|
st.metric( |
|
|
label="Active Connections", |
|
|
value="127", |
|
|
delta="5", |
|
|
delta_color="normal" |
|
|
) |
|
|
|
|
|
with col3: |
|
|
st.metric( |
|
|
label="Data Points", |
|
|
value="1,234", |
|
|
delta="156", |
|
|
delta_color="normal" |
|
|
) |
|
|
|
|
|
with col4: |
|
|
st.metric( |
|
|
label="Success Rate", |
|
|
value="99.8%", |
|
|
delta="0.2%", |
|
|
delta_color="normal" |
|
|
) |
|
|
|
|
|
|
|
|
st.header("π Analytics") |
|
|
|
|
|
|
|
|
sample_data = generate_sample_data() |
|
|
|
|
|
|
|
|
col1, col2 = st.columns(2) |
|
|
|
|
|
with col1: |
|
|
st.subheader("Time Series Analysis") |
|
|
fig_line = px.line( |
|
|
sample_data, |
|
|
x='timestamp', |
|
|
y='value', |
|
|
title='Data Trends Over Time', |
|
|
color_discrete_sequence=['#1f77b4'] |
|
|
) |
|
|
fig_line.update_layout( |
|
|
xaxis_title="Time", |
|
|
yaxis_title="Value", |
|
|
showlegend=False |
|
|
) |
|
|
st.plotly_chart(fig_line, use_container_width=True) |
|
|
|
|
|
with col2: |
|
|
st.subheader("Distribution Analysis") |
|
|
fig_hist = px.histogram( |
|
|
sample_data, |
|
|
x='value', |
|
|
bins=20, |
|
|
title='Value Distribution', |
|
|
color_discrete_sequence=['#ff7f0e'] |
|
|
) |
|
|
fig_hist.update_layout( |
|
|
xaxis_title="Value", |
|
|
yaxis_title="Frequency", |
|
|
showlegend=False |
|
|
) |
|
|
st.plotly_chart(fig_hist, use_container_width=True) |
|
|
|
|
|
|
|
|
st.header("π Data Overview") |
|
|
|
|
|
|
|
|
col1, col2, col3 = st.columns(3) |
|
|
|
|
|
with col1: |
|
|
show_raw_data = st.checkbox("Show Raw Data", value=False) |
|
|
|
|
|
with col2: |
|
|
max_rows = st.number_input("Max Rows", min_value=10, max_value=1000, value=100) |
|
|
|
|
|
with col3: |
|
|
if st.button("Export Data"): |
|
|
try: |
|
|
success = save_data(sample_data.to_dict('records'), 'dashboard_export.json') |
|
|
if success: |
|
|
show_success("Data exported successfully!") |
|
|
else: |
|
|
show_error("Failed to export data") |
|
|
except Exception as e: |
|
|
show_error(f"Export error: {e}") |
|
|
|
|
|
if show_raw_data: |
|
|
st.dataframe( |
|
|
sample_data.head(max_rows), |
|
|
use_container_width=True, |
|
|
hide_index=True |
|
|
) |
|
|
|
|
|
|
|
|
with st.expander("π§ System Information"): |
|
|
system_info = { |
|
|
"Application": "MONA Dashboard", |
|
|
"Version": "1.0.0", |
|
|
"Last Updated": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), |
|
|
"Data Points": len(sample_data), |
|
|
"Status": "Operational" |
|
|
} |
|
|
|
|
|
for key, value in system_info.items(): |
|
|
st.text(f"{key}: {value}") |
|
|
|
|
|
|
|
|
st.markdown("---") |
|
|
st.markdown( |
|
|
"**MONA Dashboard** - Monitoring & Analytics | " |
|
|
f"Last updated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" |
|
|
) |
|
|
|
|
|
def generate_sample_data(): |
|
|
""" |
|
|
Generate sample data for demonstration |
|
|
""" |
|
|
try: |
|
|
|
|
|
dates = pd.date_range( |
|
|
start=datetime.now() - timedelta(days=30), |
|
|
end=datetime.now(), |
|
|
freq='H' |
|
|
) |
|
|
|
|
|
|
|
|
np.random.seed(42) |
|
|
trend = np.linspace(100, 200, len(dates)) |
|
|
noise = np.random.normal(0, 10, len(dates)) |
|
|
seasonal = 20 * np.sin(2 * np.pi * np.arange(len(dates)) / 24) |
|
|
|
|
|
values = trend + seasonal + noise |
|
|
|
|
|
df = pd.DataFrame({ |
|
|
'timestamp': dates, |
|
|
'value': values, |
|
|
'category': np.random.choice(['A', 'B', 'C'], len(dates)), |
|
|
'status': np.random.choice(['Active', 'Inactive'], len(dates), p=[0.8, 0.2]) |
|
|
}) |
|
|
|
|
|
return df |
|
|
|
|
|
except Exception as e: |
|
|
logger.error(f"Error generating sample data: {e}") |
|
|
|
|
|
return pd.DataFrame({ |
|
|
'timestamp': [datetime.now()], |
|
|
'value': [100], |
|
|
'category': ['A'], |
|
|
'status': ['Active'] |
|
|
}) |
|
|
|
|
|
def load_dashboard_config(): |
|
|
""" |
|
|
Load dashboard configuration |
|
|
""" |
|
|
try: |
|
|
config = load_data('dashboard_config.json') |
|
|
if config is None: |
|
|
|
|
|
default_config = { |
|
|
'theme': 'light', |
|
|
'refresh_interval': 30, |
|
|
'max_data_points': 1000, |
|
|
'charts_enabled': True |
|
|
} |
|
|
save_data(default_config, 'dashboard_config.json') |
|
|
return default_config |
|
|
return config |
|
|
except Exception as e: |
|
|
logger.error(f"Error loading dashboard config: {e}") |
|
|
return {} |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
create_dashboard_page() |