Multi Index/Levels DataTable or AG Grid

@marsdev

As I mentioned above, it’s possible to format the grid so it looks the way you want. If you are working with dataframes it’s easier to turn mulit-level data into a flat dataframe with pandas first.

Note that the grid can accept more complex data (such as a dict or a list in cells) but it cannot accept a dataframe directly. (ie you can’t do rowData=df It needs to be in a json format.

Please be sure to read the sections on Column Groups and Row Spanning I referenced above for more information

Note also that if you would like to sort and/or filter the grid, it will be easier if you don’t include the row spanning.

from dash import Dash, html
import dash_ag_grid as dag
import pandas as pd

app = Dash(__name__)

data = [
    ['Categories', 'Tag / Vers', 'first_1', 'sec_1', 'first_2', 'sec_2', 'first_3', 'sec_3', 'first_4', 'sec_4', 'first_5', 'sec_5',
     'first_6', 'sec_6', ''],
    ['FirstCat', 'Divider1', '6', '7', '2', '3', '8', '8', '6', '7', '2', '4', '8', '8', ''],
    ['FirstCat', 'Divider2', '0', '1', '0', '1', '0', '0', '0', '1', '0', '2', '0', '0', ''],
    ['SecondCat', 'Divider1', '1', '1', '3', '2', '2', '1', '1', '2', '2', '2', '3', '1', ''],
    ['SecondCat', 'Divider2', '0', '0', '1', '0', '1', '0', '0', '1', '0', '0', '2', '0', '']
]

df = pd.DataFrame(data)
# make the first row the column names
df = pd.DataFrame(data[1:], columns=data[0])

# Replace empty strings with NaN
df.replace("", pd.NA, inplace=True)

columnDefs = [
    {
        "field": "Categories",
        "rowSpan": {"function": "params.node.id %2 === 0 ? 2 : 1"},
        "cellStyle": {"backgroundColor": "var(--ag-header-background-color"},
        "minWidth": 125
    },
    {"field": "Tag / Vers"},
] + [
    {
        "headerName": f"Level { i}",
        "children": [
            {"field": f"first_{i}", "headerName": "First"},
            {"field": f"sec_{i}", "headerName": "Second"},
        ],
    }
    for i in range(1, 7)
]


app.layout = html.Div(
    [
        dag.AgGrid(
            id="grid",
            rowData=df.to_dict("records"),
            columnDefs=columnDefs,
            columnSize="sizeToFit",
            defaultColDef={"minWidth": 100, "sortable": False},
            dashGridOptions={"suppressRowTransform": True},
        )
    ]
)

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

4 Likes