使用Chart.js与Firebase实时数据库时图表仅在窗口调整/切换后显示的问题求助
解决Chart.js图表仅在窗口调整后显示的问题
你遇到的问题确实和异步操作的执行顺序有关,这是新手接触JavaScript异步逻辑时很容易踩的坑,我来帮你理清楚并解决:
问题根源
你的代码里,Firebase的db1.once('value')是异步操作——它会在后台请求数据,主线程不会等待它完成,而是直接继续执行后面创建Chart的代码。这就导致:
- 当
new Chart(ctx, config)执行时,rent_data还是空数组,图表虽然被创建了,但没有数据所以无法显示 - 当你调整窗口或切换应用时,Chart.js会自动触发重绘逻辑,这时候异步请求已经完成,
rent_data有了真实数据,图表就正常显示出来了
解决方案
把图表的初始化(或者数据更新逻辑)放到Firebase数据获取完成的回调里,确保只有当数据加载完毕后,Chart才能拿到有效的数据。
修改后的完整代码如下:
var rent_data = []; auth.onAuthStateChanged(function(user) { if (user != null) { const db1 = ...; // 你的数据库引用 db1.once('value').then(function (snapshot) { snapshot.forEach(function(childSnaphot){ rent_data.push(childSnaphot.val()) }); // 数据加载完成后,再初始化图表 var ctx = document.getElementById('chart'); var labelms = ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']; var config = { type: 'line', data: { labels: labelms, datasets: [{ label: '# of Votes', data: rent_data, backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ], borderColor: [ 'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderWidth: 1 }] } }; var chart2 = new Chart(ctx, config); }); } });
补充方案(提前初始化图表)
如果你想提前创建图表(比如显示加载状态),也可以先初始化空图表,然后在数据加载完成后更新数据并调用update():
var chart2; auth.onAuthStateChanged(function(user) { if (user != null) { // 先初始化空图表 var ctx = document.getElementById('chart'); var labelms = ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']; var config = { type: 'line', data: { labels: labelms, datasets: [{ label: '# of Votes', data: [], // 初始空数据 backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ], borderColor: [ 'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderWidth: 1 }] } }; chart2 = new Chart(ctx, config); // 然后获取数据并更新图表 const db1 = ...; db1.once('value').then(function (snapshot) { var rent_data = []; snapshot.forEach(function(childSnaphot){ rent_data.push(childSnaphot.val()) }); // 更新图表数据 chart2.data.datasets[0].data = rent_data; chart2.update(); // 这里调用update就会生效了 }); } });
两种方案的核心逻辑一致:确保图表的创建或数据更新操作,发生在异步数据加载完成之后。
内容的提问来源于stack exchange,提问作者Mauricio S
相关产品推荐
相关产品推荐

