petter2025 commited on
Commit
cd1f0e3
ยท
verified ยท
1 Parent(s): d265a89

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +275 -145
app.py CHANGED
@@ -1,6 +1,7 @@
1
  """
2
  ๐Ÿš€ ARF Ultimate Investor Demo v3.8.0 - ENTERPRISE EDITION
3
  With Audit Trail, Incident History, Memory Graph, and Enterprise Features
 
4
  """
5
 
6
  import logging
@@ -346,7 +347,7 @@ class AuditTrailManager:
346
  }, indent=2, default=str)
347
 
348
  # ===========================================
349
- # ENHANCED VISUALIZATION ENGINE
350
  # ===========================================
351
 
352
  class EnhancedVisualizationEngine:
@@ -375,40 +376,67 @@ class EnhancedVisualizationEngine:
375
  "stable": "darkgreen"
376
  }
377
 
378
- for event in events:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
379
  fig.add_trace(go.Scatter(
380
- x=[event["time"]],
381
- y=[1],
382
- mode='markers+text',
383
- marker=dict(
384
- size=15,
385
- color=color_map[event["type"]],
386
- symbol='circle' if event["type"] in ['problem', 'alert'] else 'diamond',
387
- line=dict(width=2, color='white')
388
- ),
389
- text=[event["event"]],
390
- textposition="top center",
391
- name=event["type"].capitalize(),
392
- hovertemplate="<b>%{text}</b><br>%{x|%H:%M:%S}<extra></extra>"
393
  ))
394
 
395
  fig.update_layout(
396
  title="<b>Incident Timeline - Cache Miss Storm Resolution</b>",
397
  xaxis_title="Time โ†’",
398
- yaxis_title="Event Type",
 
 
 
 
399
  height=450,
400
- showlegend=True,
401
- paper_bgcolor='rgba(0,0,0,0)',
402
- plot_bgcolor='rgba(0,0,0,0)',
403
  hovermode='closest',
404
  xaxis=dict(
405
  tickformat='%H:%M',
406
- gridcolor='rgba(200,200,200,0.2)'
 
407
  ),
408
- yaxis=dict(
409
- showticklabels=False,
410
- gridcolor='rgba(200,200,200,0.1)'
411
- )
412
  )
413
 
414
  return fig
@@ -510,12 +538,21 @@ class EnhancedVisualizationEngine:
510
  fig.update_layout(
511
  height=700,
512
  showlegend=True,
513
- paper_bgcolor='rgba(0,0,0,0)',
514
- plot_bgcolor='rgba(0,0,0,0)',
515
  title_text="<b>Executive Business Dashboard</b>",
516
- barmode='group'
 
517
  )
518
 
 
 
 
 
 
 
 
 
519
  return fig
520
 
521
  @staticmethod
@@ -526,10 +563,12 @@ class EnhancedVisualizationEngine:
526
  if not executions:
527
  fig = go.Figure()
528
  fig.update_layout(
529
- title="No execution history yet",
530
  height=400,
531
- paper_bgcolor='rgba(0,0,0,0)',
532
- plot_bgcolor='rgba(0,0,0,0)'
 
 
533
  )
534
  return fig
535
 
@@ -559,11 +598,18 @@ class EnhancedVisualizationEngine:
559
  xaxis_title="Scenario",
560
  yaxis_title="Cost Saved ($)",
561
  height=500,
562
- paper_bgcolor='rgba(0,0,0,0)',
563
- plot_bgcolor='rgba(0,0,0,0)',
564
- showlegend=False
 
 
 
565
  )
566
 
 
 
 
 
567
  return fig
568
 
569
  @staticmethod
@@ -576,43 +622,63 @@ class EnhancedVisualizationEngine:
576
  incidents = list(audit_manager.incident_history)[:20] # Last 20 incidents
577
 
578
  if not incidents:
579
- # Create sample graph
580
- nodes = [
581
- {"id": "Incident_1", "label": "Cache Miss", "type": "incident", "size": 20},
582
- {"id": "Action_1", "label": "Scale Cache", "type": "action", "size": 15},
583
- {"id": "Outcome_1", "label": "Resolved", "type": "outcome", "size": 15},
584
- {"id": "Component_1", "label": "Redis", "type": "component", "size": 18},
585
- ]
 
 
 
 
 
586
 
