Spaces:
Runtime error
Runtime error
| """ | |
| Enhanced investor-grade visualizations | |
| """ | |
| import plotly.graph_objects as go | |
| import plotly.express as px | |
| import pandas as pd | |
| import numpy as np | |
| from plotly.subplots import make_subplots | |
| from datetime import datetime | |
| from typing import Dict, Optional, List | |
| from core.data_models import IncidentScenario | |
| class EnhancedVisualizationEngine: | |
| """Interactive, investor-grade visualizations""" | |
| def __init__(self): | |
| self.color_palette = px.colors.qualitative.Set3 | |
| self.theme = { | |
| "background": "rgba(0,0,0,0)", | |
| "grid": "rgba(200,200,200,0.1)", | |
| "critical": "#FF6B6B", | |
| "warning": "#FFE66D", | |
| "success": "#4ECDC4", | |
| "info": "#45B7D1" | |
| } | |
| def create_interactive_timeline(self, scenario: IncidentScenario) -> go.Figure: | |
| """Create truly interactive timeline with annotations""" | |
| fig = go.Figure() | |
| # Create timeline events | |
| events = [ | |
| {"time": "T-5m", "event": "📉 Cache hit rate drops below 20%", "type": "problem"}, | |
| {"time": "T-4m", "event": "⚠️ Database load exceeds 90%", "type": "alert"}, | |
| {"time": "T-3m", "event": "🤖 ARF detects pattern", "type": "detection"}, | |
| {"time": "T-2m", "event": "🧠 Analysis complete", "type": "analysis"}, | |
| {"time": "T-1m", "event": "⚡ Healing executed", "type": "action"}, | |
| {"time": "T-0m", "event": "✅ System recovered", "type": "recovery"} | |
| ] | |
| # Color mapping | |
| color_map = { | |
| "problem": self.theme["critical"], | |
| "alert": self.theme["warning"], | |
| "detection": self.theme["info"], | |
| "analysis": "#9B59B6", | |
| "action": self.theme["success"], | |
| "recovery": "#2ECC71" | |
| } | |
| # Add events | |
| for event in events: | |
| fig.add_trace(go.Scatter( | |
| x=[event["time"]], | |
| y=[1], | |
| mode='markers+text', | |
| marker=dict( | |
| size=20, | |
| color=color_map[event["type"]], | |
| symbol='circle', | |
| line=dict(width=2, color='white') | |
| ), | |
| text=[event["event"]], | |
| textposition="top center", | |
| hoverinfo='text', | |
| name=event["type"].capitalize(), | |
| hovertemplate="<b>%{text}</b><br>Click for details<extra></extra>" | |
| )) | |
| # Add connecting line | |
| fig.add_trace(go.Scatter( | |
| x=[e["time"] for e in events], | |
| y=[1] * len(events), | |
| mode='lines', | |
| line=dict(color='gray', width=2, dash='dash'), | |
| hoverinfo='none', | |
| showlegend=False | |
| )) | |
| fig.update_layout( | |
| title="<b>Interactive Incident Timeline</b><br><sup>Click events for details</sup>", | |
| height=450, | |
| paper_bgcolor=self.theme["background"], | |
| plot_bgcolor=self.theme["background"], | |
| hovermode='closest', | |
| clickmode='event+select', | |
| yaxis=dict( | |
| showticklabels=False, | |
| range=[0.5, 1.5], | |
| gridcolor=self.theme["grid"] | |
| ), | |
| xaxis=dict( | |
| gridcolor=self.theme["grid"] | |
| ), | |
| showlegend=True, | |
| legend=dict( | |
| yanchor="top", | |
| y=0.99, | |
| xanchor="left", | |
| x=0.01 | |
| ) | |
| ) | |
| return fig | |
| def create_executive_dashboard(self, user_roi: Optional[Dict] = None) -> go.Figure: | |
| """Create comprehensive executive dashboard""" | |
| fig = make_subplots( | |
| rows=2, cols=2, | |
| subplot_titles=( | |
| '<b>Cost Transformation</b>', | |
| '<b>Team Capacity Shift</b>', | |
| '<b>MTTR Comparison</b>', | |
| '<b>ROI Analysis</b>' | |
| ), | |
| vertical_spacing=0.2, | |
| horizontal_spacing=0.15 | |
| ) | |
| # 1. Cost Transformation | |
| cost_labels = ['Without ARF', 'With ARF Enterprise', 'Net Savings'] | |
| cost_values = [2.96, 1.0, 1.96] # In millions | |
| fig.add_trace( | |
| go.Bar( | |
| x=cost_labels, | |
| y=cost_values, | |
| marker_color=[self.theme["critical"], self.theme["success"], '#45B7D1'], | |
| text=[f'${v}M' for v in cost_values], | |
| textposition='auto', | |
| name='Annual Cost', | |
| hovertemplate="<b>%{x}</b><br>Cost: $%{y}M<extra></extra>" | |
| ), | |
| row=1, col=1 | |
| ) | |
| # 2. Team Capacity Shift | |
| activities = ['Firefighting', 'Innovation', 'Strategic Work'] | |
| before = [60, 20, 20] | |
| after = [10, 60, 30] | |
| fig.add_trace( | |
| go.Bar( | |
| x=activities, | |
| y=before, | |
| name='Before ARF', | |
| marker_color=self.theme["critical"], | |
| opacity=0.7, | |
| hovertemplate="Before: %{y}%%<extra></extra>" | |
| ), | |
| row=1, col=2 | |
| ) | |
| fig.add_trace( | |
| go.Bar( | |
| x=activities, | |
| y=after, | |
| name='After ARF Enterprise', | |
| marker_color=self.theme["success"], | |
| opacity=0.7, | |
| hovertemplate="After: %{y}%%<extra></extra>" | |
| ), | |
| row=1, col=2 | |
| ) | |
| # 3. MTTR Comparison | |
| mttr_methods = ['Manual', 'Traditional', 'ARF OSS', 'ARF Enterprise'] | |
| mttr_times = [120, 45, 25, 8] | |
| fig.add_trace( | |
| go.Bar( | |
| x=mttr_methods, | |
| y=mttr_times, | |
| marker_color=[self.theme["critical"], '#FFE66D', '#45B7D1', self.theme["success"]], | |
| text=[f'{t} min' for t in mttr_times], | |
| textposition='auto', | |
| name='MTTR', | |
| hovertemplate="<b>%{x}</b><br>Resolution: %{y} min<extra></extra>" | |
| ), | |
| row=2, col=1 | |
| ) | |
| # 4. ROI Gauge | |
| roi_value = user_roi.get('roi_multiplier', 5.2) if user_roi else 5.2 | |
| fig.add_trace( | |
| go.Indicator( | |
| mode="gauge+number+delta", | |
| value=roi_value, | |
| title={'text': "<b>ROI Multiplier</b>", 'font': {'size': 16}}, | |
| delta={'reference': 1.0, 'increasing': {'color': self.theme["success"]}}, | |
| gauge={ | |
| 'axis': {'range': [0, 10], 'tickwidth': 1}, | |
| 'bar': {'color': self.theme["success"]}, | |
| 'steps': [ | |
| {'range': [0, 2], 'color': 'lightgray'}, | |
| {'range': [2, 4], 'color': 'gray'}, | |
| {'range': [4, 6], 'color': 'lightgreen'}, | |
| {'range': [6, 10], 'color': self.theme["success"]} | |
| ], | |
| 'threshold': { | |
| 'line': {'color': "red", 'width': 4}, | |
| 'thickness': 0.75, | |
| 'value': roi_value | |
| } | |
| } | |
| ), | |
| row=2, col=2 | |
| ) | |
| # Update layout | |
| fig.update_layout( | |
| height=700, | |
| showlegend=True, | |
| paper_bgcolor=self.theme["background"], | |
| plot_bgcolor=self.theme["background"], | |
| title_text="<b>Executive Business Dashboard</b>", | |
| barmode='group', | |
| legend=dict( | |
| yanchor="top", | |
| y=0.99, | |
| xanchor="left", | |
| x=0.01, | |
| bgcolor='rgba(255,255,255,0.9)' | |
| ) | |
| ) | |
| # Update axes | |
| fig.update_xaxes(title_text="Cost Model", row=1, col=1, gridcolor=self.theme["grid"]) | |
| fig.update_yaxes(title_text="Annual Cost ($M)", row=1, col=1, gridcolor=self.theme["grid"]) | |
| fig.update_xaxes(title_text="Activity", row=1, col=2, gridcolor=self.theme["grid"]) | |
| fig.update_yaxes(title_text="Time Allocation (%)", row=1, col=2, gridcolor=self.theme["grid"]) | |
| fig.update_xaxes(title_text="Resolution Method", row=2, col=1, gridcolor=self.theme["grid"]) | |
| fig.update_yaxes(title_text="Minutes to Resolve", row=2, col=1, gridcolor=self.theme["grid"]) | |
| return fig |