fixing chart timescales

This commit is contained in:
Alpha Nerd 2025-11-20 09:53:28 +01:00
parent e0c6861f2f
commit 0d187e91b9

View file

@ -229,7 +229,7 @@
}
.chart-container {
position: relative;
height: 300px;
height: 600px;
margin-top: 1rem;
}
.pie-chart-container {
@ -387,64 +387,59 @@ document.addEventListener('DOMContentLoaded', () => {
/* ---------- Global renderTimeSeriesChart ---------- */
function renderTimeSeriesChart(timeSeriesData, chart, minutes) {
console.log('renderTimeSeriesChart called with minutes:', minutes, 'data length:', timeSeriesData?.length);
// Safety check
if (!timeSeriesData || !Array.isArray(timeSeriesData)) {
console.warn('No valid time series data provided');
chart.data.labels = [];
chart.data.datasets[0].data = [];
chart.data.datasets[1].data = [];
chart.update();
return;
}
// Filter data based on selected timeframe (use UTC for consistency)
const now = Date.now();
const cutoffTime = now - (minutes * 60 * 1000);
// Group data by hour for better visualization
const groupedData = {};
timeSeriesData.forEach(item => {
// Database stores UTC timestamps, multiply by 1000 to get milliseconds
const timestampMs = item.timestamp * 1000;
if (timestampMs >= cutoffTime) {
// Convert UTC timestamp to local time for display
const date = new Date(timestampMs);
// Group by hour and minute in local time
const hourStr = date.toLocaleString([], {
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
if (!groupedData[hourStr]) {
groupedData[hourStr] = {
input: 0,
output: 0,
timestamp: timestampMs // Keep for sorting
};
}
groupedData[hourStr].input += item.input_tokens || 0;
groupedData[hourStr].output += item.output_tokens || 0;
}
});
// Convert to arrays for chart, sorted by timestamp
const sortedEntries = Object.entries(groupedData).sort((a, b) => a[1].timestamp - b[1].timestamp);
const labels = sortedEntries.map(([label]) => label);
const inputData = sortedEntries.map(([, data]) => data.input);
const outputData = sortedEntries.map(([, data]) => data.output);
console.log('Chart updated with', labels.length, 'data points');
// Update chart data
chart.data.labels = labels;
chart.data.datasets[0].data = inputData;
chart.data.datasets[1].data = outputData;
// Guard clause
if (!Array.isArray(timeSeriesData) || !timeSeriesData.length) {
chart.data.labels = [];
chart.data.datasets[0].data = [];
chart.data.datasets[1].data = [];
chart.update();
return;
}
/* ── 1⃣ Cutoff & bucket interval ──────────────────────────────── */
const nowMs = Date.now(); // UTC millis
const cutoffMs = nowMs - minutes * 60 * 1000; // UTC window start
const intervalMs = 60 * 60 * 1000; // 1h buckets
/* ── 2⃣ Build ordered bucket slots (UTC) ───────────────────────────── */
const slots = [];
for (let ts = cutoffMs; ts <= nowMs; ts += intervalMs) {
slots.push(ts);
}
/* ── 3⃣ Aggregate raw rows into those slots ───────────────────────────── */
const bucketMap = {}; // epoch ms → {input, output}
timeSeriesData.forEach(row => {
// If your DB already stores ms, drop the * 1000
const tsMs = row.timestamp * 1000; // <-- keep *1000 **only** if the DB stores seconds
if (tsMs < cutoffMs || tsMs > nowMs) return;
const slot = Math.floor((tsMs - cutoffMs) / intervalMs) * intervalMs + cutoffMs;
if (!bucketMap[slot]) bucketMap[slot] = { input: 0, output: 0 };
bucketMap[slot].input += row.input_tokens || 0;
bucketMap[slot].output += row.output_tokens || 0;
});
/* ── 4⃣ Build labels & data arrays (UTC labels) ──────────────────────── */
const labels = slots.map(ts => {
const d = new Date(ts); // UTC millisecond timestamp
return d.toLocaleString(undefined, { // <-- force UTC for display
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
timeZoneName: 'short'
}).replace(/UTC$/, 'UTC'); // keep the “UTC” suffix if you like
});
const inputData = slots.map(ts => (bucketMap[ts]?.input ?? 0));
const outputData = slots.map(ts => (bucketMap[ts]?.output ?? 0));
/* ── 5⃣ Push into the Chart.js instance ─────────────────────────────── */
chart.data.labels = labels;
chart.data.datasets[0].data = inputData;
chart.data.datasets[1].data = outputData;
chart.update();
}
/* ---------- Utility ---------- */
async function fetchJSON(url) {