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

[DataGrid] Expand/collapse all hierarchy levels #8505

Open
2 tasks done
nsmolczyk opened this issue Apr 4, 2023 · 10 comments
Open
2 tasks done

[DataGrid] Expand/collapse all hierarchy levels #8505

nsmolczyk opened this issue Apr 4, 2023 · 10 comments
Labels
component: data grid This is the name of the generic UI component, not the React module! plan: Pro Impact at least one Pro user support: commercial Support request from paid users waiting for 👍 Waiting for upvotes

Comments

@nsmolczyk
Copy link

Order ID or Support key 💳 (optional)

51619

Duplicates

  • I have searched the existing issues

Latest version

  • I have tested the latest version

The problem in depth 🔍

I'd like to add a button in the toolbar which expands or collapses all children in the DataGridPro when using tree data. I'm using the GridApiContext to achieve this, but performance is slow.

Here's what I tried. This is the custom Toolbar I'm using for my DataGridPro. First I use the method getAllRowIds, and then use it to set the expanded state of each row using the setRowChildrenExpansion method.

const CustomToolbar = () => {
    const [expanded, setExpanded] = useState(false)
    const apiRef = useGridApiContext();

    return (
        <GridToolbarContainer>
            <Button
                onClick={() => {
                    const allIds = apiRef.current.getAllRowIds();
                    for (let id of allIds) {
                        apiRef.current.setRowChildrenExpansion(id, !expanded)
                    }
                    setExpanded(!expanded)
                }}
            >{expanded ? 'Collapse All' : 'Expand All'}
          </Button>
        </GridToolbarContainer>
    );
};

This does result in the expected behavior, but is very slow when there are lots of rows, presumably because of the numerous calls to setRowChildrenExpansion(). However, there doesn't seem to be a method in the grid api to handle setting multiple row Ids at once, hence why I'm looping through all the Ids and setting them one by one.

Any idea how I can optimize this for large amounts of rows?

Your environment 🌎

System:
OS: Windows 10 10.0.19045
Binaries:
Node: 18.8.0 - C:\Program Files\nodejs\node.EXE
Yarn: Not Found
npm: 8.18.0 - C:\Program Files\nodejs\npm.CMD
Browsers:
Chrome: Not Found
Edge: Spartan (44.19041.1266.0), Chromium (111.0.1661.44)
npmPackages:
@emotion/react: ^11.7.1 => 11.10.6
@emotion/styled: ^11.6.0 => 11.10.6
@mui/base: 5.0.0-alpha.118
@mui/core-downloads-tracker: 5.11.9
@mui/icons-material: ^5.2.5 => 5.11.9
@mui/lab: ^5.0.0-alpha.63 => 5.0.0-alpha.120
@mui/material: ^5.2.7 => 5.11.10
@mui/private-theming: 5.11.9
@mui/styled-engine: 5.11.9
@mui/styles: ^5.2.3 => 5.11.9
@mui/system: 5.11.9
@mui/types: 7.2.3
@mui/utils: 5.11.9
@mui/x-data-grid: 5.17.24
@mui/x-data-grid-pro: ^5.17.2 => 5.17.24
@mui/x-date-pickers: ^5.0.7 => 5.0.19
@mui/x-date-pickers-pro: ^6.0.0 => 6.0.0
@mui/x-license-pro: 5.17.12
@types/react: 17.0.53
react: ^17.0.2 => 17.0.2
react-dom: ^17.0.2 => 17.0.2
typescript: 4.9.5

@nsmolczyk nsmolczyk added status: waiting for maintainer These issues haven't been looked at yet by a maintainer support: commercial Support request from paid users labels Apr 4, 2023
@zannager zannager added component: data grid This is the name of the generic UI component, not the React module! plan: Pro Impact at least one Pro user labels Apr 5, 2023
@m4theushw m4theushw removed the status: waiting for maintainer These issues haven't been looked at yet by a maintainer label Apr 6, 2023
@m4theushw
Copy link
Member

Currently, there's no way to optimize this. The only method exposed is setRowChildrenExpansion. We could add another method accepting multiple IDs to toggle.

