Cell Data Types

Working with values of different data types is made easy by using cell data types.

This allows different grid features to work without any additional configuration,
including Rendering, Editing,
Filtering, Sorting
and CSV Export (
and Row Grouping, Excel Export
and Clipboard with AG Grid Enterprise).

Enable Cell Data Types

There are five pre-defined cell data types that can be used with Dash AG
Grid: 'text', 'number', 'boolean', 'dateString' and 'object'.

Note - AG Grid also has a 'date' cell data type used for date values that are represented as JavaScript Date objects.
However, it’s not recommended for use with Dash because it’s not JSON-compatible so its behavior is only guaranteed
clientside. For more information see the AG Grid docs.

These are enabled by default, with the data type being inferred from the row data if possible
(see Inferring Data Types).

Specific cell data types can also be defined by setting the cellDataType property on the column definition.

columnDefs = [
    {
        'field': 'athlete',
        # enables cell data type `text`
        'cellDataType': 'text'
    }
]

The following example demonstrates the five pre-defined cell data types (inferred from the row data).

import json
import dash_ag_grid as dag
from dash import Dash, html, callback, Input, Output


app = Dash(__name__)

rowData = [
    {
        "item": "Item A",
        "item_number": 1,
        "date_string": "2023-01-01",
        "boolean_value": False,
        "name_dict": {"name": "Ann Marie"},
    },
    {
        "item": "Item B",
        "item_number": 2,
        "date_string": "2023-02-01",
        "boolean_value": True,
        "name_dict": {"name": "Bryan"},
    },
    {
        "item": "Item C",
        "item_number": 3,
        "date_string": "2023-03-01",
        "boolean_value": True,
        "name_dict": {"name": "Alex"},
    },
    {
        "item": "Item D",
        "item_number": 4,
        "date_string": "2023-04-01",
        "boolean_value": False,
        "name_dict": {"name": "Sebastien"},
    },
]

columnDefs = [
    {"field": "item", "headerName": "Text"},
    {"field": "item_number", "headerName": "Number"},
    {"field": "date_string", "headerName": "dateString"},
    {"field": "boolean_value", "headerName": "Boolean"},
    {"field": "name_dict", "headerName": "Object"},
]


defaultColDef = {
    "flex": 1,
    "minWidth": 125,
    "filter": True,
    "floatingFilter": True,
    "editable": True,
}

dataTypeDefinitions = {
    "object": {
        "baseDataType": "object",
        "extendsDataType": "object",
        "valueParser": {"function": "({ name: params.newValue })"},
        "valueFormatter": {"function": "params.value == null ? '' : params.value.name"},
    },
}
app.layout = html.Div(
    [
        dag.AgGrid(
            id="grid-cell-data-types",
            columnDefs=columnDefs,
            rowData=rowData,
            defaultColDef=defaultColDef,
            dashGridOptions={"dataTypeDefinitions": dataTypeDefinitions, "animateRows": False},
        ),
        html.Pre(id="output-cell-data-types"),
    ],
)


@callback(
    Output("output-cell-data-types", "children"),
    Input("grid-cell-data-types", "cellValueChanged"),
    Input("grid-cell-data-types", "virtualRowData"),
)
def update(changed, data):
    return json.dumps(data, indent=2)


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

Inferring Data Types

By default, the grid will infer cell data types the first time that row data is passed into the grid.

For inference to work for a column, it must contain non-null values and have the field property set. The resolved
column definition (including the default column definition and column types) must also not have the Value Getter, Value
Parser or reference data properties set, or be
using Sparklines. If these conditions are not met, no cell data
type will be set (it will need to be defined directly on the column if desired).

Data type inference can be disabled by setting cellDataType = False on an individual column, or for all columns on
the Default Column Definition.

columnDefs = [
    {
        'field': 'age',
        # disable cell data type 
        'cellDataType': False
    }
]

Note that where inference is possible, but it does not match any of the pre-defined cell data types, it will default
to object.

Inferring cell data types only works for
the Client-Side Row Model. For other row models, you
will need to define cell data types for each column.

Pre-Defined Cell Data Types

Each of the pre-defined cell data types work by setting specific column definition properties with default
values/functions. This enables the different grid features to work correctly for that data type.

The column definition properties that are set based on the cell data type will override any in
the Default Column Definition, but will be overridden by
any Column Type properties as well as
properties set directly on individual column definitions. Note that for filterParams, only nested properties on the
Default Column Definition will be overridden (rather than the entire object).

If you wish to override one of the properties set below for all types, you can do so by creating
a Column Type, and assigning the column type
to the Default Column Definition.

All the cell data types set the following (unless specified):

