Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DataGridPro] Autosize columns #10180

Merged
merged 67 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
58b81d8
feat: setup api typings
romgrk Aug 31, 2023
fbacef8
lint
romgrk Aug 31, 2023
6eb4c33
draft
romgrk Sep 6, 2023
7bb5eed
Merge branch 'master' into feat-auto-sizing
romgrk Sep 6, 2023
fbd645e
feat: calculate widths
romgrk Sep 6, 2023
fec64c5
feat: disable virtualization while getting widths
romgrk Sep 6, 2023
6db3879
draft: first implementation
romgrk Sep 7, 2023
3819972
docs: add demo
romgrk Sep 7, 2023
b423465
lint
romgrk Sep 7, 2023
93b135e
refactor
romgrk Sep 7, 2023
aba5388
lint
romgrk Sep 7, 2023
8d899d0
lint
romgrk Sep 7, 2023
9c723e5
refactor
romgrk Sep 7, 2023
1967163
refactor
romgrk Sep 7, 2023
8b24ed1
docs
romgrk Sep 7, 2023
3e8edb8
lint
romgrk Sep 7, 2023
34142a0
feat: add autosizing props
romgrk Sep 9, 2023
978fbc1
refactor: new approach
romgrk Sep 12, 2023
52986f2
lint
romgrk Sep 12, 2023
310bbe0
lint
romgrk Sep 12, 2023
b8c1a82
lint
romgrk Sep 12, 2023
2ff9ecb
lint
romgrk Sep 12, 2023
1db9646
doc: comments
romgrk Sep 12, 2023
dd165c9
lint
romgrk Sep 12, 2023
1d14a37
fix: types
romgrk Sep 12, 2023
f272533
lint
romgrk Sep 12, 2023
a0cd6bb
lint
romgrk Sep 12, 2023
f9f2d02
lint
romgrk Sep 13, 2023
ae8f7b9
lint
romgrk Sep 13, 2023
e35854b
lint
romgrk Sep 13, 2023
df10cc3
feat: make it work
romgrk Sep 13, 2023
7c5ce54
glork
romgrk Sep 13, 2023
675d094
lint
romgrk Sep 13, 2023
e34ac05
doc
romgrk Sep 13, 2023
9bc48b6
lint
romgrk Sep 13, 2023
2c8af8b
lint
romgrk Sep 13, 2023
bbe3ab4
lint
romgrk Sep 13, 2023
7a08e0a
feat: scrollWidth
romgrk Sep 13, 2023
386ea98
lint
romgrk Sep 13, 2023
0e549df
lint
romgrk Sep 14, 2023
29134e9
feat: double-click implementation
romgrk Sep 14, 2023
3c7fe6a
lint
romgrk Sep 14, 2023
d69754d
fix
romgrk Sep 14, 2023
afea006
fix
romgrk Sep 14, 2023
ea7a6b6
lint
romgrk Sep 14, 2023
6e3df33
doc
romgrk Sep 17, 2023
b427a75
doc
romgrk Sep 17, 2023
9401db1
Merge branch 'master' into feat-auto-sizing
romgrk Sep 17, 2023
8f8261c
fix
romgrk Sep 17, 2023
7bda608
doc
romgrk Sep 17, 2023
c04048f
doc: update
romgrk Sep 18, 2023
1f2b19f
fix: bugs
romgrk Sep 18, 2023
0fdad6d
fix
romgrk Sep 18, 2023
f590190
lint
romgrk Sep 18, 2023
c454521
lint
romgrk Sep 18, 2023
dc5e4c9
refactor
romgrk Sep 18, 2023
c2d66ef
lint
romgrk Sep 18, 2023
4efe879
Update packages/grid/x-data-grid-pro/src/hooks/features/columnResize/…
romgrk Sep 20, 2023
bc7eb22
Update packages/grid/x-data-grid-pro/src/hooks/features/columnResize/…
romgrk Sep 20, 2023
600a4f2
Update docs/data/data-grid/column-dimensions/column-dimensions.md
romgrk Sep 20, 2023
9d5d1de
Update docs/data/data-grid/column-dimensions/ColumnAutosizing.tsx
romgrk Sep 20, 2023
23323c3
lint
romgrk Sep 20, 2023
c8b52c0
lint
romgrk Sep 20, 2023
0556e3f
lint
romgrk Sep 20, 2023
0d5d9a8
fix: tests
romgrk Sep 20, 2023
486b522
lint
romgrk Sep 20, 2023
581e3f6
Merge branch 'master' into feat-auto-sizing
romgrk Sep 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions docs/data/data-grid/column-dimensions/ColumnAutosizing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import * as React from 'react';
import { Button, Checkbox, FormControlLabel, Stack, TextField } from '@mui/material';
import { useGridApiRef } from '@mui/x-data-grid';
import { DataGridPro, DEFAULT_GRID_AUTOSIZE_OPTIONS } from '@mui/x-data-grid-pro';
import { useDemoData } from '@mui/x-data-grid-generator';

