fix: resolve history chart data misalignment and missing providers
Build and Push Docker Image / build-and-push (push) Canceled after 0s

This commit is contained in:
Jannik committed 2026-09-05 00:58:30 +02:00
1 parent e4b0dffb51
commit 85fb13b7c5
1 file changed
+41 -38
+41 -38
View File
@@ -209,11 +209,42 @@ async function fetchHistory() {
const response = await fetch('/api/history');
const history = await response.json();
const labels = [...new Set(history.map(item => new Date(item.timestamp).toLocaleTimeString()))].sort();
// Group by 5-minute intervals to align points from the same fetch batch
const snapshots = {};
history.forEach(item => {
const time = new Date(item.timestamp);
const coeff = 1000 * 60 * 5;
const roundedTime = new Date(Math.round(time.getTime() / coeff) * coeff);
const timeKey = roundedTime.getTime();
if (!snapshots[timeKey]) {
snapshots[timeKey] = {
label: roundedTime.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}),
data: {}
};
}
snapshots[timeKey].data[item.provider] = item.percentage;
});
const sortedKeys = Object.keys(snapshots).sort((a, b) => a - b);
const labels = sortedKeys.map(k => snapshots[k].label);
const antigravityData = history.filter(item => item.provider === 'Antigravity').map(item => item.percentage);
const poeData = history.filter(item => item.provider === 'POE').map(item => item.percentage);
const minimaxData = history.filter(item => item.provider === 'MiniMax').map(item => item.percentage);
const datasetsConfig = [
{ label: 'AG Gemini (5h)', provider: 'AG Gemini (5h)', color: '#58a6ff' },
{ label: 'AG Claude (5h)', provider: 'AG Claude (5h)', color: '#8957e5' },
{ label: 'POE', provider: 'POE', color: '#3fb950' },
{ label: 'MiniMax (5h)', provider: 'MiniMax (5h)', color: '#d29922' }
];
const datasets = datasetsConfig.map(config => ({
label: config.label,
data: sortedKeys.length ? sortedKeys.map(k => snapshots[k].data[config.provider] || 0) : [0, 0, 0, 0],
borderColor: config.color,
backgroundColor: config.color + '1a', // will be overridden by theme
borderWidth: 2,
tension: 0.3,
fill: true
}));
const ctx = document.getElementById('historyChart').getContext('2d');
@@ -221,35 +252,7 @@ async function fetchHistory() {
type: 'line',
data: {
labels: labels.length ? labels : ['10:00', '11:00', '12:00', '13:00'],
datasets: [
{
label: 'Antigravity (%)',
data: antigravityData.length ? antigravityData : [10, 30, 50, 68],
borderColor: '#58a6ff',
backgroundColor: 'rgba(88, 166, 255, 0.1)',
borderWidth: 2,
tension: 0.3,
fill: true
},
{
label: 'POE (%)',
data: poeData.length ? poeData : [5, 10, 20, 45],
borderColor: '#3fb950',
backgroundColor: 'rgba(63, 185, 80, 0.1)',
borderWidth: 2,
tension: 0.3,
fill: true
},
{
label: 'MiniMax (%)',
data: minimaxData.length ? minimaxData : [0, 0, 30, 60],
borderColor: '#d29922',
backgroundColor: 'rgba(210, 153, 34, 0.1)',
borderWidth: 2,
tension: 0.3,
fill: true
}
]
datasets: datasets
},
options: {
responsive: true,
@@ -284,20 +287,20 @@ async function fetchHistory() {
function updateChartTheme(themeClass) {
if (!historyChart) return;
let colors = ['#58a6ff', '#3fb950', '#d29922']; // Default
let colors = ['#58a6ff', '#8957e5', '#3fb950', '#d29922']; // Default
switch (themeClass) {
case 'style-pacman':
colors = ['#f1c40f', '#f39c12', '#e67e22'];
colors = ['#f1c40f', '#f39c12', '#e67e22', '#d35400'];
break;
case 'style-nyancat':
colors = ['#ff0000', '#33ff00', '#0099ff'];
colors = ['#ff0000', '#ff9900', '#33ff00', '#0099ff'];
break;
case 'style-matrix':
colors = ['#0f0', '#0a0', '#050'];
colors = ['#0f0', '#0c0', '#0a0', '#050'];
break;
case 'style-lava':
colors = ['#ff4e00', '#ec9f05', '#bf3a00'];
colors = ['#ff4e00', '#ff7a00', '#ec9f05', '#bf3a00'];
break;
}