Skip to main content
Glama

CodeAnalysis MCP Server

by 0xjcf
maturity_dashboard.py14 kB
#!/usr/bin/env python3 """Maturity Model Dashboard Generator This script generates an interactive HTML dashboard for visualizing component maturity across the codebase. Maturity: beta Why: - Visual representation makes maturity patterns more apparent - Interactive dashboard allows exploration of maturity data - Timeline view shows progression of components through maturity levels - Helps plan development efforts to mature experimental components """ import argparse import json import os from datetime import datetime from pathlib import Path import pandas as pd import plotly.express as px import plotly.graph_objects as go from plotly.subplots import make_subplots from jinja2 import Environment, FileSystemLoader class MaturityDashboard: """Generates an interactive dashboard for maturity visualization.""" def __init__(self, template_dir=None): if template_dir is None: # Use default templates directory relative to this script template_dir = Path(__file__).parent / "templates" self.template_dir = Path(template_dir) # Create template directory if it doesn't exist if not self.template_dir.exists(): self.template_dir.mkdir(parents=True) self._create_default_template() self.env = Environment(loader=FileSystemLoader(self.template_dir)) def _create_default_template(self): """Create a default HTML template if none exists.""" template_path = self.template_dir / "dashboard_template.html" default_template = """<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Component Maturity Dashboard</title> <style> body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: #f5f5f5; } .dashboard-title { text-align: center; margin-bottom: 30px; } .dashboard-container { max-width: 1200px; margin: 0 auto; background-color: white; padding: 20px; border-radius: 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); } .dashboard-summary { margin-bottom: 30px; padding: 15px; background-color: #f9f9f9; border-radius: 5px; } .chart-container { margin-bottom: 40px; } .component-table { width: 100%; border-collapse: collapse; margin-top: 20px; } .component-table th, .component-table td { padding: 8px 12px; border: 1px solid #ddd; text-align: left; } .component-table th { background-color: #f2f2f2; } .component-table tr:nth-child(even) { background-color: #f9f9f9; } .experimental { background-color: #ffebee !important; } .beta { background-color: #e3f2fd !important; } .stable { background-color: #e8f5e9 !important; } .deprecated { background-color: #fff3e0 !important; } .filter-controls { margin-bottom: 20px; padding: 10px; background-color: #f2f2f2; border-radius: 5px; } </style> </head> <body> <div class="dashboard-container"> <div class="dashboard-title"> <h1>Component Maturity Dashboard</h1> <p>Generated on {{ generated_date }}</p> </div> <div class="dashboard-summary"> <h2>Summary</h2> <p>Total Components: {{ total_components }}</p> <p>Components by Maturity Level:</p> <ul> <li>Experimental: {{ experimental_count }} ({{ experimental_percent }}%)</li> <li>Beta: {{ beta_count }} ({{ beta_percent }}%)</li> <li>Stable: {{ stable_count }} ({{ stable_percent }}%)</li> <li>Deprecated: {{ deprecated_count }} ({{ deprecated_percent }}%)</li> </ul> </div> <div class="filter-controls"> <h3>Filter Components</h3> <div id="maturity-filter"></div> <div id="filetype-filter"></div> </div> <div class="chart-container"> <h2>Maturity Distribution</h2> {{ maturity_distribution_chart|safe }} </div> <div class="chart-container"> <h2>Maturity by File Type</h2> {{ file_type_chart|safe }} </div> <div class="chart-container"> <h2>Component Maturity Timeline</h2> <p>Shows when components were last modified, grouped by maturity level.</p> {{ timeline_chart|safe }} </div> <div class="component-table-container"> <h2>Component Details</h2> <table class="component-table" id="componentTable"> <thead> <tr> <th>Component Name</th> <th>Maturity</th> <th>File Type</th> <th>Since Version</th> <th>Next Level</th> <th>Last Modified</th> </tr> </thead> <tbody> {% for component in components %} <tr class="{{ component.maturity }}"> <td>{{ component.name }}</td> <td>{{ component.maturity }}</td> <td>{{ component.file_type }}</td> <td>{{ component.since_version }}</td> <td>{{ component.next_level if component.next_level else "N/A" }}</td> <td>{{ component.last_modified }}</td> </tr> {% endfor %} </tbody> </table> </div> </div> <script> // Simple table filtering functionality document.addEventListener('DOMContentLoaded', function() { const table = document.getElementById('componentTable'); const rows = table.getElementsByTagName('tr'); // Add more sophisticated filtering if needed }); </script> </body> </html> """ with open(template_path, 'w', encoding='utf-8') as f: f.write(default_template) def generate_dashboard(self, maturity_report_path, output_path=None): """Generate an HTML dashboard from a maturity report.""" # Load the maturity report try: with open(maturity_report_path, 'r', encoding='utf-8') as f: report = json.load(f) except Exception as e: print(f"Error loading maturity report: {e}") return if output_path is None: output_path = Path(maturity_report_path).parent / "maturity_dashboard.html" # Convert components to DataFrame for easier manipulation components_df = pd.DataFrame.from_dict(report['components'], orient='index') # Extract file types components_df['file_type'] = components_df['path'].apply( lambda x: os.path.splitext(x)[1][1:] if os.path.splitext(x)[1] else "unknown" ) # Format dates for display components_df['last_modified'] = pd.to_datetime(components_df['last_modified']).dt.strftime('%Y-%m-%d') # Calculate summary statistics total_components = len(components_df) maturity_counts = components_df['maturity'].value_counts() # Create visualizations maturity_distribution_chart = self._create_maturity_distribution_chart(components_df) file_type_chart = self._create_file_type_chart(components_df) timeline_chart = self._create_timeline_chart(components_df) # Prepare template variables template_vars = { 'generated_date': datetime.now().strftime('%Y-%m-%d %H:%M:%S'), 'total_components': total_components, 'experimental_count': maturity_counts.get('experimental', 0), 'beta_count': maturity_counts.get('beta', 0), 'stable_count': maturity_counts.get('stable', 0), 'deprecated_count': maturity_counts.get('deprecated', 0), 'experimental_percent': round((maturity_counts.get('experimental', 0) / total_components) * 100 if total_components > 0 else 0, 1), 'beta_percent': round((maturity_counts.get('beta', 0) / total_components) * 100 if total_components > 0 else 0, 1), 'stable_percent': round((maturity_counts.get('stable', 0) / total_components) * 100 if total_components > 0 else 0, 1), 'deprecated_percent': round((maturity_counts.get('deprecated', 0) / total_components) * 100 if total_components > 0 else 0, 1), 'maturity_distribution_chart': maturity_distribution_chart, 'file_type_chart': file_type_chart, 'timeline_chart': timeline_chart, 'components': components_df.to_dict('records') } # Render the template template = self.env.get_template('dashboard_template.html') output_html = template.render(**template_vars) # Save to file with open(output_path, 'w', encoding='utf-8') as f: f.write(output_html) print(f"Maturity dashboard generated at {output_path}") def _create_maturity_distribution_chart(self, df): """Create a pie chart of maturity distribution.""" maturity_counts = df['maturity'].value_counts() fig = px.pie( names=maturity_counts.index, values=maturity_counts.values, color=maturity_counts.index, color_discrete_map={ 'experimental': '#ffcdd2', 'beta': '#bbdefb', 'stable': '#c8e6c9', 'deprecated': '#ffe0b2' }, title="Component Maturity Distribution" ) fig.update_traces(textinfo='percent+label') return fig.to_html(full_html=False, include_plotlyjs='cdn') def _create_file_type_chart(self, df): """Create a stacked bar chart of maturity by file type.""" # Create a cross-tabulation of file type and maturity file_type_maturity = pd.crosstab(df['file_type'], df['maturity']) # Create stacked bar chart fig = px.bar( file_type_maturity, barmode='stack', color_discrete_map={ 'experimental': '#ffcdd2', 'beta': '#bbdefb', 'stable': '#c8e6c9', 'deprecated': '#ffe0b2' }, title="Component Maturity by File Type" ) fig.update_layout( xaxis_title="File Type", yaxis_title="Number of Components", legend_title="Maturity Level" ) return fig.to_html(full_html=False, include_plotlyjs='cdn') def _create_timeline_chart(self, df): """Create a timeline chart of component modifications by maturity level.""" # Convert last_modified to datetime df['last_modified_dt'] = pd.to_datetime(df['last_modified']) # Sort by date df_sorted = df.sort_values('last_modified_dt') # Create a figure with subplots fig = make_subplots(rows=4, cols=1, shared_xaxes=True, vertical_spacing=0.05, subplot_titles=("Experimental", "Beta", "Stable", "Deprecated")) # Colors for each maturity level colors = { 'experimental': '#ffcdd2', 'beta': '#bbdefb', 'stable': '#c8e6c9', 'deprecated': '#ffe0b2' } # Create a trace for each maturity level for i, maturity in enumerate(['experimental', 'beta', 'stable', 'deprecated']): level_df = df_sorted[df_sorted['maturity'] == maturity] if not level_df.empty: fig.add_trace( go.Scatter( x=level_df['last_modified_dt'], y=[1] * len(level_df), # All points on same y-level mode='markers', marker=dict( size=12, color=colors[maturity], line=dict(width=1, color='gray') ), text=level_df['name'], hovertemplate='<b>%{text}</b><br>Last Modified: %{x}<extra></extra>' ), row=i+1, col=1 ) # Update layout fig.update_layout( height=600, showlegend=False, hovermode='closest' ) # Update y-axes to hide ticks and labels for i in range(1, 5): fig.update_yaxes(showticklabels=False, row=i, col=1) return fig.to_html(full_html=False, include_plotlyjs='cdn') def main(): parser = argparse.ArgumentParser(description="Generate maturity dashboard") parser.add_argument("report", help="Path to the maturity report JSON file") parser.add_argument("--output", help="Output HTML file path") parser.add_argument("--template-dir", help="Directory containing templates") args = parser.parse_args() dashboard = MaturityDashboard(template_dir=args.template_dir) dashboard.generate_dashboard(args.report, output_path=args.output) if __name__ == "__main__": main()

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/0xjcf/MCP_CodeAnalysis'

If you have feedback or need assistance with the MCP directory API, please join our Discord server