Column Definitions

Define columns on the AgGrid component using the columnDefs property, provided as a list of dictionaries. Columns
render in the order they are provided.

See AG Grid
documentation Column Properties
for a list of all properties that can be applied to a column.

Here, we define a grid with 3 columns:

columnsDefs = [
    {'field': 'Name'},
    {'field': 'PetalLength'},
    {'field': 'PetalWidth'},
]

Use defaultColDef to set properties that all columns will inherit. Adding to the previous example, here we configure
all columns to be editable:

columnsDefs = [
    {'field': 'Name'},
    {'field': 'PetalLength'},
    {'field': 'PetalWidth'},
],
defaultColDef = {'editable': True}

And here, we make all columns editable, except the Name column:

columnsDefs = [
    {'field': 'Name', 'editable': False},
    {'field': 'PetalLength'},
    {'field': 'PetalWidth'},
],
defaultColDef = {'editable': True}

The previous example makes all columns editable, except the Name column, because when the grid creates a column, it
starts with the default column definition. It then adds properties defined via column types (see the next section) and
then finally adds properties from the specific column definition.

Basic Column Definitions

Here’s a complete example using ColumnDefs and defaultColDef. In this example, all columns are sortable, except
for the Name column, which has sortable set to False.

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/iris.csv"
)

columnDefs = [
    {"field": "Name", "sortable": False },
    {"field": "SepalWidth"},
    {"field": "PetalLength"},
    {"field": "PetalWidth"},
    {"field": "SepalLength"},
]

app.layout = html.Div(
    [
        dag.AgGrid(
            id="column-definitions-basic",
            rowData=df.to_dict("records"),
            defaultColDef={"filter": True},
            columnDefs=columnDefs,
            columnSize="sizeToFit",
            dashGridOptions={"animateRows": False}
        ),
    ]
)

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

Grouping Columns

If you want the columns to be grouped, you can include them as children like so:

# put the three columns into a group
columnDefs = [
    {
        'headerName': 'Sepal',
        'children': [
            {'field': "SepalWidth", 'headerName': 'Width'},
            {'field': "SepalLength", 'headerName': 'Length'},
        ]
    },
]

Here is an example using columns grouping:

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/iris.csv"
)

columnDefs = [
    {"field": "Name", "sortable": False },
    {
        'headerName': 'Sepal',
        'children': [
            {'field': "SepalWidth", 'headerName': 'Width'},
            {'field': "SepalLength", 'headerName': 'Length'},
        ]
    },
    {
        'headerName': 'Petal',
        'children': [
            {'field': "PetalWidth", 'headerName': 'Width'},
            {'field': "SepalLength", 'headerName': 'Length'},
        ]
    }
]

app.layout = html.Div(
    [
        dag.AgGrid(
            id="column-definitions-groups",
            rowData=df.to_dict("records"),
            defaultColDef={"filter": True},
            columnDefs=columnDefs,
            columnSize="sizeToFit",
            dashGridOptions={"animateRows": False}
        ),
    ]
)

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

Groups are explained in more detail in the
section Column Groups.

Accessing Nested Data Values

The field property is used to access values from the row data. In most cases the field will be a
property name. If, however, the row data contains nested dictionaries, you can use dot notation to
reference deep property values.

For example, if the row data has a dictionary property Sepal that contains the Width and Length of the Sepal, then
use the field values Sepal.Width and Sepal.Length to display the Width and Length.

rowData = [
    {
        'Name': 'Iris-setosa',
        'Sepal': {
            'Width': 3.5,
            'Length': 5.1
        },
        'Petal': {
            'Width': 0.2,
            'Length': 1.4
        },
    },
]

columnDefs = [
    {"field": "Name"},
    # Uses dot notation to access nested properties
    {"field": "Sepal.Width"},
    {"field": "Sepal.Length"},
    {"field": "Petal.Width"},
    {"field": "Petal.Length"},
]

Here is an example using nested properties for the fields of the grid:

import dash_ag_grid as dag
from dash import Dash, html

app = Dash(__name__)