@github-project-automation github-project-automation bot moved this to 🆕 Needs refinement in MUI X Data Grid Apr 6, 2023
@m4theushw m4theushw moved this from 🆕 Needs refinement to 📋 Backlog in MUI X Data Grid Apr 6, 2023
@nsmolczyk
Copy link
Author

Ok, thanks for the response! Should I create a feature request for a new method?

@romgrk romgrk changed the title How can I efficiently Expand/Collapse all Hierarchy levels in DataGridPro? [DataGrid] Expand/Collapse all hierarchy levels Aug 14, 2023
@romgrk romgrk changed the title [DataGrid] Expand/Collapse all hierarchy levels [DataGrid] Expand/collapse all hierarchy levels Aug 14, 2023
@romgrk
Copy link
Contributor

romgrk commented Aug 14, 2023

@sbmaggarwal If you want a workaround, you can implement the logic to expand/collapse all by peaking at the implementation of setRowChildrenExpansion, but note that the state of apiRef.current.setState is not considered part of the public API, so you'll need to pin your version to ensure it doesn't break.

@romgrk romgrk added the waiting for 👍 Waiting for upvotes label Aug 14, 2023
@romgrk
Copy link
Contributor

romgrk commented Aug 14, 2023

@mui/xgrid Does someone have an opinion on the API we should expose to solve this problem?

Wdyt about something like this?

api.setRowsChildrenExpansion((node: GridRowNode) => node.id < 42 ? true : false)

@karlyanelson
Copy link

My dataset isn't huge, so maybe this won't solve your performance issues but I was able to make an expand/collapse all button by using isGroupExpandedByDefault and having its value controlled by state

export const DataGrid: React.FunctionComponent = () => {
  const [expanded, setExpanded] = useState(false);

  const apiRef = useGridApiRef();

  const toggleRowExpansion = () => {
    setExpanded(!expanded);
  };

  return (
    <div>
      <Button onClick={toggleRowExpansion}>Toggle Expansion</Button>
      <DataGridPro
        {...data}
        apiRef={apiRef}
        isGroupExpandedByDefault={() => expanded}
      />
    </div>
  );
};

@genepaul
Copy link
Contributor

@sbmaggarwal If you want a workaround, you can implement the logic to expand/collapse all by peaking at the implementation of setRowChildrenExpansion, but note that the state of apiRef.current.setState is not considered part of the public API, so you'll need to pin your version to ensure it doesn't break.

I tried doing something like this, but it doesn't seem to correctly rerender the table after I forceUpdate. Here's a sandbox that shows the issue:

https://codesandbox.io/p/sandbox/zealous-albattani-nntd7m?file=%2Fsrc%2FDemo.tsx

After clicking the chevron on the header, all the top-level rows change their chevron direction but their children don't show. Clicking one of the top-level row chevrons causes the table to rerender then all child rows show. Any help with this code would be appreciated.

@MBilalShafi
Copy link
Member

I tried to do a solution in the userland that should work for both tree-data and row grouping: https://stackblitz.com/edit/react-ucmhy1?file=Demo.tsx

It has a limitation though, the Expand and Collapse buttons must render inside the Data Grid (like in a Toolbar) for it to work properly.

@mui/xgrid Would it be worth adding it as a recipe?

@romgrk
Copy link
Contributor

romgrk commented Oct 1, 2024

Sure, a recipe would be fine.

I think a portal could be used to render the elements outside the grid.

@genepaul
Copy link
Contributor

genepaul commented Oct 2, 2024

@MBilalShafi - this solution works great! Of note: I changed useGridPrivateApiContext to the externally exported useGridApiContext and the solution still worked. Was there a specific reason you chose to use the internal context? I'm hesitant to use that as an external consumer, considering it's not part of the officially supported API so could conceivably break between non-major versions.

@MBilalShafi
Copy link
Member

Hey @genepaul,

Glad it worked for you. You are right, the public API context should work here and is better to use. Previously I was doing it differently where I had to use an internal method, but later I updated the logic to use public API only.

I'll update the example and the recipe accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: data grid This is the name of the generic UI component, not the React module! plan: Pro Impact at least one Pro user support: commercial Support request from paid users waiting for 👍 Waiting for upvotes
Projects
Status: 📋 Backlog
Development

No branches or pull requests

7 participants