ceneka-bot-battle/templates/index.html
2024-10-03 15:46:12 +02:00

128 lines
4.2 KiB
HTML

{% extends "header.html" %} {% block content %}
<div class="card m-5">
<div class="card-content is-size-2 has-text-centered">
Zeus Leaderboard - CeneBotBattle
</div>
</div>
<div class="columns m-5 is-gapless">
<div class="column">
<div class="card ">
<div class="card-content" style="height: 1000px">
<canvas id="le_graph" width="300" height="150" style="height: 100%;width:100%"></canvas>
</div>
</div>
</div>
<div class="column ml-5 is-one-third">
<div class="card">
<div class="card-content">
<table class="table is-fullwidth is-size-4">
<thead>
<tr>
<th>Position</th>
<th>Name</th>
<th>Elo</th>
<th>Username</th>
</tr>
</thead>
<tbody id="leaderboard-body">
{% for row in data %}
<tr>
<td>{{ row['global_position'] }}</td>
<td>{{ row['name'] }}</td>
<td>{{ row['elo'] }}</td>
<td>{{ row['username'] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
<script>
async function fetchLeaderboardData() {
try {
const response = await fetch("/leaderboard");
if (!response.ok) return;
const data = await response.json();
const tableBody = document.getElementById("leaderboard-body");
tableBody.innerHTML = "";
data.forEach((row) => {
const tr = document.createElement("tr");
tr.innerHTML = `
<td>${row.global_position}</td>
<td>${row.name}</td>
<td>${row.elo}</td>
<td><span class="tag is-large" style="background-color: ${row.color_ring}">${row.username}</span></td>
`;
tableBody.appendChild(tr);
});
} catch (error) {
console.error("Failed to fetch leaderboard data:", error);
}
}
function getX(width, margin, min_game, max_game, game) {
return ((game - min_game) / (max_game - min_game) * (width - margin * 2)) + margin
}
function getY(height, margin, min_elo, max_elo, elo) {
return (height - ((elo - min_elo) / (max_elo - min_elo) * (height - margin * 2))) - margin
}
async function draw_graph() {
let canvas = document.getElementById('le_graph')
let ctx = canvas.getContext("2d")
try {
let res = await fetch("/graph")
let graph_data = await res.json()
let bots = graph_data.bots
resizeToParent(canvas)
const width = canvas.width
const height = canvas.height
const margin = 20
for (const [_, bot] of Object.entries(bots)) {
ctx.lineWidth = 4
ctx.strokeStyle = bot.color_ring
ctx.beginPath()
ctx.moveTo(getX(width, margin, 0, graph_data.game, bot.x[0]), getY(height, margin, graph_data.min_elo, graph_data.max_elo, bot.y[0]))
for (let i = 1; i < bot.x.length; i++) {
ctx.lineTo(getX(width, margin, 0, graph_data.game, bot.x[i]), getY(height, margin, graph_data.min_elo, graph_data.max_elo, bot.y[i]))
}
ctx.stroke()
}
} catch (err) {
console.log("Failed to fetch graph data:", err)
}
}
function resizeToParent(canvas) {
/* https://stackoverflow.com/questions/70128894/how-to-force-a-canvas-size-to-real-size-of-a-window-in-pixels-disregarding-the */
canvas.width = canvas.clientWidth * window.devicePixelRatio;
canvas.height = canvas.clientHeight * window.devicePixelRatio;
}
// Poll the server every 60 seconds
setInterval(fetchLeaderboardData, 60_000);
setInterval(draw_graph, 60_000);
// Initial load
fetchLeaderboardData();
draw_graph();
</script>
{% endblock %}