rowData = [
    {
        'Name': 'Iris-setosa',
        'Sepal': {
            'Width': 3.5,
            'Length': 5.1
        },
        'Petal': {
            'Width': 0.2,
            'Length': 1.4
        },
    },
    {'Name': 'Iris-setosa', 'Sepal': {'Width': 3.0, 'Length': 4.9}, 'Petal': {'Width': 0.2, 'Length': 1.4}},
    {'Name': 'Iris-setosa', 'Sepal': {'Width': 3.2, 'Length': 4.7}, 'Petal': {'Width': 0.2, 'Length': 1.3}},
    {'Name': 'Iris-setosa', 'Sepal': {'Width': 3.2, 'Length': 4.6}, 'Petal': {'Width': 0.2, 'Length': 1.5}},
    {'Name': 'Iris-setosa', 'Sepal': {'Width': 3.1, 'Length': 5.0}, 'Petal': {'Width': 0.2, 'Length': 1.4}},
    {'Name': 'Iris-versicolor', 'Sepal': {'Width': 3.2, 'Length': 7.0}, 'Petal': {'Width': 1.4, 'Length': 4.7}},
    {'Name': 'Iris-versicolor', 'Sepal': {'Width': 3.2, 'Length': 6.4}, 'Petal': {'Width': 1.5, 'Length': 4.5}},
    {'Name': 'Iris-versicolor', 'Sepal': {'Width': 3.1, 'Length': 6.9}, 'Petal': {'Width': 1.5, 'Length': 4.9}},
    {'Name': 'Iris-versicolor', 'Sepal': {'Width': 2.3, 'Length': 5.5}, 'Petal': {'Width': 1.3, 'Length': 4.0}},
    {'Name': 'Iris-versicolor', 'Sepal': {'Width': 2.8, 'Length': 6.5}, 'Petal': {'Width': 1.5, 'Length': 4.6}},
    {'Name': 'Iris-virginica', 'Sepal': {'Width': 3.3, 'Length': 6.3}, 'Petal': {'Width': 2.5, 'Length': 6.0}},
    {'Name': 'Iris-virginica', 'Sepal': {'Width': 2.7, 'Length': 5.8}, 'Petal': {'Width': 1.9, 'Length': 5.1}},
    {'Name': 'Iris-virginica', 'Sepal': {'Width': 3.0, 'Length': 7.1}, 'Petal': {'Width': 2.1, 'Length': 5.9}},
    {'Name': 'Iris-virginica', 'Sepal': {'Width': 2.9, 'Length': 6.3}, 'Petal': {'Width': 1.8, 'Length': 5.6}},
    {'Name': 'Iris-virginica', 'Sepal': {'Width': 3.0, 'Length': 6.5}, 'Petal': {'Width': 2.2, 'Length': 5.8}},
]

columnDefs = [
    {"field": "Name"},
    {"field": "Sepal.Width"},
    {"field": "Sepal.Length"},
    {"field": "Petal.Width"},
    {"field": "Petal.Length"},
]

app.layout = html.Div(
    [
        dag.AgGrid(
            id="column-definitions-nested-data",
            rowData=rowData,
            defaultColDef={"filter": True},
            columnDefs=columnDefs,
            columnSize="sizeToFit",
            dashGridOptions={"animateRows": False}
        )
    ]
)

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

For alternative ways to provide cell data, such as value getters, see the documentation
on Value Getters.

Suppressing Field Dot Notation

If your row data have dots in their property names, for example, with the structure:

rowData = [
    {
        'Name': 'Iris-setosa',
        'Sepal.Width': 3.5, 'Sepal.Length': 5.1,
        'Petal.Width': 0.2, 'Petal.Length': 1.4
    },
    # ...
]

Then, trying to use the rowData parameters, setting :

columnDefs = [
    {"field": "Sepal.Width"},
    # ...
]

The grid will look for a nested value as shown in the previous example, but will not find it and the column will be
empty.

To prevent this behavior and be able to use dots in rowData parameter names, it is possible to set the Grid Option:

dashGridOptions = {"suppressFieldDotNotation": True}

This prevents the dots from being interpreted as deep references across all column definitions. For
example, "Sepal.Width" will be treated as plain text.

Column Types

Use columnTypes to specify properties that different types of column should have.

In this example, we define three column types: numberColumn, medalColumn, and nonEditableColumn, and we use these
types in the column definitions. For example, the age column has a type of numberColumn.

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"
)

columnTypes = {
    "numberColumn": {"width": 130, "filter": "agNumberColumnFilter"},
    "medalColumn": {"width": 100, "columnGroupShow": "open", "filter": False},
    "nonEditableColumn": {"editable": False},
}

columnDefs = [
    # Using default ColDef
    {"field": "athlete"},
    {"field": "sport"},
    # Using number column type
    {"field": "age", "type": "numberColumn"},
    # Overrides the default with a number filter
    {"field": "year", "filter": "agNumberColumnFilter"},
    # Using non-editable column types
    {"field": "date", "type": "nonEditableColumn", "width": 220},
    {
        "headerName": "Medals",
        "groupId": "medalsGroup",
        "children": [
            # Using medal column type
            {"headerName": "Gold", "field": "gold", "type": "medalColumn"},
            {"headerName": "Silver", "field": "silver", "type": "medalColumn"},
            {"headerName": "Bronze", "field": "bronze", "type": "medalColumn"},
            {"headerName": "Total", "field": "total", "type": "medalColumn", "columnGroupShow": "closed"},
        ],
    },
]

defaultColDef = {
    # set the default column width
    "width": 100,
    # make every column editable
    "editable": True,
    # make every column use 'text' filter by default
    "filter": "agTextColumnFilter",
    # enable floating filters by default
    "floatingFilter": True,
}

defaultColGroupDef = {
    # Moving the columns outside the group (and hence breaking the group) is not allowed
    "marryChildren": True,
}

