Spaces:
Running
Running
Update services/analytics_tab_module.py
Browse files- services/analytics_tab_module.py +46 -25
services/analytics_tab_module.py
CHANGED
@@ -3,7 +3,7 @@ import gradio as gr
|
|
3 |
import pandas as pd
|
4 |
import logging
|
5 |
import time
|
6 |
-
from datetime import datetime, timedelta
|
7 |
import numpy as np
|
8 |
from collections import OrderedDict, defaultdict
|
9 |
import asyncio
|
@@ -99,6 +99,29 @@ class AnalyticsTab:
|
|
99 |
is_custom = selection == "Intervallo Personalizzato"
|
100 |
return gr.update(visible=is_custom), gr.update(visible=is_custom)
|
101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
async def _handle_panel_action(
|
103 |
self, plot_id_clicked: str, action_type: str, current_active_action_from_state: dict,
|
104 |
current_chat_histories: dict, current_chat_plot_id: str,
|
@@ -228,19 +251,19 @@ class AnalyticsTab:
|
|
228 |
|
229 |
# Order of updates must match self.action_panel_outputs_list
|
230 |
final_updates = [
|
231 |
-
action_col_visible_update,
|
232 |
-
insights_chatbot_visible_update,
|
233 |
-
chatbot_content_update,
|
234 |
insights_chat_input_visible_update, # insights_chat_input_ui
|
235 |
insights_suggestions_row_visible_update, # insights_suggestions_row_ui
|
236 |
-
s1_upd, s2_upd, s3_upd,
|
237 |
-
formula_display_visible_update,
|
238 |
-
formula_content_update,
|
239 |
-
formula_close_hint_visible_update,
|
240 |
-
new_active_action_state_to_set,
|
241 |
-
new_current_chat_plot_id,
|
242 |
-
updated_chat_histories,
|
243 |
-
new_explored_plot_id_to_set
|
244 |
]
|
245 |
final_updates.extend(generated_panel_vis_updates) # Plot panel visibilities
|
246 |
final_updates.extend(generated_bomb_btn_updates) # Bomb button icons
|
@@ -370,30 +393,26 @@ class AnalyticsTab:
|
|
370 |
logging.info("Refreshing analytics graph UI elements and resetting actions/chat (within module).")
|
371 |
start_time = time.time()
|
372 |
|
373 |
-
|
|
|
|
|
|
|
|
|
|
|
374 |
|
375 |
-
# --- NEW FIX STARTS HERE ---
|
376 |
-
# The error "too many values to unpack (expected 3)" and "received 21 elements" confirms the function
|
377 |
-
# returns a flat tuple/list of (status, fig1, fig2, ..., fig19, summary_dict).
|
378 |
-
# This revised unpacking logic handles that specific structure by slicing.
|
379 |
try:
|
380 |
-
# Check if we got the expected number of results (status + 19 plots + summary)
|
381 |
expected_count = len(PLOT_CONFIGS) + 2
|
382 |
if len(plot_gen_results) == expected_count:
|
383 |
status_msg = plot_gen_results[0]
|
384 |
-
# Gather all middle elements (the figures) into a list using slicing
|
385 |
gen_figs = list(plot_gen_results[1:-1])
|
386 |
new_summaries_for_chatbot = plot_gen_results[-1]
|
387 |
else:
|
388 |
-
# This will handle cases where the number of returned items is unexpected
|
389 |
raise ValueError(f"Expected {expected_count} elements, but got {len(plot_gen_results)}")
|
390 |
except (ValueError, TypeError, IndexError) as e:
|
391 |
logging.error(f"Could not unpack results from update_analytics_plots_figures. Error: {e}")
|
392 |
-
# Fallback to error state
|
393 |
status_msg = f"Errore: L'aggiornamento dei grafici non è riuscito a causa di un formato di dati imprevisto."
|
394 |
gen_figs = [self.create_placeholder_plot("Error", f"Dati non validi {i}") for i in range(len(PLOT_CONFIGS))]
|
395 |
new_summaries_for_chatbot = {}
|
396 |
-
# --- FIX ENDS HERE ---
|
397 |
|
398 |
all_updates = []
|
399 |
# 1. Status Markdown
|
@@ -431,7 +450,7 @@ class AnalyticsTab:
|
|
431 |
gr.update(value=self.BOMB_ICON), # bomb_button
|
432 |
gr.update(value=self.FORMULA_ICON), # formula_button
|
433 |
gr.update(value=self.EXPLORE_ICON), # explore_button
|
434 |
-
gr.update(visible=True)
|
435 |
])
|
436 |
|
437 |
# 6. Explored Plot ID State Reset (1 state)
|
@@ -604,8 +623,10 @@ class AnalyticsTab:
|
|
604 |
label="Seleziona Intervallo Date per Grafici", value="Sempre", scale=3
|
605 |
)
|
606 |
with gr.Column(scale=2):
|
607 |
-
|
608 |
-
|
|
|
|
|
609 |
|
610 |
self.apply_filter_btn = gr.Button("🔍 Applica Filtro & Aggiorna Grafici", variant="primary")
|
611 |
|
|
|
3 |
import pandas as pd
|
4 |
import logging
|
5 |
import time
|
6 |
+
from datetime import datetime, date, timedelta
|
7 |
import numpy as np
|
8 |
from collections import OrderedDict, defaultdict
|
9 |
import asyncio
|
|
|
99 |
is_custom = selection == "Intervallo Personalizzato"
|
100 |
return gr.update(visible=is_custom), gr.update(visible=is_custom)
|
101 |
|
102 |
+
# --- NEW HELPER FUNCTION ---
|
103 |
+
# This function handles the conversion from a date object (from gr.Date)
|
104 |
+
# to a datetime object, which the plotting function likely expects.
|
105 |
+
def _handle_date_input(self, date_val):
|
106 |
+
"""Converts various date inputs to a timezone-aware datetime object."""
|
107 |
+
if date_val is None:
|
108 |
+
return None
|
109 |
+
if isinstance(date_val, datetime):
|
110 |
+
return date_val # Already a datetime object
|
111 |
+
if isinstance(date_val, date):
|
112 |
+
# Combine the date with the beginning of the day to create a datetime object
|
113 |
+
return datetime.combine(date_val, datetime.min.time())
|
114 |
+
# Add handling for string if necessary, though gr.Date usually returns date/datetime objects
|
115 |
+
if isinstance(date_val, str):
|
116 |
+
try:
|
117 |
+
# Attempt to parse a date string like 'YYYY-MM-DD'
|
118 |
+
parsed_date = datetime.strptime(date_val, '%Y-%m-%d').date()
|
119 |
+
return datetime.combine(parsed_date, datetime.min.time())
|
120 |
+
except ValueError:
|
121 |
+
logging.warning(f"Could not parse date string: {date_val}")
|
122 |
+
return None
|
123 |
+
return None
|
124 |
+
|
125 |
async def _handle_panel_action(
|
126 |
self, plot_id_clicked: str, action_type: str, current_active_action_from_state: dict,
|
127 |
current_chat_histories: dict, current_chat_plot_id: str,
|
|
|
251 |
|
252 |
# Order of updates must match self.action_panel_outputs_list
|
253 |
final_updates = [
|
254 |
+
action_col_visible_update, # global_actions_column_ui
|
255 |
+
insights_chatbot_visible_update, # insights_chatbot_ui (visibility)
|
256 |
+
chatbot_content_update, # insights_chatbot_ui (content)
|
257 |
insights_chat_input_visible_update, # insights_chat_input_ui
|
258 |
insights_suggestions_row_visible_update, # insights_suggestions_row_ui
|
259 |
+
s1_upd, s2_upd, s3_upd, # suggestion buttons
|
260 |
+
formula_display_visible_update, # formula_display_markdown_ui (visibility)
|
261 |
+
formula_content_update, # formula_display_markdown_ui (content)
|
262 |
+
formula_close_hint_visible_update, # formula_close_hint_md
|
263 |
+
new_active_action_state_to_set, # active_panel_action_state
|
264 |
+
new_current_chat_plot_id, # current_chat_plot_id_st
|
265 |
+
updated_chat_histories, # chat_histories_st
|
266 |
+
new_explored_plot_id_to_set # explored_plot_id_state
|
267 |
]
|
268 |
final_updates.extend(generated_panel_vis_updates) # Plot panel visibilities
|
269 |
final_updates.extend(generated_bomb_btn_updates) # Bomb button icons
|
|
|
393 |
logging.info("Refreshing analytics graph UI elements and resetting actions/chat (within module).")
|
394 |
start_time = time.time()
|
395 |
|
396 |
+
# --- MODIFICATION: Use the helper function to convert date inputs ---
|
397 |
+
# This ensures that the `update_analytics_plots_figures` function receives a consistent datetime format.
|
398 |
+
start_date_dt = self._handle_date_input(custom_start_val)
|
399 |
+
end_date_dt = self._handle_date_input(custom_end_val)
|
400 |
+
|
401 |
+
plot_gen_results = self.update_analytics_plots_figures(current_token_state_val, date_filter_val, start_date_dt, end_date_dt, PLOT_CONFIGS)
|
402 |
|
|
|
|
|
|
|
|
|
403 |
try:
|
|
|
404 |
expected_count = len(PLOT_CONFIGS) + 2
|
405 |
if len(plot_gen_results) == expected_count:
|
406 |
status_msg = plot_gen_results[0]
|
|
|
407 |
gen_figs = list(plot_gen_results[1:-1])
|
408 |
new_summaries_for_chatbot = plot_gen_results[-1]
|
409 |
else:
|
|
|
410 |
raise ValueError(f"Expected {expected_count} elements, but got {len(plot_gen_results)}")
|
411 |
except (ValueError, TypeError, IndexError) as e:
|
412 |
logging.error(f"Could not unpack results from update_analytics_plots_figures. Error: {e}")
|
|
|
413 |
status_msg = f"Errore: L'aggiornamento dei grafici non è riuscito a causa di un formato di dati imprevisto."
|
414 |
gen_figs = [self.create_placeholder_plot("Error", f"Dati non validi {i}") for i in range(len(PLOT_CONFIGS))]
|
415 |
new_summaries_for_chatbot = {}
|
|
|
416 |
|
417 |
all_updates = []
|
418 |
# 1. Status Markdown
|
|
|
450 |
gr.update(value=self.BOMB_ICON), # bomb_button
|
451 |
gr.update(value=self.FORMULA_ICON), # formula_button
|
452 |
gr.update(value=self.EXPLORE_ICON), # explore_button
|
453 |
+
gr.update(visible=True) # panel_component (plot visibility itself)
|
454 |
])
|
455 |
|
456 |
# 6. Explored Plot ID State Reset (1 state)
|
|
|
623 |
label="Seleziona Intervallo Date per Grafici", value="Sempre", scale=3
|
624 |
)
|
625 |
with gr.Column(scale=2):
|
626 |
+
# Using gr.Date to ensure the calendar popup appears reliably.
|
627 |
+
# The conversion to a datetime object is handled in the _refresh_analytics_graphs_ui method.
|
628 |
+
self.custom_start_date_picker = gr.Date(label="Data Inizio", visible=False)
|
629 |
+
self.custom_end_date_picker = gr.Date(label="Data Fine", visible=False)
|
630 |
|
631 |
self.apply_filter_btn = gr.Button("🔍 Applica Filtro & Aggiorna Grafici", variant="primary")
|
632 |
|