diff --git a/src/graph_manager.py b/src/graph_manager.py index a222abd..15ffad2 100644 --- a/src/graph_manager.py +++ b/src/graph_manager.py @@ -4,6 +4,8 @@ import matplotlib.figure from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.axes import Axes from tkinter import ttk +import tkinter as tk +from typing import Dict class GraphManager: @@ -16,17 +18,75 @@ class GraphManager: self.parent_frame.grid_rowconfigure(0, weight=1) self.parent_frame.grid_columnconfigure(0, weight=1) + # Initialize toggle variables for chart elements + self.toggle_vars: Dict[str, tk.BooleanVar] = { + "depression": tk.BooleanVar(value=True), + "anxiety": tk.BooleanVar(value=True), + "sleep": tk.BooleanVar(value=True), + "appetite": tk.BooleanVar(value=True), + } + + # Create control frame for toggles + self.control_frame: ttk.Frame = ttk.Frame(self.parent_frame) + self.control_frame.grid(row=0, column=0, sticky="ew", padx=5, pady=5) + + # Create toggle checkboxes + self._create_toggle_controls() + + # Create graph frame + self.graph_frame: ttk.Frame = ttk.Frame(self.parent_frame) + self.graph_frame.grid(row=1, column=0, sticky="nsew", padx=5, pady=5) + + # Reconfigure parent frame for new layout + self.parent_frame.grid_rowconfigure(1, weight=1) + self.parent_frame.grid_columnconfigure(0, weight=1) + # Initialize matplotlib figure and canvas self.fig: matplotlib.figure.Figure self.ax: Axes self.fig, self.ax = plt.subplots() self.canvas: FigureCanvasTkAgg = FigureCanvasTkAgg( - figure=self.fig, master=self.parent_frame + figure=self.fig, master=self.graph_frame ) self.canvas.get_tk_widget().pack(fill="both", expand=True) + # Store current data for replotting + self.current_data: pd.DataFrame = pd.DataFrame() + + def _create_toggle_controls(self) -> None: + """Create toggle controls for chart elements.""" + ttk.Label(self.control_frame, text="Show/Hide Elements:").pack( + side="left", padx=5 + ) + + toggle_configs = [ + ("depression", "Depression"), + ("anxiety", "Anxiety"), + ("sleep", "Sleep"), + ("appetite", "Appetite"), + ] + + for key, label in toggle_configs: + checkbox = ttk.Checkbutton( + self.control_frame, + text=label, + variable=self.toggle_vars[key], + command=self._on_toggle_changed, + ) + checkbox.pack(side="left", padx=5) + + def _on_toggle_changed(self) -> None: + """Handle toggle changes by replotting the graph.""" + if not self.current_data.empty: + self._plot_graph_data(self.current_data) + def update_graph(self, df: pd.DataFrame) -> None: """Update the graph with new data.""" + self.current_data = df.copy() if not df.empty else pd.DataFrame() + self._plot_graph_data(df) + + def _plot_graph_data(self, df: pd.DataFrame) -> None: + """Plot the graph data with current toggle settings.""" self.ax.clear() if not df.empty: # Convert dates and sort @@ -35,22 +95,30 @@ class GraphManager: df = df.sort_values(by="date") df.set_index(keys="date", inplace=True) - # Plot data series - self._plot_series( - df, "depression", "Depression (0:good, 10:bad)", "o", "-" - ) - self._plot_series( - df, "anxiety", "Anxiety (0:good, 10:bad)", "o", "-" - ) - self._plot_series( - df, "sleep", "Sleep (0:bad, 10:good)", "o", "dashed" - ) - self._plot_series( - df, "appetite", "Appetite (0:bad, 10:good)", "o", "dashed" - ) + # Track if any series are plotted + has_plotted_series = False + + # Plot data series based on toggle states + if self.toggle_vars["depression"].get(): + self._plot_series( + df, "depression", "Depression (0:good, 10:bad)", "o", "-" + ) + has_plotted_series = True + if self.toggle_vars["anxiety"].get(): + self._plot_series(df, "anxiety", "Anxiety (0:good, 10:bad)", "o", "-") + has_plotted_series = True + if self.toggle_vars["sleep"].get(): + self._plot_series(df, "sleep", "Sleep (0:bad, 10:good)", "o", "dashed") + has_plotted_series = True + if self.toggle_vars["appetite"].get(): + self._plot_series( + df, "appetite", "Appetite (0:bad, 10:good)", "o", "dashed" + ) + has_plotted_series = True # Configure graph appearance - self.ax.legend() + if has_plotted_series: + self.ax.legend() self.ax.set_title("Medication Effects Over Time") self.ax.set_xlabel("Date") self.ax.set_ylabel("Rating (0-10)")