When using cell data types, the Value Formatter will not run for values in group columns (as they have already been
formatted), or for aggregated values where the data type can differ. To apply custom formatting in these cases, cell
data types will need to be disabled for the underlying columns.

Text

The 'text' cell data type is used for string values. As most grid functionality works directly with string values,
the 'text' cell data type does not set any properties outside of the ones specified above for all data types.

Number

The 'number' cell data type is used for number values.

The following properties are set:

To show only a certain number of decimal places, you
can Override the Pre-Defined Cell Data Type Definitions
and provide your own Value Formatter. It is also possible to control the number of decimal places allowed during
editing, by providing a precision to
the Number Cell Editor

Boolean

The 'boolean' cell data type is used for boolean values.

The following properties are set:

Date as String

The 'dateString' cell data type is used for date values that are represented as string values.

This data type uses the ISO string format 'yyyy-mm-dd'. If you wish to use a different date format, then you
can Override the Pre-Defined Cell Data Type Definitions.

The following properties are set:

Object

The 'object' cell data type is used for values that are complex objects (like none of the above data types).

If you have different types of complex object, you will want
to Provide Custom Cell Data Types.

For objects to work properly, you must provide a Value Formatter, and a Value Parser if editing is enabled. This is
because their behaviour needs to change based on the object structure. Generally these should be provided on the data
type definition, but they can be provided directly on the column if necessary.

The following properties are set:

Providing Custom Cell Data Types

Custom cell data types can be added by setting the grid option dataTypeDefinitions.
For more details, see the AG Grid
documentation dataTypeDefinitions.

dataTypeDefinitions = {
    'percentage': {
        'extendsDataType': 'number',
        'baseDataType': 'number',
        "valueFormatter": {"function": "params.value == null ? '' :  d3.format(',.1%')(params.value)"}
    }
}

Each custom data type definition must have a baseDataType of one of the
five Pre-Defined Cell Data Types, which
represents the data type of the underlying cell values.

Data type definitions support inheritance via the extendsDataType property. Each custom cell data type must either
extend one of the pre-defined types, or another custom type. Any non-overridden properties are inherited from the parent
definition. To prevent inheriting properties from the parent definition, suppressDefaultProperties = True can be set
on the definition.

Column Types can be set via the columnTypes
property to allow other column definition properties to be set for the data type. By default, these will replace any
column types against the parent definition. To allow these to be appended to the parent definition column types,
appendColumnTypes = True can be set.

To allow Inferring Cell Data Types to work for custom
types, the dataTypeMatcher property can be set. This returns true if the value is of the correct type. Note that the
data type matchers will be called in the order they are provided in dataTypeDefinitions (for custom only), and then
the pre-defined data type matchers will be called.

The following example demonstrates providing custom cell data types:

In this example, the cell data type is not inferred, as it is set in the column definitions.

import dash_ag_grid as dag
from dash import Dash, html

app = Dash(__name__)

rowData = [
    {
        "company": {"name": "Apple"},
        "sector": {"sector": "Info Tech"},
        "weight": 0.074657,
    },
    {"company": {"name": "Microsoft"}, "sector": {"sector": "Info Tech"}, "weight": 0.06948567},
    {"company": {"name": "Amazon"}, "sector": {"sector": "Consumer Discretionary"}, "weight": 0.02730574},
    {"company": {"name": "Alphabet"}, "sector": {"sector": "Communication Services"}, "weight": 0.0182345},
]

columnDefs = [
    {"field": "company", "cellDataType": "company"},
    {"field": "sector", "cellDataType": "sector"},
    {"field": "weight", "cellDataType": "percentage", "filter": "agNumberColumnFilter"},
]

defaultColDef = {"flex": 1, "minWidth": 150, "filter": True, "editable": True}

dataTypeDefinitions = {
    "company": {
        "baseDataType": "object",
        "extendsDataType": "object",
        "valueParser": {
            "function": """
            params.newValue == null || params.newValue === ''
              ? null
              : { name: params.newValue }
            """
        },
        "valueFormatter": {"function": "params.value == null ? '' : params.value.name"},
    },
    "sector": {
        "baseDataType": "object",
        "extendsDataType": "object",
        "valueParser": {
            "function": """
           params.newValue == null || params.newValue === ''
             ? null
             : { sector: params.newValue }
           """
        },
        "valueFormatter": {
            "function": "params.value == null ? '' : params.value.sector"
        },
    },
    "percentage": {
        "baseDataType": "number",
        "extendsDataType": "number",
        "valueFormatter": {
            "function": "params.value == null ? '' :  d3.format(',.1%')(params.value)"
        },
    },
}

app.layout = html.Div(
    [
        dag.AgGrid(
            id="grid-cell-data-types-custom",
            columnDefs=columnDefs,
            rowData=rowData,
            defaultColDef=defaultColDef,
            dashGridOptions={"dataTypeDefinitions": dataTypeDefinitions, "animateRows": False},
        ),
    ],
)

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

