GuglielmoTor commited on
Commit
13c5511
·
verified ·
1 Parent(s): 46dea86

Update ui_generators.py

Browse files
Files changed (1) hide show
  1. ui_generators.py +81 -67
ui_generators.py CHANGED
@@ -322,112 +322,126 @@ def run_follower_stats_tab_display(token_state):
322
  follower_html_output = "\n".join(html_parts)
323
  return follower_html_output, plot_monthly_gains, plot_seniority_dist, plot_industry_dist
324
 
325
-
326
- # --- UI GENERATION LOGIC FOR ANALYTICS TAB ---
327
  def create_analytics_plot_panel(plot_label_str, plot_id_str):
328
  """
329
  Creates an individual plot panel with its plot component and action buttons.
 
330
  Returns the panel (Column), plot component, and button components.
331
  """
332
- with gr.Column(visible=True) as panel_component: # Main container for this plot
333
- with gr.Row(variant="compact"):
334
- gr.Markdown(f"#### {plot_label_str}") # Plot title
335
- with gr.Row(elem_classes="plot-actions", scale=0): # Action buttons container
336
- # Ensure icons are defined (e.g., BOMB_ICON, EXPLORE_ICON, FORMULA_ICON)
337
- # If not defined globally, pass them or use placeholders
338
- bomb_button = gr.Button(value="💣", variant="tool", size="sm", min_width=30, elem_id=f"bomb_btn_{plot_id_str}")
339
- formula_button = gr.Button(value="ƒ", variant="tool", size="sm", min_width=30, elem_id=f"formula_btn_{plot_id_str}")
340
- explore_button = gr.Button(value="🧭", variant="tool", size="sm", min_width=30, elem_id=f"explore_btn_{plot_id_str}")
341
-
342
- # Placeholder for the actual plot - this will be updated by the analytics generation logic
343
- plot_component = gr.Plot(label=plot_label_str, show_label=False)
344
- # Example of adding some specific styling or structure if needed
345
- # gr.HTML(f"<div class='plot-container' id='plot_container_{plot_id_str}'></div>") # If you were embedding plots differently
346
 
347
- logging.debug(f"Created analytics panel for: {plot_label_str} (ID: {plot_id_str})")
348
- return panel_component, plot_component, bomb_button, explore_button, formula_button
 
 
 
 
 
 
 
 
349
 
350
 
351
  def build_analytics_tab_plot_area(plot_configs):
352
  """
353
- Builds the main plot area for the Analytics tab, arranging plot panels into rows of two.
 
354
 
355
  Returns a tuple:
356
  - plot_ui_objects (dict): Dictionary of plot UI objects.
357
  - section_titles_map (dict): Dictionary mapping section names to their gr.Markdown title components.
358
  """
359
- logging.info(f"Building plot area for {len(plot_configs)} analytics plots.")
360
  plot_ui_objects = {}
361
- section_titles_map = {} # NEW: To store section title Markdown components
362
-
363
- current_section_title = ""
364
 
365
- # Determine unique sections in order to correctly create Markdown components for them
366
- # This ensures that section_titles_map will have keys for all sections defined in plot_configs
367
- # and that they are created in the UI in the correct order.
368
 
369
- # First pass to create all section title Markdown objects and store them
370
- # This is to ensure they are Gradio components that can be targeted for visibility updates.
371
- # We use a temporary list to hold sections already processed to avoid duplicate Markdown objects for the same section.
372
- processed_sections_for_md_creation = []
373
- for config in plot_configs:
374
- section_name = config["section"]
375
- if section_name not in processed_sections_for_md_creation:
376
- # Create the Markdown component for the section title
377
- # The actual rendering order will be handled in the layout loop below
378
- section_md_component = gr.Markdown(f"### {section_name}", visible=True) # Initially visible
379
- section_titles_map[section_name] = section_md_component
380
- processed_sections_for_md_creation.append(section_name)
381
- logging.debug(f"Created Markdown component for section title: {section_name}")
382
-
383
- # Layout loop: Iterate through plot_configs to place section titles and plot panels
384
- i = 0
385
- last_rendered_section_title = None # Keep track of the last section title that was actually rendered
386
-
387
- while i < len(plot_configs):
388
- config1 = plot_configs[i]
389
 
390
- # Render the section title if it's a new section and hasn't been rendered yet in this layout pass
391
- if config1["section"] != last_rendered_section_title:
392
- current_section_title = config1["section"]
393
-
394
- last_rendered_section_title = current_section_title
395
- logging.info(f"Processing section: {current_section_title}")
396
-
397
-
398
- # Create row for one or two plot panels
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
399
  with gr.Row(equal_height=False):
 
 
 
 
 
 
 
 
 
 
 
 
400
  panel_col1, plot_comp1, bomb_btn1, explore_btn1, formula_btn1 = \
