GuglielmoTor commited on
Commit
fe8e3bb
·
verified ·
1 Parent(s): 3c03ffc

Update ui_generators.py

Browse files
Files changed (1) hide show
  1. ui_generators.py +53 -45
ui_generators.py CHANGED
@@ -23,6 +23,12 @@ from config import (
23
  # Configure logging for this module if not already configured at app level
24
  # logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(module)s - %(message)s')
25
 
 
 
 
 
 
 
26
 
27
  def display_main_dashboard(token_state):
28
  """Generates HTML for the main dashboard display using data from token_state."""
@@ -157,9 +163,9 @@ def run_mentions_tab_display(token_state):
157
  logging.error(f"Error generating mentions plot: {e}", exc_info=True)
158
  # fig remains None
159
  finally:
160
- if fig is not None and fig is not plt: # Ensure we don't close the global plt if fig is just an alias
161
- plt.close(fig) # Close the specific figure to free memory
162
- elif fig is None and plt.get_fignums(): # If fig is None but some global figure might exist from error
163
  plt.close('all')
164
 
165
 
@@ -208,7 +214,7 @@ def run_follower_stats_tab_display(token_state):
208
  plot_data = monthly_gains_df_sorted_plot.groupby('_plot_month').agg(
209
  organic=(FOLLOWER_STATS_ORGANIC_COLUMN, 'sum'),
210
  paid=(FOLLOWER_STATS_PAID_COLUMN, 'sum')
211
- ).reset_index().sort_values(by='_plot_month') # Ensure month order for plot
212
 
213
  fig_gains, ax_gains = plt.subplots(figsize=(10,5))
214
  ax_gains.plot(plot_data['_plot_month'], plot_data['organic'], marker='o', linestyle='-', label='Organic Gain')
@@ -307,75 +313,77 @@ def run_follower_stats_tab_display(token_state):
307
  return follower_html_output, plot_monthly_gains, plot_seniority_dist, plot_industry_dist
308
 
309
 
310
- # --- NEW UI GENERATION LOGIC FOR ANALYTICS TAB ---
311
  def create_analytics_plot_panel(label, plot_id_str):
312
  """
313
  Creates a Gradio Column representing a single plot panel.
314
- This panel contains the plot and its associated "bomb" button to the right.
315
- Returns the panel (gr.Column), the plot component, and the bomb button.
 
 
 
 
 
316
  """
317
- with gr.Column() as panel_col: # This is the component that will go into the two-column rows
318
- with gr.Row(equal_height=False, variant="panel"): # A sub-row for plot and button
319
- with gr.Column(scale=8): # Adjust scale as needed for plot vs button
320
- plot_component = gr.Plot(label=label)
321
- with gr.Column(scale=2, min_width=70): # Removed vertical_alignment
322
- bomb_button = gr.Button("💣", variant="secondary", size="sm", elem_id=f"bomb_{plot_id_str}")
323
- return panel_col, plot_component, bomb_button
 
324
 
325
  def build_analytics_tab_plot_area(plot_configs):
326
  """
327
  Builds the main plot area for the Analytics tab, arranging plot panels into rows of two.
328
- This function should be called within the "Analytics" TabItem context in app.py,
329
- specifically within the main column designated for plots.
330
  Returns a dictionary of plot UI objects.
331
  """
332
  logging.info(f"Building plot area for {len(plot_configs)} analytics plots.")
333
- plot_ui_objects = {} # Stores {"plot_id": {"plot_component": gr.Plot, "bomb_button": gr.Button, "label": str}}
 
334
 
335
  current_section_title = ""
336
 
337
- # Iterate through plot_configs to create sections and then rows of plots
338
- for i in range(0, len(plot_configs), 2): # Process in pairs for two plots per row
339
- # Handle section header
340
- # Check if the section of the first plot in the potential pair is new
341
  if plot_configs[i]["section"] != current_section_title:
342
  current_section_title = plot_configs[i]["section"]
343
  gr.Markdown(f"### {current_section_title}")
344
 
345
- with gr.Row(): # Create a new row for up to two plot panels
346
  # First plot in the pair
347
  config1 = plot_configs[i]
348
- panel_col1, plot_component1, bomb_button1 = \
349
  create_analytics_plot_panel(config1["label"], config1["id"])
350
  plot_ui_objects[config1["id"]] = {
351
- "plot_component": plot_component1,
352
- "bomb_button": bomb_button1,
353
- "label": config1["label"]
 
 
 
354
  }
355
  logging.debug(f"Created UI panel for plot_id: {config1['id']}")
356
 
357
  # Second plot in the pair, if it exists
358
  if i + 1 < len(plot_configs):
359
  config2 = plot_configs[i+1]
360
- # Check if the second plot starts a new section (edge case if sections aren't aligned with pairs)
361
- if config2["section"] != current_section_title:
362
- # This row is finished, start a new section header for the next plot
363
- # This might leave the current row with only one plot if sections change mid-pair
364
- # For simplicity, we assume sections align well or the header appears before the row with the new section's first plot
365
- # The current loop structure will create a new header before the next gr.Row if section changes
366
- pass # The next iteration's section check will handle this.
367
-
368
- panel_col2, plot_component2, bomb_button2 = \
369
- create_analytics_plot_panel(config2["label"], config2["id"])
370
- plot_ui_objects[config2["id"]] = {
371
- "plot_component": plot_component2,
372
- "bomb_button": bomb_button2,
373
- "label": config2["label"]
374
- }
375
- logging.debug(f"Created UI panel for plot_id: {config2['id']}")
376
- else:
377
- # If there's no second plot, this row will just have one panel
378
- pass
379
 
380
  logging.info(f"Finished building plot area. Total plot objects: {len(plot_ui_objects)}")
381
  return plot_ui_objects
 
23
  # Configure logging for this module if not already configured at app level
24
  # logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(module)s - %(message)s')
25
 
26
+ # --- Constants for Button Icons/Text ---
27
+ BOMB_ICON = "💣 Insights"
28
+ EXPLORE_ICON = "🔍 Explore"
29
+ FORMULA_ICON = "ƒ Formula"
30
+ ACTIVE_ICON = "❌ Close"
31
+
32
 
33
  def display_main_dashboard(token_state):
34
  """Generates HTML for the main dashboard display using data from token_state."""
 
163
  logging.error(f"Error generating mentions plot: {e}", exc_info=True)
164
  # fig remains None
165
  finally:
166
+ if fig is not None and fig is not plt:
167
+ plt.close(fig)
168
+ elif fig is None and plt.get_fignums():
169
  plt.close('all')
170
 
171
 
 
214
  plot_data = monthly_gains_df_sorted_plot.groupby('_plot_month').agg(
215
  organic=(FOLLOWER_STATS_ORGANIC_COLUMN, 'sum'),
216
  paid=(FOLLOWER_STATS_PAID_COLUMN, 'sum')
217
+ ).reset_index().sort_values(by='_plot_month')
218
 
219
  fig_gains, ax_gains = plt.subplots(figsize=(10,5))
220
  ax_gains.plot(plot_data['_plot_month'], plot_data['organic'], marker='o', linestyle='-', label='Organic Gain')
 
313
  return follower_html_output, plot_monthly_gains, plot_seniority_dist, plot_industry_dist
314
 
315
 
316
+ # --- UI GENERATION LOGIC FOR ANALYTICS TAB ---
317
  def create_analytics_plot_panel(label, plot_id_str):
318
  """
319
  Creates a Gradio Column representing a single plot panel.
320
+ This panel contains the plot and its associated action buttons.
321
+ Returns:
322
+ panel_col (gr.Column): The main column for this plot panel.
323
+ plot_component (gr.Plot): The plot display area.
324
+ bomb_button (gr.Button): Insights button.
325
+ explore_button (gr.Button): Explore/Zoom button.
326
+ formula_button (gr.Button): Formula button.
327
  """
328
+ with gr.Column() as panel_col:
329
+ with gr.Row(equal_height=False, variant="panel"):
330
+ plot_component = gr.Plot(label=label, scale=8) # Plot takes more space
331
+ with gr.Column(scale=2, min_width=100): # Column for all buttons
332
+ bomb_button = gr.Button(BOMB_ICON, variant="secondary", size="sm", elem_id=f"bomb_{plot_id_str}")
333
+ explore_button = gr.Button(EXPLORE_ICON, variant="secondary", size="sm", elem_id=f"explore_{plot_id_str}")
334
+ formula_button = gr.Button(FORMULA_ICON, variant="secondary", size="sm", elem_id=f"formula_{plot_id_str}")
335
+ return panel_col, plot_component, bomb_button, explore_button, formula_button
336
 
337
  def build_analytics_tab_plot_area(plot_configs):
338
  """
339
  Builds the main plot area for the Analytics tab, arranging plot panels into rows of two.
 
 
340
  Returns a dictionary of plot UI objects.
341
  """
342
  logging.info(f"Building plot area for {len(plot_configs)} analytics plots.")
343
+ # Stores {"plot_id": {"plot_component": gr.Plot, "bomb_button": gr.Button, "explore_button": gr.Button, "formula_button": gr.Button, "label": str, "panel_component": gr.Column}}
344
+ plot_ui_objects = {}
345
 
346
  current_section_title = ""
347
 
348
+ for i in range(0, len(plot_configs), 2):
 
 
 
349
  if plot_configs[i]["section"] != current_section_title:
350
  current_section_title = plot_configs[i]["section"]
351
  gr.Markdown(f"### {current_section_title}")
352
 
353
+ with gr.Row(equal_height=False): # Main row for two plot panels
354
  # First plot in the pair
355
  config1 = plot_configs[i]
356
+ panel_col1, plot_comp1, bomb_btn1, explore_btn1, formula_btn1 = \
357
  create_analytics_plot_panel(config1["label"], config1["id"])
358
  plot_ui_objects[config1["id"]] = {
359
+ "plot_component": plot_comp1,
360
+ "bomb_button": bomb_btn1,
361
+ "explore_button": explore_btn1,
362
+ "formula_button": formula_btn1,
363
+ "label": config1["label"],
364
+ "panel_component": panel_col1 # Store the panel itself for visibility/scale changes
365
  }
366
  logging.debug(f"Created UI panel for plot_id: {config1['id']}")
367
 
368
  # Second plot in the pair, if it exists
369
  if i + 1 < len(plot_configs):
370
  config2 = plot_configs[i+1]
371
+ # If the second plot is in a new section, this row will only contain the first plot.
372
+ # The new section header for config2 will be handled in the next iteration of the outer loop.
373
+ if config2["section"] == current_section_title:
374
+ panel_col2, plot_comp2, bomb_btn2, explore_btn2, formula_btn2 = \
375
+ create_analytics_plot_panel(config2["label"], config2["id"])
376
+ plot_ui_objects[config2["id"]] = {
377
+ "plot_component": plot_comp2,
378
+ "bomb_button": bomb_btn2,
379
+ "explore_button": explore_btn2,
380
+ "formula_button": formula_btn2,
381
+ "label": config2["label"],
382
+ "panel_component": panel_col2
383
+ }
384
+ logging.debug(f"Created UI panel for plot_id: {config2['id']}")
385
+ # If config2 is in a new section, its panel will be created in the next iteration's new row.
386
+ # else: panel for config1 is already in the row.
 
 
 
387
 
388
  logging.info(f"Finished building plot area. Total plot objects: {len(plot_ui_objects)}")
389
  return plot_ui_objects