By default, the table’s height will expand in order
to render up to 250 rows.
After 250 rows, the table will display a pagination UI
which enables viewing of up to 250 rows at a time.
If you are using pagination, you can control the height by displaying
fewer rows at a time. Instead of 250 rows, you could display
10 rows at a time. By default and without wrapping,
each row takes up 30px. So 10 rows with one header would set the
table to be 330px tall. The pagination UI itself is around 60px tall.
from dash import Dash, dash_table
import pandas as pd
from collections import OrderedDict
app = Dash(__name__)
data = OrderedDict(
[
("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]),
("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]),
("Temperature", [1, -20, 3.512, 4, 10423, -441.2]),
("Humidity", [10, 20, 30, 40, 50, 60]),
("Pressure", [2, 10924, 3912, -10, 3591.2, 15]),
]
)
df = pd.DataFrame(
OrderedDict([(name, col_data * 10) for (name, col_data) in data.items()])
)
app.layout = dash_table.DataTable(
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns],
page_size=10
)
if __name__ == '__main__':
app.run(debug=True)
In this example, the pagination is done natively in the browser:
all of the data are sent up front to the browser and
Dash renders new pages as you click on the buttons. You can also
do pagination in the backend so that only 10 rows are sent to the
browser at a time (lowering network costs and memory). This is a good
strategy if you have more than 10,000-50,000 rows.
Learn about backend pagination.
If the table contains less than roughly 1000 rows,
one option is to remove pagination,
constrain the height, and display a vertical scrollbar.
from dash import Dash, dash_table
import pandas as pd
from collections import OrderedDict
app = Dash(__name__)
data = OrderedDict(
[
("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]),
("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]),
("Temperature", [1, -20, 3.512, 4, 10423, -441.2]),
("Humidity", [10, 20, 30, 40, 50, 60]),
("Pressure", [2, 10924, 3912, -10, 3591.2, 15]),
]
)
df = pd.DataFrame(
OrderedDict([(name, col_data * 10) for (name, col_data) in data.items()])
)
app.layout = dash_table.DataTable(
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns],
page_action='none',
style_table={'height': '300px', 'overflowY': 'auto'}
)
if __name__ == '__main__':
app.run(debug=True)
Limitations
If you have more than 1000 rows, then the browser will slow
down when trying to render the table. With more than 1000 rows, we
recommend switching to browser or server pagination (as above) or
virtualization (as below).
If you have more than \~1000 rows, then you could keep pagination at
the bottom of the table, constrain the height, and display a
vertical scrollbar.
from dash import Dash, dash_table
import pandas as pd
from collections import OrderedDict
app = Dash(__name__)
data = OrderedDict(
[
("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]),
("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]),
("Temperature", [1, -20, 3.512, 4, 10423, -441.2]),
("Humidity", [10, 20, 30, 40, 50, 60]),
("Pressure", [2, 10924, 3912, -10, 3591.2, 15]),
]
)
df = pd.DataFrame(
OrderedDict([(name, col_data * 10) for (name, col_data) in data.items()])
)
app.layout = dash_table.DataTable(
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns],
page_size=20, # we have less data in this example, so setting to 20
style_table={'height': '300px', 'overflowY': 'auto'}
)
if __name__ == '__main__':
app.run(debug=True)
You can also fix headers so that the table content scrolls but the
headers remain visible.
from dash import Dash, dash_table
import pandas as pd
from collections import OrderedDict
app = Dash(__name__)
data = OrderedDict(
[
("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]),
("Region", ["Montreal", "Toronto", "New York City", "Miami", "San Francisco", "London"]),
("Temperature", [1, -20, 3.512, 4, 10423, -441.2]),
("Humidity", [10, 20, 30, 40, 50, 60]),
("Pressure", [2, 10924, 3912, -10, 3591.2, 15]),
]
)
df = pd.DataFrame(
OrderedDict([(name, col_data * 10) for (name, col_data) in data.items()])
)
app.layout = dash_table.DataTable(
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns],
fixed_rows={'headers': True},
style_table={'height': 400} # defaults to 500
)
if __name__ == '__main__':
app.run(debug=True)
Limitations
fixed_rows
& table-layout: fixed
.fixed_rows
and without table-layout: fixed
overflow: 'hidden'
.Example of the wide-header limitation
If the headers are wider than the cells and the table’s
container isn’t wide enough to display all of the headers,
then the column headers will be truncated on most browsers or
will overflow on Firefox.
from dash import Dash, dash_table
import pandas as pd
from collections import OrderedDict
app = Dash(__name__)
df = pd.DataFrame(OrderedDict(
[
[
'Column {}'.format(i + 1), list(range(30))
] for i in range(15)
]
))
app.layout = dash_table.DataTable(
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns],
fixed_rows={'headers': True}
)
if __name__ == '__main__':
app.run(debug=True)
Workaround Option 1: Hiding the header overflow for Firefox users
(If you are not on Firefox, then this example will look the same as above)
from dash import Dash, dash_table
import pandas as pd
from collections import OrderedDict
app = Dash(__name__)
df = pd.DataFrame(OrderedDict(
[
[
'Column {}'.format(i + 1), list(range(30))
] for i in range(15)
]
))
app.layout = dash_table.DataTable(
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns],
fixed_rows={'headers': True},
style_header={
'overflow': 'hidden',
'textOverflow': 'ellipsis',
'maxWidth': 0,
},
)
if __name__ == '__main__':
app.run(debug=True)
Workaround Option 2: Fixing the width of the columns
from dash import Dash, dash_table
import pandas as pd
from collections import OrderedDict
app = Dash(__name__)
df = pd.DataFrame(OrderedDict(
[
[
'Column {}'.format(i + 1), list(range(30))
] for i in range(15)
]
))
app.layout = dash_table.DataTable(
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns],
fixed_rows={'headers': True},
style_cell={
'minWidth': 95, 'maxWidth': 95, 'width': 95
}
)
if __name__ == '__main__':
app.run(debug=True)
As mentioned above, the browser has difficulty rendering thousands of
rows in a table. By rendering rows on the fly as you scroll,
virtualization works around rendering performance issues
inherent with the web browser.
All of the data for your table will still be sent over the network
to the browser, so if you are displaying more than 10,000-100,000 rows
you may consider using backend pagination
to reduce the volume of data that is transferred over the network
and associated memory usage.
from dash import Dash, dash_table
import pandas as pd
from collections import OrderedDict
app = Dash(__name__)
df = pd.DataFrame(OrderedDict(
[
[
'Column {}'.format(i + 1), list(range(30))
] for i in range(15)
]
))
app.layout = dash_table.DataTable(
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns],
virtualization=True,
fixed_rows={'headers': True},
style_cell={'minWidth': 95, 'width': 95, 'maxWidth': 95},
style_table={'height': 300} # default is 500
)
if __name__ == '__main__':
app.run(debug=True)
Limitations
fixed_rows
limitations exist as mentioned above.