如何在MUI Data Grid或Ag-grid中添加垂直月份栏?
在Ag-Grid/MUI Data Grid中实现匹配月份行数的垂直月份栏
核心思路确认
你的思路方向是正确的:通过自定义列渲染实现垂直月份栏,并结合月份分组的行范围来控制栏的高度与圆角效果。但需要结合表格的行分组/数据关联逻辑,确保月份栏的高度精准匹配对应月份的所有数据行。
分框架实现方案
1. Ag-Grid 实现方式
- 步骤1:将数据按月份分组,确保同一月份的行连续排列
- 步骤2:新增一列作为月份栏,使用
cellRenderer自定义渲染垂直文本与背景栏 - 步骤3:通过计算分组行的总高度,动态设置月份栏的高度;同时根据是否是月份的首行/末行,添加顶部/底部圆角
示例代码(React + Ag-Grid):
import { AgGridReact } from 'ag-grid-react'; import 'ag-grid-community/styles/ag-grid.css'; import 'ag-grid-community/styles/ag-theme-alpine.css'; const MonthRenderer = (props) => { const isFirstRowOfMonth = props.node.firstChild; const isLastRowOfMonth = props.node.lastChild; const borderRadius = `${isFirstRowOfMonth ? '20px 20px 0 0' : '0'} ${isLastRowOfMonth ? '0 0 20px 20px' : '0'}`; // 仅在月份首行渲染完整的垂直栏 if (!isFirstRowOfMonth) return null; // 计算当前月份所有行的总高度 const totalRowHeight = props.node.parent.children.length * props.api.getRowHeight(); return ( <div className="month-vertical-bar" style={{ height: `${totalRowHeight}px`, borderRadius, writingMode: 'vertical-rl', textOrientation: 'sideways', backgroundColor: '#ff4444', color: 'white', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '1.2rem', width: '40px' }} > {props.value} </div> ); }; const MyGrid = () => { const columnDefs = [ { headerName: '月份', field: 'month', cellRenderer: MonthRenderer, width: 60, suppressSizeToFit: true }, { headerName: '日期', field: 'date' }, { headerName: '数据', field: 'data' } ]; const rowData = [ { month: '一月', date: '2024-01-01', data: '数据1' }, // ... 其他一月数据行 { month: '二月', date: '2024-02-01', data: '数据32' }, // ... 其他二月数据行 ]; const gridOptions = { rowGroupPanelShow: 'never', groupDefaultExpanded: -1, autoGroupColumnDef: { headerName: '分组', width: 200 } }; return ( <div className="ag-theme-alpine" style={{ height: 800, width: '100%' }}> <AgGridReact columnDefs={columnDefs} rowData={rowData} gridOptions={gridOptions} groupUseEntireRow={false} /> </div> ); }; export default MyGrid;
2. MUI Data Grid 实现方式
- 步骤1:确保数据按月份+日期排序,保证同月份行连续
- 步骤2:自定义列组件,利用表格API判断当前行是否为月份首/末行,动态设置垂直栏的高度与圆角
- 步骤3:计算当前月份所有行的总高度,仅在首行渲染完整垂直栏
示例代码(React + MUI Data Grid):
import { DataGrid, GridColDef } from '@mui/x-data-grid'; import { useGridApiContext } from '@mui/x-data-grid'; const MonthColumnComponent = (props) => { const api = useGridApiContext(); const { row, field } = props; const monthRows = api.getAllRows().filter(r => r.month === row.month); const isFirstRow = monthRows[0].id === row.id; const isLastRow = monthRows[monthRows.length - 1].id === row.id; const totalHeight = monthRows.length * api.getRowHeight(); if (!isFirstRow) return null; return ( <div style={{ height: `${totalHeight}px`, borderRadius: `${isFirstRow ? '20px 20px 0 0' : ''} ${isLastRow ? '0 0 20px 20px' : ''}`, backgroundColor: '#ff4444', color: 'white', writingMode: 'vertical-rl', textOrientation: 'sideways', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '1.2rem', width: '40px' }} > {row[field]} </div> ); }; const columns: GridColDef[] = [ { field: 'month', headerName: '月份', width: 60, renderCell: (params) => <MonthColumnComponent {...params} /> }, { field: 'date', headerName: '日期', width: 150 }, { field: 'data', headerName: '数据', width: 200 } ]; const rows = [ { id: 1, month: '一月', date: '2024-01-01', data: '数据1' }, // ... 其他一月数据 { id: 32, month: '二月', date: '2024-02-01', data: '数据32' }, // ... 其他二月数据 ]; export default function MonthGrid() { return ( <div style={{ height: 800, width: '100%' }}> <DataGrid rows={rows} columns={columns} initialState={{ sorting: { sortModel: [{ field: 'date', sort: 'asc' }], }, }} /> </div> ); }
关键注意点
- 必须保证数据按月份+日期排序,否则垂直栏会因行错位显示异常
- 动态计算高度时要适配表格的行高设置(固定/自适应行高)
- 仅在月份首行渲染完整垂直栏,避免重复渲染导致视觉混乱
内容的提问来源于stack exchange,提问作者ufghd34
相关产品推荐
相关产品推荐