401
  create_analytics_plot_panel(config1["label"], config1["id"])
402
  plot_ui_objects[config1["id"]] = {
403
  "plot_component": plot_comp1, "bomb_button": bomb_btn1,
404
  "explore_button": explore_btn1, "formula_button": formula_btn1,
405
  "label": config1["label"], "panel_component": panel_col1,
406
- "section": config1["section"] # Store section for easier lookup
407
  }
408
- logging.debug(f"Created UI panel for plot_id: {config1['id']}")
409
- i += 1
410
 
411
- if i < len(plot_configs):
412
- config2 = plot_configs[i]
 
413
  # Check if the next plot is in the SAME section to place it in the same row
414
- if config2["section"] == current_section_title:
415
  panel_col2, plot_comp2, bomb_btn2, explore_btn2, formula_btn2 = \
416
  create_analytics_plot_panel(config2["label"], config2["id"])
417
  plot_ui_objects[config2["id"]] = {
418
  "plot_component": plot_comp2, "bomb_button": bomb_btn2,
419
  "explore_button": explore_btn2, "formula_button": formula_btn2,
420
  "label": config2["label"], "panel_component": panel_col2,
421
- "section": config2["section"] # Store section
422
  }
423
- logging.debug(f"Created UI panel for plot_id: {config2['id']} in same row")
424
- i += 1
425
- # If config2 is in a different section, it will be handled by the next iteration of the outer loop
426
- # which will then print its own section title.
427
 
428
  logging.info(f"Finished building plot area. Total plot objects: {len(plot_ui_objects)}. Section titles created: {len(section_titles_map)}")
429
  if len(plot_ui_objects) != len(plot_configs):
430
  logging.error(f"MISMATCH: Expected {len(plot_configs)} plot objects, but created {len(plot_ui_objects)}.")
431
 
432
- # Return both the plot UI objects and the map of section title components
433
  return plot_ui_objects, section_titles_map
 
322
  follower_html_output = "\n".join(html_parts)
323
  return follower_html_output, plot_monthly_gains, plot_seniority_dist, plot_industry_dist
324
 
 
 
325
  def create_analytics_plot_panel(plot_label_str, plot_id_str):
326
  """
327
  Creates an individual plot panel with its plot component and action buttons.
328
+ This version matches the original structure provided by the user.
329
  Returns the panel (Column), plot component, and button components.
330
  """
331
+ # Values for BOMB_ICON, EXPLORE_ICON, FORMULA_ICON should be sourced from where they are defined,
332
+ # e.g., imported from config or passed as arguments if they vary.
333
+ # For consistency with app.py, let's assume they are globally accessible or correctly imported.
334
+ # If not, replace "BOMB_ICON", "EXPLORE_ICON", "FORMULA_ICON" with their actual string values like "�".
335
+ # This function will use string literals for icons if not found in global scope,
336
+ # but it's better practice to ensure they are consistently defined.
337
+ try:
338
+ from config import BOMB_ICON, EXPLORE_ICON, FORMULA_ICON # Try to import if they are in config
339
+ except ImportError:
340
+ logging.warning("Icons BOMB_ICON, EXPLORE_ICON, FORMULA_ICON not found in config, using defaults.")
341
+ BOMB_ICON = "💣"
342
+ EXPLORE_ICON = "🧭"
343
+ FORMULA_ICON = "ƒ"
 
344
 
345
+
346
+ with gr.Column() as panel_col:
347
+ with gr.Row(equal_height=False, variant="panel"):
348
+ plot_component = gr.Plot(label=plot_label_str, scale=8, show_label=True) # Ensure plot label is shown
349
+ with gr.Column(scale=2, min_width=100):
350
+ bomb_button = gr.Button(BOMB_ICON, variant="secondary", size="sm", elem_id=f"bomb_{plot_id_str}")
351
+ explore_button = gr.Button(EXPLORE_ICON, variant="secondary", size="sm", elem_id=f"explore_{plot_id_str}")
352
+ formula_button = gr.Button(FORMULA_ICON, variant="secondary", size="sm", elem_id=f"formula_{plot_id_str}")
353
+ logging.debug(f"Created analytics panel for: {plot_label_str} (ID: {plot_id_str}) using original structure.")
354
+ return panel_col, plot_component, bomb_button, explore_button, formula_button
355
 
356
 
357
  def build_analytics_tab_plot_area(plot_configs):
358
  """
359
+ Builds the main plot area for the Analytics tab, arranging plot panels into rows of two,
360
+ with section titles appearing before their respective plots.
361
 
362
  Returns a tuple:
363
  - plot_ui_objects (dict): Dictionary of plot UI objects.
364
  - section_titles_map (dict): Dictionary mapping section names to their gr.Markdown title components.
365
  """
