Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Gold Price Prediction System</title> | |
| <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> | |
| <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet"> | |
| <style> | |
| .gradient-bg { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| color: white; | |
| } | |
| .gold-accent { | |
| color: #FFD700; | |
| } | |
| .prediction-card { | |
| border: none; | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
| transition: transform 0.3s ease; | |
| } | |
| .prediction-card:hover { | |
| transform: translateY(-5px); | |
| } | |
| .price-up { | |
| color: #28a745; | |
| } | |
| .price-down { | |
| color: #dc3545; | |
| } | |
| .loading-spinner { | |
| display: none; | |
| } | |
| .navbar-brand { | |
| font-weight: bold; | |
| } | |
| .hero-section { | |
| background: linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)), url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 300"><defs><linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:%23FFD700;stop-opacity:0.3" /><stop offset="100%" style="stop-color:%23FFA500;stop-opacity:0.1" /></linearGradient></defs><rect width="1000" height="300" fill="url(%23grad)"/></svg>'); | |
| color: white; | |
| padding: 100px 0; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Navigation --> | |
| <nav class="navbar navbar-expand-lg navbar-dark gradient-bg"> | |
| <div class="container"> | |
| <a class="navbar-brand" href="#"> | |
| <i class="fas fa-coins gold-accent"></i> | |
| Gold Price Predictor | |
| </a> | |
| <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"> | |
| <span class="navbar-toggler-icon"></span> | |
| </button> | |
| <div class="collapse navbar-collapse" id="navbarNav"> | |
| <ul class="navbar-nav ms-auto"> | |
| <li class="nav-item"> | |
| <a class="nav-link active" href="/">Home</a> | |
| </li> | |
| <li class="nav-item"> | |
| <a class="nav-link" href="/data-analysis">Data Analysis</a> | |
| </li> | |
| </ul> | |
| </div> | |
| </div> | |
| </nav> | |
| <!-- Hero Section --> | |
| <section class="hero-section text-center"> | |
| <div class="container"> | |
| <h1 class="display-4 mb-4"> | |
| <i class="fas fa-chart-line gold-accent"></i> | |
| Prediksi Harga Emas 7 Hari Kedepan | |
| </h1> | |
| <p class="lead mb-5">Sistem prediksi harga emas menggunakan Machine Learning dengan Linear Regression</p> | |
| <button class="btn btn-warning btn-lg" onclick="predictGoldPrice()"> | |
| <i class="fas fa-magic"></i> Prediksi Sekarang | |
| </button> | |
| </div> | |
| </section> | |
| <!-- Main Content --> | |
| <div class="container my-5"> | |
| <!-- Loading Spinner --> | |
| <div class="text-center loading-spinner" id="loadingSpinner"> | |
| <div class="spinner-border text-warning" role="status" style="width: 3rem; height: 3rem;"> | |
| <span class="visually-hidden">Loading...</span> | |
| </div> | |
| <p class="mt-3">Menganalisis data dan membuat prediksi...</p> | |
| </div> | |
| <!-- Results Section --> | |
| <div id="resultsSection" style="display: none;"> | |
| <!-- Current Prices --> | |
| <div class="row mb-4"> | |
| <div class="col-md-6"> | |
| <div class="card prediction-card text-center"> | |
| <div class="card-body"> | |
| <h5 class="card-title"><i class="fas fa-clock"></i> Harga Saat Ini</h5> | |
| <div id="currentPrices"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="col-md-6"> | |
| <div class="card prediction-card text-center"> | |
| <div class="card-body"> | |
| <h5 class="card-title"><i class="fas fa-trending-up"></i> Perkiraan Perubahan Total</h5> | |
| <div id="totalChanges"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Prediction Chart --> | |
| <div class="card prediction-card mb-4"> | |
| <div class="card-header"> | |
| <h5 class="mb-0"><i class="fas fa-chart-area"></i> Grafik Prediksi Harga Emas</h5> | |
| </div> | |
| <div class="card-body text-center"> | |
| <img id="predictionChart" class="img-fluid" alt="Prediction Chart"> | |
| </div> | |
| </div> | |
| <!-- Predictions Table --> | |
| <div class="card prediction-card"> | |
| <div class="card-header"> | |
| <h5 class="mb-0"><i class="fas fa-table"></i> Prediksi Harga 7 Hari Kedepan</h5> | |
| </div> | |
| <div class="card-body"> | |
| <div class="table-responsive"> | |
| <table class="table table-striped table-hover"> | |
| <thead class="table-dark"> | |
| <tr> | |
| <th>Tanggal</th> | |
| <th>Harga Tutup (IDR)</th> | |
| <th>Perubahan Tutup (%)</th> | |
| <th>Harga Buka (IDR)</th> | |
| <th>Perubahan Buka (%)</th> | |
| </tr> | |
| </thead> | |
| <tbody id="predictionsTable"> | |
| </tbody> | |
| </table> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Error Section --> | |
| <div id="errorSection" style="display: none;"> | |
| <div class="alert alert-danger text-center" role="alert"> | |
| <i class="fas fa-exclamation-triangle"></i> | |
| <span id="errorMessage"></span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Footer --> | |
| <footer class="gradient-bg text-center py-4 mt-5"> | |
| <div class="container"> | |
| <p class="mb-0">© 2025 Kelompok 4 - Sistem Prediksi Harga Emas. Powered by Machine Learning.</p> | |
| </div> | |
| </footer> | |
| <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script> | |
| <script> | |
| function predictGoldPrice() { | |
| // Show loading spinner | |
| document.getElementById('loadingSpinner').style.display = 'block'; | |
| document.getElementById('resultsSection').style.display = 'none'; | |
| document.getElementById('errorSection').style.display = 'none'; | |
| // Make API call | |
| fetch('/predict', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| } | |
| }) | |
| .then(response => response.json()) | |
| .then(data => { | |
| document.getElementById('loadingSpinner').style.display = 'none'; | |
| if (data.success) { | |
| displayResults(data); | |
| } else { | |
| displayError(data.error || 'Unknown error occurred'); | |
| } | |
| }) | |
| .catch(error => { | |
| document.getElementById('loadingSpinner').style.display = 'none'; | |
| displayError('Network error: ' + error.message); | |
| }); | |
| } | |
| function displayResults(data) { | |
| // Display current prices | |
| const currentPricesHtml = ` | |
| <p class="mb-1"><strong>Harga Tutup:</strong> <span class="gold-accent">IDR ${data.current_prices.close.toLocaleString()}</span></p> | |
| <p class="mb-0"><strong>Harga Buka:</strong> <span class="gold-accent">IDR ${data.current_prices.open.toLocaleString()}</span></p> | |
| `; | |
| document.getElementById('currentPrices').innerHTML = currentPricesHtml; | |
| // Display total changes | |
| const totalChangesHtml = ` | |
| <p class="mb-1"><strong>Tutup:</strong> | |
| <span class="${data.total_changes.close >= 0 ? 'price-up' : 'price-down'}"> | |
| ${data.total_changes.close >= 0 ? '+' : ''}${data.total_changes.close}% | |
| <i class="fas fa-arrow-${data.total_changes.close >= 0 ? 'up' : 'down'}"></i> | |
| </span> | |
| </p> | |
| <p class="mb-0"><strong>Buka:</strong> | |
| <span class="${data.total_changes.open >= 0 ? 'price-up' : 'price-down'}"> | |
| ${data.total_changes.open >= 0 ? '+' : ''}${data.total_changes.open}% | |
| <i class="fas fa-arrow-${data.total_changes.open >= 0 ? 'up' : 'down'}"></i> | |
| </span> | |
| </p> | |
| `; | |
| document.getElementById('totalChanges').innerHTML = totalChangesHtml; | |
| // Display chart | |
| document.getElementById('predictionChart').src = 'data:image/png;base64,' + data.chart; | |
| // Display predictions table | |
| let tableHtml = ''; | |
| data.predictions.forEach(prediction => { | |
| tableHtml += ` | |
| <tr> | |
| <td><strong>${prediction.date}</strong></td> | |
| <td>IDR ${prediction.close_price.toLocaleString()}</td> | |
| <td class="${prediction.close_change >= 0 ? 'price-up' : 'price-down'}"> | |
| ${prediction.close_change >= 0 ? '+' : ''}${prediction.close_change}% | |
| <i class="fas fa-arrow-${prediction.close_change >= 0 ? 'up' : 'down'}"></i> | |
| </td> | |
| <td>IDR ${prediction.open_price.toLocaleString()}</td> | |
| <td class="${prediction.open_change >= 0 ? 'price-up' : 'price-down'}"> | |
| ${prediction.open_change >= 0 ? '+' : ''}${prediction.open_change}% | |
| <i class="fas fa-arrow-${prediction.open_change >= 0 ? 'up' : 'down'}"></i> | |
| </td> | |
| </tr> | |
| `; | |
| }); | |
| document.getElementById('predictionsTable').innerHTML = tableHtml; | |
| document.getElementById('resultsSection').style.display = 'block'; | |
| } | |
| function displayError(errorMessage) { | |
| document.getElementById('errorMessage').textContent = errorMessage; | |
| document.getElementById('errorSection').style.display = 'block'; | |
| } | |
| function formatNumber(num) { | |
| return new Intl.NumberFormat('id-ID').format(num); | |
| } | |
| </script> | |
| </body> | |
| </html> |