fix live updates

This commit is contained in:
Dobromir Popov
2025-12-10 14:39:06 +02:00
parent e200600a0a
commit 732c5b4941
6 changed files with 290 additions and 8 deletions

View File

@@ -0,0 +1 @@
[]

View File

@@ -773,9 +773,14 @@ class ChartManager {
const volumeColor = candle.close >= candle.open ? '#10b981' : '#ef4444'; const volumeColor = candle.close >= candle.open ? '#10b981' : '#ef4444';
Plotly.extendTraces(plotId, { Plotly.extendTraces(plotId, {
x: [[formattedTimestamp]], x: [[formattedTimestamp]],
y: [[candle.volume]], y: [[candle.volume]]
marker: { color: [[volumeColor]] }
}, [1]).then(() => { }, [1]).then(() => {
// Update volume color separately using restyle
const currentTrace = plotElement.data[1];
if (currentTrace && currentTrace.marker && currentTrace.marker.color) {
const newColors = [...currentTrace.marker.color, volumeColor];
Plotly.restyle(plotId, {'marker.color': [newColors]}, [1]);
}
console.log(`[${timeframe}] Volume trace extended successfully`); console.log(`[${timeframe}] Volume trace extended successfully`);
}).catch(err => { }).catch(err => {
console.error(`[${timeframe}] Error extending volume trace:`, err); console.error(`[${timeframe}] Error extending volume trace:`, err);
@@ -4393,7 +4398,6 @@ class ChartManager {
this.liveMetricsOverlay = null; this.liveMetricsOverlay = null;
} }
}
// Debug method to manually trigger pivot recalculation // Debug method to manually trigger pivot recalculation
debugRecalculatePivots(timeframe) { debugRecalculatePivots(timeframe) {
@@ -4425,3 +4429,4 @@ class ChartManager {
}); });
console.log('========================'); console.log('========================');
} }
}

125
CHART_UPDATES_FIX.md Normal file
View File

@@ -0,0 +1,125 @@
# Chart Updates Fix - JavaScript Errors Resolved
## Issues Fixed
### 1. JavaScript Syntax Error ✅
**Error**: `Uncaught SyntaxError: Unexpected token '{' (at chart_manager.js:4399:39)`
**Cause**: Debug methods were added outside the ChartManager class
**Fix**: Moved debug methods inside the class before the closing brace
```javascript
class ChartManager {
// ... existing methods
// Debug methods moved inside class
debugRecalculatePivots(timeframe) { ... }
debugPivotStatus() { ... }
} // ← Proper class closing
```
### 2. Plotly extendTraces Marker Error ✅
**Error**: `attribute marker must be an array of length equal to indices array length`
**Cause**: Incorrect marker.color format in volume trace extension
**Before (Broken):**
```javascript
Plotly.extendTraces(plotId, {
x: [[formattedTimestamp]],
y: [[candle.volume]],
marker: { color: [[volumeColor]] } // ❌ Wrong format
}, [1]);
```
**After (Fixed):**
```javascript
Plotly.extendTraces(plotId, {
x: [[formattedTimestamp]],
y: [[candle.volume]]
// ✅ No marker in extendTraces
}, [1]).then(() => {
// ✅ Update color separately with restyle
const currentTrace = plotElement.data[1];
if (currentTrace && currentTrace.marker && currentTrace.marker.color) {
const newColors = [...currentTrace.marker.color, volumeColor];
Plotly.restyle(plotId, {'marker.color': [newColors]}, [1]);
}
});
```
### 3. Empty Annotations File ✅
**Error**: `Expecting value: line 1 column 1 (char 0)`
**Cause**: Empty annotations JSON file
**Fix**: Created proper empty JSON array structure
```json
[]
```
## Root Cause Analysis
### Plotly extendTraces Limitation
The issue was that `Plotly.extendTraces()` has specific requirements for marker arrays:
- When extending traces, marker properties must match the exact structure
- For volume bars, the marker.color array must have the same length as the data being added
- The `[[volumeColor]]` format was incorrect for this use case
### Solution Approach
Instead of trying to extend traces with marker colors, the fix:
1. **Extends traces without marker data** - Adds new data points cleanly
2. **Updates colors separately** - Uses `Plotly.restyle()` to update the entire color array
3. **Maintains color consistency** - Preserves existing colors and adds new ones
## Expected Results
### Live Chart Updates Should Now:
-**Add new candles** without JavaScript errors
-**Update volume colors** correctly (green for up, red for down)
-**Maintain chart performance** with proper Plotly API usage
-**Show live data** from the unified WebSocket → DataProvider pipeline
### Console Should Show:
```
[1m] Successfully added new candle. Total candles: 152
[1m] Volume trace extended successfully
✅ Chart update fix working correctly!
```
Instead of:
```
❌ Error adding new candle: attribute marker must be an array...
```
## Files Modified
### JavaScript:
- `ANNOTATE/web/static/js/chart_manager.js` - Fixed extendTraces marker issue and syntax error
### Data:
- `ANNOTATE/data/annotations/annotations_db.json` - Created proper empty JSON structure
### Test:
- `test_chart_updates.html` - Test file to verify the fix works
## Testing
The fix can be verified by:
1. **Opening ANNOTATE dashboard** - Should load without JavaScript errors
2. **Watching live updates** - Charts should update smoothly with new candles
3. **Checking console** - No more Plotly marker errors
4. **Volume colors** - Should show green/red based on price direction
## Technical Details
### Plotly API Correct Usage:
- **extendTraces()** - For adding new data points to existing traces
- **restyle()** - For updating trace properties like colors, styles
- **relayout()** - For updating layout properties like axes, titles
### Volume Color Logic:
```javascript
const volumeColor = candle.close >= candle.open ? '#10b981' : '#ef4444';
// Green for bullish candles (close >= open)
// Red for bearish candles (close < open)
```
The chart updates should now work smoothly with live data! 🎯

