You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

D3.js实时折线图无法显示求助:蓝牙心率监测模拟场景

我最近在开发一款适配蓝牙心率监测仪的应用,核心用D3.js实现心率数据的实时可视化。目前先搭了个简单的Demo,后续会对接真实的蓝牙硬件数据,现阶段先做了模拟数据的可视化——只展示过去一分钟内随机生成的心率数据,给你分享下我的实现思路和代码:

核心数据结构

模拟数据存在readings数组里,每条数据的格式是:

{timestamp: 生成时间(时间戳), hr: 0至1之间的数值}

初始时我会给readings填充过去一分钟的若干条随机数据,保证页面加载后就有可视化内容。

实现步骤
  • 数据维护:用定时器每隔1秒生成一条新的模拟数据,同时移除超过一分钟的旧数据,确保数组始终只保留最近60秒的数据
  • D3.js可视化:每次数据更新后,重新计算比例尺、渲染折线图,配合过渡动画让更新更流畅
核心代码示例
// 初始化readings数组:填充过去60秒的模拟数据
const readings = [];
const initialTime = Date.now();
for (let i = 0; i < 60; i++) {
  readings.push({
    timestamp: initialTime - (60 - i) * 1000,
    hr: Math.random()
  });
}

// 设置SVG画布
const width = 600;
const height = 300;
const svg = d3.select("#heart-rate-container")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

// 定义时间和数值比例尺
const xScale = d3.scaleTime()
  .range([0, width]);
const yScale = d3.scaleLinear()
  .range([height, 0])
  .domain([0, 1]); // 模拟数据范围是0-1,后续对接真实数据可改成60-180

// 定义折线生成器
const lineGenerator = d3.line()
  .x(d => xScale(d.timestamp))
  .y(d => yScale(d.hr));

// 图表更新函数
function updateHeartRateChart() {
  // 更新x轴的时间范围:最近一分钟
  const oneMinuteAgo = Date.now() - 60 * 1000;
  xScale.domain([oneMinuteAgo, Date.now()]);

  // 过滤掉超过一分钟的旧数据
  readings.splice(0, readings.findIndex(d => d.timestamp >= oneMinuteAgo));

  // 渲染/更新折线
  svg.selectAll(".hr-line")
    .data([readings])
    .join("path")
    .attr("class", "hr-line")
    .attr("d", lineGenerator)
    .attr("fill", "none")
    .attr("stroke", "#e74c3c")
    .attr("stroke-width", 2)
    .transition()
    .duration(500)
    .ease(d3.easeLinear);

  // 更新x坐标轴
  svg.selectAll(".x-axis")
    .data([null])
    .join("g")
    .attr("class", "x-axis")
    .attr("transform", `translate(0, ${height})`)
    .call(d3.axisBottom(xScale).ticks(5));
}

// 初始渲染图表
updateHeartRateChart();

// 每1秒生成新数据并更新图表
setInterval(() => {
  readings.push({
    timestamp: Date.now(),
    hr: Math.random()
  });
  updateHeartRateChart();
}, 1000);
后续优化方向
  • 对接真实蓝牙数据:把Math.random()替换成蓝牙API获取的真实心率值,同时调整yScale的domain为真实心率范围(比如60-180),让图表更有实际意义
  • 交互增强:添加鼠标hover时显示具体心率数值和时间戳的提示框
  • 样式优化:添加网格线、坐标轴标签,调整折线颜色和粗细让视觉效果更好
  • 性能优化:对于高频数据更新,可以优化D3的渲染逻辑,减少DOM操作次数

内容的提问来源于stack exchange,提问作者Guy McLean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:10:17