app.layout = html.Div(
    [
        dag.AgGrid(
            id="column-definitions-type",
            columnDefs=columnDefs,
            rowData=df.to_dict("records"),
            defaultColDef=defaultColDef,
            dashGridOptions={
                'defaultColGroupDef': defaultColGroupDef,
                'columnTypes': columnTypes,
                "animateRows": False
            }
        ),
    ]
)

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

Right Aligned and Numeric Columns

Set a column definition type to rightAligned to align a column header and contents to the right.

Because right alignment is used for numbers, we also provided an alias numericColumn that can be used to align the
header and cell text to the right.

columnDefs = [
    {'headerName': 'Column A', 'field': 'a'},
    {'headerName': 'Column B', 'field': 'b', 'type': 'rightAligned'},
    {'headerName': 'Column C', 'field': 'c', 'type': 'numericColumn'},
]

The rightAligned column type works by setting the header and cell class properties as follows.

rightAligned = {
    'headerClass': 'ag-right-aligned-header',
    'cellClass': 'ag-right-aligned-cell'
}

If you manually set
either headerClass or cellClass then you may need to include the right aligned CSS classes yourself, as column type
properties are overridden by explicitly defined column properties.

Here is an example using the type 'rightAligned' and 'numericColumn'

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 = [
    {"field": "athlete"},
    {"field": "sport", "type": "rightAligned"},
    {"field": "gold", "type": "numericColumn"},
    {"field": "silver", "type": "numericColumn"},
    {"field": "bronze", "type": "numericColumn"},
]

app.layout = html.Div(
    [
        dag.AgGrid(
            id="column-definitions-right-aligned",
            columnDefs=columnDefs,
            rowData=df.to_dict("records"),
            columnSize="sizeToFit",
            dashGridOptions={"animateRows": False}
        )
    ]
)

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

Centered Columns

To center the header and the cell content, you can add the following classes to any *.css file in the assets folder:

.center-aligned-header .ag-header-cell-label {
    justify-content: center;
}

.center-aligned-cell {
    text-align: center;
}

Then add the classes to the column using headerClass and cellClass.

Alternatively, to center the content of the cells, it is possible to use "cellStyle": {'textAlign': 'center'} in the
column definition.

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 = [
    {"field": "athlete"},
    {"field": "sport", "cellClass": 'center-aligned-cell'},
    {"field": "gold", "cellStyle": {'textAlign': 'center'}},
    {"field": "silver", "cellStyle": {'textAlign': 'center'}},
    {"field": "bronze", "cellStyle": {'textAlign': 'center'}},
]

defaultColDef = {"headerClass": 'center-aligned-header'}

app.layout = html.Div(
    [
        dag.AgGrid(
            id="column-definitions-centered",
            columnDefs=columnDefs,
            rowData=df.to_dict("records"),
            defaultColDef=defaultColDef,
            columnSize="sizeToFit",
            dashGridOptions={"animateRows": False}
        ),
    ]
)

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

Column IDs

Each column generated by the grid is given a unique column ID, which is used in parts of the Grid API.

If you are using the API and the column IDs are a little complex (for example, if two columns have the same field, or
if you
are using valueGetter instead of field) then it is useful to understand how column IDs are generated.

If the user provides colId in the column definition, then this is used, otherwise field is used. If neither
colId nor field exists then a number is assigned.
Finally, the ID is ensured to be unique by appending ‘_n’ if necessary, where n is the first positive number that allows
uniqueness.

import dash_ag_grid as dag
from dash import Dash, html, 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 = [
    {'colId': 'firstCol', "field": "athlete", "headerName": "Col1"},
    {'colId': 'firstCol', "field": "athlete", "headerName": "Col2"},
    {"field": "sport", "headerName": "Col3"},
    {"field": "sport", "headerName": "Col4"},
    {"valueGetter": {"function": "params.data.age"}, "headerName": "Col5"},
    {"valueGetter": {"function": "params.data.age"}, "headerName": "Col6"},
]

app.layout = html.Div(
    [
        dag.AgGrid(
            id="column-definition-ID",
            rowData=df.to_dict("records"),
            columnDefs=columnDefs,
            defaultColDef={"filter": True},
            columnSize="sizeToFit",
            dashGridOptions={"animateRows": False}
        ),
        html.Pre(id="pre-col-ID", style={'display': 'inline-block'}),
        html.Pre(id="pre-col-def", style={'display': 'inline-block'}),
    ]
)


@callback(
    Output("pre-col-ID", "children"),
    Output("pre-col-def", "children"),
    Input("column-definition-ID", "columnState"),
    State("column-definition-ID", "columnDefs"),
    prevent_initial_call=True,
)
def display_state(col_state, col_def):
    output_colId = ["COLUMN ID\n"] + [col_state[i]['colId'] for i in range(len(col_state))]
    output_coldef = ["COLUMN DEFINITIONS\n"] + [str(col_def[i]) for i in range(len(col_def))]
    return '\n'.join(output_colId), '\n'.join(output_coldef)


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