class MiningDashboard { constructor() { this.statsHistory = { timestamps: [], hashrates: [], totalHashes: [], blocksFound: [] }; this.setupEventListeners(); this.setupCharts(); this.startAutoRefresh(); } setupEventListeners() { document.getElementById('startMining').addEventListener('click', () => this.startMining()); document.getElementById('stopMining').addEventListener('click', () => this.stopMining()); } setupCharts() { // Initialize empty charts this.hashrateChart = Plotly.newPlot('hashrateChart', [{ x: [], y: [], type: 'scatter', mode: 'lines+markers', name: 'Hashrate', line: { color: '#2ecc71' } }], { title: 'Mining Hashrate (KH/s)', template: 'plotly_dark', paper_bgcolor: '#2d2d2d', plot_bgcolor: '#2d2d2d', xaxis: { title: 'Time' }, yaxis: { title: 'Hashrate (KH/s)' } }); this.totalHashesChart = Plotly.newPlot('totalHashesChart', [{ x: [], y: [], type: 'scatter', mode: 'lines', name: 'Total Hashes', line: { color: '#3498db' } }], { title: 'Total Hashes', template: 'plotly_dark', paper_bgcolor: '#2d2d2d', plot_bgcolor: '#2d2d2d', xaxis: { title: 'Time' }, yaxis: { title: 'Total Hashes' } }); } async startMining() { try { const response = await fetch('/start_mining', { method: 'POST' }); const data = await response.json(); this.updateStatus(data.message); } catch (error) { console.error('Error starting mining:', error); this.updateStatus('Error starting mining'); } } async stopMining() { try { const response = await fetch('/stop_mining', { method: 'POST' }); const data = await response.json(); this.updateStatus(data.message); } catch (error) { console.error('Error stopping mining:', error); this.updateStatus('Error stopping mining'); } } async updateStats() { try { const response = await fetch('/get_stats'); const stats = await response.json(); // Update stats display document.getElementById('status').textContent = stats.status; document.getElementById('hashrate').textContent = stats.hashrate; document.getElementById('totalHashes').textContent = stats.total_hashes; document.getElementById('blocksFound').textContent = stats.blocks_found; document.getElementById('bestHash').textContent = stats.best_hash; document.getElementById('difficulty').textContent = stats.difficulty; // Update block alert const alertBox = document.getElementById('blockAlert'); alertBox.textContent = stats.block_alert; alertBox.className = 'alert-box' + (stats.blocks_found > 0 ? ' success' : ''); // Update charts if (stats.status === 'Running') { this.updateCharts(stats); } } catch (error) { console.error('Error updating stats:', error); } } updateCharts(stats) { const currentTime = new Date().toLocaleTimeString(); // Update history this.statsHistory.timestamps.push(currentTime); this.statsHistory.hashrates.push(parseFloat(stats.hashrate)); this.statsHistory.totalHashes.push(parseInt(stats.total_hashes.replace(/,/g, ''))); // Keep only last 100 points if (this.statsHistory.timestamps.length > 100) { this.statsHistory.timestamps.shift(); this.statsHistory.hashrates.shift(); this.statsHistory.totalHashes.shift(); } // Update plots Plotly.update('hashrateChart', { x: [this.statsHistory.timestamps], y: [this.statsHistory.hashrates] }); Plotly.update('totalHashesChart', { x: [this.statsHistory.timestamps], y: [this.statsHistory.totalHashes] }); } startAutoRefresh() { setInterval(() => this.updateStats(), 1000); } updateStatus(message) { document.getElementById('status').textContent = message; } } // Initialize dashboard when page loads document.addEventListener('DOMContentLoaded', () => { window.dashboard = new MiningDashboard(); });