import os import pandas as pd import plotly.graph_objects as go from flask import url_for from abc import ABC, abstractmethod from .base import BaseAnalysis from app.analysis.data_utils import prepare_data, mk_plotdir # ------------------------------------------- # Base Class for All Plotly Plot Analyses # ------------------------------------------- class BasePlotlyAnalysis(BaseAnalysis, ABC): """ Base class for all Plotly plot-based analyses. It enforces a structure for: - Data preparation - Transformation - Plot generation - Memory cleanup """ plot_filename = "default_plot.html" alt_text = "Default Alt Text" def execute(self, df: pd.DataFrame): """Executes the full analysis pipeline""" df = prepare_data(df) # Step 1: Prepare data paths = mk_plotdir(self.plot_filename) self.output_path, self.plot_url = paths['output_path'], paths['plot_url'] df = self.transform_data(df) # Step 2: Transform data (implemented by subclass) self.plot_data(df) # Step 3: Create the plot # Save the plot as an HTML file self.fig.write_html(self.output_path) del df # Step 4: Free memory return f'' @abstractmethod def transform_data(self, df: pd.DataFrame) -> pd.DataFrame: """Subclasses must define how they transform the data""" pass @abstractmethod def plot_data(self, df: pd.DataFrame): """Subclasses must define how they generate the plot""" pass