mrradix commited on
Commit
b84426c
Β·
verified Β·
1 Parent(s): 021c822

Update pages/dashboard.py

Browse files
Files changed (1) hide show
  1. pages/dashboard.py +280 -271
pages/dashboard.py CHANGED
@@ -1,317 +1,326 @@
 
 
 
1
  import streamlit as st
2
  import pandas as pd
3
- import numpy as np
4
  import plotly.express as px
5
  import plotly.graph_objects as go
6
  from datetime import datetime, timedelta
7
-
8
  from utils.storage import load_data, save_data, load_dataframe, save_dataframe
9
- from utils.config import load_config, get_config_value
10
- from utils.error_handling import handle_ui_exceptions
11
- from utils.logging import get_logger
12
 
13
- logger = get_logger(__name__)
14
 
15
- @handle_ui_exceptions
16
  def create_dashboard_page():
17
- """Create the main dashboard page"""
18
- st.title("πŸ“Š MONA Dashboard")
19
-
20
- config = load_config()
21
-
22
- # Create tabs for different dashboard sections
23
- tab1, tab2, tab3, tab4 = st.tabs(["Overview", "Analytics", "Data Upload", "Real-time"])
24
-
25
- with tab1:
26
- create_overview_section()
27
-
28
- with tab2:
29
- create_analytics_section()
30
-
31
- with tab3:
32
- create_data_upload_section()
33
-
34
- with tab4:
35
- create_realtime_section()
36
-
37
- @handle_ui_exceptions
38
- def create_overview_section():
39
- """Create the overview section of the dashboard"""
40
- st.header("πŸ“ˆ Overview")
41
-
42
- # Create sample metrics
43
- col1, col2, col3, col4 = st.columns(4)
44
-
45
- with col1:
46
- st.metric("Total Records", "1,234", "12%")
47
-
48
- with col2:
49
- st.metric("Active Users", "567", "8%")
50
-
51
- with col3:
52
- st.metric("Processing Time", "2.3s", "-0.5s")
53
-
54
- with col4:
55
- st.metric("Success Rate", "98.5%", "1.2%")
56
-
57
- # Create sample charts
58
- col1, col2 = st.columns(2)
59
-
60
- with col1:
61
- st.subheader("πŸ“Š Trend Analysis")
62
- # Generate sample data
63
- dates = pd.date_range(start='2024-01-01', end='2024-12-31', freq='D')
64
- values = np.random.randn(len(dates)).cumsum() + 100
65
 
66
- df = pd.DataFrame({
67
- 'Date': dates,
68
- 'Value': values
69
- })
70
 
71
- fig = px.line(df, x='Date', y='Value', title='Daily Trend')
72
- st.plotly_chart(fig, use_container_width=True)
73
-
74
- with col2:
75
- st.subheader("πŸ“¦ Category Distribution")
76
- categories = ['A', 'B', 'C', 'D', 'E']
77
- values = np.random.randint(10, 100, size=len(categories))
78
 
79
- fig = px.pie(values=values, names=categories, title='Category Distribution')
80
- st.plotly_chart(fig, use_container_width=True)
 
 
 
 
 
 
 
 
81
 
82
- @handle_ui_exceptions
83
- def create_analytics_section():
84
- """Create the analytics section"""
85
- st.header("πŸ” Analytics")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
- # Data filtering options
88
- col1, col2, col3 = st.columns(3)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
  with col1:
91
- date_range = st.date_input(
92
- "Select Date Range",
93
- value=(datetime.now() - timedelta(days=30), datetime.now()),
94
- max_value=datetime.now()
95
  )
96
 
97
  with col2:
98
- chart_type = st.selectbox(
99
- "Chart Type",
100
- ["Line", "Bar", "Scatter", "Area", "Histogram"]
 
101
  )
102
 
103
  with col3:
104
- metric = st.selectbox(
105
- "Metric",
106
- ["Revenue", "Users", "Sessions", "Conversions"]
 
107
  )
108
 
