如何通过JSON更新Chart.js环形图表?API数据更新图表失败求助
问题:Chart.js环形图点击按钮后无法更新数据
问题现状
点击按钮能正常从API获取数据并更新页面上的.indexProduced文本,但环形图始终显示初始值,无法同步更新。
问题原因
- 图表初始化时使用的是页面加载时的初始空值生成的数据源(此时
.indexProduced为空,转换后是0) - 更新页面文本后,没有修改Chart实例的数据源,也没有触发图表重绘——Chart.js不会自动监听DOM内容变化,必须手动更新数据并调用重绘方法。
解决方法
修改getProduced函数,在更新页面文本后,直接操作Chart实例的数据源并触发更新:
const getDataFromSheet = async () => { try { const res = await axios.get('https://sheetdb.io/api/v1/pr969olea08op') return res.data; } catch (e) { console.log('error', e) } } const produced = document.querySelector('.indexProduced'); const indexButton = document.querySelector('.indexButton'); // 提前声明Chart实例变量,让全局可访问 let myChart; const getProduced = async () => { const PRO = await getDataFromSheet(); const newVal = Number(PRO[0].Val); // 更新页面文本 produced.innerText = newVal; // 直接修改图表数据源 myChart.data.datasets[0].data[0] = newVal; // 触发图表重绘 myChart.update(); } indexButton.addEventListener('click', getProduced); // 初始化图表,修复backgroundColor语法错误(原代码少了闭合括号) const chart1 = document.getElementById("doughnutChart"); myChart = new Chart(chart1, { type: 'doughnut', data: { labels: ["발전량", "총 소모량"], datasets: [ { label: "발전량/총 소모량", backgroundColor: ["rgb(58, 149, 231)", "rgba(58, 149, 231, 0.2)"], data: [0, 720] // 初始默认值 } ] }, });
关键修改点:
- 将
myChart改为全局可访问的变量(用let声明) - 在
getProduced中直接修改myChart.data.datasets[0].data的对应值 - 调用
myChart.update()触发图表重绘 - 修复了
backgroundColor的语法错误(原代码第二个rgba值缺少闭合括号) - 初始化时用明确的默认值
[0, 720]代替依赖DOM的indexData
更优实现方案
跳过DOM中转,直接用API数据更新图表
不需要通过页面文本传递数据,直接用API返回的值更新图表,减少不必要的DOM操作:const getProduced = async () => { const PRO = await getDataFromSheet(); const newVal = Number(PRO[0].Val); // 同时更新页面文本和图表 produced.innerText = newVal; myChart.data.datasets[0].data[0] = newVal; myChart.update(); }添加加载状态,防止重复点击
const getProduced = async () => { // 点击后禁用按钮,显示加载状态 indexButton.disabled = true; indexButton.innerText = "加载中..."; try { const PRO = await getDataFromSheet(); const newVal = Number(PRO[0].Val); produced.innerText = newVal; myChart.data.datasets[0].data[0] = newVal; myChart.update(); } catch (e) { console.log('error', e); } finally { // 恢复按钮状态 indexButton.disabled = false; indexButton.innerText = "Click ME"; } }可选:等待首次数据加载后再初始化图表
如果不想显示初始的0值,可以在页面加载时先获取数据,再创建图表:// 页面加载时自动获取数据并初始化图表 const initChart = async () => { const PRO = await getDataFromSheet(); const initialVal = Number(PRO[0].Val); produced.innerText = initialVal; const chart1 = document.getElementById("doughnutChart"); myChart = new Chart(chart1, { type: 'doughnut', data: { labels: ["발전량", "총 소모량"], datasets: [ { label: "발전량/총 소모량", backgroundColor: ["rgb(58, 149, 231)", "rgba(58, 149, 231, 0.2)"], data: [initialVal, 720] } ] }, }); } // 执行初始化 initChart(); indexButton.addEventListener('click', getProduced);
内容的提问来源于stack exchange,提问作者KevinK
相关产品推荐
相关产品推荐

