window.onload = async (e) => { const res = await (await fetch("https://www.nporadio2.nl/api/charts/npo-radio-2-top-2000-van-2025-12-25", {})).json(); window.ranking = res.positions; const offset = +window.location.search.slice(1); window.offset = offset; const now = Date.now() - offset * 1000; const curr = window.ranking.find(it => it.broadcastUnixTime < now); var current = curr.position.current; update(curr) setInterval(() => { const now = Date.now() - offset * 1000; const curr = window.ranking.find(it => it.broadcastUnixTime < now); if (curr.position.current != current) { current = curr.position.current; update(curr); } }, 1000); }; function update(curr) { console.log("Updating"); document.querySelector("#song-image").src = curr.track.coverUrl; const diff = document.querySelector("#song-diff"); diff.innerText = curr.position.label; diff.classList = curr.position.type; document.querySelector("#title").innerText = curr.track.title; document.querySelector("#artist").innerText = curr.track.artist; document.querySelector("#position").innerText = `Nummer ${curr.position.current}`; getGraph(curr.track.artist, curr.track.title); queue(curr.position.current); getTrivia(curr) } async function getGraph(artist, title) { const res = await (await fetch(`/graph/${artist.replace("?", "")}/${title}`, {})).json(); const width = 500; const labelSpace = 50; const barWidth = (width - labelSpace) / res.length; const height = 500; const cv = document.querySelector("#graph"); const ctx = cv.getContext('2d'); ctx.clearRect(0, 0, width, height); for (let i = 0; i <= 2000; i += 200) { const fraction = (i / 2000) * height; ctx.beginPath(); ctx.strokeStyle = "#808080"; ctx.lineWidth = 1; ctx.moveTo(labelSpace, fraction); ctx.lineTo(width, fraction); ctx.stroke(); ctx.font = "20px sans-serif"; ctx.fillStyle = "#808080"; ctx.fillText(i.toString(), 0, fraction); } for (let i = 0; i < res.length; i++) { const position = res[i].position; const fraction = (position / 2000) * height; // ctx.fillRect(barWidth * i, 0, barWidth, position / 10) ctx.beginPath(); ctx.fillStyle = "white"; ctx.arc(labelSpace + barWidth * i + 10, fraction, 2.5, 0, 2*Math.PI); ctx.fill(); } for (let i = 0; i < res.length-1; i++) { const curr = res[i].position; const next = res[i+1].position; const currFraction = (curr / 2000) * height; const nextFraction = (next / 2000) * height; // ctx.fillRect(barWidth * i, 0, barWidth, position / 10) ctx.beginPath(); ctx.strokeStyle = "white"; ctx.lineWidth = 5; ctx.lineCap = "round"; ctx.moveTo(labelSpace + barWidth * i + 10, currFraction); ctx.lineTo(labelSpace + barWidth * (i+1) + 10, nextFraction); ctx.stroke(); } } function queue(currPos) { const upcoming = window.ranking.filter(it => currPos - it.position.current < 10 && currPos - it.position.current >= -1) const queueEl = document.querySelector('#queue') queueEl.innerHTML = ""; for (const song of upcoming.reverse()) { const broadcastDT = new Date(song.broadcastUnixTime - offset * 1000); queueEl.innerHTML += `

${song.track.title}

${song.track.artist}

${broadcastDT.getHours().toString().padStart(2, "0")}:${broadcastDT.getMinutes().toString().padStart(2, "0")}

` } } async function getTrivia(curr) { const res = await (await fetch(`/trivia/${curr.track.artist.replace("?", "")}`, {})).json(); document.querySelector("#trivia-songcount").innerText = `${curr.track.artist} staat ${res.length} keer in de lijst.`; const artistsSongs = res.map(function (it) { return { position: window.ranking.find(rank => rank.track.title == it.title)?.position?.current, title: it.title } }).filter(it => it.position != undefined).sort((a,b) => a.position - b.position) if (artistsSongs[0].position == curr.position.current) { document.querySelector("#trivia-first").innerText = `Dit is het hoogste nummer van ${curr.track.artist} in de lijst.`; } else { document.querySelector("#trivia-first").innerText = `Het hoogste nummer van ${curr.track.artist} is ${artistsSongs[0].title}.`; } if (artistsSongs.at(-1).position == curr.position.current) { document.querySelector("#trivia-last").innerText = `Dit is het laagste nummer van ${curr.track.artist} in de lijst.`; } else { document.querySelector("#trivia-last").innerText = `Het laagste nummer van ${curr.track.artist} is ${artistsSongs.at(-1).title}.`; } }