Column autosize dash ag-grid table does not allow to see the headers

My problem
Hi, I’m trying to make a table using dash_ag_grid with some columns and autosize them, but the width of the columns does not allow the headers to be seen correctly.

Obatined table

Target table:

My code:

from dash import Dash, html
import dash_bootstrap_components as dbc
import dash_ag_grid as dag
import pandas as pd

app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])

#measure table
df = pd.DataFrame(
  {"Energy Acumulated [kWh]": [2],
   "Voltage [V]": [220],
   "Current [A]":[10],
   "Energy [kWh]": [1],
   "Date":["10-5-2023"],
   "Temperature [°C]":[23.5],
   "Humidity [%]":[50.0],
   "Pressure [hPa]":[1000.3],
  }
)

columnDefs = [
{"field": "Energy Acumulated [kWh]","checkboxSelection": True, "headerCheckboxSelection": True,},
{"field": "Voltage [V]"},
{"field": "Current [A]"},
{"field": "Energy [kWh]"},
{"field": "Date"},
{"field": "Temperature [°C]"},
{"field": "Humidity [%]"},
{"field": "Pressure [hPa]"},
]

defaultColDef = {
                 "minWidth": 1, 
                 "sortable": True, 
                 "resizable": True, 
                 "filter": False}

meas_table=[
    dag.AgGrid(
        id="grid",
        columnDefs=columnDefs,
        rowData=df.to_dict("records"),
        defaultColDef=defaultColDef,
        dashGridOptions={"rowSelection":"multiple"},
        columnSize="responsiveSizeToFit",
        #columnSize="autoSize",
    )
]

app.layout =dbc.Row([
              dbc.Col(
                html.Div(
                    meas_table,
                    className="m-3")
              ),
              dbc.Col(html.Div("something")),
              ])

app.run_server(debug=True)

This run in W10 with:

  • python 3.11.5 64-bit,
  • dash 2.14.2,
  • dash_bootstrap_components 1.5.0,
  • dash_ad_grid 31.0.1,
  • pandas 2.1.1

Expected answer

A modification of my code that adjusts the widths of the columns well, if it can be done automatically, great, but if the only way is to adjust the widths individually, I am also interested in knowing how to do it.

Thanks for your time.

Hello @juliancaba,

Welcome to the community!

responsiveSizeToFit = having the columns fit the available width of the grid. This will cause the issue that you are describing above.

With that said, if you want to do that, I’d recommend that you use flex for your columnDefs instead, as this is innate for the grid.

Now, to have your grid display the headers all the time, I’d recommend the autoSize. If this doesnt work for you, you can always go through and make adjustments to the column sizes and get them where you want them. Then export the columnState to get the current widths and set them in your code. :slight_smile:

