$${train.price.toFixed(2)}
`;
trainList.appendChild(trainEl);
createSparkline(train);
});
}
function createSparkline(train) {
const ctx = document.getElementById(`sparkline-${train.id}`).getContext('2d');
new Chart(ctx, {
type: 'line',
data: {
labels: Array(30).fill(''),
datasets: [{
data: train.history,
borderColor: train.history[29] > train.history[0] ? '#ef4444' : '#22c55e',
borderWidth: 2,
pointRadius: 0,
}]
},
options: { plugins: { legend: { display: false } }, scales: { x: { display: false }, y: { display: false } } }
});
}
trainList.addEventListener('click', (e) => {
if (e.target.classList.contains('track-btn')) {
const trainId = parseInt(e.target.dataset.id);
openTrackerModal(trainId);
}
});
function openTrackerModal(trainId) {
const train = trainData.find(t => t.id === trainId);
modalContent.innerHTML = `
${train.name}
Price History & Alerts
`;
trackerModal.classList.remove('hidden');
createPriceHistoryChart(train);
document.getElementById('close-modal-btn').addEventListener('click', () => trackerModal.classList.add('hidden'));
document.getElementById('set-alert-btn').addEventListener('click', setPriceAlert);
document.getElementById('pdf-download-btn').addEventListener('click', generatePdf);
}
function createPriceHistoryChart(train) {
const ctx = document.getElementById('price-history-chart').getContext('2d');
if(priceHistoryChart) priceHistoryChart.destroy();
priceHistoryChart = new Chart(ctx, {
type: 'line',
data: {
labels: Array.from({length: 30}, (_, i) => `Day ${i + 1}`),
datasets: [{
label: 'Price ($)',
data: train.history,
borderColor: '#4f46e5',
backgroundColor: 'rgba(79, 70, 229, 0.1)',
fill: true,
tension: 0.3
}]
},
options: { responsive: true, maintainAspectRatio: false }
});
}
function setPriceAlert(e) {
const trainId = parseInt(e.target.dataset.id);
const targetPrice = parseFloat(document.getElementById('alert-price').value);
if (targetPrice > 0) {
priceAlerts[trainId] = { target: targetPrice, name: trainData.find(t=>t.id===trainId).name };
alert('Price alert set for ' + priceAlerts[trainId].name);
}
}
function simulatePriceChanges() {
trainData = trainData.map(train => {
const change = (Math.random() - 0.5) * 5;
train.price = Math.max(50, train.price + change);
train.history.shift();
train.history.push(train.price);
return train;
});
if (!resultsContainer.classList.contains('hidden')) {
displayTrains();
}
checkAlerts();
}
function checkAlerts() {
for (const id in priceAlerts) {
const train = trainData.find(t => t.id == id);
if (train && train.price <= priceAlerts[id].target) {
document.getElementById('alert-text').textContent = `Price for ${priceAlerts[id].name} dropped to $${train.price.toFixed(2)}!`;
alertNotification.classList.add('show');
delete priceAlerts[id]; // One-time alert
setTimeout(() => alertNotification.classList.remove('show'), 5000);
}
}
}
function generatePdf() {
const { jsPDF } = jspdf;
const pdf = new jsPDF();
const content = document.getElementById('pdf-content');
html2canvas(content, {scale: 2}).then(canvas => {
const imgData = canvas.toDataURL('image/png');
const { width, height } = pdf.internal.pageSize;
const imgHeight = canvas.height * width / canvas.width;
pdf.addImage(imgData, 'PNG', 0, 0, width, imgHeight);
pdf.save('train-price-report.pdf');
});
}
setInterval(simulatePriceChanges, 5000); // Simulate price changes every 5 seconds
});