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

从Firebase实时数据库读取数值数组,Plotly绘图失败求助

解决Plotly绘制Firebase实时数据库数值的问题

我一眼就瞅出问题所在了——你的analogval()函数里藏着异步操作的坑!Firebase的on('value')是异步回调,也就是说函数会直接返回,等数据从Firebase拉回来后才会执行回调里的代码。你直接调用analogval()的时候,根本拿不到返回的数值,Plotly当然画不出东西。而且你把on('value')放在定时函数里,还会重复创建监听,容易导致数据重复触发,反而添乱。

给你两种解决方案,看你需求选:


方案一:定时拉取数据(适合固定间隔更新的场景)

把数据获取改成单次请求,用async/await处理异步,确保拿到数据再传给Plotly:

<script src="plotly.min.js"></script>
</head>
<body>
<script src="https://www.gstatic.com/firebasejs/7.2.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.2.0/firebase-analytics.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.2.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.2.1/firebase-database.js"></script>
<div class="navbar"><span>Analog Plotter by remidosol</span></div>
<div class="wrapper">
<div id="chart"></div>
<script src="FireConfig.js"></script>
<script>
// 先初始化一个空的折线图
Plotly.plot('chart', [{ y: [], type: 'line' }]);
var cnt = 0;

// 封装数据获取逻辑,返回Promise便于异步处理
function getAnalogData() {
  return databaseiot.orderByChild("analog").once('value')
    .then(dataSnapshot => {
      let arru = dataSnapshot.val().analog;
      // 处理数据成有效数字
      arru = arru.toString().replace(/\\r/g,'').slice(1, 4);
      return Number(arru);
    });
}

// 定时拉取数据并更新图表
setInterval(async () => {
  try {
    const value = await getAnalogData();
    console.log('当前数值:', value);
    // 给图表添加新数据点
    Plotly.extendTraces('chart', { y: [[value]] }, [0]);
    cnt++;
    // 超过300个点后,只显示最近300个
    if (cnt > 300) {
      Plotly.relayout('chart', { xaxis: { range: [cnt - 300, cnt] } });
    }
  } catch (err) {
    console.error('获取数据失败:', err);
  }
}, 15); // 这里15ms间隔太密,建议改成100ms以上,避免性能问题
</script>
</div>
</body>

方案二:实时监听数据变化(适合数据主动推送的场景)

如果Firebase的数据是实时更新的,直接监听变化就行,不用定时拉取:

<script src="plotly.min.js"></script>
</head>
<body>
<script src="https://www.gstatic.com/firebasejs/7.2.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.2.0/firebase-analytics.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.2.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.2.1/firebase-database.js"></script>
<div class="navbar"><span>Analog Plotter by remidosol</span></div>
<div class="wrapper">
<div id="chart"></div>
<script src="FireConfig.js"></script>
<script>
// 初始化空图表
Plotly.plot('chart', [{ y: [], type: 'line' }]);
var cnt = 0;

// 实时监听Firebase节点变化,数据更新就自动绘图
databaseiot.orderByChild("analog").on('value', dataSnapshot => {
  let arru = dataSnapshot.val().analog;
  arru = arru.toString().replace(/\\r/g,'').slice(1, 4);
  const value = Number(arru);
  console.log('实时更新数值:', value);
  
  Plotly.extendTraces('chart', { y: [[value]] }, [0]);
  cnt++;
  if (cnt > 300) {
    Plotly.relayout('chart', { xaxis: { range: [cnt - 300, cnt] } });
  }
});
</script>
</div>
</body>

额外提醒:

  1. 确认databaseiot是正确指向你Firebase里的目标节点,别写错路径了。
  2. 检查控制台打印的value是不是有效数字,如果是NaN,说明数据处理逻辑还要调整。
  3. 15ms的更新间隔真的太频繁了,浏览器和Firebase都可能扛不住,建议改成100ms以上,根据你的实际需求调整。

内容的提问来源于stack exchange,提问作者İbrahim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:25:48