ZeyuLing's picture
Sync benchmark navigation and uTMR-first ordering
70cab81 verified
Raw
History Blame Contribute Delete
33.9 kB
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:,">
<title>Sequential Text-to-Motion · BABEL · Motius</title>
<style>
:root {
--ink: #18231f;
--muted: #63706c;
--line: #dce3df;
--soft: #f4f7f5;
--paper: #ffffff;
--green: #087d72;
--green-soft: #e7f4f1;
--blue: #315f9d;
--coral: #c7563f;
--amber: #ad6d00;
--shadow: 0 8px 24px rgba(24, 35, 31, 0.07);
}
* { box-sizing: border-box; }
body {
margin: 0;
color: var(--ink);
background: var(--paper);
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
font-size: 14px;
letter-spacing: 0;
}
a { color: inherit; }
button, input, select { font: inherit; letter-spacing: 0; }
.shell { width: min(1480px, calc(100% - 40px)); margin: 0 auto; }
.leaderboard-nav {
display: flex;
align-items: center;
gap: 6px;
min-height: 54px;
border-bottom: 1px solid var(--line);
overflow-x: auto;
}
.nav-label {
margin-right: 10px;
color: var(--muted);
font-size: 12px;
font-weight: 700;
text-transform: uppercase;
}
.nav-link {
padding: 8px 10px;
border-radius: 6px;
color: #47544f;
text-decoration: none;
white-space: nowrap;
}
.nav-link:hover { background: var(--soft); }
.nav-link[aria-current="page"] { color: var(--green); background: var(--green-soft); font-weight: 700; }
header { padding: 34px 0 24px; border-bottom: 1px solid var(--line); }
.title-row { display: flex; justify-content: space-between; gap: 28px; align-items: flex-start; }
h1 { margin: 0 0 10px; font-size: 32px; line-height: 1.2; font-weight: 760; }
.lede { max-width: 820px; margin: 0; color: var(--muted); font-size: 15px; line-height: 1.65; }
.status {
flex: none;
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 10px;
border: 1px solid #b8dcd6;
border-radius: 6px;
color: #086c63;
background: #eef9f6;
font-size: 12px;
font-weight: 700;
}
.status::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--green); }
.header-actions { flex: none; display: flex; align-items: center; gap: 8px; }
.audit-link {
padding: 8px 10px;
border: 1px solid #cbd5d0;
border-radius: 6px;
color: #34423d;
background: var(--paper);
font-size: 12px;
font-weight: 700;
text-decoration: none;
}
.audit-link:hover { border-color: var(--green); color: var(--green); background: var(--green-soft); }
.badges { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
.badge { padding: 6px 9px; border: 1px solid var(--line); border-radius: 5px; color: #47544f; background: var(--paper); font-size: 12px; }
.summary { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-bottom: 1px solid var(--line); }
.summary-item { padding: 22px 18px; border-right: 1px solid var(--line); }
.summary-item:first-child { padding-left: 0; }
.summary-item:last-child { border-right: 0; }
.summary .value { font-size: 25px; font-weight: 760; }
.summary .label { margin-top: 5px; color: var(--muted); font-size: 12px; }
section { padding: 28px 0; border-bottom: 1px solid var(--line); }
.section-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 18px; margin-bottom: 16px; }
h2 { margin: 0; font-size: 19px; }
.caption { margin: 6px 0 0; color: var(--muted); line-height: 1.55; }
.controls { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.field { display: grid; gap: 5px; }
.field label { color: var(--muted); font-size: 11px; font-weight: 700; text-transform: uppercase; }
select, .search {
height: 38px;
border: 1px solid #cbd5d0;
border-radius: 6px;
color: var(--ink);
background: var(--paper);
padding: 0 10px;
outline: 0;
}
select:focus, .search:focus { border-color: var(--green); box-shadow: 0 0 0 3px rgba(8,125,114,.12); }
.chart-grid { display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(360px, .8fr); gap: 14px; }
.chart-panel { min-width: 0; padding: 17px; border: 1px solid var(--line); border-radius: 8px; box-shadow: var(--shadow); }
.chart-panel h3 { margin: 0; font-size: 14px; }
.chart-note { min-height: 19px; margin: 5px 0 12px; color: var(--muted); font-size: 12px; }
.canvas-wrap { position: relative; height: 310px; }
.tabs { display: flex; gap: 4px; padding: 3px; border: 1px solid var(--line); border-radius: 7px; background: var(--soft); }
.tab { border: 0; border-radius: 5px; padding: 7px 11px; color: var(--muted); background: transparent; cursor: pointer; }
.tab[aria-selected="true"] { color: var(--ink); background: var(--paper); box-shadow: 0 1px 4px rgba(24,35,31,.1); font-weight: 700; }
.table-tools { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.search { width: min(280px, 100%); }
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 8px; }
table { width: 100%; min-width: 980px; border-collapse: collapse; }
th, td { padding: 11px 12px; border-bottom: 1px solid #e6ebe8; text-align: right; white-space: nowrap; }
th:first-child, td:first-child, th:nth-child(2), td:nth-child(2) { text-align: left; }
th { position: sticky; top: 0; z-index: 1; color: #4a5752; background: #f8faf9; font-size: 11px; text-transform: uppercase; cursor: pointer; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: #fafcfb; }
.method { font-weight: 720; }
.version { color: var(--muted); font-size: 12px; }
.rank { display: inline-flex; justify-content: center; min-width: 28px; margin-right: 7px; padding: 3px 5px; border-radius: 4px; color: #187066; background: #dff1ed; font-size: 10px; font-weight: 800; }
.rank.second { color: #815600; background: #f8edcf; }
.rank.reference { color: #56625e; background: #e9eeeb; }
.best { color: #08766c; background: #edf8f5; font-weight: 760; }
.second-best { color: #8a5b00; background: #fff8e8; font-weight: 720; }
.empty { padding: 36px 18px; color: var(--muted); text-align: center; }
.metric-key { display: flex; flex-wrap: wrap; gap: 20px; margin-top: 14px; color: var(--muted); font-size: 16px; line-height: 1.4; }
.key { display: inline-flex; align-items: center; gap: 6px; }
.swatch { width: 12px; height: 12px; border-radius: 3px; background: #edf8f5; border: 1px solid #b9ddd6; }
.swatch.second { background: #fff8e8; border-color: #ecd598; }
.swatch.ref { background: #e9eeeb; border-color: #cfd7d3; }
.protocol { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; background: var(--line); }
.protocol div { padding: 16px; background: var(--paper); }
.protocol dt { color: var(--muted); font-size: 11px; font-weight: 700; text-transform: uppercase; }
.protocol dd { margin: 6px 0 0; line-height: 1.5; }
.explorer-frame { width: 100%; height: min(790px, 88vh); min-height: 640px; border: 1px solid var(--line); border-radius: 8px; background: var(--soft); }
footer { padding: 22px 0 34px; color: var(--muted); font-size: 12px; }
footer a { color: var(--green); }
@media (max-width: 900px) {
.shell { width: min(100% - 24px, 1480px); }
.title-row, .section-head { align-items: stretch; flex-direction: column; }
.header-actions { align-self: flex-start; }
.summary { grid-template-columns: repeat(2, 1fr); }
.summary-item:nth-child(2) { border-right: 0; }
.summary-item:nth-child(-n+2) { border-bottom: 1px solid var(--line); }
.summary-item:nth-child(3) { padding-left: 0; }
.chart-grid { grid-template-columns: 1fr; }
.protocol { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
h1 { font-size: 27px; }
.status { align-self: flex-start; }
.controls, .field, select { width: 100%; }
.table-tools { align-items: stretch; flex-direction: column; }
.search { width: 100%; }
.canvas-wrap { height: 280px; }
}
</style>
<!-- motius-benchmark-nav-style:start -->
<style id="motius-benchmark-nav-style">
.motius-benchmark-nav {
position: relative;
z-index: 1000;
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
width: min(1420px, calc(100% - 36px));
min-height: 50px;
margin: 14px auto 0;
padding: 8px 10px 8px 14px;
border: 1px solid #d8dfdc;
border-radius: 7px;
background: #ffffff;
color: #17211e;
box-shadow: 0 5px 18px rgba(23, 33, 30, 0.06);
font: 13px/1.4 Inter, ui-sans-serif, system-ui, -apple-system, sans-serif;
letter-spacing: 0;
}
.motius-benchmark-nav *,
.motius-benchmark-nav *::before,
.motius-benchmark-nav *::after { box-sizing: border-box; }
.motius-benchmark-brand {
color: #0a746b;
font-weight: 760;
text-decoration: none;
white-space: nowrap;
}
.motius-benchmark-context {
min-width: 0;
margin-left: auto;
overflow: hidden;
color: #53615c;
text-overflow: ellipsis;
white-space: nowrap;
}
.motius-benchmark-menu { position: relative; flex: 0 0 auto; }
.motius-benchmark-menu > summary {
display: flex;
align-items: center;
min-height: 34px;
padding: 6px 10px;
border: 1px solid #cbd5d1;
border-radius: 6px;
background: #f7f9f8;
color: #26332f;
cursor: pointer;
font-weight: 680;
list-style: none;
user-select: none;
}
.motius-benchmark-menu > summary::-webkit-details-marker { display: none; }
.motius-benchmark-menu > summary::after {
content: "▾";
margin-left: 8px;
color: #0a746b;
}
.motius-benchmark-menu[open] > summary::after { content: "▴"; }
.motius-benchmark-list {
position: absolute;
top: calc(100% + 8px);
right: 0;
display: grid;
grid-template-columns: repeat(2, minmax(260px, 1fr));
width: min(720px, calc(100vw - 36px));
max-height: min(70vh, 620px);
padding: 8px;
overflow: auto;
border: 1px solid #cbd5d1;
border-radius: 7px;
background: #ffffff;
box-shadow: 0 16px 42px rgba(23, 33, 30, 0.16);
}
.motius-benchmark-link {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 12px;
align-items: center;
min-height: 42px;
padding: 8px 10px;
border-radius: 5px;
color: #26332f;
text-decoration: none;
}
.motius-benchmark-link:hover { background: #f0f5f3; }
.motius-benchmark-link[aria-current="page"] {
background: #e5f3ef;
color: #075e57;
font-weight: 720;
}
.motius-benchmark-status {
color: #69756f;
font: 10px/1.2 ui-monospace, SFMono-Regular, Consolas, monospace;
white-space: nowrap;
}
.motius-benchmark-status[data-status="complete"] { color: #087267; }
.motius-benchmark-status[data-status="metrics_complete"] { color: #946018; }
.motius-benchmark-status[data-status="protocol_ready"] { color: #315f9d; }
.motius-benchmark-status[data-status="paused"] { color: #a1453a; }
.motius-benchmark-status[data-status="settings"] { color: #315f9d; }
.motius-setting-nav {
display: flex;
align-items: center;
gap: 6px;
width: min(1420px, calc(100% - 36px));
margin: 10px auto 0;
padding: 4px;
overflow-x: auto;
border: 1px solid #d8dfdc;
border-radius: 7px;
background: #eef2f0;
font: 13px/1.35 Inter, ui-sans-serif, system-ui, -apple-system, sans-serif;
letter-spacing: 0;
}
.motius-setting-label {
flex: 0 0 auto;
padding: 0 10px;
color: #69756f;
font: 10px/1.2 ui-monospace, SFMono-Regular, Consolas, monospace;
text-transform: uppercase;
}
.motius-setting-link {
display: flex;
flex: 0 0 auto;
align-items: baseline;
gap: 8px;
min-height: 36px;
padding: 8px 12px;
border: 1px solid transparent;
border-radius: 5px;
color: #53615c;
text-decoration: none;
}
.motius-setting-link:hover {
border-color: #cbd5d1;
background: #ffffff;
color: #17211e;
}
.motius-setting-link[aria-current="page"] {
border-color: #adc9c2;
background: #ffffff;
color: #075e57;
box-shadow: 0 3px 10px rgba(23, 33, 30, 0.06);
font-weight: 720;
}
.motius-setting-detail {
color: #7a8581;
font: 10px/1.2 ui-monospace, SFMono-Regular, Consolas, monospace;
}
@media (max-width: 720px) {
.motius-benchmark-nav {
width: calc(100% - 24px);
margin-top: 10px;
gap: 8px;
padding-left: 10px;
}
.motius-benchmark-context { display: none; }
.motius-benchmark-list {
position: fixed;
top: 64px;
right: 12px;
grid-template-columns: 1fr;
width: calc(100vw - 24px);
max-height: calc(100vh - 82px);
}
.motius-setting-nav { width: calc(100% - 24px); }
.motius-setting-label { display: none; }
}
</style>
<!-- motius-benchmark-nav-style:end -->
</head>
<body data-benchmark-id="sequential_text_to_motion_babel">
<div class="shell">
<!-- motius-benchmark-nav:start -->
<nav class="motius-benchmark-nav" data-benchmark-id="sequential_text_to_motion_babel" aria-label="Motius benchmark navigation">
<a class="motius-benchmark-brand" href="https://github.com/ZeyuLing/Motius/tree/main/docs/leaderboards" target="_blank" rel="noopener noreferrer">Motius Benchmark Hub</a>
<span class="motius-benchmark-context">Sequential Text-to-Motion · BABEL</span>
<details class="motius-benchmark-menu">
<summary>All benchmarks</summary>
<div class="motius-benchmark-list">
<a class="motius-benchmark-link" href="https://zeyuling-t2m-humanml3d-leaderboard.static.hf.space/" target="_self" rel="noopener noreferrer"><span>Text-to-Motion</span><span class="motius-benchmark-status" data-status="settings">2 settings</span></a>
<a class="motius-benchmark-link" href="https://zeyuling-m2t-humanml3d-leaderboard.static.hf.space/" target="_self" rel="noopener noreferrer"><span>Motion-to-Text · HumanML3D</span><span class="motius-benchmark-status" data-status="complete">Complete</span></a>
<a class="motius-benchmark-link" href="https://zeyuling-babel-sequential-generation-leaderboard.static.hf.space/" target="_self" rel="noopener noreferrer" aria-current="page"><span>Sequential Text-to-Motion · BABEL</span><span class="motius-benchmark-status" data-status="complete">Complete</span></a>
<a class="motius-benchmark-link" href="https://zeyuling-temporal-condition-leaderboard.static.hf.space/" target="_self" rel="noopener noreferrer"><span>Temporal Motion Completion · HumanML3D</span><span class="motius-benchmark-status" data-status="complete">Complete</span></a>
<a class="motius-benchmark-link" href="https://zeyuling-body-part-condition-humanml3d-leaderboard.static.hf.space/" target="_self" rel="noopener noreferrer"><span>Part-Level Motion Control · HumanML3D</span><span class="motius-benchmark-status" data-status="complete">Complete</span></a>
<a class="motius-benchmark-link" href="https://zeyuling-motion-edit-leaderboard.static.hf.space/" target="_self" rel="noopener noreferrer"><span>Motion Editing · Style and Content</span><span class="motius-benchmark-status" data-status="complete">Complete</span></a>
<a class="motius-benchmark-link" href="https://zeyuling-instruction-editing-leaderboard.static.hf.space/" target="_self" rel="noopener noreferrer"><span>Motion Editing · MotionFix Instructions</span><span class="motius-benchmark-status" data-status="complete">Complete</span></a>
<a class="motius-benchmark-link" href="https://zeyuling-motion-repair-brokenamass-leaderboard.static.hf.space/" target="_self" rel="noopener noreferrer"><span>Motion Repair · BrokenAMASS</span><span class="motius-benchmark-status" data-status="complete">Complete</span></a>
<a class="motius-benchmark-link" href="https://zeyuling-motion-reconstruction-humanml3d-leaderboard.static.hf.space/" target="_self" rel="noopener noreferrer"><span>Motion Reconstruction · HumanML3D</span><span class="motius-benchmark-status" data-status="complete">Complete</span></a>
<a class="motius-benchmark-link" href="https://zeyuling-music-to-dance-aistpp-leaderboard.static.hf.space/" target="_self" rel="noopener noreferrer"><span>Music-to-Dance · AIST++</span><span class="motius-benchmark-status" data-status="complete">Complete</span></a>
<a class="motius-benchmark-link" href="https://zeyuling-dance-to-music-aistpp-leaderboard.static.hf.space/" target="_self" rel="noopener noreferrer"><span>Dance-to-Music · AIST++</span><span class="motius-benchmark-status" data-status="complete">Complete</span></a>
<a class="motius-benchmark-link" href="https://zeyuling-speech-to-gesture-beat2-leaderboard.static.hf.space/" target="_self" rel="noopener noreferrer"><span>Speech-to-Gesture · BEAT2</span><span class="motius-benchmark-status" data-status="complete">Complete</span></a>
<a class="motius-benchmark-link" href="https://zeyuling-monocular-motion-capture-leaderboard.static.hf.space/" target="_self" rel="noopener noreferrer"><span>Monocular Motion Capture · 3DPW Test</span><span class="motius-benchmark-status" data-status="complete">Complete</span></a>
<a class="motius-benchmark-link" href="https://zeyuling-motion-tracking-mujoco-leaderboard.static.hf.space/" target="_self" rel="noopener noreferrer"><span>Motion Tracking</span><span class="motius-benchmark-status" data-status="settings">2 settings</span></a>
</div>
</details>
</nav>
<!-- motius-benchmark-nav:end -->
<header>
<div class="title-row">
<div>
<h1>Sequential Text-to-Motion · BABEL</h1>
<p class="lede">Long-form human motion composition from an ordered sequence of text prompts. Every method is retargeted to the same SMPL-22 joints; uTMR FID is computed only after per-sample L2 normalization of the motion embeddings.</p>
</div>
<div class="header-actions">
<span class="status" id="status">Normalized uTMR FID</span>
<a class="audit-link" href="#case-explorer">Compare all 1,295 episodes</a>
</div>
</div>
<div class="badges">
<span class="badge">BABEL validation split</span>
<span class="badge">1,295 validation episodes</span>
<span class="badge">30 fps</span>
<span class="badge">Motius Joint-Position Evaluator</span>
<span class="badge">L2-normalized embedding FID</span>
</div>
</header>
<div class="summary">
<div class="summary-item"><div class="value" id="method-count">0</div><div class="label">Ranked methods</div></div>
<div class="summary-item"><div class="value">1,295</div><div class="label">Episodes</div></div>
<div class="summary-item"><div class="value">7,285</div><div class="label">Captioned segments</div></div>
<div class="summary-item"><div class="value">5,990</div><div class="label">Transition boundaries</div></div>
</div>
<section>
<div class="section-head">
<div><h2>Method Comparison</h2><p class="caption">Generated methods only; reference rows never set the chart scale.</p></div>
<div class="controls">
<div class="field"><label for="chart-group">Metric group</label><select id="chart-group"><option value="semantic">Semantic</option><option value="transition">Transition</option></select></div>
<div class="field"><label for="chart-metric">Metric</label><select id="chart-metric"></select></div>
</div>
</div>
<div class="chart-grid">
<article class="chart-panel"><h3>Ranked Values</h3><p class="chart-note" id="bar-note"></p><div class="canvas-wrap"><canvas id="bar-chart"></canvas></div></article>
<article class="chart-panel"><h3>Normalized Profile</h3><p class="chart-note">100 is the best generated-method value on each axis.</p><div class="canvas-wrap"><canvas id="radar-chart"></canvas></div></article>
</div>
</section>
<section id="case-explorer">
<div class="section-head"><div><h2>All-Case Comparison</h2><p class="caption">Search every processed validation episode, switch between all measured methods, and inspect the exact caption active at each frame.</p></div></div>
<iframe class="explorer-frame" src="cases/index.html" title="BABEL sequential all-case comparison" loading="lazy"></iframe>
</section>
<section>
<div class="section-head"><div><h2>Results</h2><p class="caption">Click any metric header to sort. Best and second-best values are recomputed within the active view.</p></div></div>
<div class="table-tools">
<div class="tabs" role="tablist" aria-label="metric view">
<button class="tab" type="button" data-view="semantic" aria-selected="true">Semantic</button>
<button class="tab" type="button" data-view="transition" aria-selected="false">Transition</button>
</div>
<input class="search" id="search" type="search" placeholder="Filter method" aria-label="Filter method">
</div>
<div class="table-wrap"><table><thead id="table-head"></thead><tbody id="table-body"></tbody></table></div>
<div class="metric-key"><span class="key"><span class="swatch"></span>Best</span><span class="key"><span class="swatch second"></span>Second</span><span class="key"><span class="swatch ref"></span>Reference, excluded from ranking</span></div>
</section>
<section>
<div class="section-head"><div><h2>Protocol</h2><p class="caption">A single conversion and metric contract for every sequential-generation method.</p></div></div>
<dl class="protocol">
<div><dt>Prompts</dt><dd>All 1,295 eligible processed BABEL validation episodes; 7,285 action intervals after short-action merging and LLM caption rewriting.</dd></div>
<div><dt>References</dt><dd>Paired GT subsequences and transition windows from the same episode boundaries; no independent reference pools.</dd></div>
<div><dt>Representation</dt><dd>Neutral zero-beta SMPL-22 joints66. Every semantic subclip is independently first-frame canonicalized before uTMR; each transition window is canonicalized once so its cross-boundary gap remains intact.</dd></div>
<div><dt>Semantic Metrics</dt><dd>Official BABEL act_cat action-group R-Precision, nearest-positive MM-Dist, and L2-normalized embedding FID from the Motius Joint-Position Evaluator. Synonymous captions are retained without becoming false negatives.</dd></div>
<div><dt>Transition Metrics</dt><dd>L2-normalized embedding FID and AUJ gap are ranked; Diversity and absolute Peak Jerk are diagnostic reference statistics.</dd></div>
<div><dt>Ranking</dt><dd>GT/reference and paper-only values are visible but cannot receive best or second-best styling.</dd></div>
</dl>
</section>
<footer>Protocol and implementation: <a href="https://github.com/ZeyuLing/Motius">ZeyuLing/Motius</a>. Composition protocol adapted from <a href="https://github.com/BarqueroGerman/FlowMDM">FlowMDM</a>; motion data from <a href="https://babel.is.tue.mpg.de/data.html">BABEL</a>.</footer>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js"></script>
<script>
const rows = Object.freeze([
{method:"BABEL val", version:"Paired GT · action groups v3", samples:7285, isReference:true, r1:0.3614, r2:0.5284, r3:0.6317, fid:0.0, mmDist:47.8378, diversity:49.2886, transitionFid:0.0, transitionDiversity:43.7889, peakJerk:56.3384, aujGap:0.0},
{method:"MotionCanvas", version:"Epoch 1964 · CFG 5.0 · context 5 · seed 42 · 3-frame low-pass", samples:7285, r1:0.4240, r2:0.6049, r3:0.7134, fid:0.0587, mmDist:46.2662, diversity:49.7064, transitionFid:0.0481, transitionDiversity:42.4862, peakJerk:170.9196, aujGap:80.0543},
{method:"FlowMDM", version:"Official checkpoint · seed 42 · action groups v3", samples:7285, r1:0.2504, r2:0.3925, r3:0.4818, fid:0.0467, mmDist:50.8503, diversity:50.3880, transitionFid:0.0555, transitionDiversity:44.9407, peakJerk:335.6733, aujGap:34.4040},
{method:"MotionStreamer", version:"Official checkpoint · seed 42 · action groups v3", samples:7285, r1:0.2130, r2:0.3303, r3:0.4175, fid:0.0610, mmDist:52.0339, diversity:46.5873, transitionFid:0.0702, transitionDiversity:40.8189, peakJerk:206.2215, aujGap:76.2889},
{method:"MotionLab", version:"Official checkpoint · context 5 · seed 42", samples:7285, r1:0.2580, r2:0.3793, r3:0.4536, fid:0.2011, mmDist:51.3873, diversity:41.6184, transitionFid:0.2499, transitionDiversity:34.3793, peakJerk:204.6691, aujGap:25.7259},
{method:"PRISM", version:"Epoch 26 · fixed 360 · CFG 5.0 · AR5 · seed 42", samples:7285, r1:0.2833, r2:0.4314, r3:0.5168, fid:0.0591, mmDist:51.0135, diversity:50.5232, transitionFid:0.0739, transitionDiversity:46.7228, peakJerk:503.3991, aujGap:157.8457}
]);
const groups = {
semantic: [
{key:"r3", label:"R@3", direction:"max", digits:4},
{key:"r1", label:"R@1", direction:"max", digits:4},
{key:"r2", label:"R@2", direction:"max", digits:4},
{key:"fid", label:"Normalized FID", direction:"min", digits:4},
{key:"mmDist", label:"MM-Dist", direction:"min", digits:4},
{key:"diversity", label:"Diversity", direction:"max", digits:4, referenceStatistic:true}
],
transition: [
{key:"transitionFid", label:"Normalized Transition FID", direction:"min", digits:4},
{key:"transitionDiversity", label:"Transition Diversity", direction:"max", digits:4, referenceStatistic:true},
{key:"peakJerk", label:"Peak Jerk", direction:"min", digits:2, referenceStatistic:true},
{key:"aujGap", label:"AUJ Gap", direction:"min", digits:4}
]
};
const baseColumns = [
{key:"method", label:"Method"}, {key:"version", label:"Version"},
{key:"samples", label:"Segments", numeric:true}
];
const colors = ["#087d72", "#315f9d", "#c7563f", "#ad6d00", "#6e5aa5"];
const state = {view:"semantic", query:"", sortKey:"r3", sortDirection:"desc"};
let barChart = null;
let radarChart = null;
function rankable(row) { return !row.isReference && !row.paperOnly && !row.rankExcluded; }
function colorFor(row) {
const index = rows.filter(rankable).indexOf(row);
return colors[(index < 0 ? 0 : index) % colors.length];
}
function metric(key) { return groups[state.view].find(item => item.key === key); }
function format(value, spec) {
if (value === null || value === undefined || Number.isNaN(Number(value))) return "-";
if (spec && spec.digits !== undefined) return Number(value).toFixed(spec.digits);
return Number(value).toLocaleString();
}
function ranking(spec) {
if (spec.referenceStatistic) return [];
return rows.filter(row => rankable(row) && Number.isFinite(Number(row[spec.key])))
.sort((a,b) => spec.direction === "min" ? a[spec.key]-b[spec.key] : b[spec.key]-a[spec.key]);
}
function classFor(row, spec) {
if (!rankable(row)) return "";
const ranked = ranking(spec);
if (ranked[0] === row) return "best";
if (ranked[1] === row) return "second-best";
return "";
}
function filteredRows() {
const q = state.query.trim().toLowerCase();
const values = rows.filter(row => !q || `${row.method} ${row.version || ""}`.toLowerCase().includes(q));
const spec = metric(state.sortKey);
return values.sort((a,b) => {
if (a.isReference !== b.isReference) return a.isReference ? -1 : 1;
const av = a[state.sortKey], bv = b[state.sortKey];
if (typeof av === "number" && typeof bv === "number") return state.sortDirection === "asc" ? av-bv : bv-av;
return String(av || "").localeCompare(String(bv || "")) * (state.sortDirection === "asc" ? 1 : -1);
});
}
function renderTable() {
const metrics = groups[state.view];
const columns = [...baseColumns, ...metrics];
document.getElementById("table-head").innerHTML = `<tr>${columns.map(col => `<th data-key="${col.key}">${col.label}${state.sortKey===col.key ? (state.sortDirection==="asc" ? " ↑" : " ↓") : ""}</th>`).join("")}</tr>`;
const body = document.getElementById("table-body");
const visible = filteredRows();
if (!visible.length) {
body.innerHTML = `<tr><td class="empty" colspan="${columns.length}">${rows.length ? "No matching method." : "Measured benchmark run in progress."}</td></tr>`;
} else {
body.innerHTML = visible.map(row => {
const ranked = groups[state.view].length ? ranking(groups[state.view][0]) : [];
const rank = !rankable(row) ? '<span class="rank reference">REF</span>' : ranked.indexOf(row) >= 0 ? `<span class="rank${ranked.indexOf(row)===1 ? " second" : ""}">#${ranked.indexOf(row)+1}</span>` : "";
return `<tr><td class="method">${rank}${row.method}</td><td class="version">${row.version || "-"}</td><td>${format(row.samples)}</td>${metrics.map(spec => `<td class="${classFor(row,spec)}">${format(row[spec.key],spec)}</td>`).join("")}</tr>`;
}).join("");
}
document.querySelectorAll("th[data-key]").forEach(head => head.addEventListener("click", () => {
const key = head.dataset.key;
if (state.sortKey === key) state.sortDirection = state.sortDirection === "asc" ? "desc" : "asc";
else { state.sortKey = key; state.sortDirection = metric(key)?.direction === "min" ? "asc" : "desc"; }
renderTable();
}));
}
function normalized(row, spec, ranked) {
const values = ranked.map(item => Number(item[spec.key])).filter(Number.isFinite);
if (!values.length) return 0;
const min = Math.min(...values), max = Math.max(...values);
if (max === min) return 100;
return spec.direction === "min" ? 100*(max-row[spec.key])/(max-min) : 100*(row[spec.key]-min)/(max-min);
}
function renderCharts() {
if (typeof Chart === "undefined") return;
const specs = groups[state.view].filter(item => !item.referenceStatistic);
const key = document.getElementById("chart-metric").value || specs[0].key;
const spec = specs.find(item => item.key === key) || specs[0];
const ranked = rows.filter(rankable).filter(row => specs.some(item => Number.isFinite(Number(row[item.key]))));
const ordered = [...ranked].filter(row => Number.isFinite(Number(row[spec.key]))).sort((a,b) => spec.direction === "min" ? a[spec.key]-b[spec.key] : b[spec.key]-a[spec.key]);
document.getElementById("bar-note").textContent = `${spec.label}; ${spec.direction === "min" ? "lower" : "higher"} is better.`;
if (barChart) barChart.destroy();
if (radarChart) radarChart.destroy();
barChart = new Chart(document.getElementById("bar-chart"), {type:"bar", data:{labels:ordered.map(row=>row.method), datasets:[{data:ordered.map(row=>row[spec.key]), backgroundColor:ordered.map(colorFor), borderRadius:4}]}, options:{animation:false,indexAxis:"y", responsive:true, maintainAspectRatio:false, plugins:{legend:{display:false}}, scales:{x:{beginAtZero:true, grid:{color:"#e7ebe9"}},y:{grid:{display:false},ticks:{font:{size:15,weight:"600"},color:"#34413d"}}}}});
radarChart = new Chart(document.getElementById("radar-chart"), {type:"radar", data:{labels:specs.map(item=>item.label), datasets:ranked.map(row=>({label:row.method,data:specs.map(item=>normalized(row,item,ranked)),borderColor:colorFor(row),backgroundColor:colorFor(row)+"18",pointRadius:2,borderWidth:2}))}, options:{animation:false,responsive:true,maintainAspectRatio:false,scales:{r:{min:0,max:100,ticks:{display:false},pointLabels:{font:{size:14,weight:"600"},color:"#46534f"},grid:{color:"#e0e6e3"},angleLines:{color:"#e0e6e3"}}},plugins:{legend:{position:"bottom",labels:{boxWidth:14,boxHeight:14,padding:18,font:{size:16,weight:"600"},color:"#34413d"}}}}});
}
function configureMetrics() {
const select = document.getElementById("chart-metric");
const rankedMetrics = groups[state.view].filter(item => !item.referenceStatistic);
select.innerHTML = rankedMetrics.map(item=>`<option value="${item.key}">${item.label}</option>`).join("");
state.sortKey = rankedMetrics[0].key;
state.sortDirection = rankedMetrics[0].direction === "min" ? "asc" : "desc";
renderTable(); renderCharts();
}
document.querySelectorAll(".tab").forEach(tab => tab.addEventListener("click", () => {
state.view = tab.dataset.view;
document.querySelectorAll(".tab").forEach(item=>item.setAttribute("aria-selected",String(item===tab)));
document.getElementById("chart-group").value = state.view;
configureMetrics();
}));
document.getElementById("search").addEventListener("input", event => { state.query=event.target.value; renderTable(); });
document.getElementById("chart-group").addEventListener("change", event => { state.view=event.target.value; document.querySelectorAll(".tab").forEach(item=>item.setAttribute("aria-selected",String(item.dataset.view===state.view))); configureMetrics(); });
document.getElementById("chart-metric").addEventListener("change", renderCharts);
document.getElementById("method-count").textContent = rows.filter(rankable).length;
configureMetrics();
</script>
</body>
</html>