<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>蓝牙心率实时监控</title> <script src="/static/chart.js"></script> <style> body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #f0f2f5; margin: 0; padding: 20px; display: flex; flex-direction: column; align-items: center; } .container { background-color: white; border-radius: 10px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); padding: 20px; width: 90%; max-width: 800px; margin-bottom: 20px; } .header { text-align: center; margin-bottom: 30px; } .current-hr { text-align: center; margin-bottom: 20px; } .bpm-value { font-size: 72px; font-weight: bold; color: #e74c3c; } .bpm-label { font-size: 24px; color: #7f8c8d; } .chart-container { position: relative; height: 400px; width: 100%; } .status { text-align: center; color: #95a5a6; font-size: 14px; margin-top: 10px; } </style> </head> <body>
<div class="container"> <div class="header"> <h1>实时心率监控</h1> </div> <div class="current-hr"> <div class="bpm-value" id="currentBpm">--</div> <div class="bpm-label">BPM</div> </div> </div>
<div class="container"> <h2>历史趋势 (近1小时)</h2> <div class="chart-container"> <canvas id="hrChart"></canvas> </div> <div class="status" id="lastUpdated">等待数据...</div> </div>
<script> const ctx = document.getElementById('hrChart').getContext('2d'); let hrChart;
function initChart() { hrChart = new Chart(ctx, { type: 'line', data: { labels: [], datasets: [{ label: '心率 (BPM)', data: [], borderColor: '#e74c3c', backgroundColor: 'rgba(231, 76, 60, 0.2)', borderWidth: 2, tension: 0.4, fill: true, pointRadius: 2 }] }, options: { responsive: true, maintainAspectRatio: false, scales: { x: { type: 'category', ticks: { maxTicksLimit: 10 } }, y: { beginAtZero: false, suggestedMin: 40, suggestedMax: 200 } }, animation: false } }); }
async function fetchLatestHR() { try { const response = await fetch('/api/heart-rate/latest'); if (response.ok) { const data = await response.json(); document.getElementById('currentBpm').textContent = data.bpm; document.getElementById('lastUpdated').textContent = `最后更新: ${new Date(data.time).toLocaleString()}`; } } catch (error) { console.error('获取最新心率失败:', error); } }
async function fetchHistoryHR() { try { const response = await fetch('/api/heart-rate/history?minutes=60'); if (response.ok) { const data = await response.json(); const labels = data.map(point => { const date = new Date(point.time); return date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}); }); const values = data.map(point => point.bpm);
hrChart.data.labels = labels; hrChart.data.datasets[0].data = values; hrChart.update(); } } catch (error) { console.error('获取历史数据失败:', error); } }
document.addEventListener('DOMContentLoaded', () => { initChart(); fetchLatestHR(); fetchHistoryHR();
setInterval(fetchLatestHR, 2000); setInterval(fetchHistoryHR, 10000); }); </script> </body> </html>
|