mirror of
https://github.com/multipleof4/lynchmark.git
synced 2026-03-17 11:21:00 +00:00
48 lines
1.3 KiB
JavaScript
48 lines
1.3 KiB
JavaScript
export async function createStreamVisualizer(asyncIterable, options = {}) {
|
|
const {
|
|
maxPoints = 500,
|
|
alpha = 0.2,
|
|
width = 800,
|
|
height = 300,
|
|
yDomain = [0, 1]
|
|
} = options
|
|
|
|
const d3 = await import('https://cdn.jsdelivr.net/npm/d3@7/+esm')
|
|
|
|
const cap = Math.max(1, maxPoints | 0)
|
|
const a = Math.min(1, Math.max(0, Number(alpha)))
|
|
const data = []
|
|
let prevEma
|
|
|
|
for await (const item of asyncIterable) {
|
|
const timestamp = Number(item?.timestamp)
|
|
const value = Number(item?.value)
|
|
|
|
if (!Number.isFinite(timestamp) || !Number.isFinite(value)) continue
|
|
|
|
prevEma = prevEma === undefined ? value : a * value + (1 - a) * prevEma
|
|
data.push({ timestamp, value, ema: prevEma })
|
|
|
|
if (data.length > cap) data.splice(0, data.length - cap)
|
|
}
|
|
|
|
if (!data.length) return { data, path: '' }
|
|
|
|
const first = data[0].timestamp
|
|
const last = data[data.length - 1].timestamp
|
|
const x0 = first === last ? first - 1 : first
|
|
const x1 = first === last ? last + 1 : last
|
|
|
|
const x = d3.scaleLinear().domain([x0, x1]).range([0, width])
|
|
const y = d3.scaleLinear().domain(yDomain).range([height, 0])
|
|
|
|
const path =
|
|
d3.line()
|
|
.x(d => x(d.timestamp))
|
|
.y(d => y(d.ema))(data) || ''
|
|
|
|
return { data, path }
|
|
}
|
|
export default createStreamVisualizer;
|
|
// Generation time: 4.457s
|
|
// Result: PASS
|