You need to enable JavaScript to run this app. 如何统计AJAX获取的JSON时序数据trolleys总和并填充表格Total行
优惠活动
大模型
产品
解决方案
定价
更多

如何统计AJAX获取的JSON时序数据trolleys总和并填充表格Total行

这是我此前提出的「通过jQuery向动态新增td绑定JSON对象数据」问题的延续。

我正使用jQuery、HTML/CSS和AJAX开发时间表/资源时间线,数据从REST API获取。我已完成所有部门行的展示,但卡在了Total部分的开发:在最后一行Total中,我需要向该行追加td,展示基于AJAX返回的JSON数据、按时段统计的所有部门的trolleys总和。

![TimeTable]

HTML代码

<div style="overflow-x:auto;">
  <table id="time_table" class="table-bordered table-condensed">
    <tr>
      <th class="first-column">Department</th>
      <th>7am</th>
      <th>730am</th>
      <th>8am</th>
      <th>830am</th>
      <th>9am</th>
      <th>930am</th>
      <th>10am</th>
      <th>1030am</th>
      <th>11am</th>
      <th>1130am</th>
      <th>12pm</th>
      <th>1230pm</th>
      <th>1pm</th>
      <th>130pm</th>
      <th>2pm</th>
      <th>230pm</th>
      <th>3pm</th>
      <th>330pm</th>
      <th>4pm</th>
      <th>430pm</th>
      <th>5pm</th>
      <th>530pm</th>
      <th>6pm</th>
      <th>630pm</th>
      <th>7pm</th>
      <th>730pm</th>
      <th>8pm</th>
      <th>830pm</th>
      <th>9pm</th>
      <th>930pm</th>
      <th>10pm</th>
      <th>1030pm</th>
      <th>11pm</th>
    </tr>
    <tr id="department01_row">
      <td class="first-column">Department01</td>
      <td>Department01</td>
    </tr>
    <tr id="depatment02_row">
      <td class="first-column">Depatment02</td>
    </tr>
    <tr id="department03_row">
      <td class="first-column">Department03</td>
    </tr>
    <tr id="department04_row">
      <td class="first-column">Department04</td>
    </tr>
    <tr id="department05_row">
      <td class="first-column">Department05</td>
    </tr>
    <tr><td class="first-column"></td></tr>
    <tr id="total_row">
      <td class="first-column">Total</td>
    </tr>
  </table>
</div>

通过AJAX获取的JSON数据结构如下:

{
  "is_active": true,
  "timeslots": [
    {
      "department": "department05",
      "end_time": "13:00:00",
      "id": 3,
      "start_time": "09:00:00",
      "trolleys": 10
    },
    {
      "department": "department03",
      "end_time": "13:00:00",
      "id": 7,
      "start_time": "12:30:00",
      "trolleys": 1
    },
    {
      "department": "department01",
      "end_time": "10:30:00",
      "id": 14,
      "start_time": "09:00:00",
      "trolleys": 4
    },
    {
      "department": "department01",
      "end_time": "13:00:00",
      "id": 20,
      "start_time": "12:00:00",
      "trolleys": 1
    },
    {
      "department": "department04",
      "end_time": "10:30:00",
      "id": 22,
      "start_time": "10:00:00",
      "trolleys": 3
    },
    {
      "department": "department03",
      "end_time": "12:30:00",
      "id": 26,
      "start_time": "12:00:00",
      "trolleys": 7
    }
  ]
}

原有jQuery/JavaScript代码

//The code below is extracted from a function
//timeSlotData is data['timeslots'] which I retrieved via AJAX.

let sortedTimeSlotData = timeSlotData.sort(function(a, b) {
  return parseFloat(a.start_time) - parseFloat(b.start_time)
})

//The times are fixed, i.e. 7am up to 1130pm which is 33 tds 
let timeArray = [7.00, 7.30, 8.00, 8.30,
    9.00, 9.30, 10.00, 10.30,
    11.00, 11.30, 12.00, 12.30,
    13.00, 13.30, 14.00, 14.30,
    15.00, 15.30, 16.00, 16.30,
    17.00, 17.30, 18.00, 18.30,
    19.00, 19.30, 20.00, 20.30,
    21.00, 21.30, 22.00, 22.30,
    23.00]
let $totalRowHTML = Array(33).fill('<td></td>')

