How to conditional formatting with multiple index header

I’m trying to create a multiple index (merge header) dash datatable and format it with style_data_conditional but it did not work.

I tried something as below:

from dash import Dash, dash_table
import pandas as pd

app = Dash(__name__)

app.layout = dash_table.DataTable(
    columns=[
        {"name": ["", "Year"], "id": "year"},
        {"name": ["City", "Montreal"], "id": "montreal"},
        {"name": ["City", "Toronto"], "id": "toronto"},
        {"name": ["City", "Ottawa"], "id": "ottawa"},
        {"name": ["City", "Vancouver"], "id": "vancouver"},
        {"name": ["Climate", "Temperature"], "id": "temp"},
        {"name": ["Climate", "Humidity"], "id": "humidity"},
    ],
    data=[
        {
            "year": i,
            "montreal": i * 10,
            "toronto": i * 100,
            "ottawa": i * -1,
            "vancouver": i * -10,
            "temp": i * -100,
            "humidity": i * 5,
        }
        for i in range(10)
    ],
    merge_duplicate_headers=True,style_data_conditional=[
        {
            'if': {
                'filter_query': '{{{col}}} < 1'.format(col=col),
                'column_id': col
            },
            'backgroundColor': '#B10DC9',
            'color': 'white'
        } for col in df.columns
    ]
)

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

So I have 2 questions need your suggestions:

  • Is there any way to style dataframe in pandas first then use this style to pass to dash datatable?
  • Is there any way to style_data_conditional with dataframe that has multiple index.

Thank you.

Hello @hoatran,

You should check out ag-grid, it can handle this.

Merged headers will be columnDefs with children arguments.


Here is the documentation for grouping:

And here is how you can conditionally format cells:

Row formatting is similar to this, you will just use the prop name getRowStyle instead with conditional like the prop above.

1 Like

@jinnyzor: Thank for suggestion, I think I figure it out. But I have another question that if children has same name, how can I return data to exact columns. For example:

data = [{'Name':'ABC',
         '1D': 6,
         '7D': 2,
         '1M': 2,
         '1D':6,
         '7D':4,
         '1M':2}]
columnDefs = [
    {
        "headerName": "Name",
        "children": [
            {"field": "Name", "resizable": True}
        ],
    },
    {
        "headerName": "ABC",
        "children": [
            {"field": "1D", "resizable": True},
            {"field": "7D", "resizable": True},
            {"field": "1M", "resizable": True}
        ],
    },
    {
        "headerName": "BCD",
        "children": [
            {"field": "1D", "resizable": True},
            {"field": "7D", "resizable": True},
            {"field": "1M", "resizable": True}
        ],
    },
]


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

app.layout = html.Div(
    [
        dag.AgGrid(
            className="ag-theme-alpine headers1",
            columnDefs=columnDefs,
            rowData=data,
            defaultColDef=defaultColDef,
                        cellStyle={
                "styleConditions": [
                    {"condition": "value > 5", "style": {"color": "orange"}},
                ]
            },
        ),
        html.Hr(),
    ]
)


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

As you see it just pass the last data. Actually I can change children name but I just curious.

I dont think there is a way to differentiate.

I believe that you would run into issues with updating and I wouldnt recommend doing that, for obvious reasons. Haha.

You can however, display a headerName that is the same, but have different fields. :wink:

1 Like

@jinnyzor: Sorry I’m new with ag grid, so can you help me about how to display a headerName that is the same, but have different fields? Thank.

headerName is just display name, and field is the columns id, so you could:

data = [{'Name':'ABC',
         '1D': 6,
         '7D': 2,
         '1M': 2,
         '1D_2':6,
         '7D':4,
         '1M':2}]



"headerName": "BCD",
        "children": [
            {"field": "1D_2", "resizable": True, "headerName": "1D"},
            {"field": "7D", "resizable": True},
            {"field": "1M", "resizable": True}
        ],
3 Likes

@jinnyzor: Thank you, you are wonderful! I will try to learn more about ag grid.

3 Likes