91
test_chart_updates.html Normal file
View File

@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html>
<head>
<title>Chart Updates Test</title>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<div id="test-plot" style="width:100%;height:400px;"></div>
<script>
// Test the fixed chart update logic
console.log('Testing chart update fix...');
// Create initial chart with volume trace
const plotElement = document.getElementById('test-plot');
const candlestickTrace = {
x: ['2025-12-10T09:00:00Z', '2025-12-10T09:01:00Z'],
open: [3320, 3322],
high: [3325, 3324],
low: [3318, 3320],
close: [3322, 3318],
type: 'candlestick',
name: 'Price'
};
const volumeTrace = {
x: ['2025-12-10T09:00:00Z', '2025-12-10T09:01:00Z'],
y: [100, 150],
type: 'bar',
name: 'Volume',
yaxis: 'y2',
marker: {
color: ['#10b981', '#ef4444'],
opacity: 0.3
}
};
const layout = {
title: 'Chart Update Test',
xaxis: { type: 'date' },
yaxis: { title: 'Price', domain: [0.3, 1] },
yaxis2: { title: 'Volume', domain: [0, 0.25] }
};
Plotly.newPlot('test-plot', [candlestickTrace, volumeTrace], layout).then(() => {
console.log('✅ Initial chart created');
// Test extending traces (simulating live update)
setTimeout(() => {
console.log('Testing extendTraces...');
const newTimestamp = '2025-12-10T09:02:00Z';
const newCandle = { open: 3318, high: 3320, low: 3316, close: 3319, volume: 200 };
// Test candlestick extension
Plotly.extendTraces('test-plot', {
x: [[newTimestamp]],
open: [[newCandle.open]],
high: [[newCandle.high]],
low: [[newCandle.low]],
close: [[newCandle.close]]
}, [0]).then(() => {
console.log('✅ Candlestick extended successfully');
// Test volume extension (the fixed version)
return Plotly.extendTraces('test-plot', {
x: [[newTimestamp]],
y: [[newCandle.volume]]
}, [1]);
}).then(() => {
console.log('✅ Volume extended successfully');
// Update volume color separately
const currentTrace = plotElement.data[1];
if (currentTrace && currentTrace.marker && currentTrace.marker.color) {
const volumeColor = newCandle.close >= newCandle.open ? '#10b981' : '#ef4444';
const newColors = [...currentTrace.marker.color, volumeColor];
return Plotly.restyle('test-plot', {'marker.color': [newColors]}, [1]);
}
}).then(() => {
console.log('✅ Volume color updated successfully');
console.log('✅ Chart update fix working correctly!');
}).catch(err => {
console.error('❌ Chart update failed:', err);
});
}, 2000);
});
</script>
</body>
</html>

60
test_live_updates_api.py Normal file
View File

@@ -0,0 +1,60 @@
#!/usr/bin/env python3
"""
Test script to check live updates API
"""
import requests
import json
import time
from datetime import datetime
def test_live_updates():
"""Test the live-updates-batch API"""
print("Testing live-updates-batch API...")
print("-" * 50)
url = "http://localhost:8051/api/live-updates-batch"
payload = {
"symbol": "ETH/USDT",
"timeframes": ["1s", "1m"]
}
# Make 3 requests with 3 second intervals to see if data changes
for i in range(3):
try:
print(f"\n=== Request {i+1} at {datetime.now().strftime('%H:%M:%S')} ===")
response = requests.post(url, json=payload, timeout=10)
if response.status_code == 200:
data = response.json()
print(f"Success: {data.get('success')}")
print(f"Server time: {data.get('server_time')}")
if data.get('success') and data.get('chart_updates'):
for timeframe, update in data['chart_updates'].items():
candle = update.get('candle', {})
timestamp = candle.get('timestamp', 'N/A')
close_price = candle.get('close', 'N/A')
is_confirmed = update.get('is_confirmed', False)
print(f" {timeframe}: {timestamp} | Close: {close_price} | Confirmed: {is_confirmed}")
else:
print(f" Error: {data.get('error', 'Unknown error')}")
else:
print(f" HTTP Error: {response.status_code}")
print(f" Response: {response.text}")
except Exception as e:
print(f" Request failed: {e}")
if i < 2: # Don't sleep after last request
time.sleep(3)
print("\nTest completed!")
if __name__ == "__main__":
test_live_updates()