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

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) […] }

问题分析与解决方案

核心问题

  1. 循环逻辑错误:原动态代码中,for循环仅将所有货币名称存入allCurrency数组,之后在循环体外创建data对象时,i已经是循环结束后的最后一个索引,因此仅能获取最后一个货币名称,且datasets数组仅初始化了一个对象,自然只生成单个数据集。
  2. 图表更新硬编码:更新图表时硬编码了数据集索引,无法适配动态生成的数据集数量。

修正后的动态代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 05:12:17