587
- edges = [
588
- {"source": "Incident_1", "target": "Action_1", "weight": 0.9, "label": "resolved_by"},
589
- {"source": "Action_1", "target": "Outcome_1", "weight": 1.0, "label": "leads_to"},
590
- {"source": "Incident_1", "target": "Component_1", "weight": 0.8, "label": "affects"},
591
- ]
592
- else:
593
- # Create nodes from actual incidents
594
- nodes = []
595
- edges = []
596
 
597
- for i, incident in enumerate(incidents):
598
- node_id = f"Incident_{i}"
599
- nodes.append({
600
- "id": node_id,
601
- "label": incident["type"][:20],
602
- "type": "incident",
603
- "size": 15 + (incident.get("severity", 2) * 5),
604
- "severity": incident.get("severity", 2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
605
  })
606
-
607
- # Create edges to previous incidents
608
- if i > 0:
609
- prev_id = f"Incident_{i-1}"
610
- edges.append({
611
- "source": prev_id,
612
- "target": node_id,
613
- "weight": 0.7,
614
- "label": "related_to"
615
- })
616
 
617
  # Color mapping
618
  color_map = {
@@ -622,70 +688,73 @@ class EnhancedVisualizationEngine:
622
  "component": "#96CEB4"
623
  }
624
 
625
- # Add nodes
626
- node_x = []
627
- node_y = []
628
- node_text = []
629
- node_color = []
630
- node_size = []
631
-
632
- for i, node in enumerate(nodes):
633
- # Simple layout - could be enhanced with networkx
634
- angle = 2 * np.pi * i / len(nodes)
635
  radius = 1.0
 
 
636
 
637
- node_x.append(radius * np.cos(angle))
638
- node_y.append(radius * np.sin(angle))
639
- node_text.append(f"{node['label']}<br>Type: {node['type']}")
640
- node_color.append(color_map.get(node["type"], "#999999"))
641
- node_size.append(node.get("size", 15))
642
-
643
- fig.add_trace(go.Scatter(
644
- x=node_x,
645
- y=node_y,
646
- mode='markers+text',
647
- marker=dict(
648
- size=node_size,
649
- color=node_color,
650
- line=dict(width=2, color='white')
651
- ),
652
- text=[node["label"] for node in nodes],
653
- textposition="top center",
654
- hovertext=node_text,
655
- hoverinfo="text",
656
- name="Nodes"
657
- ))
658
-
659
- # Add edges
660
- for edge in edges:
661
- try:
662
- source_idx = next(i for i, n in enumerate(nodes) if n["id"] == edge["source"])
663
- target_idx = next(i for i, n in enumerate(nodes) if n["id"] == edge["target"])
664
-
665
- fig.add_trace(go.Scatter(
666
- x=[node_x[source_idx], node_x[target_idx], None],
667
- y=[node_y[source_idx], node_y[target_idx], None],
668
- mode='lines',
669
- line=dict(
670
- width=2 * edge.get("weight", 1.0),
671
- color='rgba(100, 100, 100, 0.5)'
672
- ),
673
- hoverinfo='none',
674
- showlegend=False
675
- ))
676
- except StopIteration:
677
- continue
678
 
679
  fig.update_layout(
680
- title="<b>Incident Memory Graph</b>",
681
- showlegend=True,
682
  height=600,
683
- paper_bgcolor='rgba(0,0,0,0)',
684
- plot_bgcolor='rgba(0,0,0,0)',
685
  hovermode='closest',
686
- xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
687
- yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
688
- margin=dict(l=20, r=20, t=40, b=20)
 
 
 
 
 
 
 
 
 
 
689
  )
690
 
691
  return fig
@@ -697,7 +766,8 @@ class EnhancedVisualizationEngine:
697
  rows=2, cols=2,
698
  subplot_titles=('Incident Frequency', 'Resolution Times',
699
  'Success Rates', 'Pattern Correlation'),
700
- vertical_spacing=0.15
 
701
  )
702
 
703
  # Sample data - in real app this would come from analysis
@@ -708,19 +778,34 @@ class EnhancedVisualizationEngine:
708
 
709
  # Incident Frequency
710
  fig.add_trace(
711
- go.Bar(x=patterns, y=frequencies, name='Frequency'),
 
 
 
 
 
712
  row=1, col=1
713
  )
714
 
715
  # Resolution Times
