Why are you using responsiveSizeToFit exactly?
Could you use flex instead?
Why are you using responsiveSizeToFit exactly?
Could you use flex instead?
This emulates the same thing that you are wanting to do:
import dash_ag_grid as dag
import dash_mantine_components as dmc
import pandas as pd
from dash import Dash, dcc, html, Input, Output, State
# Random dataframe
d = {'col1': [1, 2, 3], 'col2': ['A', 'B', 'C'], 'col3': ['X', 'Y', 'Z']}
df = pd.DataFrame(data=d)
grid_data = df.to_dict('records')
# AG Grid column defs
columnDefs = [
{
"headerName": "Column 1",
"field": "col1",
},
{
"headerName": "Column 2",
"field": "col2",
},
{
"headerName": "Column 3",
"field": "col3",
},
]
defaultColDef = {
"filter": True,
"resizable": True,
"sortable": True,
"editable": False,
"enableRowGroup": True,
"flex": 1
}
app = Dash(__name__)
app.layout = dmc.MantineProvider(
id="mantine-theme",
withGlobalStyles=True,
withNormalizeCSS=True,
children=[
dmc.Container(
size="sm",
children=[
# Checkboxes
dmc.CheckboxGroup(
id="checkbox-grp",
label="Select the columns you want to see",
orientation="horizontal",
offset="md",
persistence=True,
persistence_type="session",
persisted_props=["value"],
children=[
dmc.Checkbox(label="Column 1", value="col1"),
dmc.Checkbox(label="Column 2", value="col2"),
dmc.Checkbox(label="Column 3", value="col3"),
],
value=[
"col1",
"col2",
"col3",
]
),
dmc.Space(h=30),
# AG Grid
dag.AgGrid(
id="data-grid",
columnDefs=columnDefs,
defaultColDef=defaultColDef,
dashGridOptions={
"maintainColumnOrder": True,
"skipHeaderOnAutoSize": True,
"pagination": True,
"enableCellTextSelection": True,
"ensureDomOrder": True,
},
rowData=grid_data,
# columnSize="responsiveSizeToFit",
suppressDragLeaveHidesColumns=False,
# style={"height": "100px", "width": "100%"}
)
],
mt=100,
)
],
)
# Adjust column display
@app.callback(
Output('data-grid', 'columnState'),
Input('checkbox-grp', 'value'),
State('data-grid', 'columnState'),
prevent_initial_call=True,
)
def display_selected_columns(col_selections, col_state):
for c in col_state:
if c['colId'] in col_selections:
c['hide'] = False
else:
c['hide'] = True
return col_state
if __name__ == '__main__':
app.run_server(debug=True)
That works! Removing responsiveSizeToFit and adding "flex": 1 is a perfectly good solution for me. ![]()
Thanks @AnnMarieW ! I overlooked that comment regarding columnSize="sizeToFit".
@jinnyzor I was using responsiveSizeToFit so users could resize the browser and columns would adjust accordingly (my grid is set to the width of the browser window). But this solution works too.
Flex should be set for the same, it also responded to browser window adjustments.
@jinnyzor Revisiting this as I’m now wondering if there’s any way I can grab the column state on page load before any grid interactions (and without prevent_initial_call). This is different from the original topic of this thread, but I wanted to come back your comment here.
I’ll explain -
I have this callback to store columnState:
# Get column state
@callback(
Output('column-state-store', 'data'),
Input('data-grid', 'columnState'),
)
def store_column_state(col_state):
return col_state
… so that I can iterate over it in another callback, which takes checkbox inputs to adjust the grid:
# Adjust column display
@callback(
Output('data-grid', 'columnState'),
Input('columns-checkbox-grp', 'value'),
Input('column-state-store', 'data'),
prevent_initial_call=True,
)
def display_selected_columns(col_selections, col_state):
for c in col_state:
if c['colId'] in col_selections:
c['hide'] = False
else:
c['hide'] = True
return col_state
This technically works but the browser does initially log a circular dependency error on page load (html: "Error: Dependency Cycle Found: column-state-store.data -> data-grid.columnState -> column-state-store.data").
Even though the callbacks end up working like I want them to, it doesn’t feel optimal. Is there a way to check when column state is available before trying to store it and use it?
If you have a columnState initially, you can pass it whenever.
If you wanted to create a columnState based on the columnDefs you can do that as well. The biggest change is the field becomes the colId.
Ah, that works really well! I can also remove my use of dcc.Store since I can just use the state of my columnDefs instead of trying to grab columnState which isn’t initially available, esp. when preventing initial call.
Here’s my new simplified code which works well
Thanks @jinnyzor
# Adjust column display
@callback(
Output('data-grid', 'columnDefs'),
# Output('data-grid', 'columnState'), # switched to ColumnDefs
Input('columns-checkbox-grp', 'value'), # user selections persisted locally
State('data-grid', 'columnDefs'),
# prevent_initial_call=True, # Don't need this anymore
)
def display_selected_columns(col_selections, col_defs):
for c in col_defs:
if c['field'] in col_selections: # iterating over columnDefs
c['hide'] = False
else:
c['hide'] = True
return col_defs