Thanks for your answer. But removing the responsiveSizeToFit and using the `autosize´ does not resolve the problem. The only way that I find is fix the minimun width of each column manually.

autoSize seems to work on your example for me.
I’m running code exactly as yours except for:

meas_table=[
    dag.AgGrid(
        id="grid",
        columnDefs=columnDefs,
        rowData=df.to_dict("records"),
        defaultColDef=defaultColDef,
        dashGridOptions={"rowSelection":"multiple",
                         },
        columnSize="autoSize",
    )
]

You may need to add

"suppressColumnVirtualisation": True

to dashGridOptions to get it to autosize columns that are not visible on initial load.

Hi @davidharris, thanks for your answer I try your solution and works perfectly.

But I have another problem, in my real project I want to put this table in one dbc.Tab() and when I do that if the table is in the first tab the table look good but if the table is not in the first tab the table doesn’t look good. Do you know what I’m doing wrong?

Table in the first tab (good)


Table in second tab (bad)

The same code with tab

from dash import Dash, html
import dash_bootstrap_components as dbc
import dash_ag_grid as dag
import pandas as pd

app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])

#measure table
df = pd.DataFrame(
  {"Energy Acumulated [kWh]": [2],
   "Voltage [V]": [220],
   "Current [A]":[10],
   "Energy [kWh]": [1],
   "Date":["10-5-2023"],
   "Temperature [°C]":[23.5],
   "Humidity [%]":[50.0],
   "Pressure [hPa]":[1000.3],
  }
)

columnDefs = [
{"field": "","checkboxSelection": True, "headerCheckboxSelection": True},
{"field": "Energy Acumulated [kWh]"},
{"field": "Voltage [V]"},
{"field": "Current [A]"},
{"field": "Energy [kWh]"},
{"field": "Date"},
{"field": "Temperature [°C]"},
{"field": "Humidity [%]"},
{"field": "Pressure [hPa]"},
]

defaultColDef = {
                 "flex":1,
                 "sortable": True, 
                 "resizable": True, 
                 "filter": False}

meas_table=[
    dag.AgGrid(
        id="measure-table",
        columnDefs=columnDefs,
        rowData=df.to_dict("records"),
        defaultColDef=defaultColDef,
        dashGridOptions={
                         "rowSelection":"multiple",
                         "suppressColumnVirtualisation": True
                         },
        columnSize="autoSize",
    )
]

app.layout =dbc.Card(
            dbc.Tabs([
              dbc.Tab(html.Div("Nothing 1"),label="N1"),
              dbc.Tab([
                dbc.Row([
                  dbc.Col(
                    html.Div(
                        meas_table,
                        className="m-3"
                        )
                  ),
                  dbc.Col(html.Div("something")),
                  ])
              ],label="Table"),
              dbc.Tab(html.Div("Nothing 2"),label="N2"),
            ])
            
)

app.run_server(debug=True)

Not really sure. It looks like it may not be initialised properly if it’s in the second tab. (And is initialised properly if it’s in the first tab because that is visible on initial page load maybe?)

One (speculative) possibility for a fix is to try the ‘Tabs with callback’ approach described here:

https://dash-bootstrap-components.opensource.faculty.ai/docs/components/tabs/

You were right again @davidharris !
This is very strange, but activating the tabs with callbacks do the table looks good although the table is not in the first tab.

Table looks good in third table

The code

from dash import Dash, html, Input, Output
import dash_bootstrap_components as dbc
import dash_ag_grid as dag
import pandas as pd

app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])

#measure table
df = pd.DataFrame(
  {"Energy Acumulated [kWh]": [2],
   "Voltage [V]": [220],
   "Current [A]":[10],
   "Energy [kWh]": [1],
   "Date":["10-5-2023"],
   "Temperature [°C]":[23.5],
   "Humidity [%]":[50.0],
   "Pressure [hPa]":[1000.3],
  }
)

columnDefs = [
{"field": "","checkboxSelection": True, "headerCheckboxSelection": True},
{"field": "Energy Acumulated [kWh]"},
{"field": "Voltage [V]"},
{"field": "Current [A]"},
{"field": "Energy [kWh]"},
{"field": "Date"},
{"field": "Temperature [°C]"},
{"field": "Humidity [%]"},
{"field": "Pressure [hPa]"},
]

defaultColDef = {
                 "flex":1,
                 "sortable": True, 
                 "resizable": True, 
                 "filter": False}

meas_table=[
    dag.AgGrid(
        id="measure-table",
        columnDefs=columnDefs,
        rowData=df.to_dict("records"),
        defaultColDef=defaultColDef,
        dashGridOptions={
                         "rowSelection":"multiple",
                         "suppressColumnVirtualisation": True
                         },
        columnSize="autoSize",
    )
]

app.layout =html.Div([
            dbc.Tabs([
              dbc.Tab(label="N2",tab_id="N2-tab"),
              dbc.Tab(label="N1",tab_id="N1-tab"),
              dbc.Tab(label="Table",tab_id="table-tab"),
            ],
            id="tabs",
            active_tab="N2-tab"),
            html.Div(id="content")
])

@app.callback(Output(component_id="content", component_property="children"), 
              [Input(component_id="tabs", component_property="active_tab")])
def switch_tab(at):
    if at == "N1-tab":
        return html.Div("Nothing 1")
    elif at == "N2-tab":
        return html.Div("Nothing 2")
    elif at == "table-tab":
        table_layout= html.Div([
            dbc.Card(
                dbc.Row([
                  dbc.Col(
                    html.Div(
                        meas_table,
                        className="m-3"
                        )
                  ),
                  dbc.Col(html.Div("something")),
                  ])
            ,className="m-3")
          ])
        return table_layout
    return html.P("This shouldn't ever be displayed...")

app.run_server(debug=True)