Overriding the Pre-Defined Cell Data Type Definitions

The default properties for
the Pre-Defined Cell Data Types
can be overridden. For example, this is required if a different date format is desired.

This works in the same way as
when Providing Custom Cell Data Types.

The following example demonstrates overriding pre-defined cell data types:

Note that this example define the full dataTypeDefinitions parameter in Javascript.

View the JavaScript function used for this example.

This JavaScript function must be added to the dashAgGridFunctions.js file in the assets folder.
See JavaScript Functions
for more information.

var dagfuncs = (window.dashAgGridFunctions = window.dashAgGridFunctions || {});

dagfuncs.dataTypeDefinitions = {
    dateString: {
        baseDataType: 'dateString',
        extendsDataType: 'dateString',
        valueParser: (params) =>
            params.newValue != null &&
            params.newValue.match('\\d{2}/\\d{2}/\\d{4}')
                ? params.newValue
                : null,
        valueFormatter: (params) => (params.value == null ? '' : params.value),
        dataTypeMatcher: (value) =>
            typeof value === 'string' && !!value.match('\\d{2}/\\d{2}/\\d{4}'),
        dateParser: (value) => {
            if (value == null || value === '') {
                return undefined;
            }
            const dateParts = value.split('/');
            return dateParts.length === 3
                ? new Date(
                    parseInt(dateParts[2]),
                    parseInt(dateParts[1]) - 1,
                    parseInt(dateParts[0])
                )
                : undefined;
        },
        dateFormatter: (value) => {
            if (value == null) {
                return undefined;
            }
            const date = String(value.getDate());
            const month = String(value.getMonth() + 1);
            return `${date.length === 1 ? '0' + date : date}/${
                month.length === 1 ? '0' + month : month
            }/${value.getFullYear()}`;
        },
    },
};
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": 'age'}, {"field": 'date'}]

defaultColDef = {"filter": True, "floatingFilter": True, "editable": True}

app.layout = html.Div(
    [
        dag.AgGrid(
            id="grid-cell-data-types-overriding",
            columnDefs=columnDefs,
            rowData=df.to_dict("records"),
            defaultColDef=defaultColDef,
            dashGridOptions={"dataTypeDefinitions": {"function": "dataTypeDefinitions"}},
        ),
    ],
)

app.run(debug=True)

Right Align Numeric columns

Be sure to click on the “more details” link in the AG Grid docs dataTypeDefinitions
section to see more information on the cell data type props.

It’s possible to make all numeric columns right aligned by overriding the number pre-defined cell data type. In the
data type definitions, set the columnTypes=rightAligned. See more information in the Column Types section.

Here we define the dataTypeDefinitions for the number cell data type:


dataTypeDefinitions = {
    "number": {
        "baseDataType": "number",
        "extendsDataType": "number",
        "columnTypes": "rightAligned",
        "appendColumnTypes": True
    },
}
dag.AgGrid(
    dashGridOptions={"dataTypeDefinitions":  dataTypeDefinitions},
)

In this example, note that the numeric columns are automatically right aligned for all datasets selected in the dropdown.

import dash
import dash_ag_grid as dag
from dash import Dash, dcc, html, callback, Input, Output
import plotly.express as px

app = Dash(__name__)

datasets = {
    "gapminder": px.data.gapminder(),
    "tips": px.data.tips(),
    "iris": px.data.iris(),
    "stocks": px.data.stocks(),
}

dataTypeDefinitions = {
    "number": {
        "baseDataType": "number",
        "extendsDataType": "number",
        "columnTypes": "rightAligned",
        "appendColumnTypes": True
    },
}

app.layout = html.Div(
    [
        html.Label("Select Dataset:", htmlFor="select-cell-data-types-numeric"),
        dcc.Dropdown(list(datasets), value="gapminder", id="select-cell-data-types-numeric", ),
        dag.AgGrid(
            id="grid-cell-data-types-numeric",
            dashGridOptions={"dataTypeDefinitions":  dataTypeDefinitions},
        ),
    ],
)

@callback(
    Output("grid-cell-data-types-numeric", "rowData"),
    Output("grid-cell-data-types-numeric", "columnDefs"),
    Input("select-cell-data-types-numeric", "value"),
)
def update(value):
    if value is None:
        return dash.no_update
    rowData = datasets[value].to_dict("records")
    columnDefs = [{"field": i} for i in datasets[value].columns]
    return rowData, columnDefs


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

Date as String Data Type Definition

If overriding 'dateString' due to a different date format, then a couple of extra properties need to be set to handle
conversion between Date objects and the desired string format.