File size: 6,831 Bytes
312fc0e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
// Chart Page - Real-time cryptocurrency price chart
class ChartPage {
constructor() {
this.currentSymbol = 'BTC';
this.currentTimeframe = '1d';
this.chartData = null;
this.init();
}
init() {
// Parse URL parameters
const params = new URLSearchParams(window.location.search);
const urlSymbol = params.get('symbol');
if (urlSymbol) {
this.currentSymbol = urlSymbol;
}
// Setup event listeners
this.setupEventListeners();
// Load initial data
this.loadChartData();
}
setupEventListeners() {
const symbolSelect = document.getElementById('symbol-select');
const timeframeSelect = document.getElementById('timeframe-select');
const refreshBtn = document.getElementById('refresh-btn');
if (symbolSelect) {
symbolSelect.value = this.currentSymbol;
symbolSelect.addEventListener('change', (e) => {
this.currentSymbol = e.target.value;
this.loadChartData();
});
}
if (timeframeSelect) {
timeframeSelect.addEventListener('change', (e) => {
this.currentTimeframe = e.target.value;
this.loadChartData();
});
}
if (refreshBtn) {
refreshBtn.addEventListener('click', () => {
this.loadChartData();
});
}
}
async loadChartData() {
try {
const chartCanvas = document.getElementById('price-chart');
if (chartCanvas) {
chartCanvas.innerHTML = '<div class="loading">⏳ در حال بارگذاری دادهها...</div>';
}
// Fetch market data
const response = await fetch(`/api/market?limit=10`);
if (!response.ok) {
throw new Error('Failed to fetch market data');
}
const data = await response.json();
// Find current symbol data
const symbolData = data.data?.find(coin =>
coin.symbol?.toUpperCase() === this.currentSymbol ||
coin.name?.toUpperCase().includes(this.currentSymbol)
);
if (symbolData) {
this.updateChartInfo(symbolData);
this.renderChart(symbolData);
} else {
throw new Error('Symbol not found');
}
} catch (error) {
console.error('Error loading chart data:', error);
const chartCanvas = document.getElementById('price-chart');
if (chartCanvas) {
chartCanvas.innerHTML = `
<div style="text-align: center; color: #ef4444;">
❌ خطا در بارگذاری دادهها<br>
<small>${error.message}</small>
</div>
`;
}
}
}
updateChartInfo(data) {
// Update title
const title = document.getElementById('chart-title');
if (title) {
title.textContent = `نمودار ${data.name || this.currentSymbol}`;
}
// Update price info
const currentPrice = document.getElementById('current-price');
if (currentPrice && data.current_price) {
currentPrice.textContent = `$${this.formatNumber(data.current_price)}`;
}
const change24h = document.getElementById('change-24h');
if (change24h && data.price_change_percentage_24h !== undefined) {
const changeValue = data.price_change_percentage_24h;
change24h.textContent = `${changeValue > 0 ? '+' : ''}${changeValue.toFixed(2)}%`;
change24h.className = 'info-value ' + (changeValue >= 0 ? 'positive' : 'negative');
}
const volume24h = document.getElementById('volume-24h');
if (volume24h && data.total_volume) {
volume24h.textContent = `$${this.formatLargeNumber(data.total_volume)}`;
}
const high24h = document.getElementById('high-24h');
if (high24h && data.high_24h) {
high24h.textContent = `$${this.formatNumber(data.high_24h)}`;
}
const low24h = document.getElementById('low-24h');
if (low24h && data.low_24h) {
low24h.textContent = `$${this.formatNumber(data.low_24h)}`;
}
}
renderChart(data) {
const chartCanvas = document.getElementById('price-chart');
if (!chartCanvas) return;
// Create a simple visualization
const price = data.current_price || 0;
const change = data.price_change_percentage_24h || 0;
const high = data.high_24h || price * 1.1;
const low = data.low_24h || price * 0.9;
chartCanvas.innerHTML = `
<div style="width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: space-between;">
<div style="text-align: center; padding: 2rem;">
<div style="font-size: 3rem; font-weight: 700; margin-bottom: 1rem;">
${change >= 0 ? '📈' : '📉'}
</div>
<div style="font-size: 2.5rem; font-weight: 700; color: ${change >= 0 ? '#10b981' : '#ef4444'};">
$${this.formatNumber(price)}
</div>
<div style="font-size: 1.2rem; color: ${change >= 0 ? '#10b981' : '#ef4444'}; margin-top: 0.5rem;">
${change >= 0 ? '+' : ''}${change.toFixed(2)}%
</div>
</div>
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; padding: 1rem; background: rgba(0,0,0,0.2); border-radius: 10px;">
<div style="text-align: center;">
<div style="color: #94a3b8; font-size: 0.9rem;">بالاترین</div>
<div style="color: #10b981; font-size: 1.2rem; font-weight: 600;">$${this.formatNumber(high)}</div>
</div>
<div style="text-align: center;">
<div style="color: #94a3b8; font-size: 0.9rem;">میانگین</div>
<div style="color: #e2e8f0; font-size: 1.2rem; font-weight: 600;">$${this.formatNumber((high + low) / 2)}</div>
</div>
<div style="text-align: center;">
<div style="color: #94a3b8; font-size: 0.9rem;">پایینترین</div>
<div style="color: #ef4444; font-size: 1.2rem; font-weight: 600;">$${this.formatNumber(low)}</div>
</div>
</div>
<div style="text-align: center; color: #64748b; font-size: 0.9rem; padding: 1rem;">
💡 برای نمایش نمودار تکنیکال پیشرفته، از صفحه تحلیل تکنیکال استفاده کنید
</div>
</div>
`;
}
formatNumber(num) {
if (num >= 1) {
return num.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}
return num.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 8 });
}
formatLargeNumber(num) {
if (num >= 1e9) {
return (num / 1e9).toFixed(2) + 'B';
} else if (num >= 1e6) {
return (num / 1e6).toFixed(2) + 'M';
} else if (num >= 1e3) {
return (num / 1e3).toFixed(2) + 'K';
}
return num.toFixed(2);
}
}
// Initialize on page load
document.addEventListener('DOMContentLoaded', () => {
new ChartPage();
});
|