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

如何优化EJS页面表格列平均值计算代码并生成柱状图?

优化方案:后端用MongoDB Aggregate计算平均值(推荐)

直接在数据库层面完成平均值计算,既能消除前端重复循环的冗余代码,还能减少前端需要处理的数据量。

1. 修改Express路由,使用aggregate()

替换原有find()查询,通过MongoDB聚合管道直接计算4个数值列的全局平均值:

// 假设你的4个数值列字段为:price、batteryLife、screenSize、cameraMP
router.get('/phones', async (req, res) => {
  try {
    // 聚合计算各列平均值
    const avgResult = await Phone.aggregate([
      {
        $group: {
          _id: null, // 不分组,计算全表平均值
          avgPrice: { $avg: '$price' },
          avgBattery: { $avg: '$batteryLife' },
          avgScreen: { $avg: '$screenSize' },
          avgCamera: { $avg: '$cameraMP' }
        }
      }
    ]);
    // 获取原始数据用于表格展示
    const phones = await Phone.find();
    // 将平均值和原始数据一同传入EJS模板
    res.render('phones', { phones, averages: avgResult[0] });
  } catch (err) {
    console.error(err);
    res.status(500).send('服务器错误');
  }
});

后端直接返回计算好的平均值,前端无需再做任何循环计算,彻底解决代码冗余问题。

前端优化方案(无需修改后端时)

如果暂时不想调整后端逻辑,可将重复的循环计算封装为通用函数,避免代码重复:

1. 封装平均值计算函数

在EJS模板的<script>标签或独立JS文件中定义通用函数:

<script>
function getColumnAverage(dataList) {
  if (!dataList.length) return 0;
  const total = dataList.reduce((sum, val) => sum + val, 0);
  return (total / dataList.length).toFixed(2); // 保留两位小数
}
</script>

2. 调用函数计算各列平均值

在EJS中收集每列数据后,统一调用函数计算:

<% 
// 收集各列数据
const priceList = phones.map(item => item.price);
const batteryList = phones.map(item => item.batteryLife);
const screenList = phones.map(item => item.screenSize);
const cameraList = phones.map(item => item.cameraMP);

// 计算平均值
const avgPrice = getColumnAverage(priceList);
const avgBattery = getColumnAverage(batteryList);
const avgScreen = getColumnAverage(screenList);
const avgCamera = getColumnAverage(cameraList);
%>

无论后续新增多少数值列,只需复用该函数即可,避免重复编写循环逻辑。

页面底部实现柱状图

以本地引入的Chart.js为例(无需外链,将Chart.js文件放在项目静态资源目录),实现平均值柱状图:

1. 添加Canvas容器

<div style="width: 80%; margin: 2rem auto;">
  <canvas id="averageChart"></canvas>
</div>

2. 初始化柱状图

如果使用后端返回的averages数据:

<script src="/js/chart.min.js"></script> <!-- 本地引入Chart.js文件 -->
<script>
const chartCtx = document.getElementById('averageChart').getContext('2d');
new Chart(chartCtx, {
  type: 'bar',
  data: {
    labels: ['价格', '电池续航', '屏幕尺寸', '摄像头像素'],
    datasets: [{
      label: '各列平均值',
      data: [
        <%= averages.avgPrice %>,
        <%= averages.avgBattery %>,
        <%= averages.avgScreen %>,
        <%= averages.avgCamera %>
      ],
      backgroundColor: [
        'rgba(255, 99, 132, 0.6)',
        'rgba(54, 162, 235, 0.6)',
        'rgba(255, 206, 86, 0.6)',
        'rgba(75, 192, 192, 0.6)'
      ],
      borderColor: [
        'rgba(255, 99, 132, 1)',
        'rgba(54, 162, 235, 1)',
        'rgba(255, 206, 86, 1)',
        'rgba(75, 192, 192, 1)'
      ],
      borderWidth: 1
    }]
  },
  options: {
    scales: {
      y: {
        beginAtZero: true
      }
    }
  }
});
</script>

若使用前端计算的平均值,将data数组中的值替换为对应的前端变量即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 12:55:25