I have set columnGroupShow
for some columns and added a callback function to change the column size to autoSize
when the rowData
in the grid is updated. However, I noticed that the column size of closed columns won’t be auto-sized, while other opened columns are sized correctly. Do you have any suggestions on how to achieve auto-sizing for closed grouped columns along with new rowData? Thank you in advance.
Hi Wen,
Can you please share a minimal reproducible example?
Hello @wen,
I’m not sure that this is possible due to the nature of how the process works, the grid basically goes column by column and tests whether the component can be viewed in all, based upon how it is on the screen.
With the closed columns, these do not exist in the DOM tree and thus would be skipped.
There are probably some workarounds, however it would be important to note that it could keep your users from being able to actually adjust the individual column sizes.
Once you provide an MRE, as @adamschroeder recommended, it will be easier to test.
Hi @adamschroeder and @jinnyzor ,
Thanks for your reply.
Following is an example.
import dash_ag_grid as dag
from dash import Dash, html, callback, Output, Input, ctx
app = Dash(__name__)
rowDataA = [
{'make': 'Toyota', 'model': 'Celica', 'price': 35000, 'total': 100, 'male': 40, 'female': 60},
{'make': 'BMW', 'model': 'M50', 'price': 60000, 'total': 200, 'male': 140, 'female': 60},
{'make': 'Aston Martin', 'model': 'DBX', 'price': 190000, 'total': 100, 'male': 40, 'female': 60},
]
rowDataB = [
{'make': 'Toyota', 'model': 'Celica', 'price': 30000, 'total': 100, 'male': 40, 'female': 60},
{'make': 'Ford', 'model': 'Mondeo', 'price': 32000, 'total': 100, 'male': 40, 'female': 60},
{'make': 'Porsche', 'model': 'Boxster', 'price': 72000, 'total': 100, 'male': 40, 'female': 60},
{'make': 'BMW', 'model': 'M50', 'price': 62000, 'total': 100, 'male': 40, 'female': 60},
{'make': 'Aston Martin', 'model': 'DBX', 'price': 194000, 'total': 100, 'male': 40, 'female': 60},
]
columnDefs = [
{"field": "make"},
{"field": "model"},
{"field": "price", "cellRenderer": "agAnimateShowChangeCellRenderer"},
{"field": "sales", 'children': [
{'field': 'total'},
{'field': 'male', 'columnGroupShow': 'open'},
{'field': 'female', 'columnGroupShow': 'open'}
]},
]
app.layout = html.Div(
[
html.Button("Data set A", id="btn-client-side-row-model-rowdata-no-rowIDs-A"),
html.Button("Data set B", id="btn-client-side-row-model-rowdata-no-rowIDs-B"),
html.Div([
dag.AgGrid(
id="client-side-row-model-rowdata-no-rowIDs",
rowData=rowDataA,
columnDefs=columnDefs,
dashGridOptions={
"rowDragManaged": True,
"rowDragEntireRow": True
},
)
])
]
)
@callback(
Output("client-side-row-model-rowdata-no-rowIDs", "rowData"),
Output("client-side-row-model-rowdata-no-rowIDs", "columnSize"),
Input("btn-client-side-row-model-rowdata-no-rowIDs-A", "n_clicks"),
Input("btn-client-side-row-model-rowdata-no-rowIDs-B", "n_clicks"),
prevent_initial_call=True,
)
def update_rowdata(*_):
if ctx.triggered_id == 'btn-client-side-row-model-rowdata-no-rowIDs-A':
return rowDataA, 'autoSize'
else:
return rowDataB, 'autoSize'
if __name__ == "__main__":
app.run(debug=True)
As you can see, when I update rowData to Data set B, the column size of opened columns change to same as data length, but closed columns didn’t change along with data.
Here, give this a try:
js
var dagfuncs = window.dashAgGridFunctions = window.dashAgGridFunctions || {};
dagfuncs.applyAutoSize = (params) => {
params.api.autoSizeColumns(
params.columnGroups.flatMap((group) => {
if (group.expanded) {
return group.children.map((c) => c.colId)
}
return [];
}),
false
)
}
app:
import dash_ag_grid as dag
from dash import Dash, html, callback, Output, Input, ctx
app = Dash(__name__)
rowDataA = [
{'make': 'Toyota', 'model': 'Celica', 'price': 35000, 'total': 100, 'male': 40, 'female': 60},
{'make': 'BMW', 'model': 'M50', 'price': 60000, 'total': 200, 'male': 140, 'female': 60},
{'make': 'Aston Martin', 'model': 'DBX', 'price': 190000, 'total': 100, 'male': 40, 'female': 60},
]
rowDataB = [
{'make': 'Toyota', 'model': 'Celica', 'price': 30000, 'total': 100, 'male': 40, 'female': 60},
{'make': 'Ford', 'model': 'Mondeo', 'price': 32000, 'total': 100, 'male': 40, 'female': 60},
{'make': 'Porsche', 'model': 'Boxster', 'price': 72000, 'total': 100, 'male': 40, 'female': 60},
{'make': 'BMW', 'model': 'M50', 'price': 62000, 'total': 100, 'male': 40, 'female': 60},
{'make': 'Aston Martin', 'model': 'DBX', 'price': 194000, 'total': 100, 'male': 40, 'female': 60},
]
columnDefs = [
{"field": "make"},
{"field": "model"},
{"field": "price", "cellRenderer": "agAnimateShowChangeCellRenderer"},
{"field": "sales", 'children': [
{'field': 'total'},
{'field': 'male', 'columnGroupShow': 'open'},
{'field': 'female', 'columnGroupShow': 'open'}
]},
]
app.layout = html.Div(
[
html.Button("Data set A", id="btn-client-side-row-model-rowdata-no-rowIDs-A"),
html.Button("Data set B", id="btn-client-side-row-model-rowdata-no-rowIDs-B"),
html.Div([
dag.AgGrid(
id="client-side-row-model-rowdata-no-rowIDs",
rowData=rowDataA,
columnDefs=columnDefs,
dashGridOptions={
"rowDragManaged": True,
"rowDragEntireRow": True
},
columnSize="autoSize",
eventListeners={'columnGroupOpened': ["applyAutoSize(params)"]}
)
])
]
)
@callback(
Output("client-side-row-model-rowdata-no-rowIDs", "rowData"),
Output("client-side-row-model-rowdata-no-rowIDs", "columnSize"),
Input("btn-client-side-row-model-rowdata-no-rowIDs-A", "n_clicks"),
Input("btn-client-side-row-model-rowdata-no-rowIDs-B", "n_clicks"),
prevent_initial_call=True,
)
def update_rowdata(*_):
if ctx.triggered_id == 'btn-client-side-row-model-rowdata-no-rowIDs-A':
return rowDataA, 'autoSize'
else:
return rowDataB, 'autoSize'
if __name__ == "__main__":
app.run(debug=True)
You need to make sure you are using v 31.2.
Or even just this:
app
import dash_ag_grid as dag
from dash import Dash, html, callback, Output, Input, ctx
app = Dash(__name__)
rowDataA = [
{'make': 'Toyota', 'model': 'Celica', 'price': 35000, 'total': 100, 'male': 40, 'female': 60},
{'make': 'BMW', 'model': 'M50', 'price': 60000, 'total': 200, 'male': 140, 'female': 60},
{'make': 'Aston Martin', 'model': 'DBX', 'price': 190000, 'total': 100, 'male': 40, 'female': 60},
]
rowDataB = [
{'make': 'Toyota', 'model': 'Celica', 'price': 30000, 'total': 100, 'male': 40, 'female': 60},
{'make': 'Ford', 'model': 'Mondeo', 'price': 32000, 'total': 100, 'male': 40, 'female': 60},
{'make': 'Porsche', 'model': 'Boxster', 'price': 72000, 'total': 100, 'male': 40, 'female': 60},
{'make': 'BMW', 'model': 'M50', 'price': 62000, 'total': 100, 'male': 40, 'female': 60},
{'make': 'Aston Martin', 'model': 'DBX', 'price': 194000, 'total': 100, 'male': 40, 'female': 60},
]
columnDefs = [
{"field": "make"},
{"field": "model"},
{"field": "price", "cellRenderer": "agAnimateShowChangeCellRenderer"},
{"field": "sales", 'children': [
{'field': 'total'},
{'field': 'male', 'columnGroupShow': 'open'},
{'field': 'female', 'columnGroupShow': 'open'}
]},
]
app.layout = html.Div(
[
html.Button("Data set A", id="btn-client-side-row-model-rowdata-no-rowIDs-A"),
html.Button("Data set B", id="btn-client-side-row-model-rowdata-no-rowIDs-B"),
html.Div([
dag.AgGrid(
id="client-side-row-model-rowdata-no-rowIDs",
rowData=rowDataA,
columnDefs=columnDefs,
dashGridOptions={
"rowDragManaged": True,
"rowDragEntireRow": True
},
columnSize="autoSize",
eventListeners={'columnGroupOpened': ["setGridProps({columnSize: 'autoSize'})"]}
)
])
]
)
@callback(
Output("client-side-row-model-rowdata-no-rowIDs", "rowData"),
Output("client-side-row-model-rowdata-no-rowIDs", "columnSize"),
Input("btn-client-side-row-model-rowdata-no-rowIDs-A", "n_clicks"),
Input("btn-client-side-row-model-rowdata-no-rowIDs-B", "n_clicks"),
prevent_initial_call=True,
)
def update_rowdata(*_):
if ctx.triggered_id == 'btn-client-side-row-model-rowdata-no-rowIDs-A':
return rowDataA, 'autoSize'
else:
return rowDataB, 'autoSize'
if __name__ == "__main__":
app.run(debug=True)
^ no JS needed for this because it sets the props