From 411e959f8c60a9390f5f7664552d7dd60a4473c2 Mon Sep 17 00:00:00 2001 From: spacexbt Date: Sun, 29 Dec 2024 13:01:09 +0100 Subject: [PATCH] Add enhanced Bitcoin price tracker with additional features --- index.html | 48 +++++++++++++++ styles.css | 118 +++++++++++++++++++++++++++++++++++++ tracker.js | 169 ++++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 313 insertions(+), 22 deletions(-) create mode 100644 index.html create mode 100644 styles.css diff --git a/index.html b/index.html new file mode 100644 index 0000000..7e012d0 --- /dev/null +++ b/index.html @@ -0,0 +1,48 @@ + + + + + + Bitcoin Price Tracker + + + + +
+

Bitcoin Price Tracker

+
+
Loading...
+
+
+
+ +
+
+ + - +
+
+ + - +
+
+ + - +
+
+ +
+ +
+ +
+

Price Alerts

+
+ + +
+
+
+ + + \ No newline at end of file diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..4a3a59c --- /dev/null +++ b/styles.css @@ -0,0 +1,118 @@ +body { + font-family: Arial, sans-serif; + margin: 0; + padding: 20px; + background-color: #f0f2f5; +} + +.container { + max-width: 800px; + margin: 0 auto; + background-color: white; + padding: 20px; + border-radius: 10px; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); +} + +h1 { + text-align: center; + color: #333; + margin-bottom: 30px; +} + +.price-container { + text-align: center; + margin-bottom: 20px; +} + +#price { + font-size: 48px; + font-weight: bold; + color: #f7931a; +} + +#price-change { + font-size: 18px; + margin-top: 5px; +} + +#timestamp { + text-align: center; + color: #666; + font-size: 14px; + margin-bottom: 20px; +} + +.stats-container { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 20px; + margin-bottom: 30px; + padding: 20px; + background-color: #f8f9fa; + border-radius: 8px; +} + +.stat { + text-align: center; +} + +.stat label { + display: block; + color: #666; + margin-bottom: 5px; +} + +.stat span { + font-size: 20px; + font-weight: bold; + color: #333; +} + +.chart-container { + margin-bottom: 30px; + padding: 20px; + background-color: white; + border-radius: 8px; + box-shadow: 0 1px 3px rgba(0,0,0,0.1); + height: 300px; +} + +.settings { + padding: 20px; + background-color: #f8f9fa; + border-radius: 8px; +} + +.alert-settings { + display: flex; + gap: 10px; +} + +input { + padding: 8px; + border: 1px solid #ddd; + border-radius: 4px; + flex: 1; +} + +button { + padding: 8px 16px; + background-color: #f7931a; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; +} + +button:hover { + background-color: #e88a0c; +} + +.price-up { + color: #28a745; +} + +.price-down { + color: #dc3545; +} \ No newline at end of file diff --git a/tracker.js b/tracker.js index c3c5e00..d0c5b79 100644 --- a/tracker.js +++ b/tracker.js @@ -1,22 +1,147 @@ -// Bitcoin Price Tracker - -const fetchBitcoinPrice = async () => { - try { - const response = await fetch('https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd'); - const data = await response.json(); - const price = data.bitcoin.usd; - - // Update the UI - document.getElementById('price').textContent = `$${price.toLocaleString()}`; - document.getElementById('timestamp').textContent = new Date().toLocaleString(); - } catch (error) { - console.error('Error fetching Bitcoin price:', error); - document.getElementById('price').textContent = 'Error fetching price'; - } -}; - -// Fetch initial price -fetchBitcoinPrice(); - -// Update price every 2 minutes -setInterval(fetchBitcoinPrice, 120000); \ No newline at end of file +class BitcoinPriceTracker { + constructor() { + this.priceHistory = []; + this.maxHistoryPoints = 24; + this.chart = null; + this.alertPrice = null; + this.initializeChart(); + this.loadStoredData(); + this.startTracking(); + } + + loadStoredData() { + const stored = localStorage.getItem('btcPriceHistory'); + if (stored) { + this.priceHistory = JSON.parse(stored); + this.updateChart(); + this.updateStats(); + } + } + + saveData() { + localStorage.setItem('btcPriceHistory', JSON.stringify(this.priceHistory)); + } + + initializeChart() { + const ctx = document.getElementById('priceChart').getContext('2d'); + this.chart = new Chart(ctx, { + type: 'line', + data: { + labels: [], + datasets: [{ + label: 'Bitcoin Price (USD)', + data: [], + borderColor: '#f7931a', + borderWidth: 2, + fill: false, + tension: 0.1 + }] + }, + options: { + responsive: true, + maintainAspectRatio: false, + scales: { + y: { + beginAtZero: false + } + } + } + }); + } + + async fetchPrice() { + try { + const response = await fetch('https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd'); + const data = await response.json(); + return data.bitcoin.usd; + } catch (error) { + console.error('Error fetching Bitcoin price:', error); + throw error; + } + } + + updateChart() { + const labels = this.priceHistory.map(item => + new Date(item.timestamp).toLocaleTimeString() + ); + const prices = this.priceHistory.map(item => item.price); + + this.chart.data.labels = labels; + this.chart.data.datasets[0].data = prices; + this.chart.update(); + } + + updateStats() { + if (this.priceHistory.length > 0) { + const prices = this.priceHistory.map(item => item.price); + const lastPrice = prices[prices.length - 1]; + const prevPrice = prices.length > 1 ? prices[prices.length - 2] : lastPrice; + + // Update price and change + document.getElementById('price').textContent = `$${lastPrice.toLocaleString()}`; + + // Calculate 24h stats + const highPrice = Math.max(...prices); + const lowPrice = Math.min(...prices); + const dayChange = ((lastPrice - prices[0]) / prices[0] * 100).toFixed(2); + + // Update UI + document.getElementById('high-price').textContent = `$${highPrice.toLocaleString()}`; + document.getElementById('low-price').textContent = `$${lowPrice.toLocaleString()}`; + document.getElementById('day-change').textContent = `${dayChange}%`; + + // Add color coding + document.getElementById('day-change').className = dayChange >= 0 ? 'price-up' : 'price-down'; + } + } + + setAlert() { + const input = document.getElementById('alertPrice'); + const price = parseFloat(input.value); + if (!isNaN(price) && price > 0) { + this.alertPrice = price; + alert(`Alert set for $${price.toLocaleString()}`); + input.value = ''; + } + } + + checkAlert(price) { + if (this.alertPrice !== null) { + if ((this.alertPrice > price && this.priceHistory[this.priceHistory.length - 2]?.price < this.alertPrice) || + (this.alertPrice < price && this.priceHistory[this.priceHistory.length - 2]?.price > this.alertPrice)) { + alert(`Bitcoin price has crossed $${this.alertPrice.toLocaleString()}!\nCurrent price: $${price.toLocaleString()}`); + this.alertPrice = null; + } + } + } + + async startTracking() { + try { + const price = await this.fetchPrice(); + + this.priceHistory.push({ + price, + timestamp: new Date().toISOString() + }); + + // Keep only last maxHistoryPoints + if (this.priceHistory.length > this.maxHistoryPoints) { + this.priceHistory.shift(); + } + + this.updateChart(); + this.updateStats(); + this.saveData(); + this.checkAlert(price); + + } catch (error) { + document.getElementById('price').textContent = 'Error fetching price'; + } + + // Update every 2 minutes + setTimeout(() => this.startTracking(), 120000); + } +} + +// Initialize tracker +const tracker = new BitcoinPriceTracker(); \ No newline at end of file