Yuxuan-Zhang-Dexter commited on
Commit
9568660
ยท
1 Parent(s): 603247d

update gradio app with radar chart

Browse files
Files changed (1) hide show
  1. app.py +180 -64
app.py CHANGED
@@ -25,7 +25,8 @@ from data_visualization import (
25
  create_top_players_radar_chart,
26
  create_player_radar_chart,
27
  create_horizontal_bar_chart,
28
- normalize_values
 
29
  )
30
 
31
  # Define time points and their corresponding data files
@@ -246,7 +247,7 @@ def update_leaderboard(mario_overall, mario_details,
246
  "Tetris (planning only)": current_overall["Tetris (planning only)"]
247
  }
248
 
249
- # Get the appropriate DataFrame and chart based on current state
250
  if leaderboard_state["current_game"]:
251
  # For detailed view
252
  if leaderboard_state["current_game"] == "Super Mario Bros":
@@ -264,12 +265,18 @@ def update_leaderboard(mario_overall, mario_details,
264
 
265
  # Always create a new chart for detailed view
266
  chart = create_horizontal_bar_chart(df, leaderboard_state["current_game"])
 
 
 
267
  else:
268
  # For overall view
269
- df, chart = get_combined_leaderboard_with_group_bar(rank_data, selected_games)
 
 
 
270
 
271
- # Return exactly 14 values to match the expected outputs
272
- return (df, chart,
273
  current_overall["Super Mario Bros"], current_details["Super Mario Bros"],
274
  current_overall["Sokoban"], current_details["Sokoban"],
275
  current_overall["2048"], current_details["2048"],
@@ -333,13 +340,16 @@ def clear_filters():
333
  }
334
 
335
  # Get the combined leaderboard and group bar chart
336
- df, chart = get_combined_leaderboard_with_group_bar(rank_data, selected_games)
 
 
 
337
 
338
  # Reset the leaderboard state to match the default checkbox states
339
  leaderboard_state = get_initial_state()
340
 
341
- # Return exactly 14 values to match the expected outputs
342
- return (df, chart,
343
  True, False, # mario
344
  True, False, # sokoban
345
  True, False, # 2048
@@ -463,6 +473,12 @@ def create_video_gallery():
463
  game_2048_id = VIDEO_LINKS["2048"].split("?v=")[1]
464
  candy_id = VIDEO_LINKS["candy"].split("?v=")[1]
465
 
 
 
 
 
 
 
466
  # Generate news HTML
467
  news_items = []
468
  for item in NEWS_DATA["news"]:
@@ -499,6 +515,37 @@ def create_video_gallery():
499
  margin: 0 auto;
500
  padding: 20px;
501
  }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
502
  .video-grid {{
503
  display: grid;
504
  grid-template-columns: repeat(2, 1fr);
@@ -578,7 +625,7 @@ def create_video_gallery():
578
  flex: 1;
579
  display: flex;
580
  align-items: center;
581
- min-height: 169px; /* Match 16:9 video height */
582
  }}
583
  .twitter-link {{
584
  color: #2c3e50;
@@ -598,6 +645,29 @@ def create_video_gallery():
598
  color: #1da1f2;
599
  }}
600
  </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
601
  <div class="video-grid">
602
  <div class="video-card">
603
  <div class="video-wrapper">
@@ -624,6 +694,8 @@ def create_video_gallery():
624
  <div class="video-title">๐Ÿฌ Candy Crash</div>
625
  </div>
626
  </div>
 
 
627
  <div class="news-section">
628
  <div class="news-section-title">๐Ÿ“ฐ Latest News</div>
629
  {news_html}
@@ -635,19 +707,20 @@ def create_video_gallery():
635
  def build_app():
636
  with gr.Blocks(css="""
637
  .visualization-container {
638
- height: 85vh !important;
639
- max-height: 900px !important;
640
- min-height: 600px !important;
641
  background-color: #f8f9fa;
642
  border-radius: 10px;
643
- padding: 25px; /* Increased padding */
644
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
645
  overflow: hidden;
646
- margin: 0 auto !important; /* Center the visualization */
647
  }
648
  .visualization-container .plot {
649
  height: 100% !important;
650
  width: 100% !important;
 
651
  }
652
  .section-title {
653
  font-size: 1.5em;
@@ -656,9 +729,8 @@ def build_app():
656
  margin-bottom: 15px;
657
  padding-bottom: 10px;
658
  border-bottom: 2px solid #e9ecef;
659
- text-align: center; /* Center the title */
660
  }
661
- /* Add container for the entire app */
662
  .container {
663
  max-width: 1400px;
664
  margin: 0 auto;
@@ -669,28 +741,34 @@ def build_app():
669
 
670
  with gr.Tabs():
671
  with gr.Tab("๐Ÿ† Leaderboard"):
672
- # Visualization section at the very top
673
  with gr.Row():
674
  gr.Markdown("### ๐Ÿ“Š Data Visualization")
675
- with gr.Row():
676
- visualization = gr.Plot(
677
- value=get_combined_leaderboard_with_group_bar(rank_data, {
678
- "Super Mario Bros": True,
679
- "Sokoban": True,
680
- "2048": True,
681
- "Candy Crash": True,
682
- "Tetris (complete)": True,
683
- "Tetris (planning only)": True
684
- })[1],
685
- label="Performance Visualization",
686
- elem_classes="visualization-container"
687
- )
688
-
 
 
 
 
 
 
 
689
  # Game selection section
690
  with gr.Row():
691
  gr.Markdown("### ๐ŸŽฎ Game Selection")
692
  with gr.Row():
693
- # For each game, we have two checkboxes: one for overall and one for detailed view.
694
  with gr.Column():
695
  gr.Markdown("**๐ŸŽฎ Super Mario Bros**")
696
  mario_overall = gr.Checkbox(label="Super Mario Bros Score", value=True)
@@ -715,8 +793,8 @@ def build_app():
715
  gr.Markdown("**๐Ÿ“‹ Tetris (planning)**")
716
  tetris_plan_overall = gr.Checkbox(label="Tetris (planning) Score", value=True)
717
  tetris_plan_details = gr.Checkbox(label="Tetris (planning) Details", value=False)
718
-
719
- # Time progression display and control buttons - Moved below game selection
720
  with gr.Row():
721
  with gr.Column(scale=2):
722
  gr.Markdown("**โฐ Time Tracker**")
@@ -724,12 +802,12 @@ def build_app():
724
  with gr.Column(scale=1):
725
  gr.Markdown("**๐Ÿ”„ Controls**")
726
  clear_btn = gr.Button("Reset Filters", variant="secondary")
727
-
728
- # Leaderboard table section
729
  with gr.Row():
730
  gr.Markdown("### ๐Ÿ“‹ Detailed Results")
731
  with gr.Row():
732
- leaderboard_board = gr.DataFrame(
733
  value=get_combined_leaderboard(rank_data, {
734
  "Super Mario Bros": True,
735
  "Sokoban": True,
@@ -738,44 +816,82 @@ def build_app():
738
  "Tetris (complete)": True,
739
  "Tetris (planning only)": True
740
  }),
741
- interactive=True,
742
- wrap=True,
743
- label="Leaderboard"
744
  )
745
-
746
- # List of all checkboxes (in order)
747
- checkbox_list = [mario_overall, mario_details,
748
- sokoban_overall, sokoban_details,
749
- _2048_overall, _2048_details,
750
- candy_overall, candy_details,
751
- tetris_overall, tetris_details,
752
- tetris_plan_overall, tetris_plan_details]
753
-
754
- # Initialize the leaderboard state when the app starts
755
- demo.load(
756
- fn=clear_filters,
757
- inputs=[],
758
- outputs=[leaderboard_board, visualization] + checkbox_list
759
- )
760
-
761
- # Update both the leaderboard and visualization when checkboxes change
 
 
 
 
 
 
 
 
 
762
  for checkbox in checkbox_list:
763
  checkbox.change(
764
- fn=update_leaderboard,
765
  inputs=checkbox_list,
766
- outputs=[leaderboard_board, visualization] + checkbox_list
767
  )
768
-
769
- # Update both when clear button is clicked
 
 
 
 
 
 
 
 
 
 
 
 
 
770
  clear_btn.click(
 
 
 
 
 
 
 
 
 
 
 
 
771
  fn=clear_filters,
772
  inputs=[],
773
- outputs=[leaderboard_board, visualization] + checkbox_list
 
 
 
 
 
774
  )
775
-
776
  with gr.Tab("๐ŸŽฅ Gallery"):
777
  video_gallery = create_video_gallery()
778
-
779
  return demo
780
 
781
  if __name__ == "__main__":
 
25
  create_top_players_radar_chart,
26
  create_player_radar_chart,
27
  create_horizontal_bar_chart,
28
+ normalize_values,
29
+ get_combined_leaderboard_with_single_radar
30
  )
31
 
32
  # Define time points and their corresponding data files
 
247
  "Tetris (planning only)": current_overall["Tetris (planning only)"]
248
  }
249
 
250
+ # Get the appropriate DataFrame and charts based on current state
251
  if leaderboard_state["current_game"]:
252
  # For detailed view
253
  if leaderboard_state["current_game"] == "Super Mario Bros":
 
265
 
266
  # Always create a new chart for detailed view
267
  chart = create_horizontal_bar_chart(df, leaderboard_state["current_game"])
268
+ # For detailed view, we'll use the same chart for all visualizations
269
+ radar_chart = chart
270
+ group_bar_chart = chart
271
  else:
272
  # For overall view
273
+ df, group_bar_chart = get_combined_leaderboard_with_group_bar(rank_data, selected_games)
274
+ # Use the same selected_games for radar chart
275
+ _, radar_chart = get_combined_leaderboard_with_single_radar(rank_data, selected_games)
276
+ chart = group_bar_chart
277
 
278
+ # Return exactly 16 values to match the expected outputs
279
+ return (df, chart, radar_chart, group_bar_chart,
280
  current_overall["Super Mario Bros"], current_details["Super Mario Bros"],
281
  current_overall["Sokoban"], current_details["Sokoban"],
282
  current_overall["2048"], current_details["2048"],
 
340
  }
341
 
342
  # Get the combined leaderboard and group bar chart
343
+ df, group_bar_chart = get_combined_leaderboard_with_group_bar(rank_data, selected_games)
344
+
345
+ # Get the radar chart using the same selected games
346
+ _, radar_chart = get_combined_leaderboard_with_single_radar(rank_data, selected_games)
347
 
348
  # Reset the leaderboard state to match the default checkbox states
349
  leaderboard_state = get_initial_state()
350
 
351
+ # Return exactly 16 values to match the expected outputs
352
+ return (df, group_bar_chart, radar_chart, group_bar_chart,
353
  True, False, # mario
354
  True, False, # sokoban
355
  True, False, # 2048
 
473
  game_2048_id = VIDEO_LINKS["2048"].split("?v=")[1]
474
  candy_id = VIDEO_LINKS["candy"].split("?v=")[1]
475
 
476
+ # Get the latest video from news data
477
+ latest_news = NEWS_DATA["news"][0] # First item is the latest
478
+ latest_video_id = latest_news["video_link"].split("?v=")[1]
479
+ latest_date = datetime.strptime(latest_news["date"], "%Y-%m-%d")
480
+ formatted_latest_date = latest_date.strftime("%B %d, %Y")
481
+
482
  # Generate news HTML
483
  news_items = []
484
  for item in NEWS_DATA["news"]:
 
515
  margin: 0 auto;
516
  padding: 20px;
517
  }}
518
+ .highlight-section {{
519
+ margin-bottom: 40px;
520
+ }}
521
+ .highlight-card {{
522
+ background: #ffffff;
523
+ border-radius: 10px;
524
+ box-shadow: 0 4px 20px rgba(0,0,0,0.15);
525
+ overflow: hidden;
526
+ transition: transform 0.3s;
527
+ border: 2px solid #2196F3;
528
+ }}
529
+ .highlight-card:hover {{
530
+ transform: translateY(-5px);
531
+ }}
532
+ .highlight-header {{
533
+ background: #2196F3;
534
+ color: white;
535
+ padding: 15px 20px;
536
+ font-size: 1.2em;
537
+ font-weight: bold;
538
+ display: flex;
539
+ align-items: center;
540
+ gap: 10px;
541
+ }}
542
+ .highlight-date {{
543
+ font-size: 0.9em;
544
+ opacity: 0.9;
545
+ }}
546
+ .highlight-content {{
547
+ padding: 20px;
548
+ }}
549
  .video-grid {{
550
  display: grid;
551
  grid-template-columns: repeat(2, 1fr);
 
625
  flex: 1;
626
  display: flex;
627
  align-items: center;
628
+ min-height: 169px;
629
  }}
630
  .twitter-link {{
631
  color: #2c3e50;
 
645
  color: #1da1f2;
646
  }}
647
  </style>
648
+
649
+ <!-- Highlight Section -->
650
+ <div class="highlight-section">
651
+ <div class="highlight-card">
652
+ <div class="highlight-header">
653
+ <span>๐ŸŒŸ Latest Update</span>
654
+ <span class="highlight-date">{formatted_latest_date}</span>
655
+ </div>
656
+ <div class="highlight-content">
657
+ <div class="video-wrapper">
658
+ <iframe src="https://www.youtube.com/embed/{latest_video_id}"></iframe>
659
+ </div>
660
+ <div class="video-title">
661
+ <a href="{latest_news["twitter_link"]}" target="_blank" class="twitter-link">
662
+ <span class="twitter-icon">๐Ÿ“ข</span>
663
+ {latest_news["twitter_text"]}
664
+ </a>
665
+ </div>
666
+ </div>
667
+ </div>
668
+ </div>
669
+
670
+ <!-- Regular Video Grid -->
671
  <div class="video-grid">
672
  <div class="video-card">
673
  <div class="video-wrapper">
 
694
  <div class="video-title">๐Ÿฌ Candy Crash</div>
695
  </div>
696
  </div>
697
+
698
+ <!-- News Section -->
699
  <div class="news-section">
700
  <div class="news-section-title">๐Ÿ“ฐ Latest News</div>
701
  {news_html}
 
707
  def build_app():
708
  with gr.Blocks(css="""
709
  .visualization-container {
710
+ height: 70vh !important; /* Reduced from 85vh to 70vh */
711
+ max-height: 700px !important; /* Reduced from 900px to 700px */
712
+ min-height: 500px !important; /* Reduced from 600px to 500px */
713
  background-color: #f8f9fa;
714
  border-radius: 10px;
715
+ padding: 20px; /* Reduced padding from 25px to 20px */
716
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
717
  overflow: hidden;
718
+ margin: 0 auto !important;
719
  }
720
  .visualization-container .plot {
721
  height: 100% !important;
722
  width: 100% !important;
723
+ object-fit: contain !important; /* Added to ensure proper scaling */
724
  }
725
  .section-title {
726
  font-size: 1.5em;
 
729
  margin-bottom: 15px;
730
  padding-bottom: 10px;
731
  border-bottom: 2px solid #e9ecef;
732
+ text-align: center;
733
  }
 
734
  .container {
735
  max-width: 1400px;
736
  margin: 0 auto;
 
741
 
742
  with gr.Tabs():
743
  with gr.Tab("๐Ÿ† Leaderboard"):
744
+ # Visualization section
745
  with gr.Row():
746
  gr.Markdown("### ๐Ÿ“Š Data Visualization")
747
+
748
+ # Detailed view visualization (single chart)
749
+ detailed_visualization = gr.Plot(
750
+ label="Performance Visualization",
751
+ visible=False,
752
+ elem_classes="visualization-container"
753
+ )
754
+
755
+ # Overall view visualizations (two charts)
756
+ with gr.Row(visible=True) as overall_visualizations:
757
+ with gr.Column(scale=1):
758
+ radar_visualization = gr.Plot(
759
+ label="Comparative Analysis (Radar Chart)",
760
+ elem_classes="visualization-container"
761
+ )
762
+ with gr.Column(scale=1):
763
+ group_bar_visualization = gr.Plot(
764
+ label="Comparative Analysis (Group Bar Chart)",
765
+ elem_classes="visualization-container"
766
+ )
767
+
768
  # Game selection section
769
  with gr.Row():
770
  gr.Markdown("### ๐ŸŽฎ Game Selection")
771
  with gr.Row():
 
772
  with gr.Column():
773
  gr.Markdown("**๐ŸŽฎ Super Mario Bros**")
774
  mario_overall = gr.Checkbox(label="Super Mario Bros Score", value=True)
 
793
  gr.Markdown("**๐Ÿ“‹ Tetris (planning)**")
794
  tetris_plan_overall = gr.Checkbox(label="Tetris (planning) Score", value=True)
795
  tetris_plan_details = gr.Checkbox(label="Tetris (planning) Details", value=False)
796
+
797
+ # Controls
798
  with gr.Row():
799
  with gr.Column(scale=2):
800
  gr.Markdown("**โฐ Time Tracker**")
 
802
  with gr.Column(scale=1):
803
  gr.Markdown("**๐Ÿ”„ Controls**")
804
  clear_btn = gr.Button("Reset Filters", variant="secondary")
805
+
806
+ # Leaderboard table
807
  with gr.Row():
808
  gr.Markdown("### ๐Ÿ“‹ Detailed Results")
809
  with gr.Row():
810
+ leaderboard_df = gr.DataFrame(
811
  value=get_combined_leaderboard(rank_data, {
812
  "Super Mario Bros": True,
813
  "Sokoban": True,
 
816
  "Tetris (complete)": True,
817
  "Tetris (planning only)": True
818
  }),
819
+ label="Leaderboard",
820
+ interactive=False
 
821
  )
822
+
823
+ # List of all checkboxes
824
+ checkbox_list = [
825
+ mario_overall, mario_details,
826
+ sokoban_overall, sokoban_details,
827
+ _2048_overall, _2048_details,
828
+ candy_overall, candy_details,
829
+ tetris_overall, tetris_details,
830
+ tetris_plan_overall, tetris_plan_details
831
+ ]
832
+
833
+ # Update visualizations when checkboxes change
834
+ def update_visualizations(*checkbox_states):
835
+ # Check if any details checkbox is selected
836
+ is_details_view = any([
837
+ checkbox_states[1], checkbox_states[3], checkbox_states[5],
838
+ checkbox_states[7], checkbox_states[9], checkbox_states[11]
839
+ ])
840
+
841
+ # Update visibility of visualization blocks
842
+ return {
843
+ detailed_visualization: gr.update(visible=is_details_view),
844
+ overall_visualizations: gr.update(visible=not is_details_view)
845
+ }
846
+
847
+ # Add change event to all checkboxes
848
  for checkbox in checkbox_list:
849
  checkbox.change(
850
+ update_visualizations,
851
  inputs=checkbox_list,
852
+ outputs=[detailed_visualization, overall_visualizations]
853
  )
854
+
855
+ # Update leaderboard and visualizations when checkboxes change
856
+ for checkbox in checkbox_list:
857
+ checkbox.change(
858
+ update_leaderboard,
859
+ inputs=checkbox_list,
860
+ outputs=[
861
+ leaderboard_df,
862
+ detailed_visualization,
863
+ radar_visualization,
864
+ group_bar_visualization
865
+ ] + checkbox_list
866
+ )
867
+
868
+ # Update when clear button is clicked
869
  clear_btn.click(
870
+ clear_filters,
871
+ inputs=[],
872
+ outputs=[
873
+ leaderboard_df,
874
+ detailed_visualization,
875
+ radar_visualization,
876
+ group_bar_visualization
877
+ ] + checkbox_list
878
+ )
879
+
880
+ # Initialize the app
881
+ demo.load(
882
  fn=clear_filters,
883
  inputs=[],
884
+ outputs=[
885
+ leaderboard_df,
886
+ detailed_visualization,
887
+ radar_visualization,
888
+ group_bar_visualization
889
+ ] + checkbox_list
890
  )
891
+
892
  with gr.Tab("๐ŸŽฅ Gallery"):
893
  video_gallery = create_video_gallery()
894
+
895
  return demo
896
 
897
  if __name__ == "__main__":