Files
lynchmark/tests/9_stream_visualizer/outputs/minimax_minimax-m2.js
2025-12-02 15:05:25 +00:00

55 lines
1.4 KiB
JavaScript

export async function createStreamVisualizer(stream, opts = {}) {
const {
maxPoints = 1000,
alpha = 0.2,
width = 800,
height = 300,
yDomain = [-1, 1]
} = opts;
if (alpha <= 0 || alpha >= 1 || !Number.isFinite(alpha))
throw new Error('alpha must be in (0,1)');
if (!Array.isArray(yDomain) || yDomain.length !== 2 || !yDomain.every(Number.isFinite))
throw new Error('yDomain must be a [min, max] pair of numbers');
const d3 = await import('https://cdn.jsdelivr.net/npm/d3@7/+esm');
const buf = [];
let prevEma = undefined;
for await (const p of stream) {
if (!p || !('timestamp' in p) || !('value' in p)) continue;
const v = Number(p.value);
if (!Number.isFinite(v)) continue;
if (prevEma === undefined) prevEma = v;
else prevEma = alpha * v + (1 - alpha) * prevEma;
buf.push({ timestamp: p.timestamp, value: v, ema: prevEma });
if (buf.length > maxPoints) buf.shift();
}
const data = buf;
let path = '';
if (data.length) {
const xs = d3.scaleLinear()
.domain([data[0].timestamp, data[data.length - 1].timestamp])
.range([0, width]);
const ys = d3.scaleLinear()
.domain(yDomain)
.range([height, 0]);
const line = d3.line()
.x(d => xs(d.timestamp))
.y(d => ys(d.ema));
path = line(data) || '';
}
return { data, path };
}
export default createStreamVisualizer;
// Generation time: 14.769s
// Result: PASS