improve charts
This commit is contained in:
@@ -4,6 +4,7 @@ const state = {
|
||||
tz: "local",
|
||||
rangeStart: null,
|
||||
rangeEnd: null,
|
||||
singleChartId: null,
|
||||
charts: {},
|
||||
timer: null,
|
||||
};
|
||||
@@ -141,6 +142,80 @@ function computeRange(range, tz) {
|
||||
return { start, end, axisStart, axisEnd };
|
||||
}
|
||||
|
||||
function readStateFromURL() {
|
||||
const url = new URL(window.location.href);
|
||||
const range = url.searchParams.get("range");
|
||||
const tz = url.searchParams.get("tz");
|
||||
if (range) {
|
||||
state.range = range;
|
||||
}
|
||||
if (tz === "utc" || tz === "local") {
|
||||
state.tz = tz;
|
||||
}
|
||||
state.bucket = state.range === "6h" ? "1m" : "5m";
|
||||
|
||||
const chartParam = url.searchParams.get("chart");
|
||||
const chartMatch = url.pathname.match(/^\/chart\/([^/]+)/);
|
||||
if (chartMatch && chartMatch[1]) {
|
||||
state.singleChartId = chartMatch[1];
|
||||
} else if (chartParam) {
|
||||
state.singleChartId = chartParam;
|
||||
}
|
||||
}
|
||||
|
||||
function syncControls() {
|
||||
const rangeButtons = document.querySelectorAll(".btn[data-range]");
|
||||
rangeButtons.forEach((btn) => {
|
||||
btn.classList.toggle("active", btn.dataset.range === state.range);
|
||||
});
|
||||
const tzButtons = document.querySelectorAll(".btn[data-tz]");
|
||||
tzButtons.forEach((btn) => {
|
||||
btn.classList.toggle("active", btn.dataset.tz === state.tz);
|
||||
});
|
||||
}
|
||||
|
||||
function updateSingleChartMode() {
|
||||
const cards = document.querySelectorAll(".chart-card");
|
||||
if (!state.singleChartId) {
|
||||
document.body.classList.remove("single-chart");
|
||||
cards.forEach((card) => card.classList.remove("active"));
|
||||
return;
|
||||
}
|
||||
|
||||
document.body.classList.add("single-chart");
|
||||
cards.forEach((card) => {
|
||||
const id = card.dataset.chart;
|
||||
card.classList.toggle("active", id === state.singleChartId);
|
||||
});
|
||||
}
|
||||
|
||||
function buildChartURL(chartId) {
|
||||
const url = new URL(window.location.origin + "/chart/" + chartId);
|
||||
url.searchParams.set("range", state.range);
|
||||
url.searchParams.set("tz", state.tz);
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
function setupShareLinks() {
|
||||
const buttons = document.querySelectorAll(".chart-link");
|
||||
buttons.forEach((btn) => {
|
||||
btn.addEventListener("click", async () => {
|
||||
const chartId = btn.dataset.chart;
|
||||
if (!chartId) return;
|
||||
const url = buildChartURL(chartId);
|
||||
try {
|
||||
await navigator.clipboard.writeText(url);
|
||||
btn.textContent = "Copied";
|
||||
setTimeout(() => {
|
||||
btn.textContent = "Share";
|
||||
}, 1200);
|
||||
} catch (err) {
|
||||
window.prompt("Copy chart URL:", url);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function minMax(values) {
|
||||
let min = null;
|
||||
let max = null;
|
||||
@@ -399,6 +474,8 @@ function renderDashboard(data) {
|
||||
options: baseOptions(range),
|
||||
};
|
||||
upsertChart("chart-precip", precipChart);
|
||||
|
||||
updateSingleChartMode();
|
||||
}
|
||||
|
||||
function buildCommentary(latest, forecast) {
|
||||
@@ -486,6 +563,7 @@ function setupControls() {
|
||||
btn.classList.add("active");
|
||||
state.range = btn.dataset.range;
|
||||
state.bucket = state.range === "6h" ? "1m" : "5m";
|
||||
updateURLParams();
|
||||
loadAndRender();
|
||||
});
|
||||
});
|
||||
@@ -496,13 +574,25 @@ function setupControls() {
|
||||
tzButtons.forEach((b) => b.classList.remove("active"));
|
||||
btn.classList.add("active");
|
||||
state.tz = btn.dataset.tz;
|
||||
updateURLParams();
|
||||
loadAndRender();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function updateURLParams() {
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.set("range", state.range);
|
||||
url.searchParams.set("tz", state.tz);
|
||||
history.replaceState({}, "", url);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
readStateFromURL();
|
||||
syncControls();
|
||||
setupControls();
|
||||
setupShareLinks();
|
||||
updateSingleChartMode();
|
||||
loadAndRender();
|
||||
if (state.timer) clearInterval(state.timer);
|
||||
state.timer = setInterval(loadAndRender, 60 * 1000);
|
||||
|
||||
Reference in New Issue
Block a user