Layout and empty grid issues with Dash AG Grid

Hi, I have just transferred over to using dash AG Grid rather than DataTable which I had been using for a while but I have run into a few issues, firstly with the layout, secondly with the grid.

My layout has two side panel and a central container. The idea is that these all fit on the full screen and there is no scrolling of the page involved. Using the AG Grid has now pushed the right hand panel below the first panel and container and the only change has been to use the grid instead of the dataTable. I have attempted to simplify my code and provide an example which mimics the same layout and right hand panel:

example_app.py

from dash import Dash, html, dcc
import dash_mantine_components as dmc
import dash_ag_grid as dag
import pandas as pd 

app = Dash(__name__)

def dash_ag_grid(df: pd.DataFrame, id):
        grid = dag.AgGrid(
            id=id,
            className="ag-theme-alpine compact ag-center-cols-clipper",
            rowData=df.to_dict("records"),
            columnDefs = [
                {'field': 'props', 'minWidth': 50, 'maxWidth': 100, "wrapText": True, "autoHeight": True, "cellStyle": {"wordBreak": "normal", "lineHeight": "unset"}},
                {'field': 'values', 'minWidth': 100, 'maxWidth': 150, "wrapText": True, "autoHeight": True, "cellStyle": {"wordBreak": "normal", "lineHeight": "unset"}},
            ],
            columnSize="sizeToFit",
            rowClass="bg-light",
            style={"width": "250px", "height": None},
            defaultColDef={},
            dashGridOptions = {
                'headerHeight': 0,
                "domLayout": "autoHeight",
            },
        )
        return grid