109
- # Generate analytics data based on selections
110
- if len(date_range) == 2:
111
- start_date, end_date = date_range
112
- days = (end_date - start_date).days + 1
113
-
114
- # Generate sample data
115
- dates = pd.date_range(start=start_date, end=end_date, freq='D')
116
- values = np.random.randn(len(dates)).cumsum() + np.random.randint(50, 200)
117
-
118
- df = pd.DataFrame({
119
- 'Date': dates,
120
- metric: values
121
- })
122
-
123
- # Create chart based on selection
124
- if chart_type == "Line":
125
- fig = px.line(df, x='Date', y=metric, title=f'{metric} Over Time')
126
- elif chart_type == "Bar":
127
- fig = px.bar(df, x='Date', y=metric, title=f'{metric} by Day')
128
- elif chart_type == "Scatter":
129
- df['Random'] = np.random.randn(len(df))
130
- fig = px.scatter(df, x='Random', y=metric, title=f'{metric} Scatter Plot')
131
- elif chart_type == "Area":
132
- fig = px.area(df, x='Date', y=metric, title=f'{metric} Area Chart')
133
- elif chart_type == "Histogram":
134
- fig = px.histogram(df, x=metric, title=f'{metric} Distribution')
135
-
136
- st.plotly_chart(fig, use_container_width=True)
137
-
138
- # Show data table
139
- with st.expander("View Raw Data"):
140
- st.dataframe(df)
141
 
142
- @handle_ui_exceptions
143
- def create_data_upload_section():
144
- """Create the data upload section"""
145
- st.header("πŸ“€ Data Upload")
146
-
147
- # File upload
148
- uploaded_file = st.file_uploader(
149
- "Upload your data file",
150
- type=['csv', 'xlsx', 'json'],
151
- help="Supported formats: CSV, Excel, JSON"
152
- )
153
-
154
- if uploaded_file is not None:
155
- try:
156
- # Read the uploaded file
157
- if uploaded_file.name.endswith('.csv'):
158
- df = pd.read_csv(uploaded_file)
159
- elif uploaded_file.name.endswith('.xlsx'):
160
- df = pd.read_excel(uploaded_file)
161
- elif uploaded_file.name.endswith('.json'):
162
- df = pd.read_json(uploaded_file)
163
-
164
- st.success(f"File uploaded successfully! Shape: {df.shape}")
165
-
166
- # Display data preview
167
- st.subheader("Data Preview")
168
- st.dataframe(df.head())
169
-
170
- # Data summary
171
- col1, col2 = st.columns(2)
172
-
173
- with col1:
174
- st.subheader("Data Info")
175
- st.write(f"**Rows:** {len(df)}")
176
- st.write(f"**Columns:** {len(df.columns)}")
177
- st.write(f"**File Size:** {uploaded_file.size} bytes")
178
-
179
- with col2:
180
- st.subheader("Column Types")
181
- for col, dtype in df.dtypes.items():
182
- st.write(f"**{col}:** {dtype}")
183
-
184
- # Save data option
185
- if st.button("Save Data"):
186
- save_dataframe(df, f"uploaded_data_{datetime.now().strftime('%Y%m%d_%H%M%S')}")
187
- st.success("Data saved successfully!")
188
-
189
- # Basic analytics on uploaded data
190
- if len(df.select_dtypes(include=[np.number]).columns) > 0:
191
- st.subheader("Quick Analytics")
192
- numeric_cols = df.select_dtypes(include=[np.number]).columns
193
-
194
- selected_col = st.selectbox("Select column for analysis", numeric_cols)
195
-
196
- if selected_col:
197
- col1, col2 = st.columns(2)
198
-
199
- with col1:
200
- fig = px.histogram(df, x=selected_col, title=f'Distribution of {selected_col}')
201
- st.plotly_chart(fig, use_container_width=True)
202
-
203
- with col2:
204
- fig = px.box(df, y=selected_col, title=f'Box Plot of {selected_col}')
205
- st.plotly_chart(fig, use_container_width=True)
206
-
207
- except Exception as e:
208
- st.error(f"Error processing file: {str(e)}")
209
- logger.error(f"File processing error: {str(e)}")
210
 
211
- @handle_ui_exceptions
212
- def create_realtime_section():
213
- """Create the real-time monitoring section"""
214
- st.header("⚑ Real-time Monitoring")
215
-
216
- # Auto-refresh toggle
217
- auto_refresh = st.checkbox("Enable Auto-refresh", value=False)
218
 
