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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 05:14:58