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

Chart.js结合Ajax传数组时柱状图无法显示数据的解决方法

问题现象

使用Chart.js开发柱状图时,手动填写labels与data字段的静态值图表可正常运行,但传入Ajax动态拉取的数组变量时,图表始终为空白状态,无法正常展示数据。
问题截图

问题根因

核心问题有两个:

  • 异步请求时序错误:Ajax默认是异步执行逻辑,发起3个接口请求后,代码不会等待接口返回、数组填充完成就直接初始化Chart实例。此时categoryName、usedBudgetTmonth、usedBudgetLmonth三个数组均为空数组,Chart拿到空数据自然渲染空白。后续接口返回数据后往数组push内容时,Chart不会自动监听数组变化触发重渲染。
  • 数据匹配逻辑错误:原有嵌套循环的逻辑会在遍历预算数据时,无论是否匹配当前分类都执行push操作,最终生成的数据数组长度和labels长度不匹配,即使时序正确也会出现数据错位、渲染异常的问题。
修复方案

等所有接口数据全部返回后,统一做数据对齐处理,再初始化图表即可,修正后的完整代码如下:

const ctxOne = document.querySelector('#myChartOne');

// 封装接口请求为Promise
const getCategoryList = () => {
  return new Promise(resolve => {
    $.ajax({
      url: "../controllers/getCategoryNames.php",
      method: "GET",
      success: data => resolve(JSON.parse(data))
    })
  })
}

const getThisMonthBudget = () => {
  return new Promise(resolve => {
    $.ajax({
      url: "../controllers/budgetUsedTmonth.php",
      method: "GET",
      success: data => resolve(JSON.parse(data))
    })
  })
}

const getLastMonthBudget = () => {
  return new Promise(resolve => {
    $.ajax({
      url: "../controllers/budgetUsedLmonth.php",
      method: "GET",
      success: data => resolve(JSON.parse(data))
    })
  })
}

// 等待所有接口返回后再处理数据、初始化图表
Promise.all([getCategoryList(), getThisMonthBudget(), getLastMonthBudget()]).then(results => {
  const [categoryData, thisMonthData, lastMonthData] = results;
  // 提取分类标签
  const labels = categoryData.map(item => item.category_name);
  // 按分类对齐生成本月预算占比数据
  const thisMonthPct = labels.map(cateName => {
    const matchItem = thisMonthData.find(item => item.category_name === cateName);
    return matchItem ? matchItem.pct : 0;
  });
  // 按分类对齐生成上月预算占比数据
  const lastMonthPct = labels.map(cateName => {
    const matchItem = lastMonthData.find(item => item.category_name === cateName);
    return matchItem ? matchItem.pct : 0;
  });

  // 初始化图表
  new Chart(ctxOne, {
    type: 'bar',
    data: {
      labels: labels,
      datasets: [
        {
          label: 'This Month',
          data: thisMonthPct,
          backgroundColor: 'rgba(255, 99, 132, 0.2)',
          borderColor: 'rgba(255, 99, 132, 1)',
          borderWidth: 1
        },
        {
          label: 'Last Month',
          data: lastMonthPct,
          backgroundColor: 'rgba(54, 162, 235, 0.2)',
          borderColor: 'rgba(54, 162, 235, 1)',
          borderWidth: 1
        }
      ]
    }
  });
})
补充说明

如果业务场景需要先初始化空图表,后续再动态填充数据,不要直接给原数组push内容,需要拿到新数据后替换图表实例的data属性,再调用update()方法手动触发重渲染:

// 假设已经提前初始化了myChartOne实例
myChartOne.data.labels = newLabels;
myChartOne.data.datasets[0].data = newThisMonthData;
myChartOne.data.datasets[1].data = newLastMonthData;
// 触发重渲染
myChartOne.update();

内容的提问来源于stack exchange,提问作者ibtissam elhammoumy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 20:48:15