<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Umap | Tobias Wagner</title><link>https://wgnrto.github.io/publication_types/umap/</link><atom:link href="https://wgnrto.github.io/publication_types/umap/index.xml" rel="self" type="application/rss+xml"/><description>Umap</description><generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Tue, 02 Jun 2026 00:00:00 +0000</lastBuildDate><image><url>https://wgnrto.github.io/media/icon_hu_827450d54e8da75a.png</url><title>Umap</title><link>https://wgnrto.github.io/publication_types/umap/</link></image><item><title>What Do Your Eyes Reveal About Learning from Videos? A Dataset Demonstrating the Link Between Gaze Measures, Engagement, and Learning</title><link>https://wgnrto.github.io/publication/wagner-2026-engazement/</link><pubDate>Tue, 02 Jun 2026 00:00:00 +0000</pubDate><guid>https://wgnrto.github.io/publication/wagner-2026-engazement/</guid><description> &lt;div id="data-visualizer"&gt;&lt;/div&gt;
&lt;style&gt;
data-visualizer {
min-width: 100%;
height: 200px
}
&lt;/style&gt;
&lt;script src="https://cdn.jsdelivr.net/npm/p5@1.9.4/lib/p5.min.js"&gt;&lt;/script&gt;
&lt;script&gt;
(() =&gt; {
const host = document.getElementById('data-visualizer');
if (!host || window.__engazementSketchLoaded) {
return;
}
window.__engazementSketchLoaded = true;
const sampleUrl = '/publication/wagner-2026-engazement/processed-sample.csv';
const bounds = {
tMax: 604.1925,
};
const palette = {
valid: [54, 94, 160],
l_valid: [54, 94, 160],
r_valid: [54, 94, 160],
invalid: [150, 150, 150],
};
const sketch = (p) =&gt; {
const points = [];
let loading = true;
const clamp = (value, min, max) =&gt; Math.max(min, Math.min(max, value));
const mapValue = (value, min, max) =&gt; (value - min) / (max - min);
const hashPid = (pid) =&gt; {
const text = String(pid);
let hash = 0;
for (let i = 0; i &lt; text.length; i += 1) {
hash = ((hash &lt;&lt; 5) - hash) + text.charCodeAt(i);
hash |= 0;
}
return Math.abs(hash);
};
const getPointColor = (pid) =&gt; {
return '100, 0%, 100%';
};
const toViewportX = (value) =&gt; p.lerp(0, p.width, value);
const toViewportY = (value) =&gt; p.lerp(p.height, 0, value);
const loadData = (table) =&gt; {
points.length = 0;
const rows = table.getRows();
let previous = null;
for (const row of rows) {
const point = {
pid: row.get('pid'),
time: Number.parseFloat(row.get('time')),
status: row.get('status'),
x: Number.parseFloat(row.get('x_normalized')),
y: Number.parseFloat(row.get('y_normalized')),
};
if (!Number.isFinite(point.time) || !Number.isFinite(point.x) || !Number.isFinite(point.y)) {
continue;
}
point.prev = previous &amp;&amp; previous.pid === point.pid ? previous : null;
points.push(point);
previous = point;
}
loading = false;
};
p.preload = () =&gt; {
p.loadTable(sampleUrl, 'csv', 'header', loadData);
};
p.setup = () =&gt; {
const canvas = p.createCanvas(host.offsetWidth, 400);
canvas.parent(host);
p.colorMode(p.HSL);
};
p.draw = () =&gt; {
p.clear();
p.background(247, 244, 239, 0);
if (loading || points.length === 0) {
return;
}
const sweep = (p.frameCount * 0.0025) % 1;
const activeBand = 0.08;
p.noStroke();
for (let i = 0; i &lt; points.length; i += 1) {
const point = points[i];
const time = clamp(point.time / bounds.tMax, 0, 1);
const activation = clamp(1 - Math.abs(time - sweep) / activeBand, 0, 1);
if (activation &lt;= 0.01) {
continue;
}
const x = toViewportX(point.x);
const y = toViewportY(point.y);
const color = getPointColor(point.pid);
const pulse = 0.7 + 0.3 * p.sin((point.time * 0.06) + i * 0.015);
const alpha = 2 + activation * 10;
p.fill('hsla(' + color + ',' + alpha * 0.03 + ')');
p.circle(x, y, 3 + activation * 7 * pulse);
if (point.prev) {
const previousTime = clamp(point.prev.time / bounds.tMax, 0, 1);
const previousActivation = clamp(1 - Math.abs(previousTime - sweep) / activeBand, 0, 1);
if (previousActivation &gt; 0.01) {
const previousX = toViewportX(point.prev.x);
const previousY = toViewportY(point.prev.y);
p.stroke('hsla(' + color + ',' + alpha * 0.03 + ')');
p.strokeWeight(1.1);
p.line(previousX, previousY, x, y);
}
}
}
};
p.windowResized = () =&gt; {
p.resizeCanvas(host.offsetWidth, 400);
};
};
const loadScript = () =&gt; new Promise((resolve, reject) =&gt; {
if (window.p5) {
resolve();
return;
}
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/p5@1.9.4/lib/p5.min.js';
script.async = true;
script.onload = () =&gt; resolve();
script.onerror = reject;
document.head.appendChild(script);
});
const boot = async () =&gt; {
try {
await loadScript();
new p5(sketch);
} catch (error) {
console.error('Failed to start Engazement sketch', error);
}
};
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', boot, { once: true });
} else {
boot();
}
})();
&lt;/script&gt;</description></item></channel></rss>