366
+ logging.info(f"Building plot area for {len(plot_configs)} analytics plots with interleaved section titles.")
367
  plot_ui_objects = {}
368
+ section_titles_map = {}
 
 
369
 
370
+ last_rendered_section = None # Keep track of the last section title rendered
 
 
371
 
372
+ idx = 0
373
+ while idx < len(plot_configs):
374
+ current_plot_config = plot_configs[idx]
375
+ current_section_name = current_plot_config["section"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
 
377
+ # If this plot belongs to a new section, display the section title
378
+ if current_section_name != last_rendered_section:
379
+ if current_section_name not in section_titles_map:
380
+ # Create the Markdown component for this section title if it doesn't exist
381
+ # This call to gr.Markdown() places it in the current layout flow.
382
+ section_md_component = gr.Markdown(f"### {current_section_name}", visible=True)
383
+ section_titles_map[current_section_name] = section_md_component
384
+ logging.debug(f"Rendered and stored Markdown for section: {current_section_name}")
385
+ else:
386
+ # If it exists, it means this section might have appeared before (e.g., non-contiguous sections in plot_configs)
387
+ # We need to ensure this existing component is "placed" again in the layout.
388
+ # In Gradio, re-referencing the component variable usually does this.
389
+ # This line might be needed if section_titles_map[current_section_name] was defined in a way that its
390
+ # previous rendering doesn't automatically carry to this new layout position.
391
+ # However, since we are iterating and creating if not exists, this branch might be less common
392
+ # if plot_configs are typically ordered by section.
393
+ # For safety, ensure it's visible.
394
+ section_titles_map[current_section_name].visible = True # Ensure it's visible
395
+ # section_titles_map[current_section_name] # Re-introduce to layout - often implicit
396
+ logging.debug(f"Re-using Markdown for section: {current_section_name}")
397
+
398
+ last_rendered_section = current_section_name
399
+
400
+ # Create a new row for the plot(s)
401
  with gr.Row(equal_height=False):
402
+ # --- Process the first plot in the row (config1) ---
403
+ config1 = plot_configs[idx]
404
+ # Ensure it's from the current section we just titled (should be, due to loop structure)
405
+ if config1["section"] != current_section_name:
406
+ # This case should ideally not happen if logic is correct, means we might have skipped a section title
407
+ logging.warning(f"Plot {config1['id']} is in section {config1['section']} but current rendered section is {current_section_name}. Layout might be off.")
408
+ # Force rendering the correct section title if missed
409
+ if config1["section"] not in section_titles_map:
410
+ sec_md = gr.Markdown(f"### {config1['section']}", visible=True)
411
+ section_titles_map[config1["section"]] = sec_md
412
+ last_rendered_section = config1["section"] # Update tracker
413
+
414
  panel_col1, plot_comp1, bomb_btn1, explore_btn1, formula_btn1 = \
415
  create_analytics_plot_panel(config1["label"], config1["id"])
416
  plot_ui_objects[config1["id"]] = {
417
  "plot_component": plot_comp1, "bomb_button": bomb_btn1,
418
  "explore_button": explore_btn1, "formula_button": formula_btn1,
419
  "label": config1["label"], "panel_component": panel_col1,
420
+ "section": config1["section"]
421
  }
422
+ logging.debug(f"Created UI panel for plot_id: {config1['id']} in section {config1['section']}")
423
+ idx += 1
424
 
425
+ # --- Process the second plot in the row (config2), if applicable ---
426
+ if idx < len(plot_configs):
427
+ config2 = plot_configs[idx]
428
  # Check if the next plot is in the SAME section to place it in the same row
429
+ if config2["section"] == current_section_name:
430
  panel_col2, plot_comp2, bomb_btn2, explore_btn2, formula_btn2 = \
431
  create_analytics_plot_panel(config2["label"], config2["id"])
432
  plot_ui_objects[config2["id"]] = {
433
  "plot_component": plot_comp2, "bomb_button": bomb_btn2,
434
  "explore_button": explore_btn2, "formula_button": formula_btn2,
435
  "label": config2["label"], "panel_component": panel_col2,
436
+ "section": config2["section"]
437
  }
438
+ logging.debug(f"Created UI panel for plot_id: {config2['id']} in same row, section {config2['section']}")
439
+ idx += 1
440
+ # If config2 is in a different section, the outer while loop will handle its title
441
+ # before creating its panel in a new row.
442
 
443
  logging.info(f"Finished building plot area. Total plot objects: {len(plot_ui_objects)}. Section titles created: {len(section_titles_map)}")
444
  if len(plot_ui_objects) != len(plot_configs):
445
  logging.error(f"MISMATCH: Expected {len(plot_configs)} plot objects, but created {len(plot_ui_objects)}.")
446
 
 
447
  return plot_ui_objects, section_titles_map