Grouping columns allows you to have multiple levels of columns in your header and the ability, if you want, to ‘open’/’close’ column groups to show/hide additional columns.
To group columns, provide them in a tree hierarchy to the grid. There is no limit to the number of levels you can
provide.
Here is how to create two groups of columns:
columnDefs= [
{
'headerName': 'Athlete Details',
'children': [
{ 'field': 'athlete' },
{ 'field': 'age' },
{ 'field': 'country' },
]
},
{
'headerName': 'Sports Results',
'children': [
{ 'field': 'sport' },
{ 'field': 'total', 'columnGroupShow': 'closed' },
{ 'field': 'gold', 'columnGroupShow': 'open' },
{ 'field': 'silver', 'columnGroupShow': 'open' },
{ 'field': 'bronze', 'columnGroupShow': 'open' },
]
}
]
Here is a simple example showing a column groups configuration.
import dash_ag_grid as dag
from dash import Dash, html
import pandas as pd
app = Dash(__name__)
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)
columnDefs = [
{
"headerName": "Athlete Details",
"children": [
{"field": "athlete", "width": 180},
{"field": "age", "width": 90},
{"field": "country", "width": 140},
],
},
{
"headerName": "Sports Results",
"children": [
{"field": "sport", "width": 140},
{"field": "total", "width": 100, "filter": "agNumberColumnFilter", "columnGroupShow": "closed"},
{"field": "gold", "width": 100, "filter": "agNumberColumnFilter", "columnGroupShow": "open"},
{"field": "silver", "width": 100, "filter": "agNumberColumnFilter", "columnGroupShow": "open"},
{"field": "bronze", "width": 100, "filter": "agNumberColumnFilter", "columnGroupShow": "open"},
],
},
]
app.layout = html.Div(
[
dag.AgGrid(
id="column-groups-basic",
rowData=df.to_dict("records"),
columnDefs=columnDefs,
defaultColDef={"resizable": True, "filter": True},
),
]
)
if __name__ == "__main__":
app.run(debug=True)
The list of columns in columnDefs
can be a mix of columns and column groups. Each level can have any number of columns
and column groups and in any order. The difference in column vs column group definitions is as follows:
children
attribute is mandatory for column groups and not applicable for columns.children
attribute, it is treated as a column group. If it does not have a children
groupId
is only used for groups). If you providegroupId
) they will be ignored.A group can have children shown or hidden based on the open/closed state of the group. This is controlled by
setting columnGroupShow
on one or more of the children. When a child has columnGroupShow
set, it behaves in the
following way:
'open'
: The child is only shown when the group is open.'closed'
: The child is only shown when the group is closed.If a group has any child with columnGroupShow
set as 'open'
/'closed'
, then the open/close icon will appear in
the group header. Otherwise, the icon will not be shown.
Having columns only shown when closed is useful when you want to replace a column with others. For example, in the code
snippet above (and the example below), the Total column is replaced with other columns when the group is opened.
If a group has an ‘incompatible’ set of children, then the group opening/closing will not be activated. An
incompatible set is one which will have no columns visible at some point (i.e. all are set to 'open'
or 'closed'
).
Pinned columns break groups. So if you have a group with 10 columns, 4 of which are inside the pinned area, two groups
will be created, one with 4 (pinned) and one with 6 (not pinned).
If you move columns so that columns in a group are no longer adjacent, then the group will again be broken and displayed
as one or more groups in the grid.
The grid doesn’t color the groups for you. However, you can use the column definition headerClass
for this purpose.
The headerClass
attribute is available on both columns and column groups.
columnDefs = [
# the CSS class name supplied to 'headerClass' will get applied to the header group
{"headerName": 'Athlete Details', "headerClass": 'my-css-class', "children": []}
]
The labels in the group headers are aligned to the left by default. To make the group headers center-aligned or
right-aligned, it is possible to set the CSS property justify-content
applied to the AG Grid
class .ag-header-group-cell-label
.
The following example shows how to set the header groups alignment.
View the CSS classes used for this example
These CSS classes must be added to any *.css
file in the assets folder.
See Loading CSS files for more information.
.center-aligned-group-header .ag-header-group-cell-label {
justify-content: center;
}
.right-aligned-group-header .ag-header-group-cell-label {
justify-content: right;
}
import dash_ag_grid as dag
from dash import Dash, html, dcc, Input, Output, State, callback
import pandas as pd
app = Dash(__name__)
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)
columnDefs = [
{
"headerName": "Athlete Details",
'headerClass': 'center-aligned-group-header',
"children": [
{"field": "athlete", "width": 180},
{"field": "age", "width": 90},
{"field": "country", "width": 140},
],
},
{
"headerName": "Sports Results",
'groupId': 'sports-results',
'headerClass': 'center-aligned-group-header',
"children": [
{"field": "sport", "width": 140},
{"field": "total", "width": 100, "columnGroupShow": "closed"},
{"field": "gold", "width": 100, "columnGroupShow": "open"},
{"field": "silver", "width": 100, "columnGroupShow": "open"},
{"field": "bronze", "width": 100, "columnGroupShow": "open"},
],
},
]
app.layout = html.Div(
[
dcc.RadioItems(
value='center-aligned-group-header', inline=True, id='radio-column-groups-label-align',
options=[
{'label': 'Left', 'value': ''},
{'label': 'Center', 'value': 'center-aligned-group-header'},
{'label': 'Right', 'value': 'right-aligned-group-header'},
]
),
dag.AgGrid(
id="column-groups-label-align",
rowData=df.to_dict("records"),
columnDefs=columnDefs,
defaultColDef={"resizable": True, "filter": True},
),
]
)
@callback(
Output("column-groups-label-align", "columnDefs"),
Input("radio-column-groups-label-align", "value"),
State("column-groups-label-align", "columnDefs"),
prevent_initial_call=True,
)
def change_header_align(align_class, col_def):
for group in col_def:
group['headerClass'] = align_class
return col_def
if __name__ == "__main__":
app.run(debug=True)
Sometimes you want columns of the group to always stick together. To achieve this, set the column group
property marryChildren=True
. The example below demonstrates the following:
marryChildren=True
.View the CSS classes used for this example
These CSS classes must be added to any *.css
file in the assets folder.
See Loading CSS files for more information.
.column-groups-header-background-color .ag-header-group-cell-with-group {
background-color: #00e7b1 !important;
}
import dash_ag_grid as dag
from dash import Dash, html
import pandas as pd
app = Dash(__name__)
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)
columnDefs = [
{
"headerName": "Athlete Details",
"marryChildren": True,
"children": [
{"field": "athlete"},
{"field": "country"},
],
},
{"field": "age"},
{
"headerName": "Sports Results",
"marryChildren": True,
"children": [
{"field": "sport"},
{"field": "total"},
],
},
]
app.layout = html.Div(
[
dag.AgGrid(
id="column-groups-marrychildren",
rowData=df.to_dict("records"),
columnDefs=columnDefs,
defaultColDef={"resizable": True},
columnSize="sizeToFit",
),
],
className="column-groups-headers",
)
if __name__ == "__main__":
app.run(debug=True)
When Column Groups are too wide, it might be useful to have the Header Label to be always visible while scrolling the
grid horizontally. To achieve this, set the column group property stickyLabel=True
. The example below demonstrates the
following:
Both Athlete Details and Sport Results have stickyLabel=True
.
If you scroll the grid horizontally, the header label will always be visible until it’s completely out of view.
import dash_ag_grid as dag
from dash import Dash, html
import pandas as pd
app = Dash(__name__)
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)
columnDefs = [
{
"headerName": "Athlete Details",
"stickyLabel": True,
"children": [
{"field": "athlete", "pinned": True},
{"field": "country"},
{"field": "age"},
],
},
{
"headerName": "Sports Results",
"stickyLabel": True,
"openByDefault": True,
"children": [
{"field": "sport"},
{"field": "gold", "columnGroupShow": "open"},
{"field": "silver", "columnGroupShow": "open"},
{"field": "bronze", "columnGroupShow": "open"},
{"field": "total", "columnGroupShow": "closed"},
],
},
]
app.layout = html.Div(
[
dag.AgGrid(
id="column-groups-sticky-label",
rowData=df.to_dict("records"),
columnDefs=columnDefs,
defaultColDef={"resizable": True, "width": 200},
)
],
)
if __name__ == "__main__":
app.run(debug=True)
Similar to adding and removing columns, you can also add and remove column groups. If the column definitions passed in
have column groups, then the columns will be grouped to the new configuration.
The example below shows adding and removing groups to columns.
View the CSS classes used for this example
These CSS classes must be added to any *.css
file in the assets folder.
See Loading CSS files for more information.
.column-groups-participant-group {
background-color: #119dff !important;
}
.column-groups-medals-group {
background-color: #66c2a5 !important;
}
import dash_ag_grid as dag
from dash import Dash, html, Input, Output, ctx, callback
import pandas as pd
app = Dash(__name__)
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)
participant = [
{"field": "athlete"},
{"field": "age"},
{"field": "country"},
]
medals = [
{"field": "total"},
{"field": "gold"},
{"field": "silver"},
{"field": "bronze"},
]
noGroups = participant + medals
participantInGroupOnly = [
{
"headerName": "Participant",
"headerClass": "column-groups-participant-group",
"children": participant,
},
*medals
]
medalsInGroupOnly = [
*participant,
{
"headerName": "Medals",
"headerClass": "column-groups-medals-group",
"children": medals,
},
]
participantAndMedalsInGroups = [
{
"headerName": "Participant",
"headerClass": "column-groups-participant-group",
"children": participant,
},
{
"headerName": "Medals",
"headerClass": "column-groups-medals-group",
"children": medals,
},
]
app.layout = html.Div(
[
html.Button("No Groups", id="btn-no-groups"),
html.Button("Participants in Group", id="btn-participants-in-group"),
html.Button("Medals in Group", id="btn-medals-in-group"),
html.Button("Participants and Medals in Group", id="btn-participants-and-medals-in-group"),
dag.AgGrid(
id="column-group-changes",
rowData=df.to_dict("records"),
columnDefs=noGroups,
defaultColDef={"resizable": True, "sortable": True, "filter": True, 'initialWidth': 150},
),
],
)
@callback(
Output("column-group-changes", "columnDefs"),
Input("btn-no-groups", "n_clicks"),
Input("btn-participants-in-group", "n_clicks"),
Input("btn-medals-in-group", "n_clicks"),
Input("btn-participants-and-medals-in-group", "n_clicks"),
prevent_initial_call=True,
)
def update(*_):
if ctx.triggered_id == "btn-participants-and-medals-in-group":
return participantAndMedalsInGroups
if ctx.triggered_id == "btn-participants-in-group":
return participantInGroupOnly
if ctx.triggered_id == "btn-medals-in-group":
return medalsInGroupOnly
return noGroups
if __name__ == "__main__":
app.run(debug=True)
By default, the Grid will balance the column headers with different number of levels with an empty column group header
cell. The columns which have not the same group level will have an empty Group Header cell.
Using the Column Property spanHeaderHeight
will allow the header cell to span the whole height of the header container
instead of using padding.
Note that he property
spanHeaderHeight
does not work withautoHeaderHeight
.
The example below shows when spanHeaderHeight
is used. Note the following:
spanHeaderHeight=True
and Year does not use this property.View the CSS classes used for this example
These CSS classes must be added to any *.css
file in the assets folder.
See Loading CSS files for more information.
.column-groups-headers .ag-header-group-cell-with-group {
background-color: #119dff !important;
}
import dash_ag_grid as dag
from dash import Dash, html
import pandas as pd
app = Dash(__name__)
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)
columnDefs = [
{
"headerName": "Athlete Details",
"children": [
{"field": "athlete"},
{"field": "country"},
],
},
{"field": "age", 'spanHeaderHeight': True},
{"field": "year"},
{
"headerName": "Sports Results",
"children": [
{"field": "sport"},
{"field": "total"},
],
},
]
app.layout = html.Div(
[
dag.AgGrid(
id="column-groups-span-header",
rowData=df.to_dict("records"),
columnDefs=columnDefs,
defaultColDef={"resizable": True},
columnSize="sizeToFit",
),
],
className="column-groups-headers",
)
if __name__ == "__main__":
app.run(debug=True)