import plotly.graph_objects as go import plotly.express as px from plotly.subplots import make_subplots import pandas as pd from models import EcoScoreResult class SustainabilityVisualizer: @staticmethod def create_eco_score_gauge(eco_score: float) -> go.Figure: """Create a gauge chart for the eco score""" # Determine color based on score if eco_score >= 7: color = "green" elif eco_score >= 4: color = "orange" else: color = "red" fig = go.Figure(go.Indicator( mode = "gauge+number", value = eco_score, domain = {'x': [0, 1], 'y': [0, 1]}, title = {'text': "Eco Score", 'font': {'size': 24}}, gauge = { 'axis': {'range': [1, 10], 'tickwidth': 1}, 'bar': {'color': color}, 'steps': [ {'range': [1, 4], 'color': 'lightcoral'}, {'range': [4, 7], 'color': 'lightsalmon'}, {'range': [7, 10], 'color': 'lightgreen'} ], 'threshold': { 'line': {'color': "black", 'width': 4}, 'thickness': 0.75, 'value': eco_score } } )) fig.update_layout( height=300, margin=dict(l=10, r=10, t=50, b=10) ) return fig @staticmethod def create_impact_breakdown(eco_result: EcoScoreResult) -> go.Figure: """Create a bar chart showing impact breakdown""" factors = ['Deforestation', 'Pollution', 'Biodiversity'] scores = [ eco_result.factors.deforestation_risk, eco_result.factors.pollution_risk, eco_result.factors.biodiversity_impact ] colors = ['brown' if s > 7 else 'orange' if s > 4 else 'green' for s in scores] fig = go.Figure(data=[ go.Bar( x=factors, y=scores, marker_color=colors, text=[f"{s}/10" for s in scores], textposition='outside', ) ]) fig.update_layout( title="Environmental Impact Breakdown", xaxis_title="Impact Factors", yaxis_title="Risk Level (1-10)", yaxis=dict(range=[0, 11]), height=400, showlegend=False ) return fig @staticmethod def create_radar_chart(eco_result: EcoScoreResult) -> go.Figure: """Create a radar chart for environmental impact""" categories = ['Deforestation Risk', 'Pollution Risk', 'Biodiversity Impact'] fig = go.Figure() # Add trace for product fig.add_trace(go.Scatterpolar( r=[ eco_result.factors.deforestation_risk, eco_result.factors.pollution_risk, eco_result.factors.biodiversity_impact ], theta=categories, fill='toself', name=eco_result.product_name, line_color='red' )) # Add ideal trace (low impact) fig.add_trace(go.Scatterpolar( r=[2, 2, 2], theta=categories, fill='toself', name='Ideal (Low Impact)', line_color='green', opacity=0.3 )) fig.update_layout( polar=dict( radialaxis=dict( visible=True, range=[0, 10] )), showlegend=True, height=400, title="Environmental Impact Radar" ) return fig @staticmethod def create_comparison_chart(product_name: str, alternatives: list, product_score: float, alt_scores: list) -> go.Figure: """Create a comparison chart between product and alternatives""" names = [product_name] + [alt['name'] for alt in alternatives] scores = [product_score] + alt_scores colors = ['red'] + ['green'] * len(alternatives) fig = go.Figure(data=[ go.Bar( x=names, y=scores, marker_color=colors, text=[f"{s}/10" for s in scores], textposition='outside', ) ]) fig.update_layout( title="Product vs Alternatives - Eco Score Comparison", xaxis_title="Products", yaxis_title="Eco Score (1-10)", yaxis=dict(range=[0, 11]), height=400, showlegend=False ) return fig