Material UI Data Grid - Row Grouping 使用指南与示例

class Row grouping recipes

在大型数据集的展示中,将表格数据进行分组(Row Grouping)是常见的需求,特别是在数据层次结构较为复杂时。Material UI Data Grid 提供了丰富的行分组功能,帮助开发者快速构建分层次的表格布局,使用户可以轻松浏览和操作数据。本篇博客将详细介绍如何使用 Material UI Data Grid 的行分组功能,涵盖其所有属性和方法,并结合其他 Material UI 组件进行使用。

1. 安装与准备

要使用 Material UI Data Grid 行分组功能,首先需要安装 Material UI 及其 Data Grid Pro 或 Data Grid Premium 版本。

npm install @mui/material @mui/x-data-grid-pro

Data Grid 行分组功能是高级功能,需要 DataGridProDataGridPremium 组件才能使用。

2. 基本示例 - 按字段进行分组

Material UI Data Grid 提供了一种非常方便的方式,通过指定某些列进行分组。下面是一个简单的示例,展示如何按列 category 对数据进行分组。

2.1 示例代码

import * as React from 'react';
import { DataGridPro } from '@mui/x-data-grid-pro';

const rows = [
  { id: 1, name: 'Apple', category: 'Fruit', price: 1.5 },
  { id: 2, name: 'Banana', category: 'Fruit', price: 1.0 },
  { id: 3, name: 'Carrot', category: 'Vegetable', price: 0.8 },
  { id: 4, name: 'Broccoli', category: 'Vegetable', price: 1.2 },
];

const columns = [
  { field: 'name', headerName: 'Name', width: 150 },
  { field: 'category', headerName: 'Category', width: 150 },
  { field: 'price', headerName: 'Price', width: 100, type: 'number' },
];

export default function GroupedGrid() {
  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGridPro
        rows={rows}
        columns={columns}
        groupingColDef={{
          field: 'category',
          headerName: 'Category',
        }}
        groupExpansion={{
          defaultExpanded: true, // 默认展开分组
        }}
        pageSize={5}
      />
    </div>
  );
}

2.2 代码说明

  • groupingColDef:用于定义用于分组的列。在这里我们使用 category 列进行分组。
  • groupExpansion:控制分组的默认展开状态。defaultExpanded: true 表示分组默认展开,用户可以手动折叠。
  • DataGridPro:行分组功能是 DataGridProDataGridPremium 的高级功能。

2.3 行分组的优点

  • 数据可视化增强:通过分组,用户可以更清晰地看到数据的层次结构。
  • 折叠/展开控制:通过折叠不必要的数据组,用户可以聚焦于当前所需的数据。

3. 进阶功能 - 自定义分组行为

除了通过列自动分组外,Data Grid 还允许开发者通过自定义的分组行为来处理更复杂的数据需求。

3.1 示例代码

import * as React from 'react';
import { DataGridPro } from '@mui/x-data-grid-pro';

const rows = [
  { id: 1, name: 'Apple', category: 'Fruit', price: 1.5 },
  { id: 2, name: 'Banana', category: 'Fruit', price: 1.0 },
  { id: 3, name: 'Carrot', category: 'Vegetable', price: 0.8 },
  { id: 4, name: 'Broccoli', category: 'Vegetable', price: 1.2 },
  { id: 5, name: 'Steak', category: 'Meat', price: 10.0 },
  { id: 6, name: 'Chicken', category: 'Meat', price: 5.0 },
];

const columns = [
  { field: 'name', headerName: 'Name', width: 150 },
  { field: 'category', headerName: 'Category', width: 150 },
  { field: 'price', headerName: 'Price', width: 100, type: 'number' },
];

const customGroupRows = (rows) => {
  return rows.reduce((acc, row) => {
    const groupKey = row.category;
    if (!acc[groupKey]) {
      acc[groupKey] = [];
    }
    acc[groupKey].push(row);
    return acc;
  }, {});
};

export default function CustomGroupedGrid() {
  const groupedRows = customGroupRows(rows);

  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGridPro
        rows={Object.values(groupedRows).flat()}
        columns={columns}
        pageSize={5}
        getRowId={(row) => row.id}
        isRowSelectable={(params) => params.row.category !== 'Meat'} // 自定义选择行为
      />
    </div>
  );
}

