DataTable - Typing

This section will provide an overview of the DataTable’s capabilities for typing, formatting,
presentation and user input processing.

Typing

The DataTable provides support for per-column typing and allows for data validation and
coercion behaviors to be configured on a per-column basis, so as to fit the needs of various
usage scenarios.

The following types are currently supported:
- numeric: includes both integers and floats
- text: string, sequence of characters
- datetime: string in the form ‘YYYY-MM-DD HH:MM:SS.ssssss’ or some truncation thereof
- any: any type of data

Additional types and specialized sub-types will be added in the future.

By default, the column type is any.

Presentation

The DataTable provides multiple presentation schemes that can vary depending on the column’s
type.

The following schemes are supported by all types:
- input: a text input field
- dropdown: see DataTable Dropdowns for more details

Markdown

The markdown presentation scheme allows for the raw value of each cell to be rendered
as Markdown. This includes features of Markdown such as links, images, headers, lists,
quotes, code blocks, and (yes, even) tables.

The markdown scheme is only supported by text-type columns, and sorting and filtering
behaviour occurs based on the raw value entered into the dataframe, instead of what gets
rendered.

e.g., if cell x has the raw value dash, and cell y has the raw value
[plotly](http://plotly.com), cell y will actually come before cell x when the table is
sorted in ascending order, despite the fact that the displayed value of cell y is
plotly.

Markdown cells also support syntax highlighting. For more details, please see “Syntax Highlighting With Markdown”.

By default, the column presentation is input.

User Input Processing

The DataTable provides a configurable input processing system that can accept, reject or
apply a default value when an input is provided. It can be configured to validate or coerce
the input to make it fit with the expected data type. Specific validation cases can be
configured on a per-column basis.

See the table’s reference on_change.action, on_change.failure
and validation column nested properties for details.

Formatting

The DataTable provides a configurable data formatting system that modifies how the data
is presented to the user.

The formatting can be configured by:
- explicitly writing the column format nested property
- using preconfigured Format Templates
- using the general purpose Format object

At the moment, only type='numeric' formatting can be configured.

DataTable with template formatting

This table contains two columns formatted by templates. The Variation (%) column is further
configured by changing the sign behavior so that both the “+” and “-” sign are visible. Additional
configuration changes can be chained after a Format(...) and a FormatTemplate.<template>(...) calls.

# -*- coding: utf-8 -*-
import dash
import dash_html_components as html
import dash_table
import dash_table.FormatTemplate as FormatTemplate
from dash_table.Format import Sign
import pandas as pd
from collections import OrderedDict

app = dash.Dash(__name__)

df_typing_formatting = pd.DataFrame(OrderedDict([
    ('city', ['Vancouver', 'Toronto', 'Calgary', 'Ottawa', 'Montreal', 'Halifax', 'Regina', 'Fredericton']),
    ('average_04_2018', [1092000, 766000, 431000, 382000, 341000, 316000, 276000, 173000]),
    ('change_04_2017_04_2018', [0.143, -0.051, 0.001, 0.083, 0.063, 0.024, -0.065, 0.012]),
]))

app.layout = html.Div([
    dash_table.DataTable(
        id='typing_formatting_1',
        data=df_typing_formatting.to_dict('rows'),
        columns=[{
            'id': 'city',
            'name': 'City',
            'type': 'text'
        }, {
            'id': 'average_04_2018',
            'name': 'Average Price ($)',
            'type': 'numeric',
            'format': FormatTemplate.money(0)
        }, {
            'id': 'change_04_2017_04_2018',
            'name': 'Variation (%)',
            'type': 'numeric',
            'format': FormatTemplate.percentage(1).sign(Sign.positive)
        }],
        editable=True
    )
])

if __name__ == '__main__':
    app.run_server(debug=True)

DataTable with formatting

This table contains columns with type numeric and datetime. The “max” columns have the default
behavior and will not allow for invalid data to be passed in. The “min” columns are more permissive.
The “Min Temperature (F)” column will default invalid entries to None and display “N/A”. The “Min
Temperature (Date)” column will not try to validate or coerce the data.

Both temperature columns are using the Format helper object to create the desired formatting. The
equivalent manual configuration is shown as comments in the code below. One can always see the resulting
configuration for a given Format object by using Format(...).to_plotly_json().

# -*- coding: utf-8 -*-
import dash
import dash_html_components as html
import dash_table
from dash_table.Format import Format, Scheme, Sign, Symbol
import pandas as pd
from collections import OrderedDict

app = dash.Dash(__name__)

df_typing_formatting = pd.DataFrame(OrderedDict([
    ('city', ['NYC', 'Montreal', 'Los Angeles']),
    ('max', [108, 99, 111]),
    ('max_date', ['1926-07-22', '1975-08-01', '1939-09-20']),
    ('min', [-15, -36, 28]),
    ('min_date', ['1934-02-09', '1957-01-15', '1913-01-07'])
]))

app.layout = html.Div([
    dash_table.DataTable(
        id='typing_formatting',
        data=df_typing_formatting.to_dict('rows'),
        columns=[{
            'id': 'city',
            'name': 'City',
            'type': 'text'
        }, {
            'id': 'max',
            'name': u'Max Temperature (˚F)',
            'type': 'numeric',
            'format': Format(
                precision=0,
                scheme=Scheme.fixed,
                symbol=Symbol.yes,
                symbol_suffix=u'˚F'
            ),
            # equivalent manual configuration
            # 'format': {
            #     'locale': {
            #         'symbol': ['', '˚F']
            #     },
            #     'specifier': '$.0f'
            # }
        }, {
            'id': 'max_date',
            'name': 'Max Temperature (Date)',
            'type': 'datetime'
        }, {
            'id': 'min',
            'name': u'Min Temperature (˚F)',
            'type': 'numeric',
            'format': Format(
                nully='N/A',
                precision=0,
                scheme=Scheme.fixed,
                sign=Sign.parantheses,
                symbol=Symbol.yes,
                symbol_suffix=u'˚F'
            ),
            # equivalent manual configuration
            # 'format': {
            #     'locale': {
            #         'symbol': ['', '˚F']
            #     },
            #     'nully': 'N/A'
            #     'specifier': '($.0f'
            # }
            'on_change': {
                'action': 'coerce',
                'failure': 'default'
            },
            'validation': {
                'default': None
            }
        }, {
            'id': 'min_date',
            'name': 'Min Temperature (Date)',
            'type': 'datetime',
            'on_change': {
                'action': 'none'
            }
        }],
        editable=True,
        style_table={'overflowX': 'scroll'}
    )
])

if __name__ == '__main__':
    app.run_server(debug=True)