v0.14.18
This commit is contained in:
+86
-5
@@ -3,6 +3,7 @@
|
||||
const PUBLIC_CHART_COLORS = ['--accent', '--info', '--warning', '--purple', '--danger', '--teal', '--orange', '--blue'];
|
||||
const $ = selector => document.querySelector(selector);
|
||||
const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
||||
const PUBLIC_CHART_RANGES = [6, 24, 168, 720, 2160, 8760];
|
||||
|
||||
function basePathFromScript() {
|
||||
const src = document.currentScript?.src || '';
|
||||
@@ -41,7 +42,7 @@ function preciseTime(timestamp, locale) {
|
||||
function prepareCanvas(canvas, height = 520) {
|
||||
const wrap = canvas.parentElement;
|
||||
const width = Math.max(720, Math.floor(wrap?.clientWidth || canvas.getBoundingClientRect().width || 720));
|
||||
const actualHeight = Math.max(320, Math.floor(wrap?.clientHeight || height));
|
||||
const actualHeight = Math.max(180, Math.floor(wrap?.clientHeight || height));
|
||||
const dpr = window.devicePixelRatio || 1;
|
||||
canvas.width = Math.floor(width * dpr);
|
||||
canvas.height = Math.floor(actualHeight * dpr);
|
||||
@@ -194,12 +195,64 @@ function drawChart(canvas, payload, locale) {
|
||||
bindTooltip(canvas, series, { pad, width, height, firstTs, lastTs }, locale);
|
||||
}
|
||||
|
||||
async function loadPublicChart() {
|
||||
const token = decodeURIComponent(location.pathname.split('/').filter(Boolean).pop() || '');
|
||||
let publicChartPayload = null;
|
||||
let publicChartLocale = 'en-GB';
|
||||
let publicChartResizeFrame = 0;
|
||||
|
||||
function publicChartToken() {
|
||||
return decodeURIComponent(location.pathname.split('/').filter(Boolean).pop() || '');
|
||||
}
|
||||
|
||||
function requestedPublicChartHours() {
|
||||
const value = Number(new URLSearchParams(location.search).get('hours'));
|
||||
return Number.isInteger(value) && value >= 1 && value <= 87600 ? value : null;
|
||||
}
|
||||
|
||||
function setPublicRangeLanguage(lang) {
|
||||
const pl = lang === 'pl';
|
||||
const label = $('#publicChartRangeLabel');
|
||||
const select = $('#publicChartHours');
|
||||
if (label) label.textContent = pl ? 'Zakres' : 'Range';
|
||||
if (!select) return;
|
||||
const labels = pl
|
||||
? ['6 godzin', '24 godziny', '7 dni', '30 dni', '90 dni', '1 rok']
|
||||
: ['6 hours', '24 hours', '7 days', '30 days', '90 days', '1 year'];
|
||||
[...select.options].forEach((option, index) => { if (labels[index]) option.textContent = labels[index]; });
|
||||
select.setAttribute('aria-label', pl ? 'Zakres wykresu' : 'Chart range');
|
||||
}
|
||||
|
||||
function syncPublicRangeControl(hours) {
|
||||
const select = $('#publicChartHours');
|
||||
if (!select) return;
|
||||
const value = String(hours);
|
||||
if (![...select.options].some(option => option.value === value)) {
|
||||
const option = document.createElement('option');
|
||||
option.value = value;
|
||||
option.textContent = `${value} h`;
|
||||
select.append(option);
|
||||
}
|
||||
select.value = value;
|
||||
}
|
||||
|
||||
function publicChartApiPath(token, hours) {
|
||||
const value = Number(hours);
|
||||
const hasHours = hours !== null && hours !== undefined && Number.isInteger(value) && value >= 1 && value <= 87600;
|
||||
const query = hasHours ? `?hours=${encodeURIComponent(String(value))}` : '';
|
||||
return `/api/public/charts/custom/${encodeURIComponent(token)}${query}`;
|
||||
}
|
||||
|
||||
function redrawPublicChart() {
|
||||
if (!publicChartPayload) return;
|
||||
drawChart($('#publicCustomChart'), publicChartPayload, publicChartLocale);
|
||||
}
|
||||
|
||||
async function loadPublicChart(hours = requestedPublicChartHours()) {
|
||||
const token = publicChartToken();
|
||||
const title = $('#publicChartTitle');
|
||||
const hint = $('#publicChartHint');
|
||||
const error = $('#publicChartError');
|
||||
const canvas = $('#publicCustomChart');
|
||||
const range = $('#publicChartHours');
|
||||
|
||||
if (!token.startsWith('chart_')) {
|
||||
title.textContent = 'Custom chart';
|
||||
@@ -210,7 +263,9 @@ async function loadPublicChart() {
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await fetch(withBase(`/api/public/charts/custom/${encodeURIComponent(token)}`), { headers: { Accept: 'application/json' }, cache: 'no-store' });
|
||||
if (range) range.disabled = true;
|
||||
error.hidden = true;
|
||||
const response = await fetch(withBase(publicChartApiPath(token, hours)), { headers: { Accept: 'application/json' }, cache: 'no-store' });
|
||||
if (!response.ok) {
|
||||
let message = `${response.status}`;
|
||||
try { message = (await response.json()).error || message; } catch (_) { }
|
||||
@@ -223,14 +278,40 @@ async function loadPublicChart() {
|
||||
title.textContent = payload.title || (lang === 'pl' ? 'Wykres niestandardowy' : 'Custom chart');
|
||||
hint.textContent = payload.hint || '';
|
||||
canvas.setAttribute('aria-label', title.textContent);
|
||||
setPublicRangeLanguage(lang);
|
||||
syncPublicRangeControl(payload.hours);
|
||||
publicChartPayload = payload;
|
||||
publicChartLocale = locale;
|
||||
drawChart(canvas, payload, locale);
|
||||
window.addEventListener('resize', () => drawChart(canvas, payload, locale));
|
||||
if (range) range.disabled = false;
|
||||
}
|
||||
|
||||
$('#publicChartHours')?.addEventListener('change', async event => {
|
||||
const hours = Number(event.currentTarget.value);
|
||||
if (!Number.isInteger(hours) || hours < 1 || hours > 87600) return;
|
||||
const url = new URL(location.href);
|
||||
url.searchParams.set('hours', String(hours));
|
||||
history.replaceState(null, '', url);
|
||||
try {
|
||||
await loadPublicChart(hours);
|
||||
} catch (error) {
|
||||
const host = $('#publicChartError');
|
||||
host.hidden = false;
|
||||
host.textContent = `${document.documentElement.lang === 'pl' ? 'Nie udało się wczytać wykresu' : 'Unable to load chart'}: ${error.message}`;
|
||||
event.currentTarget.disabled = false;
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
cancelAnimationFrame(publicChartResizeFrame);
|
||||
publicChartResizeFrame = requestAnimationFrame(redrawPublicChart);
|
||||
});
|
||||
|
||||
loadPublicChart().catch(error => {
|
||||
const host = $('#publicChartError');
|
||||
host.hidden = false;
|
||||
host.textContent = `Unable to load chart: ${error.message}`;
|
||||
$('#publicChartHint').textContent = '';
|
||||
$('#publicChartHours').disabled = false;
|
||||
drawEmpty($('#publicCustomChart'), host.textContent);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user