219
- if auto_refresh:
220
- refresh_interval = st.slider("Refresh Interval (seconds)", 1, 60, 5)
221
- st.info(f"Data will refresh every {refresh_interval} seconds")
222
 
223
- # Real-time metrics
224
- col1, col2, col3 = st.columns(3)
225
-
226
- # Generate real-time data
227
- current_time = datetime.now()
228
 
229
  with col1:
230
- cpu_usage = np.random.uniform(20, 80)
231
- st.metric("CPU Usage", f"{cpu_usage:.1f}%", f"{np.random.uniform(-5, 5):.1f}%")
 
 
 
 
 
 
 
 
 
 
 
 
 
232
 
233
  with col2:
234
- memory_usage = np.random.uniform(30, 90)
235
- st.metric("Memory Usage", f"{memory_usage:.1f}%", f"{np.random.uniform(-3, 3):.1f}%")
236
-
237
- with col3:
238
- active_connections = np.random.randint(100, 500)
239
- st.metric("Active Connections", active_connections, np.random.randint(-10, 20))
240
-
241
- # Real-time chart
242
- st.subheader("πŸ“Š Real-time Performance")
243
-
244
- # Generate time series data
245
- time_points = pd.date_range(end=current_time, periods=50, freq='1T')
246
- performance_data = {
247
- 'Time': time_points,
248
- 'CPU': np.random.uniform(20, 80, 50),
249
- 'Memory': np.random.uniform(30, 90, 50),
250
- 'Network': np.random.uniform(10, 60, 50)
251
- }
252
-
253
- df_realtime = pd.DataFrame(performance_data)
254
-
255
- # Create multi-line chart
256
- fig = go.Figure()
257
-
258
- for metric in ['CPU', 'Memory', 'Network']:
259
- fig.add_trace(go.Scatter(
260
- x=df_realtime['Time'],
261
- y=df_realtime[metric],
262
- mode='lines+markers',
263
- name=f'{metric} %',
264
- line=dict(width=2)
265
- ))
266
-
267
- fig.update_layout(
268
- title='System Performance Over Time',
269
- xaxis_title='Time',
270
- yaxis_title='Usage (%)',
271
- hovermode='x unified'
272
  )
273
 
274
- st.plotly_chart(fig, use_container_width=True)
 
 
 
 
 
 
 
275
 
276
- # Status indicators
277
- st.subheader("🚨 System Status")
278
 
279
- col1, col2, col3, col4 = st.columns(4)
 
280
 
281
  with col1:
282
- status = "🟒 Online" if np.random.random() > 0.1 else "πŸ”΄ Offline"
283
- st.write(f"**Database:** {status}")
284
 
285
  with col2:
286
- status = "🟒 Healthy" if np.random.random() > 0.05 else "🟑 Warning"
287
- st.write(f"**API:** {status}")
288
 
289
  with col3:
290
- status = "🟒 Running" if np.random.random() > 0.02 else "πŸ”΄ Down"
291
- st.write(f"**Services:** {status}")
292
 
293
- with col4:
294
- status = "🟒 Good" if np.random.random() > 0.15 else "🟑 Slow"
295
- st.write(f"**Network:** {status}")
296
-
297
- # Recent events log
298
- st.subheader("πŸ“ Recent Events")
299
-
300
- events = [
301
- {"time": current_time - timedelta(minutes=2), "event": "System backup completed", "type": "info"},
302
- {"time": current_time - timedelta(minutes=5), "event": "High CPU usage detected", "type": "warning"},
303
- {"time": current_time - timedelta(minutes=8), "event": "New user registration", "type": "info"},
304
- {"time": current_time - timedelta(minutes=12), "event": "Database connection restored", "type": "success"},
305
- {"time": current_time - timedelta(minutes=15), "event": "Scheduled maintenance started", "type": "info"},
306
  ]
307
 
