wangruisi1 commited on
Commit
fb265c6
·
1 Parent(s): 707db45

Update on table scheme

Browse files
Files changed (2) hide show
  1. app.py +130 -66
  2. src/display/css_html_js.py +30 -69
app.py CHANGED
@@ -1,5 +1,6 @@
1
  import gradio as gr
2
  import pandas as pd
 
3
  from collections import OrderedDict
4
 
5
  from src.about import (
@@ -46,28 +47,34 @@ DEFAULT_GROUPS = [
46
  ALWAYS_VISIBLE_COLS = ["Model", "Type"]
47
 
48
  # ============================================================
49
- # Column-to-color mapping
50
- # Soft, harmonious palette: dark/light pairs for each group
51
  # ============================================================
52
- COLUMN_COLORS = {}
53
- # Overall (dark amber)
54
- for col in ["Overall"]:
55
- COLUMN_COLORS[col] = "rgba(232, 180, 58, 0.30)"
56
- # Overall by Category (light amber)
57
- for col in ["Abst.(All)", "Know.(All)", "Perc.(All)", "Spat.(All)", "Trans.(All)"]:
58
- COLUMN_COLORS[col] = "rgba(242, 200, 90, 0.15)"
59
- # In-Domain Overall (dark green)
60
- for col in ["Overall(In-Domain)"]:
61
- COLUMN_COLORS[col] = "rgba(82, 183, 120, 0.30)"
62
- # In-Domain by Category (light green)
63
- for col in ["Abst.(ID)", "Know.(ID)", "Perc.(ID)", "Spat.(ID)", "Trans.(ID)"]:
64
- COLUMN_COLORS[col] = "rgba(110, 200, 145, 0.15)"
65
- # Out-of-Domain Overall (dark blue)
66
- for col in ["Overall(Out-of-Domain)"]:
67
- COLUMN_COLORS[col] = "rgba(95, 150, 215, 0.30)"
68
- # Out-of-Domain by Category (light blue)
69
- for col in ["Abst.(OOD)", "Know.(OOD)", "Perc.(OOD)", "Spat.(OOD)", "Trans.(OOD)"]:
70
- COLUMN_COLORS[col] = "rgba(125, 175, 228, 0.15)"
 
 
 
 
 
 
 
71
 
72
  # ============================================================
73
  # Static model scores data
@@ -86,6 +93,12 @@ MODEL_LINKS = {
86
  "HunyuanVideo-I2V": "https://huggingface.co/tencent/HunyuanVideo-I2V",
87
  }
88
 
 
 
 
 
 
 
89
  MODELS_DATA = [
90
  {
91
  "Model": "Human",
@@ -186,60 +199,105 @@ def build_full_dataframe():
186
  # Round numeric columns to 3 decimal places for clean display
187
  numeric_cols = df.select_dtypes(include="number").columns
188
  df[numeric_cols] = df[numeric_cols].round(3)
 
 
189
  return df
190
 
191
 
192
  FULL_DF = build_full_dataframe()
193
 
194
 
195
- def render_html_table(selected_groups):
196
- """Render the leaderboard as a styled HTML table with column group colors."""
197
  if not selected_groups:
198
- selected_groups = ["Overall"]
199
 
200
  cols = list(ALWAYS_VISIBLE_COLS)
201
  for group_name, group_cols in COLUMN_GROUPS.items():
202
  if group_name in selected_groups:
203
  cols.extend(group_cols)
204
 
205
- df = FULL_DF[cols]
206
-
207
- # Build HTML table
208
- html = '<div class="leaderboard-scroll"><table class="leaderboard-html-table">\n'
209
-
210
- # Header
211
- html += '<thead><tr>\n'
212
- for col in cols:
213
- bg = COLUMN_COLORS.get(col, "")
214
- style = f' style="background-color: {bg};"' if bg else ''
215
- html += f' <th{style}>{col}</th>\n'
216
- html += '</tr></thead>\n'
217
-
218
- # Body
219
- html += '<tbody>\n'
220
- for _, row in df.iterrows():
221
- html += '<tr>\n'
222
- for col in cols:
223
- bg = COLUMN_COLORS.get(col, "")
224
- style = f' style="background-color: {bg};"' if bg else ''
225
- val = row[col]
226
-
227
- if col == "Model":
228
- # Render model name with link
229
- model_name = val
230
- if model_name in MODEL_LINKS:
231
- cell = f'<a href="{MODEL_LINKS[model_name]}" target="_blank">{model_name}</a>'
232
- else:
233
- cell = model_name
234
- elif isinstance(val, float):
235
- cell = f'{val:.3f}'
236
- else:
237
- cell = str(val)
238
-
239
- html += f' <td{style}>{cell}</td>\n'
240
- html += '</tr>\n'
241
- html += '</tbody>\n</table></div>'
242
- return html
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
 
244
 
245
  # ============================================================
@@ -260,15 +318,17 @@ with demo:
260
  interactive=True,
261
  )
262
 
263
- leaderboard_html = gr.HTML(
264
- value=render_html_table(DEFAULT_GROUPS),
 
265
  elem_id="leaderboard-table",
 
266
  )
267
 
268
  column_selector.change(
269
- fn=render_html_table,
270
  inputs=[column_selector],
271
- outputs=[leaderboard_html],
272
  )
273
 
274
  with gr.TabItem("📝 About", elem_id="llm-benchmark-tab-table", id=1):
@@ -287,4 +347,8 @@ with demo:
287
  show_copy_button=True,
288
  )
289
 
 
 
 
 
290
  demo.queue(default_concurrency_limit=40).launch()
 
1
  import gradio as gr
2
  import pandas as pd
3
+ import json
4
  from collections import OrderedDict
5
 
6
  from src.about import (
 
47
  ALWAYS_VISIBLE_COLS = ["Model", "Type"]
48
 
49
  # ============================================================
50
+ # Column-to-color mapping (used by JS)
 
51
  # ============================================================
52
+ COLUMN_COLORS = {
53
+ # Overall (dark amber)
54
+ "Overall": "rgba(232, 180, 58, 0.30)",
55
+ # Overall by Category (light amber)
56
+ "Abst.(All)": "rgba(242, 200, 90, 0.15)",
57
+ "Know.(All)": "rgba(242, 200, 90, 0.15)",
58
+ "Perc.(All)": "rgba(242, 200, 90, 0.15)",
59
+ "Spat.(All)": "rgba(242, 200, 90, 0.15)",
60
+ "Trans.(All)": "rgba(242, 200, 90, 0.15)",
61
+ # In-Domain Overall (dark green)
62
+ "Overall(In-Domain)": "rgba(82, 183, 120, 0.30)",
63
+ # In-Domain by Category (light green)
64
+ "Abst.(ID)": "rgba(110, 200, 145, 0.15)",
65
+ "Know.(ID)": "rgba(110, 200, 145, 0.15)",
66
+ "Perc.(ID)": "rgba(110, 200, 145, 0.15)",
67
+ "Spat.(ID)": "rgba(110, 200, 145, 0.15)",
68
+ "Trans.(ID)": "rgba(110, 200, 145, 0.15)",
69
+ # Out-of-Domain Overall (dark blue)
70
+ "Overall(Out-of-Domain)": "rgba(95, 150, 215, 0.30)",
71
+ # Out-of-Domain by Category (light blue)
72
+ "Abst.(OOD)": "rgba(125, 175, 228, 0.15)",
73
+ "Know.(OOD)": "rgba(125, 175, 228, 0.15)",
74
+ "Perc.(OOD)": "rgba(125, 175, 228, 0.15)",
75
+ "Spat.(OOD)": "rgba(125, 175, 228, 0.15)",
76
+ "Trans.(OOD)": "rgba(125, 175, 228, 0.15)",
77
+ }
78
 
79
  # ============================================================
80
  # Static model scores data
 
93
  "HunyuanVideo-I2V": "https://huggingface.co/tencent/HunyuanVideo-I2V",
94
  }
95
 
96
+ def make_model_link(model_name):
97
+ """Create a clickable HTML link for a model if URL exists."""
98
+ if model_name in MODEL_LINKS:
99
+ return f'<a href="{MODEL_LINKS[model_name]}" target="_blank">{model_name}</a>'
100
+ return model_name
101
+
102
  MODELS_DATA = [
103
  {
104
  "Model": "Human",
 
199
  # Round numeric columns to 3 decimal places for clean display
200
  numeric_cols = df.select_dtypes(include="number").columns
201
  df[numeric_cols] = df[numeric_cols].round(3)
202
+ # Add clickable links to model names
203
+ df["Model"] = df["Model"].apply(make_model_link)
204
  return df
205
 
206
 
207
  FULL_DF = build_full_dataframe()
208
 
209
 
210
+ def get_filtered_df(selected_groups):
211
+ """Filter DataFrame columns based on selected column groups."""
212
  if not selected_groups:
213
+ selected_groups = ["Overall"] # Always show at least Overall
214
 
215
  cols = list(ALWAYS_VISIBLE_COLS)
216
  for group_name, group_cols in COLUMN_GROUPS.items():
217
  if group_name in selected_groups:
218
  cols.extend(group_cols)
219
 
220
+ return FULL_DF[cols]
221
+
222
+
223
+ # ============================================================
224
+ # Build the JS that colors columns by reading header text.
225
+ # Passed via Gradio's js= parameter on demo.load so it runs
226
+ # reliably after the page is fully rendered.
227
+ # ============================================================
228
+ COLOR_MAP_JSON = json.dumps(COLUMN_COLORS)
229
+
230
+ COLORING_JS = f"""
231
+ () => {{
232
+ const COLOR_MAP = {COLOR_MAP_JSON};
233
+
234
+ function colorColumns() {{
235
+ const container = document.querySelector('#leaderboard-table');
236
+ if (!container) return;
237
+
238
+ // Gradio Dataframe can use <table> or a virtual grid.
239
+ // Try standard <table> first.
240
+ const table = container.querySelector('table');
241
+ if (table) {{
242
+ const headers = table.querySelectorAll('thead th, thead td');
243
+ const headerTexts = [];
244
+ headers.forEach(th => headerTexts.push(th.textContent.trim()));
245
+
246
+ // Color header cells
247
+ headers.forEach((th, i) => {{
248
+ const color = COLOR_MAP[headerTexts[i]];
249
+ if (color) th.style.backgroundColor = color;
250
+ }});
251
+
252
+ // Color body cells
253
+ table.querySelectorAll('tbody tr').forEach(row => {{
254
+ const cells = row.querySelectorAll('td');
255
+ cells.forEach((td, i) => {{
256
+ const color = COLOR_MAP[headerTexts[i]];
257
+ if (color) td.style.backgroundColor = color;
258
+ }});
259
+ }});
260
+ return;
261
+ }}
262
+
263
+ // Fallback: Gradio virtual/svelte table (div-based grid)
264
+ const headerRow = container.querySelector('.header-row, .headers, [class*="header"]');
265
+ if (!headerRow) return;
266
+ const headerCells = headerRow.querySelectorAll('[class*="cell"], th, div');
267
+ const headerTexts = [];
268
+ headerCells.forEach(c => headerTexts.push(c.textContent.trim()));
269
+
270
+ headerCells.forEach((c, i) => {{
271
+ const color = COLOR_MAP[headerTexts[i]];
272
+ if (color) c.style.backgroundColor = color;
273
+ }});
274
+
275
+ const bodyRows = container.querySelectorAll('.body .row, tbody tr, [class*="row"]:not([class*="header"])');
276
+ bodyRows.forEach(row => {{
277
+ const cells = row.querySelectorAll('[class*="cell"], td, div');
278
+ cells.forEach((td, i) => {{
279
+ const color = COLOR_MAP[headerTexts[i]];
280
+ if (color) td.style.backgroundColor = color;
281
+ }});
282
+ }});
283
+ }}
284
+
285
+ // Run immediately, then with delays to catch late renders
286
+ colorColumns();
287
+ setTimeout(colorColumns, 300);
288
+ setTimeout(colorColumns, 800);
289
+ setTimeout(colorColumns, 1500);
290
+
291
+ // Also observe DOM changes to re-color when columns are toggled
292
+ const target = document.querySelector('#leaderboard-table');
293
+ if (target) {{
294
+ const obs = new MutationObserver(() => {{
295
+ setTimeout(colorColumns, 50);
296
+ }});
297
+ obs.observe(target, {{ childList: true, subtree: true }});
298
+ }}
299
+ }}
300
+ """
301
 
302
 
303
  # ============================================================
 
318
  interactive=True,
319
  )
320
 
321
+ leaderboard_table = gr.Dataframe(
322
+ value=get_filtered_df(DEFAULT_GROUPS),
323
+ interactive=False,
324
  elem_id="leaderboard-table",
325
+ datatype=["html"] + ["str"] * 20,
326
  )
327
 
328
  column_selector.change(
329
+ fn=get_filtered_df,
330
  inputs=[column_selector],
331
+ outputs=[leaderboard_table],
332
  )
333
 
334
  with gr.TabItem("📝 About", elem_id="llm-benchmark-tab-table", id=1):
 
347
  show_copy_button=True,
348
  )
349
 
350
+ # Use Gradio's js= parameter on load — this is the official way
351
+ # to run JS after the page is fully rendered
352
+ demo.load(fn=None, inputs=None, outputs=None, js=COLORING_JS)
353
+
354
  demo.queue(default_concurrency_limit=40).launch()
src/display/css_html_js.py CHANGED
@@ -22,7 +22,11 @@ custom_css = """
22
  }
23
 
24
  #leaderboard-table {
25
- margin-top: 15px;
 
 
 
 
26
  }
27
 
28
  #search-bar-table-box > div:first-child {
@@ -34,6 +38,31 @@ custom_css = """
34
  padding: 0px;
35
  }
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  .tab-buttons button {
38
  font-size: 20px;
39
  }
@@ -82,74 +111,6 @@ custom_css = """
82
  #box-filter > .form{
83
  border: 0
84
  }
85
-
86
- /* ============================================================
87
- Styled HTML leaderboard table
88
- ============================================================ */
89
-
90
- .leaderboard-scroll {
91
- overflow-x: auto;
92
- width: 100%;
93
- }
94
-
95
- .leaderboard-html-table {
96
- width: 100%;
97
- border-collapse: collapse;
98
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
99
- font-size: 14px;
100
- line-height: 1.5;
101
- }
102
-
103
- .leaderboard-html-table thead th {
104
- position: sticky;
105
- top: 0;
106
- z-index: 1;
107
- padding: 10px 14px;
108
- text-align: center;
109
- font-weight: 600;
110
- font-size: 13px;
111
- border-bottom: 2px solid #d1d5db;
112
- white-space: nowrap;
113
- }
114
-
115
- .leaderboard-html-table tbody td {
116
- padding: 8px 14px;
117
- text-align: center;
118
- border-bottom: 1px solid #e5e7eb;
119
- }
120
-
121
- /* Model column — left-aligned, wider */
122
- .leaderboard-html-table th:first-child,
123
- .leaderboard-html-table td:first-child {
124
- text-align: left;
125
- min-width: 220px;
126
- white-space: nowrap;
127
- font-weight: 500;
128
- }
129
-
130
- /* Type column — left-aligned, wider */
131
- .leaderboard-html-table th:nth-child(2),
132
- .leaderboard-html-table td:nth-child(2) {
133
- text-align: left;
134
- min-width: 170px;
135
- white-space: nowrap;
136
- }
137
-
138
- /* Row hover */
139
- .leaderboard-html-table tbody tr:hover td {
140
- filter: brightness(0.95);
141
- }
142
-
143
- /* Model links: underline + hover color change */
144
- .leaderboard-html-table td a {
145
- color: #2563eb;
146
- text-decoration: underline;
147
- text-underline-offset: 2px;
148
- transition: color 0.2s ease;
149
- }
150
- .leaderboard-html-table td a:hover {
151
- color: #d97706;
152
- }
153
  """
154
 
155
  get_window_url_params = """
 
22
  }
23
 
24
  #leaderboard-table {
25
+ margin-top: 15px
26
+ }
27
+
28
+ #leaderboard-table-lite {
29
+ margin-top: 15px
30
  }
31
 
32
  #search-bar-table-box > div:first-child {
 
38
  padding: 0px;
39
  }
40
 
41
+ /* Model column — wider to avoid truncation */
42
+ #leaderboard-table td:nth-child(1),
43
+ #leaderboard-table th:nth-child(1) {
44
+ min-width: 220px !important;
45
+ white-space: nowrap;
46
+ }
47
+
48
+ /* Type column — wider to avoid truncation */
49
+ #leaderboard-table td:nth-child(2),
50
+ #leaderboard-table th:nth-child(2) {
51
+ min-width: 170px !important;
52
+ white-space: nowrap;
53
+ }
54
+
55
+ /* Model links: underline + hover color change */
56
+ #leaderboard-table td a {
57
+ color: #2563eb;
58
+ text-decoration: underline;
59
+ text-underline-offset: 2px;
60
+ transition: color 0.2s ease;
61
+ }
62
+ #leaderboard-table td a:hover {
63
+ color: #d97706;
64
+ }
65
+
66
  .tab-buttons button {
67
  font-size: 20px;
68
  }
 
111
  #box-filter > .form{
112
  border: 0
113
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  """
115
 
116
  get_window_url_params = """