Fix pricechart if no price/historical data available.

This commit is contained in:
gerlofvanek
2025-10-10 12:26:36 +02:00
parent 73d486d6f0
commit eb46a4fcc5
2 changed files with 108 additions and 50 deletions

View File

@@ -12592,47 +12592,59 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
return return_data return return_data
if rate_source == "coingecko.com": if rate_source == "coingecko.com":
coin_ids: str = "" try:
for coin_id in coins_list: coin_ids: str = ""
if len(coin_ids) > 0: for coin_id in coins_list:
coin_ids += "," if len(coin_ids) > 0:
exchange_name: str = self.getExchangeName(coin_id, rate_source) coin_ids += ","
coin_ids += exchange_name exchange_name: str = self.getExchangeName(coin_id, rate_source)
exchange_name_map[exchange_name] = coin_id coin_ids += exchange_name
exchange_name_map[exchange_name] = coin_id
api_key: str = get_api_key_setting( api_key: str = get_api_key_setting(
self.settings, self.settings,
"coingecko_api_key", "coingecko_api_key",
default_coingecko_api_key, default_coingecko_api_key,
escape=True, escape=True,
)
url: str = (
f"https://api.coingecko.com/api/v3/simple/price?ids={coin_ids}&vs_currencies=usd&include_24hr_vol=true&include_24hr_change=true"
)
if api_key != "":
url += f"&api_key={api_key}"
js = json.loads(self.readURL(url, timeout=10, headers=headers))
for k, v in js.items():
coin_id = int(exchange_name_map[k])
volume_24h = v.get("usd_24h_vol")
price_change_24h = v.get("usd_24h_change")
# Convert to float if value exists, otherwise keep as None
volume_value = float(volume_24h) if volume_24h is not None else None
price_change_value = (
float(price_change_24h) if price_change_24h is not None else 0.0
) )
url: str = (
f"https://api.coingecko.com/api/v3/simple/price?ids={coin_ids}&vs_currencies=usd&include_24hr_vol=true&include_24hr_change=true"
)
if api_key != "":
url += f"&api_key={api_key}"
return_data[coin_id] = { js = json.loads(self.readURL(url, timeout=10, headers=headers))
"volume_24h": volume_value,
"price_change_24h": price_change_value, for k, v in js.items():
} coin_id = int(exchange_name_map[k])
new_values[coin_id] = { volume_24h = v.get("usd_24h_vol")
"volume_24h": volume_value, price_change_24h = v.get("usd_24h_change")
"price_change_24h": price_change_value,
} # Convert to float if value exists, otherwise keep as None
volume_value = (
float(volume_24h) if volume_24h is not None else None
)
price_change_value = (
float(price_change_24h)
if price_change_24h is not None
else 0.0
)
return_data[coin_id] = {
"volume_24h": volume_value,
"price_change_24h": price_change_value,
}
new_values[coin_id] = {
"volume_24h": volume_value,
"price_change_24h": price_change_value,
}
except Exception as e:
self.log.warning(f"Could not fetch volume data: {e}")
for coin_id in need_coins:
return_data[coin_id] = {
"volume_24h": None,
"price_change_24h": 0.0,
}
else: else:
raise ValueError(f"Unknown rate source {rate_source}") raise ValueError(f"Unknown rate source {rate_source}")
@@ -12723,18 +12735,24 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
) )
for coin_id in need_coins: for coin_id in need_coins:
exchange_name: str = self.getExchangeName(coin_id, rate_source) try:
url: str = ( exchange_name: str = self.getExchangeName(coin_id, rate_source)
f"https://api.coingecko.com/api/v3/coins/{exchange_name}/market_chart?vs_currency=usd&days={days}" url: str = (
) f"https://api.coingecko.com/api/v3/coins/{exchange_name}/market_chart?vs_currency=usd&days={days}"
if api_key != "": )
url += f"&api_key={api_key}" if api_key != "":
url += f"&api_key={api_key}"
js = json.loads(self.readURL(url, timeout=10, headers=headers)) js = json.loads(self.readURL(url, timeout=10, headers=headers))
if "prices" in js: if "prices" in js:
return_data[coin_id] = js["prices"] return_data[coin_id] = js["prices"]
new_values[coin_id] = js["prices"] new_values[coin_id] = js["prices"]
except Exception as e:
self.log.warning(
f"Could not fetch historical data for {Coins(coin_id).name}: {e}"
)
return_data[coin_id] = []
else: else:
raise ValueError(f"Unknown rate source {rate_source}") raise ValueError(f"Unknown rate source {rate_source}")

View File

@@ -866,8 +866,11 @@ destroyChart: function() {
const allData = await api.fetchHistoricalDataXHR([coinSymbol]); const allData = await api.fetchHistoricalDataXHR([coinSymbol]);
data = allData[coinSymbol]; data = allData[coinSymbol];
if (!data || Object.keys(data).length === 0) { if (!data || (Array.isArray(data) && data.length === 0) || Object.keys(data).length === 0) {
throw new Error(`No data returned for ${coinSymbol}`); console.warn(`No price data available for ${coinSymbol}`);
chartModule.hideChartLoader();
chartModule.showNoDataMessage(coinSymbol);
return;
} }
CacheManager.set(cacheKey, data, 'chart'); CacheManager.set(cacheKey, data, 'chart');
@@ -897,6 +900,8 @@ destroyChart: function() {
chartModule.initChart(); chartModule.initChart();
} }
chartModule.hideNoDataMessage();
const chartData = chartModule.prepareChartData(coinSymbol, data); const chartData = chartModule.prepareChartData(coinSymbol, data);
if (chartData.length > 0 && chartModule.chart) { if (chartData.length > 0 && chartModule.chart) {
chartModule.chart.data.datasets[0].data = chartData; chartModule.chart.data.datasets[0].data = chartData;
@@ -951,6 +956,41 @@ destroyChart: function() {
chart.classList.remove('hidden'); chart.classList.remove('hidden');
}, },
showNoDataMessage: function(coinSymbol) {
const chartCanvas = document.getElementById('coin-chart');
if (!chartCanvas) {
return;
}
if (this.chart) {
this.chart.data.datasets[0].data = [];
this.chart.update('none');
}
let messageDiv = document.getElementById('chart-no-data-message');
if (!messageDiv) {
messageDiv = document.createElement('div');
messageDiv.id = 'chart-no-data-message';
messageDiv.style.cssText = 'position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; color: #888; font-size: 14px; z-index: 10;';
chartCanvas.parentElement.style.position = 'relative';
chartCanvas.parentElement.appendChild(messageDiv);
}
messageDiv.innerHTML = `
<div style="padding: 20px; background: rgba(0,0,0,0.05); border-radius: 8px;">
<div style="font-size: 16px; margin-bottom: 8px;">No Price Data Available</div>
</div>
`;
messageDiv.classList.remove('hidden');
},
hideNoDataMessage: function() {
const messageDiv = document.getElementById('chart-no-data-message');
if (messageDiv) {
messageDiv.classList.add('hidden');
}
},
cleanup: function() { cleanup: function() {
if (this.pendingAnimationFrame) { if (this.pendingAnimationFrame) {
cancelAnimationFrame(this.pendingAnimationFrame); cancelAnimationFrame(this.pendingAnimationFrame);