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

求助:JavaScript无法将employeeBookedMonths推入Chart.js的dataArray

问题说明

我不是JavaScript开发者,之前在Stack Overflow的帮助下实现了Chart.js图表功能。后来把数据结构从2表调整为3表(包含一对多、多对一关系),现在接近完成,但需要解决如何将employeeBookedMonths正确推入data数组的问题——目前代码只会取员工在同一个项目下的第一条数据,而实际上一个员工可能在同一个项目里有多个employeeBookedMonths条目,需要把这些数值累加后再放入图表数据中。

数据结构 listEmployees

var listEmployees = [
{"id":1,"name":"Bill Turner","contractedFrom":"2022-09-01","contractedTo":"2022-10-30",
"employeeProjects":[
{"id":14,"project":{"id":7,"projectNumber":12345,"name":"Project 7","startDate":"2020-01-01","endDate":"2022-12-31","projectLengthInMonths":30.0,"currentBookedMonths":28.0,"remainingBookedMonths":2.0,"numberOfEmployees":5},"employeeBookedMonths":7.7},
{"id":2,"project":{"id":6,"projectNumber":66666,"name":"Project 6","startDate":"2020-10-01","endDate":"2021-12-31","projectLengthInMonths":35.0,"currentBookedMonths":60.0,"remainingBookedMonths":6.0,"numberOfEmployees":6},"employeeBookedMonths":6.0},
{"id":7,"project":{"id":7,"projectNumber":12345,"name":"Project 7","startDate":"2020-01-01","endDate":"2022-12-31","projectLengthInMonths":30.0,"currentBookedMonths":28.0,"remainingBookedMonths":2.0,"numberOfEmployees":5},"employeeBookedMonths":8.0},
{"id":5,"project":{"id":9,"projectNumber":56789,"name":"Project 9","startDate":"2020-10-01","endDate":"2021-12-31","projectLengthInMonths":35.0,"currentBookedMonths":30.0,"remainingBookedMonths":5.0,"numberOfEmployees":3},"employeeBookedMonths":8.0},
{"id":15,"project":{"id":8,"projectNumber":54321,"name":"Project 8","startDate":"2020-05-01","endDate":"2022-06-31","projectLengthInMonths":40.0,"currentBookedMonths":32.0,"remainingBookedMonths":8.0,"numberOfEmployees":4},"employeeBookedMonths":8.8}]},

{"id":2,"name":"Kate Miller","contractedFrom":"2022-01-01","contractedTo":"2022-05-30",
"employeeProjects":[
{"id":3,"project":{"id":4,"projectNumber":44444,"name":"Project 4","startDate":"2020-01-01","endDate":"2022-12-31","projectLengthInMonths":30.0,"currentBookedMonths":40.0,"remainingBookedMonths":4.0,"numberOfEmployees":4},"employeeBookedMonths":14.0},
{"id":6,"project":{"id":7,"projectNumber":12345,"name":"Project 7","startDate":"2020-01-01","endDate":"2022-12-31","projectLengthInMonths":30.0,"currentBookedMonths":28.0,"remainingBookedMonths":2.0,"numberOfEmployees":5},"employeeBookedMonths":5.0},
{"id":8,"project":{"id":9,"projectNumber":56789,"name":"Project 9","startDate":"2020-10-01","endDate":"2021-12-31","projectLengthInMonths":35.0,"currentBookedMonths":30.0,"remainingBookedMonths":5.0,"numberOfEmployees":3},"employeeBookedMonths":5.0},
{"id":13,"project":{"id":8,"projectNumber":54321,"name":"Project 8","startDate":"2020-05-01","endDate":"2022-06-31","projectLengthInMonths":40.0,"currentBookedMonths":32.0,"remainingBookedMonths":8.0,"numberOfEmployees":4},"employeeBookedMonths":6.6}]},

{"id":3,"name":"John Smith","contractedFrom":"2022-06-01","contractedTo":"2022-12-30","employeeProjects":[
{"id":12,"project":{"id":1,"projectNumber":12345,"name":"Project 1","startDate":"2020-01-01","endDate":"2022-12-31","projectLengthInMonths":30.0,"currentBookedMonths":28.0,"remainingBookedMonths":2.0,"numberOfEmployees":5},"employeeBookedMonths":2.5}]}];

当前Chart.js代码

const labels = listEmployees.reduce(function(result, item) {
  result.push(item.name);
  return result;
}, []);

const randomColorGenerator = function () {
  return '#' + (Math.random().toString(16) + '0000000').slice(2, 8);
};

const projects = listEmployees.reduce(function(result, item) {
  item.employeeProjects.forEach(function(prj){
    const prjId = prj.project.id;
    if (!result[prjId]) {
      result[prjId] = {
        label: prj.project.name,
        data: [],
        backgroundColor: randomColorGenerator()
      };
    }
  });
  return result;
}, {});

listEmployees.forEach(function(item) {
  for (const prjId of Object.keys(projects)) {
    const prj = projects[prjId];
    const empPrj = item.employeeProjects.filter(el => el.project.id === prjId);
    if (empPrj.length) {
      prj.data.push(empPrj[0].employeeBookedMonths);
    } else {
      prj.data.push(0);
    }
  }
});


const ctx = document.getElementById("myChart");
const myChart = new Chart(ctx, {
  type: 'bar',
  data: {
    labels: labels,
    datasets: Object.values(projects)
  },
  options: {
    scales: {
      x: {
        stacked: true
      },
      y: {
        stacked: true
      }
    }
  }
});

解决方案

问题出在遍历员工项目时,只取了匹配项目的第一条数据。需要把同一个员工在同一个项目下的所有employeeBookedMonths数值相加,再推入数据数组。

修改listEmployees.forEach这段代码:

listEmployees.forEach(function(item) {
  // 先统计当前员工每个项目的总预订月份
  const empProjectTotals = item.employeeProjects.reduce((totals, empPrj) => {
    const prjId = empPrj.project.id.toString(); // 转为字符串和projects的key匹配
    totals[prjId] = (totals[prjId] || 0) + empPrj.employeeBookedMonths;
    return totals;
  }, {});

  for (const prjId of Object.keys(projects)) {
    const prj = projects[prjId];
    // 取统计后的总和,没有则为0
    prj.data.push(empProjectTotals[prjId] || 0);
  }
});

这样修改后,每个员工在同一个项目下的多条employeeBookedMonths会被累加,比如Bill Turner在Project7的7.7+8.0=15.7会被正确计入图表数据。

内容的提问来源于stack exchange,提问作者Kayd Anderson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 04:05:40