46 lines
2.4 KiB
JavaScript
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();
|
|
})();
|