Files

46 lines
2.4 KiB
JavaScript

(() => {
const source = document.getElementById('fitness-data');
const initial = JSON.parse(source.textContent);
let refreshing = false;
async function refresh() {
if (document.hidden || refreshing) return;
refreshing = true;
try {
const response = await fetch(source.dataset.url, {cache: 'no-store', headers: {Accept: 'application/json'}});
if (response.ok && response.headers.get('content-type')?.includes('application/json')) {
const next = await response.json();
if (JSON.stringify(next.series) !== JSON.stringify(initial.series) ||
JSON.stringify(next.runs) !== JSON.stringify(initial.runs) ||
JSON.stringify(next.zones) !== JSON.stringify(initial.zones)) window.location.reload();
}
} catch { /* Keep the current chart available while offline. */ }
finally { refreshing = false; }
}
window.addEventListener('focus', refresh);
document.addEventListener('visibilitychange', () => { if (!document.hidden) refresh(); });
window.setInterval(refresh, 300000);
const canvas = document.getElementById('fitness-chart');
if (!canvas) return;
const series = initial.series;
const keys = ['fitness', 'fatigue', 'form'];
const colors = ['#67cbb8', '#f48459', '#b8a1f0'];
const chart = new Chart(canvas, {
type: 'line',
data: {labels: [], datasets: keys.map((key, i) => ({label: key[0].toUpperCase() + key.slice(1), data: [], borderColor: colors[i], pointRadius: 0, borderWidth: 2}))},
options: {responsive: true, maintainAspectRatio: false, interaction: {mode: 'index', intersect: false}, plugins: {legend: {labels: {color: '#eeeae4'}}, tooltip: {callbacks: {afterBody(items) {
const row = visible[items[0].dataIndex];
return [row.missing ? `${row.missing} unscored run(s); known effort only` : `Daily effort: ${row.load.toFixed(1)}`, ...(row.provisional ? ['Provisional estimate'] : [])];
}}}}, scales: {x: {ticks: {maxTicksLimit: 8, color: '#9ba4a5'}, grid: {color: '#303638'}}, y: {ticks: {color: '#9ba4a5'}, grid: {color: '#303638'}}}}
});
let visible = series;
const range = document.getElementById('fitness-range');
function update() {
visible = range.value === 'all' ? series : series.slice(-Number(range.value));
chart.data.labels = visible.map(row => row.day);
keys.forEach((key, i) => {chart.data.datasets[i].data = visible.map(row => row[key]);});
chart.update();
}
range.addEventListener('change', update);
update();
})();