716
  fig.add_trace(
717
- go.Bar(x=patterns, y=resolution_times, name='Resolution Time (min)'),
 
 
 
 
 
718
  row=1, col=2
719
  )
720
 
721
  # Success Rates
722
  fig.add_trace(
723
- go.Bar(x=patterns, y=success_rates, name='Success Rate %'),
 
 
 
 
 
724
  row=2, col=1
725
  )
726
 
@@ -734,16 +819,32 @@ class EnhancedVisualizationEngine:
734
  ])
735
 
736
  fig.add_trace(
737
- go.Heatmap(z=corr_matrix, x=patterns, y=patterns),
 
 
 
 
 
 
738
  row=2, col=2
739
  )
740
 
741
  fig.update_layout(
742
  height=700,
743
  showlegend=False,
744
- title_text="<b>Pattern Analysis Dashboard</b>"
 
 
745
  )
746
 
 
 
 
 
 
 
 
 
747
  return fig
748
 
749
  # ===========================================
@@ -1106,7 +1207,7 @@ class EnhancedBusinessLogic:
1106
  return temp_file.name
1107
 
1108
  # ===========================================
1109
- # MAIN INTERFACE
1110
  # ===========================================
1111
 
1112
  def create_interface() -> gr.Blocks:
@@ -1122,11 +1223,12 @@ def create_interface() -> gr.Blocks:
1122
  h1, h2, h3 { color: #1a365d !important; }
1123
  .critical { color: #FF6B6B !important; font-weight: bold; }
1124
  .success { color: #4ECDC4 !important; font-weight: bold; }
 
1125
  """
1126
 
1127
  with gr.Blocks(
1128
  title="๐Ÿš€ ARF Investor Demo v3.8.0",
1129
- theme=gr.themes.Soft(),
1130
  css=custom_css
1131
  ) as demo:
1132
 
@@ -1178,7 +1280,10 @@ def create_interface() -> gr.Blocks:
1178
  with gr.Column(scale=2):
1179
  # Visualization
1180
  gr.Markdown("### ๐Ÿ“ˆ Incident Timeline")
1181
- timeline_output = gr.Plot()
 
 
 
1182
 
1183
  # Action Section
1184
  gr.Markdown("### โšก Take Action")
@@ -1217,7 +1322,10 @@ def create_interface() -> gr.Blocks:
1217
  with gr.Column():
1218
  # Business Dashboard
1219
  gr.Markdown("### ๐Ÿ“Š Executive Business Dashboard")
1220
- dashboard_output = gr.Plot()
 
 
 
1221
 
1222
  # ROI Calculator
1223
  gr.Markdown("### ๐Ÿงฎ Interactive ROI Calculator")
@@ -1289,7 +1397,10 @@ def create_interface() -> gr.Blocks:
1289
  )
1290
 
1291
  gr.Markdown("### ๐Ÿ“ˆ Visual History")
1292
- execution_chart = gr.Plot()
 
 
 
1293
 
1294
  # AI Analysis Results
1295
  gr.Markdown("### ๐Ÿง  AI Pattern Analysis")
@@ -1312,7 +1423,10 @@ def create_interface() -> gr.Blocks:
1312
 
1313
  # Memory Graph Visualization
1314
  gr.Markdown("### ๐Ÿง  Memory Graph")
1315
- memory_graph = gr.Plot()
 
 
 
1316
 
1317
  # Export Area
1318
  gr.Markdown("### ๐Ÿ“ค Export & Analytics")
@@ -1444,7 +1558,10 @@ def create_interface() -> gr.Blocks:
1444
  auto_layout = gr.Checkbox(label="Auto-Layout", value=True)
1445
 
1446
  # Graph Visualization
1447
- memory_graph_plot = gr.Plot()
 
 
 
1448
 
1449
  # Node Details
1450
  gr.Markdown("### ๐Ÿ” Selected Node Details")
@@ -1711,12 +1828,24 @@ def create_interface() -> gr.Blocks:
1711
  auto_layout=auto_layout
1712
  )
1713
 
1714
- for control in [graph_type, show_weights, auto_layout]:
1715
- control.change(
1716
- fn=update_graph_view,
1717
- inputs=[graph_type, show_weights, auto_layout],
1718
- outputs=[memory_graph_plot]
1719
- )
 
 
 
 
 
 
 
 
 
 
 
 
1720
 
1721
  def search_memory(query: str) -> Tuple[List[List[str]], str]:
1722
  """Search memory"""
@@ -1762,9 +1891,10 @@ def create_interface() -> gr.Blocks:
1762
  )
1763
 
1764
  # ===========================================
1765
- # INITIALIZATION
1766
  # ===========================================
1767
 
 
1768
  demo.load(
1769
  fn=lambda: (
1770
  viz_engine.create_business_dashboard(),
 
1
  """
2
  ๐Ÿš€ ARF Ultimate Investor Demo v3.8.0 - ENTERPRISE EDITION
3
  With Audit Trail, Incident History, Memory Graph, and Enterprise Features
4
+ FIXED VERSION - No Plot Errors
5
  """
6
 
7
  import logging
 
347
  }, indent=2, default=str)
348
 
349
  # ===========================================
350
+ # ENHANCED VISUALIZATION ENGINE (FIXED)
351
  # ===========================================
352
 
353
  class EnhancedVisualizationEngine:
 
376
  "stable": "darkgreen"
377
  }
378
 
379
+ symbol_map = {
380
+ "problem": "circle", "alert": "circle", "detection": "diamond",
381
+ "analysis": "diamond", "action": "square", "recovery": "star",
382
+ "stable": "cross"
383
+ }
384
+
385
+ # Convert datetime objects to strings for Plotly
386
+ times = [event["time"] for event in events]
387
+ events_text = [event["event"] for event in events]
388
+ event_types = [event["type"] for event in events]
389
+ colors = [color_map[event_type] for event_type in event_types]
390
+ symbols = [symbol_map[event_type] for event_type in event_types]
391
+
392
+ fig.add_trace(go.Scatter(
393
+ x=times,
394
+ y=[1] * len(events), # Fixed y-position
395
+ mode='markers+text',
396
+ marker=dict(
397
+ size=20,
398
+ color=colors,
399
+ symbol=symbols,
400
+ line=dict(width=2, color='white')
401
+ ),
402
+ text=events_text,
403
+ textposition="top center",
404
+ hoverinfo="text",
405
+ hovertemplate="<b>%{text}</b><br>%{x|%H:%M:%S}<extra></extra>",
406
+ name="Timeline Events"
407
+ ))
408
+
409
+ # Add connecting lines
410
+ for i in range(len(times) - 1):
411
  fig.add_trace(go.Scatter(
412
+ x=[times[i], times[i + 1]],
413
+ y=[1, 1],
414
+ mode='lines',
415
+ line=dict(color='gray', width=1, dash='dash'),
416
+ showlegend=False,
417
+ hoverinfo='none'
 
 
 
 
 
 
 
418
  ))
419
 
420
  fig.update_layout(
421
  title="<b>Incident Timeline - Cache Miss Storm Resolution</b>",
422
  xaxis_title="Time โ†’",
423
+ yaxis=dict(
424
+ title="Event Type",
425
+ showticklabels=False,
426
+ range=[0.5, 1.5] # Fixed range for better display
427
+ ),
428
  height=450,
429
+ showlegend=False,
430
+ paper_bgcolor='white',
431
+ plot_bgcolor='white',
432
  hovermode='closest',
433
  xaxis=dict(
434
  tickformat='%H:%M',
435
+ gridcolor='rgba(200,200,200,0.2)',
436
+ showgrid=True
437
  ),
438
+ yaxis_showgrid=False,
439
+ margin=dict(l=50, r=50, t=80, b=50)
 
 
440
  )
441
 
442
  return fig
 
538
  fig.update_layout(
539
  height=700,
540
  showlegend=True,
541
+ paper_bgcolor='white',
542
+ plot_bgcolor='white',
543
  title_text="<b>Executive Business Dashboard</b>",
544
+ barmode='group',
545
+ margin=dict(l=50, r=50, t=100, b=50)
546
  )
547
 
548
+ # Update axes
549
+ fig.update_xaxes(title_text="Scenario", row=1, col=1)
550
+ fig.update_yaxes(title_text="Cost ($)", row=1, col=1)
551
+ fig.update_xaxes(title_text="Activity", row=1, col=2)
552
+ fig.update_yaxes(title_text="Percentage (%)", row=1, col=2)
553
+ fig.update_xaxes(title_text="Approach", row=2, col=1)
554
+ fig.update_yaxes(title_text="MTTR (minutes)", row=2, col=1)
555
+
556
  return fig
557
 
558
  @staticmethod
 
563
  if not executions:
564
  fig = go.Figure()
565
  fig.update_layout(
566
+ title="<b>No execution history yet</b>",
567
  height=400,
568
+ paper_bgcolor='white',
569
+ plot_bgcolor='white',
570
+ xaxis_showgrid=True,
571
+ yaxis_showgrid=True
572
  )
573
  return fig
574
 
 
598
  xaxis_title="Scenario",
599
  yaxis_title="Cost Saved ($)",
600
  height=500,
601
+ paper_bgcolor='white',
602
+ plot_bgcolor='white',
603
+ showlegend=False,
604
+ xaxis_showgrid=True,
605
+ yaxis_showgrid=True,
606
+ margin=dict(l=50, r=50, t=80, b=100)
607
  )
608
 
609
+ # Rotate x-axis labels if needed
610
+ if len(scenarios) > 5:
611
+ fig.update_xaxes(tickangle=45)
612
+
613
  return fig
614
 
615
  @staticmethod
 
622
  incidents = list(audit_manager.incident_history)[:20] # Last 20 incidents
623
 
624
  if not incidents:
625
+ # Create a simple placeholder graph
626
+ fig.add_trace(go.Scatter(
627
+ x=[0, 1, 0.5],
628
+ y=[0, 0, 0.866],
629
+ mode='markers+text',
630
+ marker=dict(
631
+ size=[30, 20, 20],
632
+ color=['#FF6B6B', '#4ECDC4', '#45B7D1']
633
+ ),
634
+ text=['Incident', 'Action', 'Outcome'],
635
+ textposition="top center"
636
+ ))
637
 
638
+ # Add edges
639
+ fig.add_trace(go.Scatter(
640
+ x=[0, 0.5, 1],
641
+ y=[0, 0.866, 0],
642
+ mode='lines',
643
+ line=dict(color='gray', width=2),
644
+ hoverinfo='none'
645
+ ))
 
646
 
647
+ fig.update_layout(
648
+ title="<b>Incident Memory Graph (Sample)</b>",
649
+ showlegend=False,
650
+ height=600,
651
+ paper_bgcolor='white',
652
+ plot_bgcolor='white',
653
+ xaxis=dict(showgrid=False, zeroline=False, showticklabels=False, range=[-0.2, 1.2]),
654
+ yaxis=dict(showgrid=False, zeroline=False, showticklabels=False, range=[-0.2, 1.2]),
655
+ margin=dict(l=20, r=20, t=60, b=20)
656
+ )
657
+ return fig
658
+
659
+ # Create nodes from actual incidents
660
+ nodes = []
661
+ edges = []
662
+
663
+ for i, incident in enumerate(incidents):
664
+ node_id = f"Incident_{i}"
665
+ nodes.append({
666
+ "id": node_id,
667
+ "label": incident["type"][:20],
668
+ "type": "incident",
669
+ "size": 15 + (incident.get("severity", 2) * 5),
670
+ "severity": incident.get("severity", 2)
671
+ })
672
+
673
+ # Create edges to previous incidents
674
+ if i > 0 and i % 3 == 0: # Connect every 3rd incident
675
+ prev_id = f"Incident_{i-1}"
676
+ edges.append({
677
+ "source": prev_id,
678
+ "target": node_id,
679
+ "weight": 0.7,
680
+ "label": "related_to"
681
  })
 
 
 
 
 
 
 
 
 
 
682
 
683
  # Color mapping
684
  color_map = {
 
688
  "component": "#96CEB4"
689
  }
690
 
691
+ # Calculate positions (circular layout)
692
+ num_nodes = len(nodes)
693
+ if num_nodes > 0:
694
+ angles = np.linspace(0, 2 * np.pi, num_nodes, endpoint=False)
 
 
 
 
 
 
695
  radius = 1.0
696
+ node_x = radius * np.cos(angles)
697
+ node_y = radius * np.sin(angles)
698
 
699
+ # Add nodes
700
+ fig.add_trace(go.Scatter(
701
+ x=node_x,
702
+ y=node_y,
703
+ mode='markers+text',
704
+ marker=dict(
705
+ size=[node.get("size", 15) for node in nodes],
706
+ color=[color_map.get(node.get("type", "incident"), "#999999") for node in nodes],
707
+ line=dict(width=2, color='white')
708
+ ),
709
+ text=[node["label"] for node in nodes],
710
+ textposition="top center",
711
+ hovertext=[f"Type: {node['type']}<br>Severity: {node.get('severity', 'N/A')}" for node in nodes],
712
+ hoverinfo="text",
713
+ name="Nodes"
714
+ ))
715
+
716
+ # Add edges if we have them
717
+ if edges:
718
+ for edge in edges:
719
+ try:
720
+ source_idx = int(edge["source"].split("_")[1])
721
+ target_idx = int(edge["target"].split("_")[1])
722
+
723
+ if source_idx < num_nodes and target_idx < num_nodes:
724
+ fig.add_trace(go.Scatter(
725
+ x=[node_x[source_idx], node_x[target_idx], None],
726
+ y=[node_y[source_idx], node_y[target_idx], None],
727
+ mode='lines',
728
+ line=dict(
729
+ width=2 * edge.get("weight", 1.0),
730
+ color='rgba(100, 100, 100, 0.5)'
731
+ ),
732
+ hoverinfo='none',
733
+ showlegend=False
734
+ ))
735
+ except (ValueError, IndexError):
736
+ continue
 
 
 
737
 
738
  fig.update_layout(
739
+ title=f"<b>Incident Memory Graph ({len(nodes)} nodes)</b>",
740
+ showlegend=False,
741
  height=600,
742
+ paper_bgcolor='white',
743
+ plot_bgcolor='white',
744
  hovermode='closest',
745
+ xaxis=dict(
746
+ showgrid=False,
747
+ zeroline=False,
748
+ showticklabels=False,
749
+ range=[-1.5, 1.5]
750
+ ),
751
+ yaxis=dict(
752
+ showgrid=False,
753
+ zeroline=False,
754
+ showticklabels=False,
755
+ range=[-1.5, 1.5]
756
+ ),
757
+ margin=dict(l=50, r=50, t=80, b=50)
758
  )
759
 
760
  return fig
 
766
  rows=2, cols=2,
767
  subplot_titles=('Incident Frequency', 'Resolution Times',
768
  'Success Rates', 'Pattern Correlation'),
769
+ vertical_spacing=0.15,
770
+ horizontal_spacing=0.15
771
  )
772
 
773
  # Sample data - in real app this would come from analysis
 
778
 
779
  # Incident Frequency
780
  fig.add_trace(
781
+ go.Bar(
782
+ x=patterns,
783
+ y=frequencies,
784
+ name='Frequency',
785
+ marker_color='#4ECDC4'
786
+ ),
787
  row=1, col=1
788
  )
789
 
790
  # Resolution Times
791
  fig.add_trace(
792
+ go.Bar(
793
+ x=patterns,
794
+ y=resolution_times,
795
+ name='Resolution Time (min)',
796
+ marker_color='#45B7D1'
797
+ ),
798
  row=1, col=2
799
  )
800
 
801
  # Success Rates
802
  fig.add_trace(
803
+ go.Bar(
804
+ x=patterns,
805
+ y=success_rates,
806
+ name='Success Rate %',
807
+ marker_color='#96CEB4'
808
+ ),
809
  row=2, col=1
810
  )
811
 
 
819
  ])
820
 
821
  fig.add_trace(
822
+ go.Heatmap(
823
+ z=corr_matrix,
824
+ x=patterns,
825
+ y=patterns,
826
+ colorscale='Blues',
827
+ showscale=True
828
+ ),
829
  row=2, col=2
830
  )
831
 
832
  fig.update_layout(
833
  height=700,
834
  showlegend=False,
835
+ title_text="<b>Pattern Analysis Dashboard</b>",
836
+ paper_bgcolor='white',
837
+ plot_bgcolor='white'
838
  )
839
 
840
+ # Update axes
841
+ fig.update_xaxes(title_text="Pattern Type", row=1, col=1)
842
+ fig.update_yaxes(title_text="Frequency", row=1, col=1)
843
+ fig.update_xaxes(title_text="Pattern Type", row=1, col=2)
844
+ fig.update_yaxes(title_text="Time (minutes)", row=1, col=2)
845
+ fig.update_xaxes(title_text="Pattern Type", row=2, col=1)
846
+ fig.update_yaxes(title_text="Success Rate (%)", row=2, col=1)
847
+
848
  return fig
849
 
850
  # ===========================================
 
1207
  return temp_file.name
1208
 
1209
  # ===========================================
1210
+ # MAIN INTERFACE (FIXED)
1211
  # ===========================================
1212
 
1213
  def create_interface() -> gr.Blocks:
 
1223
  h1, h2, h3 { color: #1a365d !important; }
1224
  .critical { color: #FF6B6B !important; font-weight: bold; }
1225
  .success { color: #4ECDC4 !important; font-weight: bold; }
1226
+ .plot-container { background: white !important; border-radius: 10px; padding: 10px; }
1227
  """
1228
 
1229
  with gr.Blocks(
1230
  title="๐Ÿš€ ARF Investor Demo v3.8.0",
1231
+ theme=gr.themes.Soft(primary_hue="blue", secondary_hue="teal"),
1232
  css=custom_css
1233
  ) as demo:
1234
 
 
1280
  with gr.Column(scale=2):
1281
  # Visualization
1282
  gr.Markdown("### ๐Ÿ“ˆ Incident Timeline")
1283
+ timeline_output = gr.Plot(
1284
+ value=viz_engine.create_incident_timeline(),
1285
+ label="Timeline Visualization"
1286
+ )
1287
 
1288
  # Action Section
1289
  gr.Markdown("### โšก Take Action")
 
1322
  with gr.Column():
1323
  # Business Dashboard
1324
  gr.Markdown("### ๐Ÿ“Š Executive Business Dashboard")
1325
+ dashboard_output = gr.Plot(
1326
+ value=viz_engine.create_business_dashboard(),
1327
+ label="Business Dashboard"
1328
+ )
1329
 
1330
  # ROI Calculator
1331
  gr.Markdown("### ๐Ÿงฎ Interactive ROI Calculator")
 
1397
  )
1398
 
1399
  gr.Markdown("### ๐Ÿ“ˆ Visual History")
1400
+ execution_chart = gr.Plot(
1401
+ value=viz_engine.create_execution_history_chart(audit_manager),
1402
+ label="Cost Savings Chart"
1403
+ )
1404
 
1405
  # AI Analysis Results
1406
  gr.Markdown("### ๐Ÿง  AI Pattern Analysis")
 
1423
 
1424
  # Memory Graph Visualization
1425
  gr.Markdown("### ๐Ÿง  Memory Graph")
1426
+ memory_graph = gr.Plot(
1427
+ value=viz_engine.create_memory_graph(audit_manager),
1428
+ label="Memory Graph"
1429
+ )
1430
 
1431
  # Export Area
1432
  gr.Markdown("### ๐Ÿ“ค Export & Analytics")
 
1558
  auto_layout = gr.Checkbox(label="Auto-Layout", value=True)
1559
 
1560
  # Graph Visualization
1561
+ memory_graph_plot = gr.Plot(
1562
+ value=viz_engine.create_memory_graph(audit_manager),
1563
+ label="Memory Graph Visualization"
1564
+ )
1565
 
1566
  # Node Details
1567
  gr.Markdown("### ๐Ÿ” Selected Node Details")
 
1828
  auto_layout=auto_layout
1829
  )
1830
 
1831
+ # Connect all graph controls
1832
+ graph_type.change(
1833
+ fn=update_graph_view,
1834
+ inputs=[graph_type, show_weights, auto_layout],
1835
+ outputs=[memory_graph_plot]
1836
+ )
1837
+
1838
+ show_weights.change(
1839
+ fn=update_graph_view,
1840
+ inputs=[graph_type, show_weights, auto_layout],
1841
+ outputs=[memory_graph_plot]
1842
+ )
1843
+
1844
+ auto_layout.change(
1845
+ fn=update_graph_view,
1846
+ inputs=[graph_type, show_weights, auto_layout],
1847
+ outputs=[memory_graph_plot]
1848
+ )
1849
 
1850
  def search_memory(query: str) -> Tuple[List[List[str]], str]:
1851
  """Search memory"""
 
1891
  )
1892
 
1893
  # ===========================================
1894
+ # INITIALIZATION - FIXED
1895
  # ===========================================
1896
 
1897
+ # Initialize with default visualizations
1898
  demo.load(
1899
  fn=lambda: (
1900
  viz_engine.create_business_dashboard(),