def panel_content():
    det_info = []

    f_data = {
        'props': [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
        'values': [100, 110, 120, 130, 140, 150, 160, 170, 180, 190]
    }

    df_data = pd.DataFrame.from_records({'props': ["address"], 'values': ["example address"]}, columns=['props', 'values'])
    det_info.append(dash_ag_grid(df_data, "ag-address"))

    feat_details = []
    df_data = pd.DataFrame.from_records(f_data, columns=['props', 'values'])
    feat_details.append(dmc.AccordionItem([dmc.AccordionControl("example data"), dmc.AccordionPanel(dash_ag_grid(df_data, {"type": "ag-detailed-info", "item": "example_data"})),], value="example_data",))

    det_info.append(dmc.Accordion(children=feat_details, chevronPosition='left', classNames={"control": "dmc-accordion-control-3", "content": "dmc-accordion-content"}))

    return det_info


app.layout = html.Div(
                [dmc.Grid(
                    children=[
                        dmc.Stack([
                            dmc.Group([
                                dmc.Col(html.Div("side_pane_left", style={'background-color': 'CornflowerBlue', 'margin': 0, 'padding': 0, "height": "100vh", "width": "250px"}), span="content"),
                                dmc.Col(html.Div("centre_map", style={'background-color': 'PeachPuff', 'margin': 0, 'padding': 0, "height": "100vh", 'width': 'calc(100vw - 2 * 250px)'}), span="auto"),
                                dmc.Col(html.Div(panel_content(), style={'background-color': 'Gainsboro', 'margin': 0, 'padding': 0, "height": "100vh", "width": "250px","overflow-y": "auto", "overflow-x": "hidden"}), span="content"),
                            ], style={"height": "100vh"}, grow=True, spacing="0px"),
                        ], style={"height": "100vh"}, spacing="0px", align="stretch", justify="center")
                    ],
                    gutter="0px",
                )],
                style={'margin': 0, 'padding': 0})


if __name__ == '__main__':
    app.run(debug=True)

custom_css.css (in assets folder)

.dmc-accordion-control-3 {
    padding-top: 5px;
    padding-bottom: 5px;
    padding-left: 0px;
    padding-right: 0px;
    background-color: DarkSalmon;
}

.dmc-accordion-content {
    padding-top: 0px;
    padding-bottom: 0px;
    padding-left: 0px;
    padding-right: 0px;
}

.ag-theme-alpine.compact {
    --ag-grid-size: 3px;
    --ag-font-size: 10px;
    --ag-borders: none;
    --ag-row-border-style: solid;
    --ag-row-border-width: 1px;
    --ag-row-border-color: Gainsboro;
}

.ag-center-cols-clipper {
    min-height: unset !important;
}

(apologies for not tidying up the styling on the elements)

You can see at the figure below, the layout is not performing correctly / as desired:

The second item you can see in the image above; the single row grid is smaller than the 150px, and even with .css update with min-height: unset !important; it still leaves the blank space. Appears that it is not performing as per docs: grid size

Any help here would be amazing as have been going round and round trying to solve these issues.

Hi @troynh

Are you sure the issue is the grid? It took the grid out, and it still had the same layout as in the image you posted.

Hi @AnnMarieW, you were quite right regarding the layout. I have updated this but still have the issue where the table with one row refuses to be <150px even with the necessary updates to min-height in the CSS.

see my updated file below:

from dash import Dash, html, dcc
import dash_mantine_components as dmc
import dash_ag_grid as dag
import pandas as pd 

app = Dash(__name__)

def dash_ag_grid(df: pd.DataFrame, id):
        grid = dag.AgGrid(
            id=id,
            className="ag-theme-alpine compact ag-center-cols-clipper",
            rowData=df.to_dict("records"),
            columnDefs = [
                {'field': 'props', 'minWidth': 50, 'maxWidth': 100, "wrapText": True, "autoHeight": True, "cellStyle": {"wordBreak": "normal", "lineHeight": "unset"}},
                {'field': 'values', 'minWidth': 100, 'maxWidth': 150, "wrapText": True, "autoHeight": True, "cellStyle": {"wordBreak": "normal", "lineHeight": "unset"}},
            ],
            columnSize="sizeToFit",
            rowClass="bg-light",
            style={"width": "250px", "height": None},
            defaultColDef={},
            dashGridOptions = {
                'headerHeight': 0,
                "domLayout": "autoHeight",
            },
        )
        return grid

def panel_content():
    det_info = []

    f_data = {
        'props': [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
        'values': [100, 110, 120, 130, 140, 150, 160, 170, 180, 190]
    }

    df_data = pd.DataFrame.from_records({'props': ["address"], 'values': ["example address"]}, columns=['props', 'values'])
    det_info.append(dash_ag_grid(df_data, "ag-address"))

    # add feature props for each layer active to as an accordion item to and accordion
    feat_details = []
    df_data = pd.DataFrame.from_records(f_data, columns=['props', 'values'])
    feat_details.append(dmc.AccordionItem([dmc.AccordionControl("example data"), dmc.AccordionPanel(dash_ag_grid(df_data, {"type": "ag-detailed-info", "item": "example_data"})),], value="example_data",))

    det_info.append(dmc.Accordion(children=feat_details, chevronPosition='left', classNames={"control": "dmc-accordion-control-3", "content": "dmc-accordion-content"}))

    return det_info


app.layout = html.Div(
                dmc.Grid([
                     dmc.Stack([
                          dmc.Group([
                               html.Div("header", style={'background-color': 'DarkOliveGreen', "height": "40px", "width": "100vw"})
                          ]),
                          dmc.Group([
                               html.Div("side_pane_left", style={'background-color': 'CornflowerBlue', "height": "100%", "width": "250px"}),
                               html.Div("centre_map", style={'background-color': 'PeachPuff', "height": "calc(100vh - 2 * 40px)", "width": "calc(100vw - 2 * 250px)"}),
                               html.Div(panel_content(), style={'background-color': 'Gainsboro', "height": "100%", "width": "250px", "overflow-y": "auto", "overflow-x": "hidden"})
                          ], spacing=0),
                          dmc.Group([
                               html.Div("footer", style={'background-color': 'DarkOrchid', "height": "40px", "width": "100vw"})
                          ],),
                     ], spacing=0) 
                ]), style={"height": "100vh", "width": "100vw", 'margin': 0, 'padding': 0}
            )



if __name__ == '__main__':
    app.run(debug=True)

And an image of the tables generated:
image

Table 1 shows the incorrect table with the white space while Table 2 in the accordion appears to be correct (although this would have the same issue if number of rows was less than 150px I suspect).

Hopefully you are able to help me resolve this - Thanks!

Hello @troynh,

More than likely, this is an issue with the accordion and the fact that you are using the group. I think it is setting up your spacing.

Thanks for the response @jinnyzor. Thats what I had thought initially but the top grid is outside of the accordion. Table/Grid 1 and the accordion are both children in the Div.

I just removed the accordion from the children of the Div and only had the grid with the single row and it results in the same outcome unfortunately.

Replace the group with a regular div. And see if that adjusts it.

Still the same issue occurring:

image

I know that its reading the CSS correctly as the grid formatting is altered to reflect that in the CSS.

So I have identified that it has to do with the className’s that I have applied. I currently have the following and while the ‘ag-theme-alpine compact’ appears to be applying, the latter part is not:

className="ag-theme-alpine compact ag-center-cols-clipper",

If I apply only the following then the min-height for the table works correctly.

className="ag-center-cols-clipper",

Im certain that I should be able to use multiple className’s but must be applying them incorrectly and not sure how to resolve this.

When applying css from the stylesheet, you need to be using:

.ag-theme-alpine.ag-center-cols-clipper {
   // settings
}

Thanks for this clarification. I tried it though and still same outcome. I have noticed though that when I inspect the styles it has the following:

image

And when I uncheck both the boxes, the grid is as desired:

From this:
image

To this:
image
image

It appears to be the .ag-center-cols-containter, could that be correct? I tried using this in the css instead but had the same outcome.

You should create a new css rule as such:

.ag-theme-alpine.customclass .ag-layout-auto-height {
    .ag-center-cols-container,
    .ag-center-cols-viewport {
    min-height: 0px !important;
    }
}

This should keep it from messing up:

image

Thats perfect, thanks @jinnyzor for this. It seems that I need to understand css a lot more.
I do note that this outcome is quite different to that in the docs though which uses ‘.ag-center-cols-clipper’. Is this intentional?

It might have been due to an update from the underlying grid.

1 Like