Clarify table sort controls
Browse files- app.py +35 -2
- assets/styles.css +69 -0
app.py
CHANGED
|
@@ -448,6 +448,32 @@ def leaderboard_columns(columns: Iterable[str], metric: object) -> list[dict]:
|
|
| 448 |
return defs
|
| 449 |
|
| 450 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 451 |
def value_text(value: object, digits: int = 3) -> str:
|
| 452 |
if value is None or pd.isna(value):
|
| 453 |
return "Not available"
|
|
@@ -1261,7 +1287,10 @@ app.layout = html.Div(
|
|
| 1261 |
html.Div(
|
| 1262 |
[
|
| 1263 |
html.Div(
|
| 1264 |
-
|
|
|
|
|
|
|
|
|
|
| 1265 |
className="leaderboard-table-wrap",
|
| 1266 |
),
|
| 1267 |
dcc.Graph(id="dataset-ranking", config={"displayModeBar": False}),
|
|
@@ -1286,6 +1315,7 @@ app.layout = html.Div(
|
|
| 1286 |
[
|
| 1287 |
html.Div(
|
| 1288 |
[
|
|
|
|
| 1289 |
dataframe_table(
|
| 1290 |
"consistency-table",
|
| 1291 |
page_size=23,
|
|
@@ -1293,7 +1323,6 @@ app.layout = html.Div(
|
|
| 1293 |
sort_action="custom",
|
| 1294 |
sort_by=[{"column_id": "alignment_score", "direction": "desc"}],
|
| 1295 |
),
|
| 1296 |
-
html.P("Click a column header to sort. Click a method row to update the 3D latent view.", className="table-hint"),
|
| 1297 |
],
|
| 1298 |
className="consistency-table-wrap",
|
| 1299 |
),
|
|
@@ -1400,6 +1429,7 @@ app.layout = html.Div(
|
|
| 1400 |
|
| 1401 |
@app.callback(
|
| 1402 |
Output("leaderboard-top", "children"),
|
|
|
|
| 1403 |
Output("leaderboard-table", "columns"),
|
| 1404 |
Output("leaderboard-table", "data"),
|
| 1405 |
Output("dataset-ranking", "figure"),
|
|
@@ -1423,6 +1453,7 @@ def update_leaderboard(dataset: str, sort_by: list[dict] | None):
|
|
| 1423 |
metric = df["metric"].dropna().iloc[0] if df["metric"].notna().any() else "score"
|
| 1424 |
return (
|
| 1425 |
leaderboard_summary(dataset, df),
|
|
|
|
| 1426 |
leaderboard_columns([c for c in visible_cols if c in table_df.columns], metric),
|
| 1427 |
records(table_df),
|
| 1428 |
ranking_figure(dataset, df),
|
|
@@ -1433,6 +1464,7 @@ def update_leaderboard(dataset: str, sort_by: list[dict] | None):
|
|
| 1433 |
@app.callback(
|
| 1434 |
Output("consistency-table", "columns"),
|
| 1435 |
Output("consistency-table", "data"),
|
|
|
|
| 1436 |
Output("latent-space", "figure"),
|
| 1437 |
Output("consistency-bars", "figure"),
|
| 1438 |
Output("consistency-heatmap", "figure"),
|
|
@@ -1449,6 +1481,7 @@ def update_consistency(dataset: str, active_cell: dict | None, sort_by: list[dic
|
|
| 1449 |
return (
|
| 1450 |
column_defs([c for c in visible_cols if c in table_df.columns]),
|
| 1451 |
records(table_df),
|
|
|
|
| 1452 |
latent_space_figure(dataset, model),
|
| 1453 |
consistency_bar_figure(dataset, df),
|
| 1454 |
consistency_heatmap(None),
|
|
|
|
| 448 |
return defs
|
| 449 |
|
| 450 |
|
| 451 |
+
def sort_status(
|
| 452 |
+
sort_by: list[dict] | None,
|
| 453 |
+
default: tuple[str, bool],
|
| 454 |
+
labels: dict[str, str] | None = None,
|
| 455 |
+
) -> str:
|
| 456 |
+
column, ascending = default
|
| 457 |
+
if sort_by:
|
| 458 |
+
for item in sort_by:
|
| 459 |
+
candidate = item.get("column_id")
|
| 460 |
+
if candidate:
|
| 461 |
+
column = candidate
|
| 462 |
+
ascending = item.get("direction") == "asc"
|
| 463 |
+
break
|
| 464 |
+
|
| 465 |
+
merged_labels = dict(TABLE_LABELS)
|
| 466 |
+
if labels:
|
| 467 |
+
merged_labels.update(labels)
|
| 468 |
+
label = merged_labels.get(column, column)
|
| 469 |
+
|
| 470 |
+
if column in {"method", "family", "hardware"}:
|
| 471 |
+
direction = "A to Z" if ascending else "Z to A"
|
| 472 |
+
else:
|
| 473 |
+
direction = "low to high" if ascending else "high to low"
|
| 474 |
+
return f"Sorted by {label}: {direction}"
|
| 475 |
+
|
| 476 |
+
|
| 477 |
def value_text(value: object, digits: int = 3) -> str:
|
| 478 |
if value is None or pd.isna(value):
|
| 479 |
return "Not available"
|
|
|
|
| 1287 |
html.Div(
|
| 1288 |
[
|
| 1289 |
html.Div(
|
| 1290 |
+
[
|
| 1291 |
+
html.Div(id="leaderboard-sort-state", className="sort-state"),
|
| 1292 |
+
dataframe_table("leaderboard-table", page_size=23, max_height="680px", sort_action="custom"),
|
| 1293 |
+
],
|
| 1294 |
className="leaderboard-table-wrap",
|
| 1295 |
),
|
| 1296 |
dcc.Graph(id="dataset-ranking", config={"displayModeBar": False}),
|
|
|
|
| 1315 |
[
|
| 1316 |
html.Div(
|
| 1317 |
[
|
| 1318 |
+
html.Div(id="consistency-sort-state", className="sort-state"),
|
| 1319 |
dataframe_table(
|
| 1320 |
"consistency-table",
|
| 1321 |
page_size=23,
|
|
|
|
| 1323 |
sort_action="custom",
|
| 1324 |
sort_by=[{"column_id": "alignment_score", "direction": "desc"}],
|
| 1325 |
),
|
|
|
|
| 1326 |
],
|
| 1327 |
className="consistency-table-wrap",
|
| 1328 |
),
|
|
|
|
| 1429 |
|
| 1430 |
@app.callback(
|
| 1431 |
Output("leaderboard-top", "children"),
|
| 1432 |
+
Output("leaderboard-sort-state", "children"),
|
| 1433 |
Output("leaderboard-table", "columns"),
|
| 1434 |
Output("leaderboard-table", "data"),
|
| 1435 |
Output("dataset-ranking", "figure"),
|
|
|
|
| 1453 |
metric = df["metric"].dropna().iloc[0] if df["metric"].notna().any() else "score"
|
| 1454 |
return (
|
| 1455 |
leaderboard_summary(dataset, df),
|
| 1456 |
+
sort_status(sort_by, ("task_score", False), {"task_score": decoding_label(metric)}),
|
| 1457 |
leaderboard_columns([c for c in visible_cols if c in table_df.columns], metric),
|
| 1458 |
records(table_df),
|
| 1459 |
ranking_figure(dataset, df),
|
|
|
|
| 1464 |
@app.callback(
|
| 1465 |
Output("consistency-table", "columns"),
|
| 1466 |
Output("consistency-table", "data"),
|
| 1467 |
+
Output("consistency-sort-state", "children"),
|
| 1468 |
Output("latent-space", "figure"),
|
| 1469 |
Output("consistency-bars", "figure"),
|
| 1470 |
Output("consistency-heatmap", "figure"),
|
|
|
|
| 1481 |
return (
|
| 1482 |
column_defs([c for c in visible_cols if c in table_df.columns]),
|
| 1483 |
records(table_df),
|
| 1484 |
+
sort_status(sort_by, ("alignment_score", False)),
|
| 1485 |
latent_space_figure(dataset, model),
|
| 1486 |
consistency_bar_figure(dataset, df),
|
| 1487 |
consistency_heatmap(None),
|
assets/styles.css
CHANGED
|
@@ -211,6 +211,21 @@ h2 {
|
|
| 211 |
min-width: 0;
|
| 212 |
}
|
| 213 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 214 |
.latent-grid {
|
| 215 |
display: grid;
|
| 216 |
grid-template-columns: minmax(360px, 0.42fr) minmax(620px, 1fr);
|
|
@@ -253,6 +268,60 @@ h2 {
|
|
| 253 |
|
| 254 |
.dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner th {
|
| 255 |
background: #f3f6f8 !important;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 256 |
}
|
| 257 |
|
| 258 |
.dash-table-container .previous-next-container {
|
|
|
|
| 211 |
min-width: 0;
|
| 212 |
}
|
| 213 |
|
| 214 |
+
.sort-state {
|
| 215 |
+
display: inline-flex;
|
| 216 |
+
align-items: center;
|
| 217 |
+
min-height: 30px;
|
| 218 |
+
margin: 0 0 8px;
|
| 219 |
+
padding: 6px 10px;
|
| 220 |
+
border: 1px solid #cfd8df;
|
| 221 |
+
border-radius: 6px;
|
| 222 |
+
background: #f7fafb;
|
| 223 |
+
color: #344452;
|
| 224 |
+
font-size: 12px;
|
| 225 |
+
font-weight: 800;
|
| 226 |
+
line-height: 1.2;
|
| 227 |
+
}
|
| 228 |
+
|
| 229 |
.latent-grid {
|
| 230 |
display: grid;
|
| 231 |
grid-template-columns: minmax(360px, 0.42fr) minmax(620px, 1fr);
|
|
|
|
| 268 |
|
| 269 |
.dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner th {
|
| 270 |
background: #f3f6f8 !important;
|
| 271 |
+
padding: 0 !important;
|
| 272 |
+
border-right: 1px solid #d8e1e7 !important;
|
| 273 |
+
overflow: visible !important;
|
| 274 |
+
}
|
| 275 |
+
|
| 276 |
+
.dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner th:last-child {
|
| 277 |
+
border-right: 0 !important;
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
.dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner th.dash-header > div {
|
| 281 |
+
display: flex !important;
|
| 282 |
+
align-items: center !important;
|
| 283 |
+
justify-content: flex-start !important;
|
| 284 |
+
gap: 8px !important;
|
| 285 |
+
min-height: 43px;
|
| 286 |
+
padding: 10px 12px !important;
|
| 287 |
+
}
|
| 288 |
+
|
| 289 |
+
.dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner .column-header-name {
|
| 290 |
+
flex: 1 1 auto !important;
|
| 291 |
+
min-width: 0;
|
| 292 |
+
color: #26323f;
|
| 293 |
+
line-height: 1.15;
|
| 294 |
+
white-space: normal;
|
| 295 |
+
}
|
| 296 |
+
|
| 297 |
+
.dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner .column-actions {
|
| 298 |
+
order: -1;
|
| 299 |
+
flex: 0 0 auto !important;
|
| 300 |
+
display: inline-flex !important;
|
| 301 |
+
align-items: center;
|
| 302 |
+
justify-content: center;
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
.dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner .column-header--sort {
|
| 306 |
+
display: inline-flex !important;
|
| 307 |
+
align-items: center;
|
| 308 |
+
justify-content: center;
|
| 309 |
+
width: 22px;
|
| 310 |
+
height: 22px;
|
| 311 |
+
border: 1px solid #c7d3dc;
|
| 312 |
+
border-radius: 5px;
|
| 313 |
+
background: #ffffff;
|
| 314 |
+
color: #526171 !important;
|
| 315 |
+
font-size: 13px;
|
| 316 |
+
font-weight: 900;
|
| 317 |
+
line-height: 1;
|
| 318 |
+
opacity: 1 !important;
|
| 319 |
+
}
|
| 320 |
+
|
| 321 |
+
.dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner th:hover .column-header--sort {
|
| 322 |
+
border-color: #1565C0;
|
| 323 |
+
background: #edf6ff;
|
| 324 |
+
color: #1565C0 !important;
|
| 325 |
}
|
| 326 |
|
| 327 |
.dash-table-container .previous-next-container {
|