Chart.js动态数据集仅获最后值?排查for循环写法问题
问题:Chart.js动态生成折线图仅显示最后一个数据集
原有静态代码可正常生成包含4个数据集的Chart.js折线图,但改造为从API返回的JSON动态生成数据集后,仅能获取并显示最后一个数据集,控制台输出也仅显示单个数据集。
静态代码
async function outlayGraph() { const ctx = document.getElementById('outlayGraph').getContext('2d'); const data = { labels: cashCreated_date, datasets: [{ label: 'ALL', borderColor: 'rgb(255, 0, 0)', data: cashAlbanianLek }, { label: 'GBP', borderColor: 'rgb(255, 0, 255)', data: cashBritishPound }, { label: 'USD', borderColor: 'rgb(0, 153, 0)', data: cashAmericanDollar }, { label: 'EUR', borderColor: 'rgb(0, 0, 255)', data: cashEuro } ] }; const config = { type: 'line', data, options: { tooltips: { mode: 'index' } } }; console.log(data); if (chart) { chart.data.labels = cashCreated_date; chart.data.datasets[0].data = cashAlbanianLek; chart.data.datasets[1].data = cashBritishPound; chart.data.datasets[2].data = cashAmericanDollar; chart.data.datasets[3].data = cashEuro; chart.update(); } else { chart = new Chart(ctx, config); } }
静态代码控制台输出
Object { labels: (12) […], datasets: (4) […] } datasets: Array(4) [ {…}, {…}, {…}, … ] 0: Object { label: "ALL", borderColor: "rgb(255, 0, 0)", data: (12) […] } 1: Object { label: "GBP", borderColor: "rgb(255, 0, 255)", data: (12) […] } 2: Object { label: "USD", borderColor: "rgb(0, 153, 0)", data: (12) […] } 3: Object { label: "EUR", borderColor: "rgb(0, 0, 255)", data: (12) […] } length: 4
动态代码(存在问题)
async function outlayGraph(label) { const context = document.getElementById('outlayGraph').getContext('2d'); let data = 0; let configuration = 0; let allCurrency = []; for (i in label) { const item = label[i]; allCurrency.push(item.name); } data = { labels: created_date, datasets: [ { label: allCurrency[i], borderColor: generateRandomColor(), data: albanianLek }, ] }; console.log(data); configuration = { type: 'line', data, options: { tooltips: { mode: 'index' } } }; if (charts) { charts.data.labels = created_date; charts.data.datasets[1].data = albanianLek; charts.data.datasets[2].data = britishPound; charts.data.datasets[3].data = americanDollar; charts.data.datasets[4].data = euro; charts.update(); console.log("update"); } else { charts = new Chart(context, configuration); console.log("create"); } }
动态代码控制台输出
Object { label: "EUR", borderColor: "#BB5889", data: (15) […] }
问题分析与解决方案
核心问题
- 循环逻辑错误:原动态代码中,
for循环仅将所有货币名称存入allCurrency数组,之后在循环体外创建data对象时,i已经是循环结束后的最后一个索引,因此仅能获取最后一个货币名称,且datasets数组仅初始化了一个对象,自然只生成单个数据集。 - 图表更新硬编码:更新图表时硬编码了数据集索引,无法适配动态生成的数据集数量。
修正后的动态代码
async function outlayGraph(label) { const context = document.getElementById('outlayGraph').getContext('2d'); // 假设你从API获取的各币种数据是一个映射,key为货币名称,value为对应数据数组 const currencyDataMap = { 'ALL': albanianLek, 'GBP': britishPound, 'USD': americanDollar, 'EUR': euro }; // 动态构建datasets数组 const datasets = label.map(item => { return { label: item.name, borderColor: generateRandomColor(), data: currencyDataMap[item.name] || [] // 匹配对应币种的数据 }; }); const data = { labels: created_date, datasets: datasets }; console.log(data); const configuration = { type: 'line', data, options: { tooltips: { mode: 'index' } } }; if (charts) { // 动态更新图表数据,无需硬编码索引 charts.data.labels = created_date; charts.data.datasets = datasets; charts.update(); console.log("update"); } else { charts = new Chart(context, configuration); console.log("create"); } }
关键修改点
- 使用
Array.map()替代for...in循环,直接遍历label数组生成完整的datasets数组,避免循环后仅能获取最后一项的问题。 - 用货币名称映射对应的数据数组,确保每个数据集能正确匹配对应的数据。
- 更新图表时直接替换整个
datasets数组,而非硬编码索引更新,适配动态数量的数据集。
内容的提问来源于stack exchange,提问作者laraCoder
相关产品推荐
相关产品推荐

