无需刷新页面,实现Chart.js图表数据更新需求
解决Chart.js图表无法用新数据覆盖的问题
你的问题核心是:每次点击提交按钮时会创建新的Chart实例,旧图表并未被移除,导致新图表叠在旧图表上方,看起来像是没有更新。下面提供两种直接有效的解决方式:
方法一:销毁旧实例后创建新实例
通过全局变量存储Chart实例,每次请求新数据前先销毁旧实例,再创建新图表:
"use strict"; /////////////////////////////// let input = document.getElementById("input"); const btn1 = document.getElementById("btn1"); // 全局变量存储Chart实例 let myChart; const toUSD = function (number) { return `$${number.toLocaleString()}`; }; const stockData = async function (stockTicker) { try { let cashFlowArr = []; let stockCompArr = []; // 获取股票数据 const resStock = await fetch( `https://financialmodelingprep.com/api/v3/cash-flow-statement/${stockTicker}?apikey=227839811b8142d28d844e99db7d19c0&limit=120` ); const dataStock = await resStock.json(); // 整理数据到数组 for (let i = 4; i > -1; i--) { cashFlowArr.push(dataStock[i].freeCashFlow); } for (let i = 4; i > -1; i--) { stockCompArr.push(dataStock[i].stockBasedCompensation); } // 关键:如果已有旧图表实例,先销毁 if (myChart) { myChart.destroy(); } // 创建新图表并赋值给全局变量 myChart = new Chart(document.getElementById("line-chart"), { type: "line", data: { labels: [2018, 2019, 2020, 2021, 2022], datasets: [ { data: cashFlowArr, label: "Free Cash Flow", borderColor: "#3cba9f", fill: false, }, { data: stockCompArr, label: "Stock Based Compensation", borderColor: "#e43202", fill: false, }, ], }, options: { title: { display: true, text: "FCF vs SBC", }, }, }); } catch (err) { console.error("获取数据或渲染图表出错:", err); } }; ////////////////////////// // 事件监听 btn1.addEventListener("click", function (e) { stockData(input.value); }); // 重置按钮可保留,但现在无需刷新也能更新图表 btn2.addEventListener("click", function (e) { location.reload(); });
方法二:直接更新现有实例数据(性能更优)
不需要销毁重建,直接修改已有图表的数据并调用update()方法,这种方式更高效:
"use strict"; /////////////////////////////// let input = document.getElementById("input"); const btn1 = document.getElementById("btn1"); let myChart; const toUSD = function (number) { return `$${number.toLocaleString()}`; }; const stockData = async function (stockTicker) { try { let cashFlowArr = []; let stockCompArr = []; const resStock = await fetch( `https://financialmodelingprep.com/api/v3/cash-flow-statement/${stockTicker}?apikey=227839811b8142d28d844e99db7d19c0&limit=120` ); const dataStock = await resStock.json(); // 整理数据 for (let i = 4; i > -1; i--) { cashFlowArr.push(dataStock[i].freeCashFlow); } for (let i = 4; i > -1; i--) { stockCompArr.push(dataStock[i].stockBasedCompensation); } // 判断是否已有图表实例 if (!myChart) { // 首次创建图表 myChart = new Chart(document.getElementById("line-chart"), { type: "line", data: { labels: [2018, 2019, 2020, 2021, 2022], datasets: [ { data: cashFlowArr, label: "Free Cash Flow", borderColor: "#3cba9f", fill: false, }, { data: stockCompArr, label: "Stock Based Compensation", borderColor: "#e43202", fill: false, }, ], }, options: { title: { display: true, text: "FCF vs SBC", }, }, }); } else { // 更新现有图表的数据 myChart.data.datasets[0].data = cashFlowArr; myChart.data.datasets[1].data = stockCompArr; // 可选:随股票代码更新标题 // myChart.options.title.text = `${stockTicker} - FCF vs SBC`; // 触发图表更新 myChart.update(); } } catch (err) { console.error("出错:", err); } }; ////////////////////////// // 事件监听 btn1.addEventListener("click", function (e) { stockData(input.value); }); // 回车触发提交,提升体验 input.addEventListener("keypress", function(e) { if (e.key === "Enter") { stockData(input.value); } }); btn2.addEventListener("click", function (e) { location.reload(); });
额外优化提示
- 可以在请求数据时添加加载状态,避免用户重复点击
- 处理数据为空或请求失败的场景,给用户显示直观的错误提示
内容的提问来源于stack exchange,提问作者Brenden Baio
相关产品推荐
相关产品推荐

