Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Cryptocurrency Price Prediction</title> | |
<link rel="shortcut icon" type="image/x-icon" href="https://raw.githubusercontent.com/belajarqywok/belajarqywok.github.io/main/favicon.ico"> | |
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> | |
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0/dist/chartjs-adapter-date-fns.bundle.min.js"></script> | |
</head> | |
<body onload="predict()"> | |
<header class="bg-dark py-3 mb-4"> | |
<div class="container"> | |
<div class="row"> | |
<div class="col"> | |
<h1 class="text-white">Cryptocurrency Price Prediction</h1> | |
</div> | |
</div> | |
</div> | |
</header> | |
<div class="container"> | |
<div class="card shadow-sm"> | |
<div class="card-body"> | |
<div class="row mb-3"> | |
<div class="col-md-3"> | |
<label for="days" class="form-label">Days to Predict:</label> | |
<input type="number" id="days" name="days" class="form-control" min="1" value="7" onchange="predict()"> | |
</div> | |
<div class="col-md-3"> | |
<label for="crypto" class="form-label">Cryptocurrency:</label> | |
<select id="crypto" class="form-select" onchange="predict()"> | |
<option value="ADA-USD">ADA-USD</option> | |
</select> | |
</div> | |
<div class="col-md-3 align-self-end"> | |
<div class="spinner-border text-primary d-none" role="status" id="loadingSpinner"> | |
<span class="visually-hidden">Loading...</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="row mt-4"> | |
<div class="col"> | |
<canvas id="myChart" width="400" height="200"></canvas> | |
</div> | |
</div> | |
</div> | |
<br \> | |
<script> | |
fetch('https://qywok-cryptocurrency-prediction.hf.space/crypto/lists') | |
.then(response => response.json()) | |
.then(data => { | |
const cryptoList = data.data | |
const selectCrypto = document.getElementById('crypto') | |
selectCrypto.innerHTML = '' | |
cryptoList.forEach(crypto => { | |
const option = document.createElement('option') | |
option.value = crypto | |
option.text = crypto | |
selectCrypto.appendChild(option) | |
}) | |
}) | |
.catch(error => console.error('Error fetching crypto list:', error)) | |
</script> | |
<script> | |
let myChart | |
const predict = async () => { | |
const days = document.getElementById('days').value | |
const crypto = document.getElementById('crypto').value | |
const loadingSpinner = document.getElementById('loadingSpinner') | |
loadingSpinner.classList.remove('d-none') | |
const apiUrl = 'https://qywok-cryptocurrency-prediction.hf.space/crypto/prediction' | |
try { | |
const response = await fetch(apiUrl, { | |
method: 'POST', | |
headers: { | |
'Accept': 'application/json', | |
'Content-Type': 'application/json' | |
}, | |
body: JSON.stringify({ | |
days: days, | |
currency: crypto | |
}) | |
}) | |
if (!response.ok) throw new Error('Network response was not ok') | |
const data = await response.json() | |
updateChart(data) | |
} catch (error) { | |
console.error('Error fetching data:', error) | |
} finally { | |
loadingSpinner.classList.add('d-none') | |
} | |
} | |
</script> | |
<script> | |
const updateChart = (data) => { | |
const actualDates = data.data.predictions | |
.actuals.map(entry => new Date(entry.date)) | |
const actualPrices = data.data.predictions | |
.actuals.map(entry => entry.price) | |
const predictionDates = data.data.predictions | |
.predictions.map(entry => new Date(entry.date)) | |
const predictionPrices = data.data.predictions | |
.predictions.map(entry => entry.price) | |
const dates = [...actualDates, ...predictionDates] | |
const prices = [...actualPrices, ...predictionPrices] | |
if (myChart) { | |
myChart.data.labels = dates | |
myChart.data.datasets[0].data = actualDates.map( | |
(date, index) => ({ x: date, y: actualPrices[index] }) | |
) | |
myChart.data.datasets[1].data = predictionDates.map( | |
(date, index) => ({ x: date, y: predictionPrices[index] }) | |
) | |
myChart.update() | |
} else { | |
const ctx = document.getElementById('myChart').getContext('2d') | |
myChart = new Chart(ctx, { | |
type: 'line', | |
data: { | |
labels: dates, | |
datasets: [ | |
{ | |
label: 'Actual', | |
data: actualDates.map( | |
(date, index) => ({ x: date, y: actualPrices[index] }) | |
), | |
borderColor: 'rgba(75, 192, 192, 1)', | |
borderWidth: 1, | |
fill: false, | |
tension: 0.1 | |
}, | |
{ | |
label: 'Prediction', | |
data: predictionDates.map( | |
(date, index) => ({ x: date, y: predictionPrices[index] }) | |
), | |
borderColor: 'rgba(255, 99, 132, 1)', | |
borderWidth: 1, | |
fill: false, | |
tension: 0.1 | |
} | |
] | |
}, | |
options: { | |
scales: { | |
x: { | |
type: 'time', | |
time: { | |
unit: 'day', | |
tooltipFormat: 'yyyy-MM-dd' | |
}, | |
title: { | |
display: true, | |
text: 'Date' | |
} | |
}, | |
y: { | |
beginAtZero: false, | |
title: { | |
display: true, | |
text: 'Price (USD)' | |
} | |
} | |
} | |
} | |
}) | |
} | |
} | |
</script> | |
</body> | |
</html> | |