export default function ColumnAutosizing() {
const apiRef = useGridApiRef();
const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 1000 });
const [sampleLength, setSampleLength] = React.useState(
DEFAULT_GRID_AUTOSIZE_OPTIONS.sampleLength,
);
const [includeHeaders, setIncludeHeaders] = React.useState(
DEFAULT_GRID_AUTOSIZE_OPTIONS.includeHeaders,
);
const [excludeOutliers, setExcludeOutliers] = React.useState(
DEFAULT_GRID_AUTOSIZE_OPTIONS.excludeOutliers,
);
const [outliersFactor, setOutliersFactor] = React.useState(
DEFAULT_GRID_AUTOSIZE_OPTIONS.outliersFactor,
);

return (
<div style={{ width: '100%' }}>
<Stack
spacing={2}
direction="row"
alignItems="center"
sx={{ marginBottom: '1em' }}
>
<div>
<Button
variant="outlined"
onClick={() =>
apiRef.current.autosizeColumns({
sampleLength,
includeHeaders,
excludeOutliers,
outliersFactor,
})
}
>
Autosize columns
</Button>
</div>
<TextField
inputProps={{ inputMode: 'numeric', pattern: '[0-9]*' }}
label="Sample length"
value={sampleLength}
onChange={(ev) => setSampleLength(parseInt(ev.target.value))}
sx={{ width: '12ch' }}
/>
<FormControlLabel
control={
<Checkbox
checked={includeHeaders}
onChange={(ev) => setIncludeHeaders(ev.target.checked)}
/>
}
label="Include headers"
/>
<FormControlLabel
control={
<Checkbox
checked={excludeOutliers}
onChange={(ev) => setExcludeOutliers(ev.target.checked)}
/>
}
label="Exclude outliers"
/>
<TextField
inputProps={{ inputMode: 'numeric', pattern: '[0-9]*' }}
label="Outliers factor"
value={outliersFactor}
onChange={(ev) => setOutliersFactor(parseInt(ev.target.value))}
sx={{ width: '12ch' }}
/>
</Stack>
<div style={{ height: 400, width: '100%' }}>
<DataGridPro apiRef={apiRef} density="compact" {...data} />
</div>
</div>
);
}
88 changes: 88 additions & 0 deletions docs/data/data-grid/column-dimensions/ColumnAutosizing.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import * as React from 'react';
import { Button, Checkbox, FormControlLabel, Stack, TextField } from '@mui/material';
import { useGridApiRef } from '@mui/x-data-grid';
import {
DataGridPro,
GridApiPro,
DEFAULT_GRID_AUTOSIZE_OPTIONS,
} from '@mui/x-data-grid-pro';
import { useDemoData } from '@mui/x-data-grid-generator';

export default function ColumnAutosizing() {
const apiRef = useGridApiRef<GridApiPro>();
const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 1000 });
const [sampleLength, setSampleLength] = React.useState(
DEFAULT_GRID_AUTOSIZE_OPTIONS.sampleLength,
);
const [includeHeaders, setIncludeHeaders] = React.useState(
DEFAULT_GRID_AUTOSIZE_OPTIONS.includeHeaders,
);
const [excludeOutliers, setExcludeOutliers] = React.useState(
DEFAULT_GRID_AUTOSIZE_OPTIONS.excludeOutliers,
);
const [outliersFactor, setOutliersFactor] = React.useState(
DEFAULT_GRID_AUTOSIZE_OPTIONS.outliersFactor,
);