//TODO: 现有逻辑循环处理数据时,无法汇总相同时段的trolleys数值
for (let singleData of sortedTimeSlotData) {
  let startTime = parseFloat(singleData.start_time.substr(0, 5))
  let endTime = parseFloat(singleData.end_time.substr(0, 5))

  let startTimeIndex = timeArray.indexOf(startTime)
  let endTimeIndex = timeArray.indexOf(endTime)
  let timeLength = endTimeIndex - startTimeIndex

  const $tdSlot = $('<td>').attr('colspan', timeLength)
  
  $tdSlot.text(singleData.trolleys);
  $tdSlot.addClass('total-booked')

  $totalRowHTML[startTimeIndex] = $tdSlot

  if (timeLength > 1) {
    for (let i = 1; i < timeLength; ++i) {
      $totalRowHTML[startTimeIndex+i] = ''
    }
  }
}

$('#total_row').append($totalRowHTML)

待解决问题

该如何调整现有代码,实现按时段汇总所有部门的trolleys数值,正确填充到Total行的对应单元格中?


解决方案

现有逻辑的核心问题是直接把单个部门的trolleys值覆盖到对应时段,没有做累计统计,同时直接拼接td元素的方式会导致同一时段的多个部门数据无法叠加。调整逻辑分为三步:

  • 初始化一个和timeArray长度一致的空数组,按索引累计每个30分钟时段的trolleys总和
  • 遍历所有timeslot数据,将每个条目覆盖范围内的每个30分钟索引对应的累计值,加上当前条目的trolleys数
  • 根据累计的数值数组生成Total行的td元素,连续数值相同的相邻时段合并为一个带colspan的单元格,减少冗余DOM

调整后的完整代码:

// 固定时段数组保持原有定义
let timeArray = [7.00, 7.30, 8.00, 8.30,
    9.00, 9.30, 10.00, 10.30,
    11.00, 11.30, 12.00, 12.30,
    13.00, 13.30, 14.00, 14.30,
    15.00, 15.30, 16.00, 16.30,
    17.00, 17.30, 18.00, 18.30,
    19.00, 19.30, 20.00, 20.30,
    21.00, 21.30, 22.00, 22.30,
    23.00]

// 1. 初始化全时段累计数组,每个时段初始值为0
let slotTotals = Array(timeArray.length).fill(0)

// 2. 遍历所有时段数据,累计每个30分钟块的总和
timeSlotData.forEach(singleData => {
  let startTime = parseFloat(singleData.start_time.substr(0,5))
  let endTime = parseFloat(singleData.end_time.substr(0,5))
  let startIdx = timeArray.indexOf(startTime)
  let endIdx = timeArray.indexOf(endTime)
  // 容错处理,跳过无效的时间配置
  if (startIdx === -1 || endIdx === -1 || endIdx <= startIdx) return
  // 把当前条目的trolleys数,累加到覆盖的所有30分钟块中
  for (let i = startIdx; i < endIdx; i++) {
    slotTotals[i] += singleData.trolleys
  }
})

// 3. 生成Total行的td元素,合并连续相同值的相邻单元格
let totalCells = []
let i = 0
while (i < slotTotals.length) {
  let currentVal = slotTotals[i]
  let spanLen = 1
  // 向后查找连续相同值的块,计算colspan长度
  while (i + spanLen < slotTotals.length && slotTotals[i + spanLen] === currentVal) {
    spanLen++
  }
  // 生成对应td,值为0的块留空
  let $td = $('<td>').attr('colspan', spanLen)
  if (currentVal > 0) {
    $td.text(currentVal).addClass('total-booked')
  }
  totalCells.push($td)
  i += spanLen
}

// 清空total_row原有动态内容,保留第一列的"Total"文本,再追加生成的单元格
$('#total_row').find('td:not(.first-column)').remove()
$('#total_row').append(totalCells)

补充说明:

  • 移除了原有按start_time排序的逻辑,因为累计统计不依赖数据的先后顺序,遍历效率不受影响
  • 增加了无效时间索引的容错处理,避免接口返回异常时间值时导致数组索引越界
  • 合并连续相同数值的单元格,和部门行的渲染逻辑保持一致,不会出现同一数值被拆成多个窄单元格的视觉问题
  • 数值为0的时段不显示文本,保持表格视觉简洁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 08:45:01