Limit Horizontal Scrolling in Dash DataTable with multi-level header (no Extra Blank Space)

I’m building a Dash app using Plotly that displays two tables dash_table.DataTable with many columns. The first table has multi-level header.

The first columns of each table are fixed and horizontal scrolling is enabled for the remaining columns.

I’m experiencing an issue when scrolling horizontally the table with multi-level header, which results in excessive blank space to the right of the last column.

I have tried using CSS to control overflow properties, but without success.

Has anyone experienced this problem before?

This is the example code to replicate the issue:

import dash
from dash import dash_table, dcc, html
from dash.dependencies import Input, Output
import pandas as pd
import numpy as np

app = dash.Dash(__name__)
app.title = 'test'

# Sample Data
data = {
    'Column 1': ['A', 'B', 'C', 'D'],
    'Column 2': [1, 2, 3, 4],
    'Column 3': [5, 6, 7, 8],
    'Column 4': [9, 10, 11, 12],
    'Column 5': [13, 14, 15, 16],
    'Column 6': [13, 14, 15, 16],
    'Column 7': [13, 14, 15, 16],
    'Column 8': [13, 14, 15, 16],
    'Column 9': [13, 14, 15, 16],
    'Column 10': [9, 10, 11, 12],
    'Column 11': [13, 14, 15, 16],
    'Column 12': [13, 14, 15, 16],
    'Column 13': [13, 14, 15, 16],
    'Column 14': [13, 14, 15, 16],
    'Column 15': [13, 14, 15, 16],
    'Column 16': [9, 10, 11, 12],
    'Column 17': [13, 14, 15, 16],
    'Column 18': [13, 14, 15, 16],
    'Column 19': [13, 14, 15, 16],
    'Column 20': [13, 14, 15, 16],
    'Column 21': [13, 14, 15, 16],

}
df = pd.DataFrame(data)

app.layout = html.Div(
    children=[
        html.Div(id='raw-data', style={'display': 'none'}, children='{}'),
        html.H1(children='Test'),
        # Monthly Data Table
        html.Div(
            className="data-table-container",
            children=[
                dash_table.DataTable(
                    id='table_monthly',
                    columns=[
                    {"name": ["A", "Column 1"], "id": "Column 1"},
                    {"name": ["A", "Column 2"], "id": "Column 2"},
                    {"name": ["B", "Column 3"], "id": "Column 3"},
                    {"name": ["B", "Column 4"], "id": "Column 4"},
                    {"name": ["B", "Column 5"], "id": "Column 5"},
                    {"name": ["C", "Column 6"], "id": "Column 6"},
                    {"name": ["C", "Column 7"], "id": "Column 7"},
                    {"name": ["C", "Column 8"], "id": "Column 8"},
                    {"name": ["C", "Column 9"], "id": "Column 9"},
                    {"name": ["C", "Column 10"], "id": "Column 10"},
                    {"name": ["D", "Column 11"], "id": "Column 11"},
                    {"name": ["D", "Column 12"], "id": "Column 12"},
                    {"name": ["D", "Column 13"], "id": "Column 13"},
                    {"name": ["E", "Column 14"], "id": "Column 14"},
                    {"name": ["E", "Column 15"], "id": "Column 15"},
                    {"name": ["E", "Column 16"], "id": "Column 16"},
                    {"name": ["E", "Column 17"], "id": "Column 17"},
                    {"name": ["F", "Column 18"], "id": "Column 18"},
                    {"name": ["G", "Column 19"], "id": "Column 19"},
                    {"name": ["G", "Column 20"], "id": "Column 20"},
                    {"name": ["H", "Column 21"], "id": "Column 21"},
                    ],
                    data=df.to_dict('records'),
                    fixed_columns={'headers': True, 'data': 1},
                                         merge_duplicate_headers=True,
                    style_table={
                        'overflowX': 'auto',
                        'minWidth': '100%',
                        'width': 'max-content',  # Use max-content to fit contents
                        'maxWidth': 'none'
                    },
                    style_cell={
                        'minWidth': 100, 'maxWidth': 200, 'width': 100,
                        'textAlign': 'center'
                    }
                )
            ]
        ),
        # Daily Data Table
        html.Div(
            className="data-table-container",
            children=[
                dash_table.DataTable(
                    id='table_daily',
                    columns=[{'name': i, 'id': i} for i in df.columns],
                    data=df.to_dict('records'),
                    fixed_columns={'headers': True, 'data': 1},
                    style_table={
                        'overflowX': 'auto',
                        'minWidth': '100%',
                        'width': 'max-content',
                        'maxWidth': 'none'
                    },
                    style_cell={
                        'minWidth': 100, 'maxWidth': 200, 'width': 100,
                        'textAlign': 'center'
                    }
                )
            ]
        )
    ]
)

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

I have also posted in SO: python - Limit Horizontal Scrolling in Dash DataTable with multi-level header (no Extra Blank Space) - Stack Overflow

Any help would be much appreciated.

Thanks

Hi @giac_man

This is a known issue - see [BUG] whitespace on DataTable when merge_duplicate_headers= True · Issue #2870 · plotly/dash · GitHub

I’d recommend using dash-ag-grid as it doesn’t have this problem :slight_smile:

Hi AnnMarieW,

thanks a lot. I did search in the blog and online but I couldn’t find anything. Thanks a lot for suggesting dash-ag-grid I will give it a try.