308
- for event in events:
309
- icon = {"info": "ℹ️", "warning": "⚠️", "success": "βœ…", "error": "❌"}.get(event["type"], "πŸ“")
310
- st.write(f"{icon} **{event['time'].strftime('%H:%M:%S')}** - {event['event']}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
 
312
- # Auto-refresh functionality
313
- if auto_refresh:
314
- # Use Streamlit's rerun to refresh the page
315
- import time
316
- time.sleep(refresh_interval)
317
- st.rerun()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Dashboard page for the application
3
+ """
4
  import streamlit as st
5
  import pandas as pd
 
6
  import plotly.express as px
7
  import plotly.graph_objects as go
8
  from datetime import datetime, timedelta
 
9
  from utils.storage import load_data, save_data, load_dataframe, save_dataframe
10
+ from utils.error_handling import handle_data_exceptions, log_error, display_error
 
 
11
 
 
12
 
13
+ @handle_data_exceptions
14
  def create_dashboard_page():
15
+ """
16
+ Create the main dashboard page
17
+ """
18
+ st.title("πŸ“Š Dashboard")
19
+ st.markdown("---")
20
+
21
+ # Initialize session state
22
+ if 'dashboard_data' not in st.session_state:
23
+ st.session_state.dashboard_data = generate_sample_data()
24
+
25
+ # Sidebar controls
26
+ with st.sidebar:
27
+ st.header("Dashboard Controls")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ # Data refresh button
30
+ if st.button("πŸ”„ Refresh Data"):
31
+ st.session_state.dashboard_data = generate_sample_data()
32
+ st.success("Data refreshed!")
33
 
34
+ # Date range selector
35
+ st.subheader("Date Range")
36
+ start_date = st.date_input("Start Date", value=datetime.now() - timedelta(days=30))
37
+ end_date = st.date_input("End Date", value=datetime.now())
 
 
 
38
 
39
+ # Chart type selector
40
+ chart_type = st.selectbox(
41
+ "Chart Type",
42
+ ["Line Chart", "Bar Chart", "Area Chart", "Scatter Plot"]
43
+ )
44
+
45
+ # Main dashboard content
46
+ create_metrics_section()
47
+ create_charts_section(chart_type)
48
+ create_data_table_section()
49
 
50
+
51
+ def generate_sample_data():
52
+ """
53
+ Generate sample data for the dashboard
54
+ """
55
+ import random
56
+ import numpy as np
57
+
58
+ # Generate date range
59
+ dates = pd.date_range(start='2024-01-01', end='2024-12-31', freq='D')
60
+
61
+ # Generate sample metrics
62
+ data = {
63
+ 'date': dates,
64
+ 'sales': [random.randint(1000, 5000) + random.randint(-500, 500) for _ in dates],
65
+ 'users': [random.randint(100, 1000) + random.randint(-100, 100) for _ in dates],
66
+ 'revenue': [random.randint(5000, 25000) + random.randint(-2000, 2000) for _ in dates],
67
+ 'conversion_rate': [round(random.uniform(0.02, 0.08), 4) for _ in dates]
68
+ }
69
 
70
+ return pd.DataFrame(data)
71
+
72
+
73
+ def create_metrics_section():
74
+ """
75
+ Create metrics cards section
76
+ """
77
+ st.subheader("πŸ“ˆ Key Metrics")
78
+
79
+ data = st.session_state.dashboard_data
80
+
81
+ # Calculate metrics
82
+ total_sales = data['sales'].sum()
83
+ total_users = data['users'].sum()
84
+ total_revenue = data['revenue'].sum()
85
+ avg_conversion = data['conversion_rate'].mean()
86
+
87
+ # Previous period comparison (last 30 days vs previous 30 days)
88
+ recent_data = data.tail(30)
89
+ previous_data = data.iloc[-60:-30] if len(data) >= 60 else data.head(30)
90
+
91
+ sales_change = ((recent_data['sales'].sum() - previous_data['sales'].sum()) / previous_data['sales'].sum()) * 100
92
+ users_change = ((recent_data['users'].sum() - previous_data['users'].sum()) / previous_data['users'].sum()) * 100
93
+ revenue_change = ((recent_data['revenue'].sum() - previous_data['revenue'].sum()) / previous_data['revenue'].sum()) * 100
94
+ conversion_change = ((recent_data['conversion_rate'].mean() - previous_data['conversion_rate'].mean()) / previous_data['conversion_rate'].mean()) * 100
95
+
96
+ # Display metrics in columns
97
+ col1, col2, col3, col4 = st.columns(4)
98
 
99
  with col1:
100
+ st.metric(
101
+ label="Total Sales",
102
+ value=f"{total_sales:,}",
103
+ delta=f"{sales_change:.1f}%"
104
  )
105
 
106
  with col2:
107
+ st.metric(
108
+ label="Total Users",
109
+ value=f"{total_users:,}",
110
+ delta=f"{users_change:.1f}%"
111
  )
112
 
113
  with col3:
114
+ st.metric(
115
+ label="Total Revenue",
116
+ value=f"${total_revenue:,}",
117
+ delta=f"{revenue_change:.1f}%"
118
  )
119
 
120
+ with col4:
121
+ st.metric(
122
+ label="Avg Conversion Rate",
123
+ value=f"{avg_conversion:.2%}",
124
+ delta=f"{conversion_change:.1f}%"
125
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
 
128
+ def create_charts_section(chart_type):
129
+ """
130
+ Create charts section
131
+ """
132
+ st.subheader("πŸ“Š Analytics Charts")
 
 
133
 
134
+ data = st.session_state.dashboard_data
 
 
135
 
136
+ # Create two columns for charts
137
+ col1, col2 = st.columns(2)
 
 
 
138
 
139
  with col1:
140
+ st.write("**Sales Over Time**")
141
+ if chart_type == "Line Chart":
142
+ fig = px.line(data, x='date', y='sales', title='Daily Sales')
143
+ elif chart_type == "Bar Chart":
144
+ # Group by month for bar chart
145
+ monthly_data = data.groupby(data['date'].dt.to_period('M'))['sales'].sum().reset_index()
146
+ monthly_data['date'] = monthly_data['date'].astype(str)
147
+ fig = px.bar(monthly_data, x='date', y='sales', title='Monthly Sales')
148
+ elif chart_type == "Area Chart":
149
+ fig = px.area(data, x='date', y='sales', title='Sales Area Chart')
150
+ else: # Scatter Plot
151
+ fig = px.scatter(data, x='date', y='sales', title='Sales Scatter Plot')
152
+
153
+ fig.update_layout(height=400)
154
+ st.plotly_chart(fig, use_container_width=True)
155
 
156
  with col2:
157
+ st.write("**Revenue vs Users**")
158
+ fig2 = px.scatter(
159
+ data,
160
+ x='users',
161
+ y='revenue',
162
+ size='sales',
163
+ color='conversion_rate',
164
+ title='Revenue vs Users (sized by Sales)',
165
+ color_continuous_scale='Viridis'
166
+ )
167
+ fig2.update_layout(height=400)
168
+ st.plotly_chart(fig2, use_container_width=True)
169
+
170
+ # Full width chart
171
+ st.write("**Multi-Metric Trend Analysis**")
172
+
173
+ # Normalize data for comparison
174
+ normalized_data = data.copy()
175
+ for col in ['sales', 'users', 'revenue']:
176
+ normalized_data[f'{col}_normalized'] = (normalized_data[col] - normalized_data[col].min()) / (normalized_data[col].max() - normalized_data[col].min())
177
+
178
+ fig3 = go.Figure()
179
+ fig3.add_trace(go.Scatter(x=normalized_data['date'], y=normalized_data['sales_normalized'], name='Sales (Normalized)'))
180
+ fig3.add_trace(go.Scatter(x=normalized_data['date'], y=normalized_data['users_normalized'], name='Users (Normalized)'))
181
+ fig3.add_trace(go.Scatter(x=normalized_data['date'], y=normalized_data['revenue_normalized'], name='Revenue (Normalized)'))
182
+
183
+ fig3.update_layout(
184
+ title='Normalized Trends Comparison',
185
+ xaxis_title='Date',
186
+ yaxis_title='Normalized Value (0-1)',
187
+ height=400
 
 
 
 
 
 
 
188
  )
189
 
190
+ st.plotly_chart(fig3, use_container_width=True)
191
+
192
+
193
+ def create_data_table_section():
194
+ """
195
+ Create data table section
196
+ """
197
+ st.subheader("πŸ“‹ Data Table")
198
 
199
+ data = st.session_state.dashboard_data
 
200
 
201
+ # Add filters
202
+ col1, col2, col3 = st.columns(3)
203
 
204
  with col1:
205
+ min_sales = st.number_input("Min Sales", value=0, max_value=int(data['sales'].max()))
 
206
 
207
  with col2:
208
+ min_users = st.number_input("Min Users", value=0, max_value=int(data['users'].max()))
 
209
 
210
  with col3:
211
+ min_revenue = st.number_input("Min Revenue", value=0, max_value=int(data['revenue'].max()))
 
212
 
213
+ # Filter data
214
+ filtered_data = data[
215
+ (data['sales'] >= min_sales) &
216
+ (data['users'] >= min_users) &
217
+ (data['revenue'] >= min_revenue)
 
 
 
 
 
 
 
 
218
  ]
219
 
220
+ # Display filtered data
221
+ st.write(f"Showing {len(filtered_data)} of {len(data)} records")
222
+
223
+ # Format data for display
224
+ display_data = filtered_data.copy()
225
+ display_data['date'] = display_data['date'].dt.strftime('%Y-%m-%d')
226
+ display_data['revenue'] = display_data['revenue'].apply(lambda x: f"${x:,}")
227
+ display_data['conversion_rate'] = display_data['conversion_rate'].apply(lambda x: f"{x:.2%}")
228
+
229
+ st.dataframe(
230
+ display_data,
231
+ use_container_width=True,
232
+ hide_index=True,
233
+ column_config={
234
+ "date": "Date",
235
+ "sales": st.column_config.NumberColumn("Sales", format="%d"),
236
+ "users": st.column_config.NumberColumn("Users", format="%d"),
237
+ "revenue": "Revenue",
238
+ "conversion_rate": "Conversion Rate"
239
+ }
240
+ )
241
 
242
+ # Download button
243
+ csv = data.to_csv(index=False)
244
+ st.download_button(
245
+ label="πŸ“₯ Download Data as CSV",
246
+ data=csv,
247
+ file_name=f"dashboard_data_{datetime.now().strftime('%Y%m%d')}.csv",
248
+ mime="text/csv"
249
+ )
250
+
251
+
252
+ def create_summary_statistics():
253
+ """
254
+ Create summary statistics section
255
+ """
256
+ data = st.session_state.dashboard_data
257
+
258
+ st.subheader("πŸ“Š Summary Statistics")
259
+
260
+ # Calculate statistics
261
+ stats = data[['sales', 'users', 'revenue', 'conversion_rate']].describe()
262
+
263
+ # Display statistics table
264
+ st.dataframe(
265
+ stats,
266
+ use_container_width=True,
267
+ column_config={
268
+ "sales": st.column_config.NumberColumn("Sales", format="%.0f"),
269
+ "users": st.column_config.NumberColumn("Users", format="%.0f"),
270
+ "revenue": st.column_config.NumberColumn("Revenue", format="%.0f"),
271
+ "conversion_rate": st.column_config.NumberColumn("Conversion Rate", format="%.4f")
272
+ }
273
+ )
274
+
275
+
276
+ # Additional utility functions
277
+ @handle_data_exceptions
278
+ def export_dashboard_data(format_type='csv'):
279
+ """
280
+ Export dashboard data in specified format
281
+ """
282
+ data = st.session_state.dashboard_data
283
+
284
+ if format_type == 'csv':
285
+ return data.to_csv(index=False)
286
+ elif format_type == 'json':
287
+ return data.to_json(orient='records', date_format='iso')
288
+ elif format_type == 'excel':
289
+ # This would require openpyxl
290
+ return data.to_excel(index=False)
291
+ else:
292
+ raise ValueError(f"Unsupported format: {format_type}")
293
+
294
+
295
+ @handle_data_exceptions
296
+ def load_dashboard_config():
297
+ """
298
+ Load dashboard configuration
299
+ """
300
+ try:
301
+ config = load_data('dashboard_config.json')
302
+ return config if config else get_default_config()
303
+ except:
304
+ return get_default_config()
305
+
306
+
307
+ def get_default_config():
308
+ """
309
+ Get default dashboard configuration
310
+ """
311
+ return {
312
+ 'theme': 'light',
313
+ 'default_chart_type': 'Line Chart',
314
+ 'refresh_interval': 300, # 5 minutes
315
+ 'show_metrics': True,
316
+ 'show_charts': True,
317
+ 'show_table': True
318
+ }
319
+
320
+
321
+ @handle_data_exceptions
322
+ def save_dashboard_config(config):
323
+ """
324
+ Save dashboard configuration
325
+ """
326
+ return save_data(config, 'dashboard_config.json')