Skip to content

Commit

Permalink
[DataGridPro] Autosize columns (#10180)
Browse files Browse the repository at this point in the history
Signed-off-by: Rom Grk <[email protected]>
Co-authored-by: Olivier Tassinari <[email protected]>
  • Loading branch information
romgrk and oliviertassinari authored Sep 22, 2023
1 parent 0666b40 commit c0796c5
Show file tree
Hide file tree
Showing 51 changed files with 1,358 additions and 351 deletions.
129 changes: 129 additions & 0 deletions docs/data/data-grid/column-dimensions/ColumnAutosizing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import * as React from 'react';
import Button from '@mui/material/Button';
import Checkbox from '@mui/material/Checkbox';
import FormControlLabel from '@mui/material/FormControlLabel';
import Rating from '@mui/material/Rating';
import Stack from '@mui/material/Stack';
import TextField from '@mui/material/TextField';
import { useGridApiRef } from '@mui/x-data-grid';
import { DataGridPro, DEFAULT_GRID_AUTOSIZE_OPTIONS } from '@mui/x-data-grid-pro';
import { randomRating, randomTraderName } from '@mui/x-data-grid-generator';

function renderRating(params) {
return <Rating readOnly value={params.value} />;
}

function useData(length) {
return React.useMemo(() => {
const names = [
'Nike',
'Adidas',
'Puma',
'Reebok',
'Fila',
'Lululemon Athletica Clothing',
'Varley',
];

const rows = Array.from({ length }).map((_, id) => ({
id,
brand: names[id % names.length],
rep: randomTraderName(),
rating: randomRating(),
}));

const columns = [
{ field: 'id', headerName: 'Brand ID' },
{ field: 'brand', headerName: 'Brand name' },
{ field: 'rep', headerName: 'Representative' },
{ field: 'rating', headerName: 'Rating', renderCell: renderRating },
];

return { rows, columns };
}, [length]);
}

export default function ColumnAutosizing() {
const apiRef = useGridApiRef();
const data = useData(100);

const [includeHeaders, setIncludeHeaders] = React.useState(
DEFAULT_GRID_AUTOSIZE_OPTIONS.includeHeaders,
);
const [includeOutliers, setExcludeOutliers] = React.useState(
DEFAULT_GRID_AUTOSIZE_OPTIONS.includeOutliers,
);
const [outliersFactor, setOutliersFactor] = React.useState(
String(DEFAULT_GRID_AUTOSIZE_OPTIONS.outliersFactor),
);
const [expand, setExpand] = React.useState(DEFAULT_GRID_AUTOSIZE_OPTIONS.expand);

const autosizeOptions = {
includeHeaders,
includeOutliers,
outliersFactor: Number.isNaN(parseFloat(outliersFactor))
? 1
: parseFloat(outliersFactor),
expand,
};

return (
<div style={{ width: '100%' }}>
<Stack
spacing={2}
direction="row"
alignItems="center"
sx={{ marginBottom: '1em' }}
>
<Button
variant="outlined"
onClick={() => apiRef.current.autosizeColumns(autosizeOptions)}
>
Autosize columns
</Button>
<FormControlLabel
control={
<Checkbox
checked={includeHeaders}
onChange={(ev) => setIncludeHeaders(ev.target.checked)}
/>
}
label="Include headers"
/>
<FormControlLabel
control={
<Checkbox
checked={includeOutliers}
onChange={(event) => setExcludeOutliers(event.target.checked)}
/>
}
label="Include outliers"
/>
<TextField
size="small"
label="Outliers factor"
value={outliersFactor}
onChange={(ev) => setOutliersFactor(ev.target.value)}
sx={{ width: '12ch' }}
/>
<FormControlLabel
control={
<Checkbox
checked={expand}
onChange={(ev) => setExpand(ev.target.checked)}
/>
}
label="Expand"
/>
</Stack>
<div style={{ height: 400, width: '100%' }}>
<DataGridPro
apiRef={apiRef}
density="compact"
{...data}
autosizeOptions={autosizeOptions}
/>
</div>
</div>
);
}
132 changes: 132 additions & 0 deletions docs/data/data-grid/column-dimensions/ColumnAutosizing.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import * as React from 'react';
import Button from '@mui/material/Button';
import Checkbox from '@mui/material/Checkbox';
import FormControlLabel from '@mui/material/FormControlLabel';
import Rating from '@mui/material/Rating';
import Stack from '@mui/material/Stack';
import TextField from '@mui/material/TextField';
import { useGridApiRef } from '@mui/x-data-grid';
import {
DataGridPro,
GridApiPro,
DEFAULT_GRID_AUTOSIZE_OPTIONS,
} from '@mui/x-data-grid-pro';
import { randomRating, randomTraderName } from '@mui/x-data-grid-generator';

function renderRating(params: any) {
return <Rating readOnly value={params.value} />;
}

function useData(length: number) {
return React.useMemo(() => {
const names = [
'Nike',
'Adidas',
'Puma',
'Reebok',
'Fila',
'Lululemon Athletica Clothing',
'Varley',
];
const rows = Array.from({ length }).map((_, id) => ({
id,
brand: names[id % names.length],
rep: randomTraderName(),
rating: randomRating(),
}));

const columns = [
{ field: 'id', headerName: 'Brand ID' },
{ field: 'brand', headerName: 'Brand name' },
{ field: 'rep', headerName: 'Representative' },
{ field: 'rating', headerName: 'Rating', renderCell: renderRating },
];

return { rows, columns };
}, [length]);
}

export default function ColumnAutosizing() {
const apiRef = useGridApiRef<GridApiPro>();
const data = useData(100);

const [includeHeaders, setIncludeHeaders] = React.useState(
DEFAULT_GRID_AUTOSIZE_OPTIONS.includeHeaders,
);
const [includeOutliers, setExcludeOutliers] = React.useState(
DEFAULT_GRID_AUTOSIZE_OPTIONS.includeOutliers,
);
const [outliersFactor, setOutliersFactor] = React.useState(
String(DEFAULT_GRID_AUTOSIZE_OPTIONS.outliersFactor),
);
const [expand, setExpand] = React.useState(DEFAULT_GRID_AUTOSIZE_OPTIONS.expand);

const autosizeOptions = {
includeHeaders,
includeOutliers,
outliersFactor: Number.isNaN(parseFloat(outliersFactor))
? 1
: parseFloat(outliersFactor),
expand,
};

return (
<div style={{ width: '100%' }}>
<Stack
spacing={2}
direction="row"
alignItems="center"
sx={{ marginBottom: '1em' }}
>
<Button
variant="outlined"
onClick={() => apiRef.current.autosizeColumns(autosizeOptions)}
>
Autosize columns
</Button>
<FormControlLabel
control={
<Checkbox
checked={includeHeaders}
onChange={(ev) => setIncludeHeaders(ev.target.checked)}
/>
}
label="Include headers"
/>
<FormControlLabel
control={
<Checkbox
checked={includeOutliers}
onChange={(event) => setExcludeOutliers(event.target.checked)}
/>
}
label="Include outliers"
/>
<TextField
size="small"
label="Outliers factor"
value={outliersFactor}
onChange={(ev) => setOutliersFactor(ev.target.value)}
sx={{ width: '12ch' }}
/>
<FormControlLabel
control={
<Checkbox
checked={expand}
onChange={(ev) => setExpand(ev.target.checked)}
/>
}
label="Expand"
/>
</Stack>
<div style={{ height: 400, width: '100%' }}>
<DataGridPro
apiRef={apiRef}
density="compact"
{...data}
autosizeOptions={autosizeOptions}
/>
</div>
</div>
);
}
39 changes: 39 additions & 0 deletions docs/data/data-grid/column-dimensions/column-dimensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,45 @@ To capture changes in the width of a column there are two callbacks that are cal
- `onColumnResize`: Called while a column is being resized.
- `onColumnWidthChange`: Called after the width of a column is changed, but not during resizing.

## Autosizing [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')

`DataGridPro` allows to autosize the columns' dimensions based on their content. Autosizing is enabled by default. To turn it off, pass the `disableAutosize` prop to the datagrid.

Autosizing can be used by one of the following methods:

- Adding the `autosizeOnMount` prop,
- Double-clicking a column header separator on the grid,
- Calling the `apiRef.current.autosizeColumns(options)` API method.

You can pass options directly to the API method when you call it. To configure autosize for the other two methods, provide the options in the `autosizeOptions` prop.

Note that for the separator double-click method, the `autosizeOptions.columns` will be replaced by the respective column user double-clicked on.

In all the cases, the `colDef.minWidth` and `colDef.maxWidth` options will be respected.

```tsx
<DataGridPro
{...otherProps}
autosizeOptions={{
columns: ['name', 'status', 'createdBy'],
includeOutliers: true,
includeHeaders: false,
}}
/>
```

{{"demo": "ColumnAutosizing.js", "disableAd": true, "bg": "inline"}}

:::warning
Autosizing has no effect if dynamic row height is enabled.
:::

:::warning
The data grid can only autosize based on the currently rendered cells.

DOM access is required to accurately calculate dimensions, so unmounted cells (when [virtualization](/x/react-data-grid/virtualization/) is on) cannot be sized. If you need a bigger row sample, [open an issue](https://github.com/mui/mui-x/issues) to discuss it further.
:::

## API

- [DataGrid](/x/api/data-grid/data-grid/)
Expand Down
1 change: 1 addition & 0 deletions docs/data/data-grid/getting-started/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ The enterprise components come in two plans: Pro and Premium.
| [Column groups](/x/react-data-grid/column-groups/) ||||
| [Column spanning](/x/react-data-grid/column-spanning/) ||||
| [Column resizing](/x/react-data-grid/column-dimensions/#resizing) ||||
| [Column autosizing](/x/react-data-grid/column-dimensions/#autosizing) ||||
| [Column reorder](/x/react-data-grid/column-ordering/) ||||
| [Column pinning](/x/react-data-grid/column-pinning/) ||||
| **Row** | | | |
Expand Down
8 changes: 8 additions & 0 deletions docs/pages/x/api/data-grid/data-grid-premium.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
"aria-labelledby": { "type": { "name": "string" } },
"autoHeight": { "type": { "name": "bool" } },
"autoPageSize": { "type": { "name": "bool" } },
"autosizeOnMount": { "type": { "name": "bool" } },
"autosizeOptions": {
"type": {
"name": "shape",
"description": "{ columns?: Array&lt;string&gt;, expand?: bool, includeHeaders?: bool, includeOutliers?: bool, outliersFactor?: number }"
}
},
"cellModesModel": { "type": { "name": "object" } },
"checkboxSelection": { "type": { "name": "bool" } },
"checkboxSelectionVisibleOnly": {
Expand Down Expand Up @@ -56,6 +63,7 @@
"type": { "name": "arrayOf", "description": "Array&lt;number<br>&#124;&nbsp;string&gt;" }
},
"disableAggregation": { "type": { "name": "bool" } },
"disableAutosize": { "type": { "name": "bool" } },
"disableChildrenFiltering": { "type": { "name": "bool" } },
"disableChildrenSorting": { "type": { "name": "bool" } },
"disableClipboardPaste": { "type": { "name": "bool" } },
Expand Down
8 changes: 8 additions & 0 deletions docs/pages/x/api/data-grid/data-grid-pro.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
"aria-labelledby": { "type": { "name": "string" } },
"autoHeight": { "type": { "name": "bool" } },
"autoPageSize": { "type": { "name": "bool" } },
"autosizeOnMount": { "type": { "name": "bool" } },
"autosizeOptions": {
"type": {
"name": "shape",
"description": "{ columns?: Array&lt;string&gt;, expand?: bool, includeHeaders?: bool, includeOutliers?: bool, outliersFactor?: number }"
}
},
"cellModesModel": { "type": { "name": "object" } },
"checkboxSelection": { "type": { "name": "bool" } },
"checkboxSelectionVisibleOnly": {
Expand Down Expand Up @@ -46,6 +53,7 @@
"detailPanelExpandedRowIds": {
"type": { "name": "arrayOf", "description": "Array&lt;number<br>&#124;&nbsp;string&gt;" }
},
"disableAutosize": { "type": { "name": "bool" } },
"disableChildrenFiltering": { "type": { "name": "bool" } },
"disableChildrenSorting": { "type": { "name": "bool" } },
"disableColumnFilter": { "type": { "name": "bool" } },
Expand Down
Loading

0 comments on commit c0796c5

Please sign in to comment.