3.2 代码说明

  • customGroupRows:通过 JavaScript 的 reduce 方法手动对 rows 数据进行分组。这种方法适合自定义的分组逻辑,尤其是当分组条件比较复杂时。
  • isRowSelectable:我们在此示例中通过 isRowSelectable 方法自定义了可选行的逻辑。这里的逻辑是 category 等于 Meat 的行不可选。

4. 行分组中的自定义渲染

行分组不仅可以用于数据分层,还可以结合自定义渲染逻辑进行更复杂的 UI 控制。我们可以通过 groupingColDef 属性来自定义每个分组的渲染方式。

4.1 示例代码

import * as React from 'react';
import { DataGridPro } from '@mui/x-data-grid-pro';

const rows = [
  { id: 1, name: 'Apple', category: 'Fruit', price: 1.5 },
  { id: 2, name: 'Banana', category: 'Fruit', price: 1.0 },
  { id: 3, name: 'Carrot', category: 'Vegetable', price: 0.8 },
  { id: 4, name: 'Broccoli', category: 'Vegetable', price: 1.2 },
  { id: 5, name: 'Steak', category: 'Meat', price: 10.0 },
  { id: 6, name: 'Chicken', category: 'Meat', price: 5.0 },
];

const columns = [
  { field: 'name', headerName: 'Name', width: 150 },
  { field: 'category', headerName: 'Category', width: 150 },
  { field: 'price', headerName: 'Price', width: 100, type: 'number' },
];

export default function CustomGroupRendering() {
  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGridPro
        rows={rows}
        columns={columns}
        groupingColDef={{
          field: 'category',
          headerName: 'Category',
          renderCell: (params) => (
            <strong style={{ color: 'green' }}>
              {params.value} ({params.row.length} items)
            </strong>
          ),
        }}
        pageSize={5}
      />
    </div>
  );
}

4.2 代码说明

  • renderCell:通过这个方法,我们可以自定义分组行的渲染。在此示例中,我们为分组行添加了绿色的样式,并显示了每个分组中的条目数量。

5. Material UI 其他组件的结合

在实际开发中,Data Grid 的分组功能常常需要结合其他 Material UI 组件,如 DialogSnackbar 等,来实现更加丰富的用户交互。

5.1 使用 Dialog 展示分组详情

import React, { useState } from 'react';
import { DataGridPro } from '@mui/x-data-grid-pro';
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import Button from '@mui/material/Button';

const rows = [
  { id: 1, name: 'Apple', category: 'Fruit', price: 1.5 },
  { id: 2, name: 'Banana', category: 'Fruit', price: 1.0 },
  { id: 3, name: 'Carrot', category: 'Vegetable', price: 0.8 },
  { id: 4, name: 'Broccoli', category: 'Vegetable

', price: 1.2 },
];

const columns = [
  { field: 'name', headerName: 'Name', width: 150 },
  { field: 'category', headerName: 'Category', width: 150 },
  { field: 'price', headerName: 'Price', width: 100, type: 'number' },
];

export default function GroupWithDialog() {
  const [open, setOpen] = useState(false);
  const [dialogContent, setDialogContent] = useState('');

  const handleRowClick = (params) => {
    setDialogContent(`You clicked on row: ${JSON.stringify(params.row)}`);
    setOpen(true);
  };

  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGridPro
        rows={rows}
        columns={columns}
        onRowClick={handleRowClick}
        pageSize={5}
      />
      <Dialog open={open} onClose={() => setOpen(false)}>
        <DialogContent>
          <DialogContentText>{dialogContent}</DialogContentText>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setOpen(false)}>Close</Button>
        </DialogActions>
      </Dialog>
    </div>
  );
}

5.2 代码说明

  • Dialog:使用 Dialog 组件展示点击行的详细信息。通过 onRowClick 事件,我们可以在用户点击某一行时弹出对话框,显示该行的详细信息。

6. 总结

通过 Material UI Data Grid 的行分组功能,开发者可以轻松地构建分层次的表格布局,并且结合自定义的分组行为和渲染逻辑,使表格的交互性和可视化效果大大增强。同时,结合 Material UI 其他组件的使用,可以构建更加丰富、用户友好的交互界面。

chat评论区
评论列表
menu