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

Node.js中使用Chart.js合并同作物总数量的图表展示问题

解决同一作物多次出现时的数量累加与合并显示问题

嘿,我来帮你搞定这个图表显示的问题!你现在遇到的核心问题是:数据库里同一作物有多条记录时,前端直接把每条记录的作物名和数量分别提取,导致图表里出现多个相同标签的柱子,而你想要的是相同作物合并为单个标签,并累加总数量。

下面提供两种可行的解决方案,你可以根据自己的场景选择:

方案一:后端SQL层面聚合(推荐)

这种方法更高效,因为让数据库直接帮你完成数据聚合,减少前端的处理逻辑和传输的数据量。只需要修改你的SQL查询语句,使用GROUP BY和SUM()函数来分组计算每个作物的总数量。

修改你的Express服务端app.js中的查询代码:

app.get('/crop', function (req, res) {
  return new Promise(function(resolve, reject){
    db.serialize(function(){
      // 修改SQL语句,分组并累加数量
      db.all('SELECT keyCrop, SUM(quantity) as totalQuantity FROM harvests GROUP BY keyCrop', function(err, rows){
        if (!err) {
          resolve(rows)
        }else{
          reject(err)
        }
      })
    })
  }).then(function(rows){
    res.json(rows);
  });
});

然后前端的脚本只需要稍微调整,把e.quantity改成e.totalQuantity即可:

$(document).ready(function(){
  $.ajax({
    url: 'http://localhost:3000/crop',
    type: 'get',
    dataType: 'json'
  }).then(function(rows){
    let labels = rows.map(function(e) {
      return e.keyCrop;
    });
    let data = rows.map(function(e) {
      // 这里改用聚合后的总数量字段
      return e.totalQuantity;
    });
    let ctx = document.getElementById('chart').getContext('2d');
    let myChart = new Chart(ctx, {
      type: 'bar',
      data: {
        labels: labels,
        datasets: [{
          label: 'What Farmers are Growing',
          data: data,
          backgroundColor: 'rgba(255, 99, 132, 0.2)',
          borderColor: 'rgba(255, 99, 132, 1)',
          borderWidth: 1
        }]
      }
    });
  });
})

方案二:前端JavaScript层面处理

如果暂时不想修改后端代码,也可以在前端拿到所有数据后,手动完成相同作物的数量累加。我们可以用一个对象来临时存储每个作物的总数量,再转换成图表需要的格式。

修改你的前端脚本如下:

$(document).ready(function(){
  $.ajax({
    url: 'http://localhost:3000/crop',
    type: 'get',
    dataType: 'json'
  }).then(function(rows){
    // 第一步:创建对象存储每个作物的总数量
    const cropTotalMap = {};
    rows.forEach(row => {
      const cropName = row.keyCrop;
      const quantity = parseInt(row.quantity); // 确保数量是数字类型
      if (cropTotalMap[cropName]) {
        // 已有该作物,累加数量
        cropTotalMap[cropName] += quantity;
      } else {
        // 首次出现该作物,初始化数量
        cropTotalMap[cropName] = quantity;
      }
    });

    // 第二步:将对象转换为图表需要的labels和data数组
    const labels = Object.keys(cropTotalMap);
    const data = Object.values(cropTotalMap);

    // 第三步:渲染图表
    let ctx = document.getElementById('chart').getContext('2d');
    let myChart = new Chart(ctx, {
      type: 'bar',
      data: {
        labels: labels,
        datasets: [{
          label: 'What Farmers are Growing',
          data: data,
          backgroundColor: 'rgba(255, 99, 132, 0.2)',
          borderColor: 'rgba(255, 99, 132, 1)',
          borderWidth: 1
        }]
      }
    });
  });
})

为什么原来的代码会有问题?

你之前的代码直接用rows.map()分别提取每个行的keyCrop和quantity,这会导致数据库里每一条记录都对应图表里的一个标签和数据点。比如如果"小麦"出现3次,图表就会显示3个"小麦"标签的柱子,而不是合并成一个显示总数量的柱子。

内容的提问来源于stack exchange,提问作者David Kiprono

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:33:09