如何用JS和MUI X Data Grid将数据转为交叉表样式?
问题:MUI X Data Grid 交叉表样式调整
使用MUI X Data Grid展示数据时出现两个问题:日期列重复显示同一日期,Charge列未正确计算为该行其他单元格的总和。需要调整为交叉表样式:每个日期仅在日期列显示一次,其余数据横向排列,Charge为行内所有数据的总和。
现有DataGrid组件代码
<DataGrid rows={recon_rows} columns={recon_columns} />
当前数据处理代码
var recon_rows = []; var recon_columns = []; var setHeaders = new Set(); var setDate = new Set(); for(let i = 0; i < reportData.length; i++) { setHeaders.add(reportData[i].hdrname); setDate.add(reportData[i].recondate); } recon_columns = [ { field: 'col1', headerName: 'Date', minWidth: 100 }, { field: 'col2', headerName: 'Charge', minWidth: 100 }, ]; for(var headers of setHeaders) { recon_columns.push({ field: headers, headerName: headers, minWidth: 150 }); for(var dates of setDate) { var charge = 0; for(var i = 0; i < reportData.length; i++) { if(reportData[i].hdrname === headers && reportData[i].recondate === dates) { charge += reportData[i].entryqty; recon_rows.push({ id: Math.random(dates), col1: dates, col2: charge, [headers]: charge }); } } } }
数据示例
[ { "recondate": "2022-07-19", "entryclass": 1, "entryid": 1, "entryqty": 16, "entrycharge": 160, "entryseq": 10001, "hdrname": "SERV-Major-2S" }, { "recondate": "2022-07-21", "entryclass": 1, "entryid": 1, "entryqty": 5, "entrycharge": 50, "entryseq": 10001, "hdrname": "SERV-Major-2S" } // 其余数据格式一致 ]
解决方案
问题根源是数据处理逻辑错误:嵌套循环导致同一日期被多次推入recon_rows,且Charge仅计算单个列的数值而非整行总和。以下是修正后的代码:
修正后的数据处理代码
var recon_rows = []; var recon_columns = []; var setHeaders = new Set(); var dateMap = new Map(); // 1. 收集表头并按日期分组数据 reportData.forEach(item => { setHeaders.add(item.hdrname); // 初始化日期分组 if (!dateMap.has(item.recondate)) { dateMap.set(item.recondate, { date: item.recondate, charge: 0, columns: {} }); } const dateEntry = dateMap.get(item.recondate); // 填充对应列的数值 dateEntry.columns[item.hdrname] = item.entryqty; // 累加当前日期的Charge总和 dateEntry.charge += item.entryqty; }); // 2. 构建列配置 recon_columns = [ { field: 'date', headerName: 'Date', minWidth: 100 }, { field: 'charge', headerName: 'Charge', minWidth: 100 }, ]; // 添加动态列 setHeaders.forEach(header => { recon_columns.push({ field: header, headerName: header, minWidth: 150 }); }); // 3. 转换为DataGrid所需的行格式 dateMap.forEach((entry, index) => { const row = { id: index + 1, // 用索引生成唯一ID,避免随机数重复 date: entry.date, charge: entry.charge }; // 合并列数据到行对象 Object.assign(row, entry.columns); recon_rows.push(row); });
修正说明
- 按日期分组:使用
Map按recondate分组,确保每个日期仅生成一行数据 - 正确计算Charge:分组时直接累加当前日期下所有
entryqty的总和 - 动态列填充:遍历分组后的列数据,将对应表头的数值填充到行对象
- 唯一ID生成:用索引替代
Math.random,避免ID重复导致的渲染异常
内容的提问来源于stack exchange,提问作者Paw
相关产品推荐
相关产品推荐