return (
<div style={{ width: '100%' }}>
<Stack
spacing={2}
direction="row"
alignItems="center"
sx={{ marginBottom: '1em' }}
>
<div>
romgrk marked this conversation as resolved.
Show resolved Hide resolved
<Button
variant="outlined"
onClick={() =>
apiRef.current.autosizeColumns({
sampleLength,
includeHeaders,
excludeOutliers,
outliersFactor,
})
}
>
Autosize columns
</Button>
</div>
<TextField
inputProps={{ inputMode: 'numeric', pattern: '[0-9]*' }}
label="Sample length"
value={sampleLength}
onChange={(ev) => setSampleLength(parseInt(ev.target.value))}
sx={{ width: '12ch' }}
/>
<FormControlLabel
control={
<Checkbox
checked={includeHeaders}
onChange={(ev) => setIncludeHeaders(ev.target.checked)}
/>
}
label="Include headers"
/>
<FormControlLabel
control={
<Checkbox
checked={excludeOutliers}
onChange={(ev) => setExcludeOutliers(ev.target.checked)}
romgrk marked this conversation as resolved.
Show resolved Hide resolved
/>
}
label="Exclude outliers"
/>
<TextField
romgrk marked this conversation as resolved.
Show resolved Hide resolved
inputProps={{ inputMode: 'numeric', pattern: '[0-9]*' }}
label="Outliers factor"
value={outliersFactor}
onChange={(ev) => setOutliersFactor(parseInt(ev.target.value))}
sx={{ width: '12ch' }}
/>
</Stack>
<div style={{ height: 400, width: '100%' }}>
<DataGridPro apiRef={apiRef} density="compact" {...data} />
</div>
</div>
);
}
8 changes: 8 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,14 @@ 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')
romgrk marked this conversation as resolved.
Show resolved Hide resolved
romgrk marked this conversation as resolved.
Show resolved Hide resolved

The `DataGridPro` also allows for auto-sizing the columns' dimensions based on their content. Be aware that it can only
calculate the column widths of a limited set of rows, namely those that are currently rendered by the virtualization
engine.

romgrk marked this conversation as resolved.
Show resolved Hide resolved
{{"demo": "ColumnAutosizing.js", "disableAd": true, "bg": "inline"}}

romgrk marked this conversation as resolved.
Show resolved Hide resolved
## API

