# utils/visual_output.py - Visual output generation for PDF Analysis & Orchestrator import json import re from typing import Dict, List, Any, Optional from datetime import datetime class VisualOutputGenerator: """Generate visual representations of analysis results""" def __init__(self): self.visual_elements = [] def create_infographic(self, data: Dict[str, Any], title: str = "Analysis Summary") -> str: """Create an infographic-style summary""" visual = f""" ## 📊 {title}
""" # Key metrics if 'metrics' in data: visual += f"""
""" for metric, value in data['metrics'].items(): visual += f"""

{value}

{metric}

""" visual += "
" visual += "
" return visual def create_data_table(self, data: List[Dict[str, Any]], title: str = "Data Table") -> str: """Create a formatted table from data""" if not data: return "" # Get headers from first row headers = list(data[0].keys()) table = f""" ## 📋 {title} | {' | '.join(headers)} | | {' | '.join(['---'] * len(headers))} | """ for row in data: values = [str(row.get(header, '')) for header in headers] table += f"| {' | '.join(values)} |\n" return table def create_progress_bar(self, value: float, max_value: float, label: str) -> str: """Create a progress bar visualization""" percentage = min(100, (value / max_value) * 100) if max_value > 0 else 0 return f"""

{label}: {value:.1f}/{max_value:.1f} ({percentage:.1f}%)

""" def create_timeline(self, events: List[Dict[str, str]], title: str = "Timeline") -> str: """Create a timeline visualization""" timeline = f""" ## ⏰ {title}
""" for i, event in enumerate(events): timeline += f"""

{event.get('title', 'Event')}

{event.get('description', '')}

{event.get('date', '')}
""" timeline += "
" return timeline def create_comparison_chart(self, data: Dict[str, float], title: str = "Comparison") -> str: """Create a comparison chart""" if not data: return "" max_value = max(data.values()) if data.values() else 1 chart = f""" ## 📈 {title}
""" for label, value in data.items(): percentage = (value / max_value) * 100 chart += f"""
{label} {value:.1f}
""" chart += "
" return chart def create_key_points(self, points: List[str], title: str = "Key Points") -> str: """Create a stunning key points section with visual elements""" if not points: return "" # Icons for different types of points icons = ["đŸŽ¯", "💡", "✅", "📊", "⚡", "🔍", "🚀", "💎", "⭐", "đŸ”Ĩ"] visual = f""" ## 💡 {title}
""" for i, point in enumerate(points, 1): icon = icons[i % len(icons)] color = ["#007bff", "#28a745", "#ffc107", "#dc3545", "#6f42c1"][i % 5] visual += f"""
{icon}

{point}

""" visual += "
" return visual def create_alert_box(self, message: str, alert_type: str = "info") -> str: """Create an alert box""" colors = { "info": "#2196F3", "success": "#4CAF50", "warning": "#FF9800", "error": "#F44336" } icons = { "info": "â„šī¸", "success": "✅", "warning": "âš ī¸", "error": "❌" } color = colors.get(alert_type, colors["info"]) icon = icons.get(alert_type, icons["info"]) return f"""
{icon}

{message}

""" def create_metric_cards(self, metrics: Dict[str, Any], title: str = "Key Metrics") -> str: """Create metric cards""" if not metrics: return "" cards = f""" ## 📊 {title}
""" for metric, value in metrics.items(): cards += f"""

{value}

{metric}

""" cards += "
" return cards def format_analysis_with_visuals(self, analysis_text: str, document_metadata: Dict[str, Any] = None) -> str: """Format analysis text with stunning visual elements""" visual_elements = [] # Add document info if available if document_metadata: visual_elements.append(self.create_metric_cards({ "📄 Pages": document_metadata.get('page_count', 'Unknown'), "💾 File Size": f"{document_metadata.get('file_size', 0) / 1024:.1f} KB", "⚡ Processing": f"{document_metadata.get('processing_time', 0):.1f}s", "đŸŽ¯ Tokens": document_metadata.get('tokens_used', 'N/A') }, "📊 Document Overview")) # Create a beautiful header visual_elements.append(self.create_analysis_header()) # Try to extract key points from analysis key_points = self._extract_key_points(analysis_text) if key_points: visual_elements.append(self.create_key_points(key_points, "đŸŽ¯ Key Insights")) # Try to extract metrics metrics = self._extract_metrics(analysis_text) if metrics: visual_elements.append(self.create_metric_cards(metrics, "📈 Key Metrics")) # Try to extract data for tables table_data = self._extract_table_data(analysis_text) if table_data: visual_elements.append(self.create_data_table(table_data, "📋 Data Summary")) # Format the main analysis with better structure formatted_analysis = self._format_analysis_text(analysis_text) # Combine all elements result = "\n\n".join(visual_elements) if formatted_analysis: result += f"\n\n---\n\n{formatted_analysis}" return result def create_analysis_header(self) -> str: """Create a beautiful analysis header""" return """

📄 AI Document Analysis

Powered by Advanced AI â€ĸ Instant Insights â€ĸ Professional Results

""" def _format_analysis_text(self, text: str) -> str: """Format analysis text with better visual structure""" # Split into sections sections = text.split('\n\n') formatted_sections = [] for section in sections: if section.strip(): # Check if it's a header if section.startswith('##'): formatted_sections.append(f"\n{section}\n") else: # Format as a content block formatted_sections.append(f"""
{section}
""") return '\n'.join(formatted_sections) def _extract_table_data(self, text: str) -> List[Dict[str, Any]]: """Extract data that can be formatted as tables""" table_data = [] # Look for comparison patterns comparison_pattern = r'(\w+):\s*(\d+(?:\.\d+)?%?)\s*vs\s*(\w+):\s*(\d+(?:\.\d+)?%?)' matches = re.findall(comparison_pattern, text, re.IGNORECASE) for match in matches: table_data.append({ "Metric": match[0], "Value": match[1], "Comparison": match[2], "Value 2": match[3] }) return table_data def _extract_key_points(self, text: str) -> List[str]: """Extract key points from analysis text""" # Look for bullet points, numbered lists, or key findings points = [] # Extract bullet points bullet_pattern = r'[-â€ĸ*]\s+(.+?)(?=\n|$)' bullets = re.findall(bullet_pattern, text, re.MULTILINE) points.extend([bullet.strip() for bullet in bullets if len(bullet.strip()) > 10]) # Extract numbered points number_pattern = r'\d+\.\s+(.+?)(?=\n|$)' numbers = re.findall(number_pattern, text, re.MULTILINE) points.extend([num.strip() for num in numbers if len(num.strip()) > 10]) # Limit to top 5 points return points[:5] def _extract_metrics(self, text: str) -> Dict[str, str]: """Extract metrics from analysis text""" metrics = {} # Look for percentage patterns percent_pattern = r'(\d+(?:\.\d+)?%)' percentages = re.findall(percent_pattern, text) if percentages: metrics["Success Rate"] = percentages[0] # Look for number patterns number_pattern = r'(\d+(?:,\d+)*(?:\.\d+)?)\s+(?:pages?|items?|points?|years?|months?)' numbers = re.findall(number_pattern, text, re.IGNORECASE) if numbers: metrics["Total Items"] = numbers[0] return metrics