dehezhang2 commited on
Commit
4cceebf
·
verified ·
1 Parent(s): 38dfd92

publish current study stats page

Browse files
Files changed (1) hide show
  1. static/stats.html +169 -0
static/stats.html ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en"><head><meta charset="utf-8">
3
+ <title>User study stats · FrameWorker</title>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
5
+ <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.4/dist/chart.umd.min.js"></script>
6
+ <style>
7
+ :root { --bg:#0f1115; --panel:#161922; --panel-2:#1c2030; --border:#2a2f42;
8
+ --fg:#e6e8ef; --muted:#8b91a8; --accent:#6aa9ff; --good:#28c76f;
9
+ --warn:#ff9f43; --bad:#ea5455; }
10
+ body { margin: 0; background: var(--bg); color: var(--fg);
11
+ font-family: -apple-system, "Inter", "PingFang SC", sans-serif; }
12
+ header { padding: 14px 24px; border-bottom: 1px solid var(--border);
13
+ background: var(--panel); display: flex; gap: 14px; align-items: baseline;
14
+ flex-wrap: wrap; }
15
+ header h1 { font-size: 18px; margin: 0; }
16
+ header .meta { color: var(--muted); font-size: 12px; }
17
+ main { padding: 18px 24px; max-width: 1100px; margin: 0 auto; }
18
+ section { background: var(--panel); border: 1px solid var(--border);
19
+ border-radius: 8px; padding: 16px 18px; margin-bottom: 16px; }
20
+ h2 { font-size: 15px; margin: 0 0 12px; color: var(--accent); }
21
+ table { border-collapse: collapse; width: 100%; font-size: 13px; }
22
+ th, td { padding: 6px 10px; border-bottom: 1px solid var(--border); text-align: left; }
23
+ th { color: var(--muted); font-weight: 600; font-size: 11px;
24
+ text-transform: uppercase; letter-spacing: 0.5px; }
25
+ .q-block { background: var(--panel-2); border: 1px solid var(--border);
26
+ border-radius: 6px; padding: 10px 12px; margin: 10px 0; }
27
+ .q-block .q-title { font-weight: 600; font-size: 13px; margin-bottom: 4px; }
28
+ .q-block .q-dim { color: var(--muted); font-size: 11px; }
29
+ canvas { background: transparent; max-height: 240px; }
30
+ .legend-dot { display: inline-block; width: 9px; height: 9px;
31
+ border-radius: 50%; margin-right: 4px; vertical-align: middle; }
32
+ .empty { color: var(--muted); font-size: 12px; padding: 20px;
33
+ text-align: center; background: var(--panel-2); border-radius: 6px; }
34
+ </style></head><body>
35
+
36
+ <header>
37
+ <h1>User study stats</h1>
38
+ <span class="meta">generated <code id="ts"></code> · raters <b id="nrater"></b>
39
+ · submissions <b id="nfile"></b> · 1–5 Likert</span>
40
+ <span style="margin-left:auto"><a href="./" style="color:var(--accent)">← back to study</a></span>
41
+ </header>
42
+
43
+ <main>
44
+ <section>
45
+ <h2>Per dimension</h2>
46
+ <canvas id="dimChart"></canvas>
47
+ <table style="margin-top:12px"><thead><tr id="dimHead"></tr></thead>
48
+ <tbody id="dimBody"></tbody></table>
49
+ </section>
50
+
51
+ <section>
52
+ <h2>Per sub-question</h2>
53
+ <table><thead><tr id="qHead"></tr></thead><tbody id="qBody"></tbody></table>
54
+ </section>
55
+
56
+ <section>
57
+ <h2>Per sub-question — model comparison</h2>
58
+ <div id="qCharts"></div>
59
+ </section>
60
+ </main>
61
+
62
+ <script id="data" type="application/json">{"n_raters": 3, "n_payloads": 4, "models": ["ours", "baseline", "huobao"], "per_question": [{"dim_label": "Instruction following", "q_label": "Controllability", "q_key": "controllability", "scores": {"ours": [3, 3, 3, 3, 3, 5, 5, 3, 4, 4, 3, 3, 3, 3, 3, 5, 5, 3, 4, 4], "baseline": [1, 3, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 1, 1, 1, 1], "huobao": [1, 3, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 1, 1, 1, 1]}}, {"dim_label": "Instruction following", "q_label": "Prompt adherence", "q_key": "prompt_adherence", "scores": {"ours": [3, 1, 3, 3, 2, 4, 4, 5, 3, 5, 3, 1, 3, 3, 2, 4, 4, 5, 3, 5], "baseline": [1, 2, 3, 4, 3, 2, 4, 3, 3, 4, 1, 2, 3, 4, 3, 2, 4, 3, 3, 4], "huobao": [3, 3, 2, 4, 4, 2, 2, 4, 5, 4, 3, 3, 2, 4, 4, 2, 2, 4, 5, 4]}}, {"dim_label": "Instruction following", "q_label": "No irrelevant frames", "q_key": "no_irrelevant_frames", "scores": {"ours": [2, 2, 2, 3, 2, 3, 4, 2, 5, 4, 2, 2, 2, 3, 2, 3, 4, 2, 5, 4], "baseline": [2, 2, 1, 4, 4, 3, 4, 1, 2, 4, 2, 2, 1, 4, 4, 3, 4, 1, 2, 4], "huobao": [2, 2, 3, 2, 3, 1, 3, 2, 4, 4, 2, 2, 3, 2, 3, 1, 3, 2, 4, 4]}}, {"dim_label": "Temporal consistency", "q_label": "Person stability", "q_key": "person_stability", "scores": {"ours": [2, 2, 3, 2, 5, 3, 3, 4, 5, 5, 2, 2, 3, 2, 5, 3, 3, 4, 5, 5], "baseline": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "huobao": [3, 1, 2, 1, 2, 1, 1, 2, 3, 3, 3, 1, 2, 1, 2, 1, 1, 2, 3, 3]}}, {"dim_label": "Temporal consistency", "q_label": "Object stability", "q_key": "object_stability", "scores": {"ours": [4, 2, 2, 5, 3, 4, 3, 4, 5, 5, 4, 2, 2, 5, 3, 4, 3, 4, 5, 5], "baseline": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "huobao": [4, 1, 3, 1, 3, 1, 1, 1, 4, 2, 4, 1, 3, 1, 3, 1, 1, 1, 4, 2]}}, {"dim_label": "Temporal consistency", "q_label": "Environment stability", "q_key": "environment_stability", "scores": {"ours": [2, 3, 5, 3, 4, 4, 4, 5, 5, 5, 2, 3, 5, 3, 4, 4, 4, 5, 5, 5], "baseline": [1, 1, 1, 2, 3, 1, 1, 1, 3, 2, 1, 1, 1, 2, 3, 1, 1, 1, 3, 2], "huobao": [2, 1, 4, 1, 4, 1, 2, 1, 3, 3, 2, 1, 4, 1, 4, 1, 2, 1, 3, 3]}}, {"dim_label": "Realism", "q_label": "Realism", "q_key": "realism", "scores": {"ours": [2, 2, 3, 3, 2, 2, 3, 4, 2, 3, 2, 2, 3, 3, 2, 2, 3, 4, 2, 3], "baseline": [1, 2, 4, 2, 1, 1, 2, 1, 4, 4, 1, 2, 4, 2, 1, 1, 2, 1, 4, 4], "huobao": [2, 1, 2, 2, 2, 1, 1, 4, 4, 2, 2, 1, 2, 2, 2, 1, 1, 4, 4, 2]}}, {"dim_label": "Realism", "q_label": "Motion logic", "q_key": "motion_logic", "scores": {"ours": [2, 3, 2, 2, 3, 4, 2, 4, 2, 2, 2, 3, 2, 2, 3, 4, 2, 4, 2, 2], "baseline": [3, 3, 3, 2, 1, 2, 3, 1, 1, 2, 3, 3, 3, 2, 1, 2, 3, 1, 1, 2], "huobao": [3, 1, 1, 2, 3, 3, 1, 3, 1, 3, 3, 1, 1, 2, 3, 3, 1, 3, 1, 3]}}, {"dim_label": "Realism", "q_label": "Camera", "q_key": "camera", "scores": {"ours": [4, 3, 3, 3, 3, 4, 2, 5, 3, 4, 4, 3, 3, 3, 3, 4, 2, 5, 3, 4], "baseline": [2, 1, 2, 2, 3, 2, 1, 2, 2, 2, 2, 1, 2, 2, 3, 2, 1, 2, 2, 2], "huobao": [3, 1, 2, 2, 3, 3, 1, 3, 2, 2, 3, 1, 2, 2, 3, 3, 1, 3, 2, 2]}}], "per_dim": [{"dim_label": "Instruction following", "scores": {"ours": [3, 3, 3, 3, 3, 5, 5, 3, 4, 4, 3, 3, 3, 3, 3, 5, 5, 3, 4, 4, 3, 1, 3, 3, 2, 4, 4, 5, 3, 5, 3, 1, 3, 3, 2, 4, 4, 5, 3, 5, 2, 2, 2, 3, 2, 3, 4, 2, 5, 4, 2, 2, 2, 3, 2, 3, 4, 2, 5, 4], "baseline": [1, 3, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 1, 1, 1, 1, 1, 2, 3, 4, 3, 2, 4, 3, 3, 4, 1, 2, 3, 4, 3, 2, 4, 3, 3, 4, 2, 2, 1, 4, 4, 3, 4, 1, 2, 4, 2, 2, 1, 4, 4, 3, 4, 1, 2, 4], "huobao": [1, 3, 1, 3, 3, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 1, 1, 1, 1, 3, 3, 2, 4, 4, 2, 2, 4, 5, 4, 3, 3, 2, 4, 4, 2, 2, 4, 5, 4, 2, 2, 3, 2, 3, 1, 3, 2, 4, 4, 2, 2, 3, 2, 3, 1, 3, 2, 4, 4]}}, {"dim_label": "Temporal consistency", "scores": {"ours": [2, 2, 3, 2, 5, 3, 3, 4, 5, 5, 2, 2, 3, 2, 5, 3, 3, 4, 5, 5, 4, 2, 2, 5, 3, 4, 3, 4, 5, 5, 4, 2, 2, 5, 3, 4, 3, 4, 5, 5, 2, 3, 5, 3, 4, 4, 4, 5, 5, 5, 2, 3, 5, 3, 4, 4, 4, 5, 5, 5], "baseline": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 3, 2, 1, 1, 1, 2, 3, 1, 1, 1, 3, 2], "huobao": [3, 1, 2, 1, 2, 1, 1, 2, 3, 3, 3, 1, 2, 1, 2, 1, 1, 2, 3, 3, 4, 1, 3, 1, 3, 1, 1, 1, 4, 2, 4, 1, 3, 1, 3, 1, 1, 1, 4, 2, 2, 1, 4, 1, 4, 1, 2, 1, 3, 3, 2, 1, 4, 1, 4, 1, 2, 1, 3, 3]}}, {"dim_label": "Realism", "scores": {"ours": [2, 2, 3, 3, 2, 2, 3, 4, 2, 3, 2, 2, 3, 3, 2, 2, 3, 4, 2, 3, 2, 3, 2, 2, 3, 4, 2, 4, 2, 2, 2, 3, 2, 2, 3, 4, 2, 4, 2, 2, 4, 3, 3, 3, 3, 4, 2, 5, 3, 4, 4, 3, 3, 3, 3, 4, 2, 5, 3, 4], "baseline": [1, 2, 4, 2, 1, 1, 2, 1, 4, 4, 1, 2, 4, 2, 1, 1, 2, 1, 4, 4, 3, 3, 3, 2, 1, 2, 3, 1, 1, 2, 3, 3, 3, 2, 1, 2, 3, 1, 1, 2, 2, 1, 2, 2, 3, 2, 1, 2, 2, 2, 2, 1, 2, 2, 3, 2, 1, 2, 2, 2], "huobao": [2, 1, 2, 2, 2, 1, 1, 4, 4, 2, 2, 1, 2, 2, 2, 1, 1, 4, 4, 2, 3, 1, 1, 2, 3, 3, 1, 3, 1, 3, 3, 1, 1, 2, 3, 3, 1, 3, 1, 3, 3, 1, 2, 2, 3, 3, 1, 3, 2, 2, 3, 1, 2, 2, 3, 3, 1, 3, 2, 2]}}], "generated_at_utc": "2026-05-11T19:44:11Z"}</script>
63
+ <script>
64
+ const DATA = JSON.parse(document.getElementById("data").textContent);
65
+ const COLORS = ["#6aa9ff","#ff9f43","#28c76f","#ea5455","#b46aff"];
66
+ const MODEL_COLOR = Object.fromEntries(DATA.models.map((m,i) => [m, COLORS[i % COLORS.length]]));
67
+
68
+ document.getElementById("ts").textContent = DATA.generated_at_utc;
69
+ document.getElementById("nrater").textContent = DATA.n_raters;
70
+ document.getElementById("nfile").textContent = DATA.n_payloads;
71
+
72
+ function mean(arr) { return arr.length ? arr.reduce((a,b)=>a+b,0)/arr.length : null; }
73
+ function std(arr) {
74
+ if (arr.length < 2) return 0;
75
+ const m = mean(arr); const v = arr.reduce((a,b)=>a+(b-m)*(b-m),0)/(arr.length-1);
76
+ return Math.sqrt(v);
77
+ }
78
+ function fmt(arr) {
79
+ if (!arr.length) return "—";
80
+ const m = mean(arr); const s = std(arr);
81
+ return arr.length > 1 ? `${m.toFixed(2)} ± ${s.toFixed(2)} (n=${arr.length})`
82
+ : `${m.toFixed(2)} (n=${arr.length})`;
83
+ }
84
+
85
+ /* Dimension table + bar chart */
86
+ {
87
+ const head = document.getElementById("dimHead");
88
+ head.innerHTML = "<th>Dimension</th>" + DATA.models.map(m =>
89
+ `<th><span class="legend-dot" style="background:${MODEL_COLOR[m]}"></span>${m}</th>`).join("");
90
+ const body = document.getElementById("dimBody");
91
+ for (const d of DATA.per_dim) {
92
+ const tr = document.createElement("tr");
93
+ tr.innerHTML = `<td>${d.dim_label}</td>` +
94
+ DATA.models.map(m => `<td>${fmt(d.scores[m] || [])}</td>`).join("");
95
+ body.appendChild(tr);
96
+ }
97
+
98
+ const labels = DATA.per_dim.map(d => d.dim_label);
99
+ const datasets = DATA.models.map(m => ({
100
+ label: m,
101
+ data: DATA.per_dim.map(d => mean(d.scores[m] || [])),
102
+ backgroundColor: MODEL_COLOR[m] + "cc",
103
+ borderColor: MODEL_COLOR[m], borderWidth: 1,
104
+ }));
105
+ new Chart(document.getElementById("dimChart"), {
106
+ type: "bar",
107
+ data: { labels, datasets },
108
+ options: {
109
+ responsive: true, scales: {
110
+ y: { min: 0, max: 5, ticks: { color: "#8b91a8" }, grid: { color: "#2a2f42" } },
111
+ x: { ticks: { color: "#e6e8ef" }, grid: { display: false } },
112
+ },
113
+ plugins: { legend: { labels: { color: "#e6e8ef" } } },
114
+ },
115
+ });
116
+ }
117
+
118
+ /* Per-question table */
119
+ {
120
+ const head = document.getElementById("qHead");
121
+ head.innerHTML = "<th>Dim</th><th>Sub-question</th>" + DATA.models.map(m =>
122
+ `<th><span class="legend-dot" style="background:${MODEL_COLOR[m]}"></span>${m}</th>`).join("");
123
+ const body = document.getElementById("qBody");
124
+ for (const q of DATA.per_question) {
125
+ const tr = document.createElement("tr");
126
+ tr.innerHTML = `<td>${q.dim_label}</td><td>${q.q_label}</td>` +
127
+ DATA.models.map(m => `<td>${fmt(q.scores[m] || [])}</td>`).join("");
128
+ body.appendChild(tr);
129
+ }
130
+ }
131
+
132
+ /* One mini bar chart per sub-question */
133
+ {
134
+ const wrap = document.getElementById("qCharts");
135
+ for (const q of DATA.per_question) {
136
+ const total = DATA.models.reduce((n, m) => n + (q.scores[m] || []).length, 0);
137
+ const block = document.createElement("div");
138
+ block.className = "q-block";
139
+ block.innerHTML = `<div class="q-title">${q.q_label}</div>
140
+ <div class="q-dim">${q.dim_label}</div>`;
141
+ if (!total) {
142
+ const e = document.createElement("div");
143
+ e.className = "empty"; e.textContent = "(no ratings yet)";
144
+ block.appendChild(e); wrap.appendChild(block); continue;
145
+ }
146
+ const c = document.createElement("canvas");
147
+ block.appendChild(c); wrap.appendChild(block);
148
+ const datasets = DATA.models.map(m => ({
149
+ label: m,
150
+ data: [mean(q.scores[m] || [])],
151
+ backgroundColor: MODEL_COLOR[m] + "cc",
152
+ borderColor: MODEL_COLOR[m], borderWidth: 1,
153
+ }));
154
+ new Chart(c, {
155
+ type: "bar",
156
+ data: { labels: [q.q_label], datasets },
157
+ options: {
158
+ indexAxis: "y", responsive: true,
159
+ scales: {
160
+ x: { min: 0, max: 5, ticks: { color: "#8b91a8" }, grid: { color: "#2a2f42" } },
161
+ y: { ticks: { display: false }, grid: { display: false } },
162
+ },
163
+ plugins: { legend: { labels: { color: "#e6e8ef" } } },
164
+ },
165
+ });
166
+ }
167
+ }
168
+ </script>
169
+ </body></html>