- [DataGrid](/x/api/data-grid/data-grid/)
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/data-grid/data-grid-premium.json
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,7 @@
"aggregationColumnHeader--alignRight",
"aggregationColumnHeaderLabel",
"autoHeight",
"autosizing",
"booleanCell",
"cell--editable",
"cell--editing",
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/data-grid/data-grid-pro.json
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,7 @@
"aggregationColumnHeader--alignRight",
"aggregationColumnHeaderLabel",
"autoHeight",
"autosizing",
"booleanCell",
"cell--editable",
"cell--editing",
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/data-grid/data-grid.json
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,7 @@
"aggregationColumnHeader--alignRight",
"aggregationColumnHeaderLabel",
"autoHeight",
"autosizing",
"booleanCell",
"cell--editable",
"cell--editing",
Expand Down
1 change: 1 addition & 0 deletions docs/pages/x/api/data-grid/grid-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { GridApi } from '@mui/x-data-grid';
| :----------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <span class="prop-name">addRowGroupingCriteria [<span class="plan-premium" title="Premium plan"></span>](/x/introduction/licensing/#premium-plan)</span> | <span class="prop-type">(groupingCriteriaField: string, groupingIndex?: number) =&gt; void</span> | Adds the field to the row grouping model. |
| <span class="prop-name">applySorting</span> | <span class="prop-type">() =&gt; void</span> | Applies the current sort model to the rows. |
| <span class="prop-name">autosizeColumns [<span class="plan-pro" title="Pro plan"></span>](/x/introduction/licensing/#pro-plan)</span> | <span class="prop-type">(options?: { columns?: GridColDef[]; includeHeader?: boolean }) =&gt; Promise&lt;void&gt;</span> | Auto-size the columns of the grid based on the cells' content and the space available. |
| <span class="prop-name">deleteFilterItem</span> | <span class="prop-type">(item: GridFilterItem) =&gt; void</span> | Deletes a [GridFilterItem](/x/api/data-grid/grid-filter-item/). |
| <span class="prop-name">exportDataAsCsv</span> | <span class="prop-type">(options?: GridCsvExportOptions) =&gt; void</span> | Downloads and exports a CSV of the grid's data. |
| <span class="prop-name">exportDataAsExcel [<span class="plan-premium" title="Premium plan"></span>](/x/introduction/licensing/#premium-plan)</span> | <span class="prop-type">(options?: GridExcelExportOptions) =&gt; Promise&lt;void&gt;</span> | Downloads and exports an Excel file of the grid's data. |
Expand Down
4 changes: 4 additions & 0 deletions docs/translations/api-docs/data-grid/data-grid-premium.json
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,10 @@
"nodeName": "the root element",
"conditions": "<code>autoHeight={true}</code>"
},
"autosizing": {
"description": "Styles applied to {{nodeName}}.",
"nodeName": "the cell element while it is being autosized"
},
"booleanCell": {
"description": "Styles applied to {{nodeName}}.",
"nodeName": "the icon of the boolean cell"
Expand Down
4 changes: 4 additions & 0 deletions docs/translations/api-docs/data-grid/data-grid-pro.json
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,10 @@
"nodeName": "the root element",
"conditions": "<code>autoHeight={true}</code>"
},
"autosizing": {
"description": "Styles applied to {{nodeName}}.",
"nodeName": "the cell element while it is being autosized"
},
"booleanCell": {
"description": "Styles applied to {{nodeName}}.",
"nodeName": "the icon of the boolean cell"
Expand Down
4 changes: 4 additions & 0 deletions docs/translations/api-docs/data-grid/data-grid.json
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,10 @@
"nodeName": "the root element",
"conditions": "<code>autoHeight={true}</code>"
},
"autosizing": {
"description": "Styles applied to {{nodeName}}.",
"nodeName": "the cell element while it is being autosized"
},
"booleanCell": {
"description": "Styles applied to {{nodeName}}.",
"nodeName": "the icon of the boolean cell"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { GridPrivateOnlyApiCommon } from '@mui/x-data-grid/internals';
import {
GridApiCommon,
GridColumnPinningApi,
GridColumnResizeApi,
GridDetailPanelApi,
GridDetailPanelPrivateApi,
GridRowPinningApi,
Expand All @@ -21,6 +22,7 @@ export interface GridApiPremium
extends GridApiCommon<GridStatePremium, GridInitialStatePremium>,
GridRowProApi,
GridColumnPinningApi,
GridColumnResizeApi,
GridDetailPanelApi,
GridRowGroupingApi,
GridExcelExportApi,
Expand All @@ -29,8 +31,7 @@ export interface GridApiPremium
GridCellSelectionApi,
// APIs that are private in Community plan, but public in Pro and Premium plans
GridRowMultiSelectionApi,
GridColumnReorderApi,
GridRowProApi {}
romgrk marked this conversation as resolved.
Show resolved Hide resolved
GridColumnReorderApi {}

export interface GridPrivateApiPremium
extends GridApiPremium,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { GridColDef } from '@mui/x-data-grid';

export const DEFAULT_GRID_AUTOSIZE_OPTIONS = {
sampleLength: 40,
includeHeaders: false,
romgrk marked this conversation as resolved.
Show resolved Hide resolved
excludeOutliers: false,
outliersFactor: 1.5,
};

export type GridAutosizeOptions = {
/**
* The columns to autosize. By default, applies to all columns.
*/
columns?: GridColDef[];
romgrk marked this conversation as resolved.
Show resolved Hide resolved
/**
* The amount of rows to sample when calculating widths. Note that this amount of rows will
* be rendered to the DOM, so increading this value might have a noticeable performance impact.
* @default 50
*/
sampleLength?: number;
/**
* If true, include the header widths in the calculation
romgrk marked this conversation as resolved.
Show resolved Hide resolved
* @default false
*/
includeHeaders?: boolean;
/**
* If true, width outliers will be ignored.
* @default false
*/
excludeOutliers?: boolean;
Copy link
Member

@MBilalShafi MBilalShafi Sep 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional: To me, excluding outliers is an amazing feature that should be expected by most of users to be turned on by default. How about keeping the naming to match includeHeaders but having it turned on by default (by keeping the default value to false)?

Suggested change
/**
* If true, width outliers will be ignored.
* @default false
*/
excludeOutliers?: boolean;
/**
* If true, width outliers will be ignored.
* @default false
*/
includeOutliers?: boolean;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Matching name: Not sure, I have a slight preference for excludeOutliers for some reason.

Default value: Yes, excluding outliers is an interesting behavior. I'd be ok with having it on by default. @cherniavskii Any opinion?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've included both these changes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for being late to the party, but I'd still like to share my opinion 🙃
While excluding outliers is a cool feature, I would expect autosizing to include outliers by default, because otherwise, it feels like autosizing doesn't work as expected (some of the values might still be truncated).

Would be great to have the autosizeOptions documented along with the default values 👍🏻

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing we overlooked is the experimental flag (or unstable_ prefix) for the new feature so that we can iterate on default behavior and/or prop names 😅
cc @MBilalShafi @romgrk @joserodolfofreitas

/**
* The IQR factor range to detect outliers.
* @default 1.5
*/
outliersFactor?: number;
};

/**
* The Resize API interface that is available in the grid `apiRef`.
*/
export interface GridColumnResizeApi {
/**
* Auto-size the columns of the grid based on the cells' content and the space available.
*/
autosizeColumns: (options?: GridAutosizeOptions) => Promise<void>;
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './columnResizeSelector';
export * from './columnResizeState';
export * from './gridColumnResizeApi';
Loading