我正在使用 Plotly 构建一个 Dash 应用程序,该应用程序显示两个带有许多列的表
dash_table.DataTable
。第一个表具有多级标题。
每个表格的第一列是固定的,其余列启用水平滚动。
我在水平滚动具有多级标题的表格时遇到问题,这会导致最后一列右侧出现过多的空白(请参见屏幕截图)。
我尝试过使用CSS来控制溢出属性,但没有成功。
有人遇到过这个问题吗?
这是复制问题的示例代码:
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=[
dcc.Interval(id="interval", interval=5 * 60 * 1000, n_intervals=0), # 5 minutes
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)
这是截图:
正如 Plotly 社区中对我的回复 post 这是一个已知的错误:https://github.com/plotly/dash/issues/2870
解决方案是使用
Dash Ag grid
库重写应用程序 https://dash.plotly.com/dash-ag-grid/getting-started
这是我使用 AgGrid 重写的示例应用程序的代码:
import dash
from dash import dcc, html
from dash_ag_grid import AgGrid
import pandas as pd
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=[
dcc.Interval(id="interval", interval=5 * 60 * 1000, n_intervals=0), # 5 minutes
html.Div(id='raw-data', style={'display': 'none'}, children='{}'),
html.H1(children='Test'),
# Monthly Data Table
html.Div(
className="data-table-container",
children=[
AgGrid(
id='table_monthly',
columnDefs=[
{"headerName": "A", "children": [{"headerName": "Column 1", "field": "Column 1"}, {"headerName": "Column 2", "field": "Column 2"}]},
{"headerName": "B", "children": [{"headerName": "Column 3", "field": "Column 3"}, {"headerName": "Column 4", "field": "Column 4"}, {"headerName": "Column 5", "field": "Column 5"}]},
{"headerName": "C", "children": [{"headerName": "Column 6", "field": "Column 6"}, {"headerName": "Column 7", "field": "Column 7"}, {"headerName": "Column 8", "field": "Column 8"}, {"headerName": "Column 9", "field": "Column 9"}, {"headerName": "Column 10", "field": "Column 10"}]},
{"headerName": "D", "children": [{"headerName": "Column 11", "field": "Column 11"}, {"headerName": "Column 12", "field": "Column 12"}, {"headerName": "Column 13", "field": "Column 13"}]},
{"headerName": "E", "children": [{"headerName": "Column 14", "field": "Column 14"}, {"headerName": "Column 15", "field": "Column 15"}, {"headerName": "Column 16", "field": "Column 16"}, {"headerName": "Column 17", "field": "Column 17"}]},
{"headerName": "F", "children": [{"headerName": "Column 18", "field": "Column 18"}]},
{"headerName": "G", "children": [{"headerName": "Column 19", "field": "Column 19"}, {"headerName": "Column 20", "field": "Column 20"}]},
{"headerName": "H", "children": [{"headerName": "Column 21", "field": "Column 21"}]},
],
rowData=df.to_dict('records'),
defaultColDef={"sortable": True, "filter": True, "resizable": True},
style={'height': '400px', 'width': '100%'},
)
]
),
# Daily Data Table
html.Div(
className="data-table-container",
children=[
AgGrid(
id='table_daily',
columnDefs=[{'headerName': col, 'field': col} for col in df.columns],
rowData=df.to_dict('records'),
defaultColDef={"sortable": True, "filter": True, "resizable": True},
style={'height': '400px', 'width': '100%'},
)
]
)
]
)
if __name__ == '__main__':
app.run_server(debug=True)