Improve dashboard rendering stability and increase DB pool size

This commit is contained in:
BTC Bot
2026-02-12 08:39:54 +01:00
parent f9559d1116
commit 38f0a21f56
3 changed files with 84 additions and 21 deletions

View File

@ -4,6 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BTC Trading Dashboard</title>
<link rel="icon" href="data:,">
<script src="https://unpkg.com/lightweight-charts@4.1.0/dist/lightweight-charts.standalone.production.js"></script>
<style>
:root {
@ -492,11 +493,29 @@
this.loadInitialData();
this.loadTA();
setInterval(() => this.loadNewData(), 15000);
// Refresh every 10 seconds for new data
setInterval(() => {
this.loadNewData();
// Occasionally refresh TA
if (new Date().getSeconds() < 15) this.loadTA();
}, 10000);
}
isAtRightEdge() {
const timeScale = this.chart.timeScale();
const visibleRange = timeScale.getVisibleLogicalRange();
if (!visibleRange) return true;
const data = this.candleSeries.data();
if (!data || data.length === 0) return true;
// If the right-most visible bar is within 5 bars of the last data point
return visibleRange.to >= data.length - 5;
}
createTimeframeButtons() {
const container = document.getElementById('timeframeContainer');
container.innerHTML = ''; // Clear existing
this.intervals.forEach(interval => {
const btn = document.createElement('button');
btn.className = 'timeframe-btn';
@ -527,10 +546,17 @@
},
rightPriceScale: {
borderColor: '#2a2e39',
autoScale: true,
},
timeScale: {
borderColor: '#2a2e39',
timeVisible: true,
secondsVisible: false,
rightOffset: 12,
barSpacing: 10,
},
handleScroll: {
vertTouchDrag: false,
},
});
@ -551,6 +577,18 @@
height: chartContainer.clientHeight,
});
});
// Handle tab visibility and focus
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
this.loadNewData();
this.loadTA();
}
});
window.addEventListener('focus', () => {
this.loadNewData();
this.loadTA();
});
}
initEventListeners() {
@ -570,11 +608,11 @@
}
async loadInitialData() {
await this.loadData(500, true);
await this.loadData(1000, true);
this.hasInitialLoad = true;
}
async loadData(limit = 500, fitToContent = false) {
async loadData(limit = 1000, fitToContent = false) {
if (this.isLoading) return;
this.isLoading = true;
@ -616,13 +654,21 @@
}
async loadNewData() {
if (!this.hasInitialLoad) return;
if (!this.hasInitialLoad || this.isLoading) return;
try {
const response = await fetch(`/api/v1/candles?symbol=BTC&interval=${this.currentInterval}&limit=100`);
const response = await fetch(`/api/v1/candles?symbol=BTC&interval=${this.currentInterval}&limit=50`);
const data = await response.json();
if (data.candles && data.candles.length > 0) {
const atEdge = this.isAtRightEdge();
// Get current data from series to find the last timestamp
const currentSeriesData = this.candleSeries.data();
const lastTimestamp = currentSeriesData.length > 0
? currentSeriesData[currentSeriesData.length - 1].time
: 0;
const chartData = data.candles.reverse().map(c => ({
time: Math.floor(new Date(c.time).getTime() / 1000),
open: parseFloat(c.open),
@ -631,13 +677,24 @@
close: parseFloat(c.close)
}));
// Only update with data that is newer than or equal to the last candle
// update() handles equal timestamps by updating the existing bar
chartData.forEach(candle => {
if (candle.time >= lastTimestamp) {
this.candleSeries.update(candle);
}
});
// Update cache
const existingData = this.allData.get(this.currentInterval) || [];
const mergedData = this.mergeData(existingData, chartData);
this.allData.set(this.currentInterval, mergedData);
this.allData.set(this.currentInterval, this.mergeData(existingData, chartData));
this.candleSeries.setData(mergedData);
// If we were at the edge, scroll to show the new candle
if (atEdge) {
this.chart.timeScale().scrollToRealTime();
}
const latest = mergedData[mergedData.length - 1];
const latest = chartData[chartData.length - 1];
this.updateStats(latest);
}
} catch (error) {