Datatable
Datatable Creation
import dash
import pandas as pd
from dash import html
from dash import dcc
from dash import dash_table
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
app = dash.Dash(__name__)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([dash_table.DataTable(id = 'table'),
html.Button('Click', id = 'button'),
html.Div(id = 'output')
])
@app.callback(
Output('table', 'data'),
Output('table', 'columns'),
Output('table', 'page_size'),
Output('table', 'page_current'),
Input('button', 'n_clicks'))
def update_table(n_clicks):
if not n_clicks:
raise PreventUpdate
data=df.to_dict('records')
columns=[{'id': c, 'name': c} for c in df.columns]
return data, columns, 20, 1
if __name__ == '__main__':
app.run_server(debug=True)
Datatable Style
import collections
import dash
import pandas as pd
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
from dash import html
from dash import dcc
from dash import dash_table
import plotly.graph_objects as go
app = dash.Dash(__name__)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = dash_table.DataTable(
style_data={
'whiteSpace': 'normal',
'height': 'auto',
},
style_header = {'color': 'red'},
style_cell_conditional=[
{'if': {'column_id': 'country'},
'width': '30%'},
{'if': {'column_id': 'pop'},
'width': '30%'},
],
style_cell = {'width': '180px'},
style_table = {'color': 'silver'},
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns],
fixed_rows = {'headers': True, 'data': 1},
page_size = 100,
page_action = 'native',
tooltip_data=[
{
column: {'value': str(value), 'type': 'markdown'}
for column, value in row.items()
} for row in df.to_dict('records')
],
tooltip_duration=None,
)
if __name__ == '__main__':
app.run_server(debug=True)
columns, list of dist
- describes various aspects about each individual column
- id, string, the id of the column, not visible in the table
- name, string, the name of the column, appears in the column header
data, list of dicts
- The contents of the table
- Can be generated from pandas dataframe
data=df.to_dict('records')
page_size, int
- the number of rows that will be displayed on a page when page_action is 'custom' or 'native'
page_action, string
- 'native', all data is passed to the table up-front
- 'custom', data is passed to the table one page at a time
- 'none', disables paging, render all of the data at once
fixed_rows, dict
- headers, boolean, fix header and filter rows
- data, int, the number of fixed content rows
- automatically decide the table height
fixed_columns, dict
- headers, bollean, fix all operation columns (see row_deletable and row_selectable)
- data, int, the number of fixed content columns
Styles Priority
1. style_data_conditional
2. style_data # excludes the header and filter cells.
3. style_filter_conditional
4. style_filter
5. style_header_conditional
6. style_header # header cells
7. style_cell_conditional
8. style_cell # includes the header cells, the data cells, and the filter cells
style_table, dict
- used for setting properties like the width or the height of the table
style_table = {'height': '600px', 'overflowY': 'auto', 'width': '300px'}
style_cell, dict
- CSS styles to be applied to each individual cell of the table
- includes the header cells, the data cells, and the filter cells
style_cell = {'background-color': 'rgba(51, 51, 51, 1)', # background color
'text-align':'center', # text alignment
'minWidth': 95, 'maxWidth': 95, 'width': 95, # fixed cell width
}
style_cell_conditional, list of dicts
- Conditional CSS styles for the cells
- if, dict
- column_id, string
- column_type, 'any' (default), 'numeric', 'text' or 'datetime'
# widths of individual columns
style_cell_conditional=[
{'if': {'column_id': 'Date'},
'width': '30%'},
{'if': {'column_id': 'Region'},
'width': '30%'},
]
style_header
- CSS styles to be applied to each individual header cell
- excludes the data and filter cells
style_header = {'color': 'red', 'fontWeight': 'bold'}
style_header_conditional, list of dicts
- Conditional CSS styles for the header cells
- if, dict
- column_editable, boolean
- column_id, string, or list of strings
- column_type, 'any' (default), 'numeric', 'text' or 'datetime'
- header_index, number, or list of numbers, 'odd', or 'even'
style_header_conditional = [
{'if': {'column_id': 'year'},
'width': '40%', 'color': 'blue'
}
]
style_data, dict
- CSS styles to be applied to each individual data cell
- excludes the header and filter cells
style_data = {'font-size': '18px'} # excludes the header and filter cells
style_data_conditional, list of dicts
- Conditional CSS styles for the data cells
- if, dict
- column_editable
- column_id, string, list of strings
- column_type, 'any' (default), 'numeric', 'text' or 'datetime'
- filter_query, string
- row_index, 'odd', 'even', or list of numbers
- state, 'active' or 'selected'
style_data_conditional=[
{
'if': {'row_index': 'odd', 'state': 'active'}, # and
'backgroundColor': 'rgb(248, 248, 248)',
'color': 'white',
},
# union
{
'if': {'state': 'active'},
'backgroundColor': 'black'
}
],
style_as_list_view
- remove borders between the columns
style_as_list_view=True, # not have borders between the columns
filtery_query, string
- =, > >=, <, <=, numeric, text, datetime, and any (default)
- contains
- datestartswith
- is nil
- is blank
style_data_conditional=[
{
'if': {
'filter_query': '{year} > 2000 &↦ {year} < 2005',
'column_id': ['country', 'year'] # colored columns, by default, color the whole row
},
'backgroundColor': 'tomato',
'color': 'white'
},
],
style_data_conditional=[
{
'if': {
'filter_query': '{{year}} = {}'.format(df['year'].max()),
},
'backgroundColor': 'tomato', # color the whole row
'color': 'white'
},
],
style_data_conditional=[
{
'if': {
'filter_query': '{continent} contains "As"',
'column_id': 'year' # colored column
},
'backgroundColor': 'RebeccaPurple'
},
],
display the top n values
style_data_conditional=[
{
'if': {
'filter_query': '{{year}} = {}'.format(i),
},
'backgroundColor': 'RebeccaPurple'
}
for i in df['year'].nlargest(3)
],
highlight the values below average in each column
style_data_conditional=[
{
'if': {
'filter_query': '{{{}}} <= {}'.format(col, value),
'column_id': col
},
'backgroundColor': '#FF4136',
'color': 'white'
} for (col, value) in df.quantile(0.5).iteritems()
],
Number Formating
from dash.dash_table.Format import Format, Group, Scheme, Trim
# the general form of a specifier in d3 rules
[[fill]align][sign][symbol][0][width][,][.precision][type]
Delimiter
columns=[{'id': c, 'name': c}
if c != 'pop' else
{'id': c, 'name': c+'_', 'type':'numeric', 'format':Format(group=True, groups=[2, 3, 2])} # 3,18,899,23
for c in df.columns],
Padding
columns=[{'id': c, 'name': c}
if c != 'pop' else
{'id': c, 'name': c+'_', 'type':'numeric', 'format':Format(padding=True, padding_width=18)}
for c in df.columns],
Precision
columns=[{'id': c, 'name': c}
if c != 'pop' else
{'id': c, 'name': c+'_', 'type':'numeric', 'format':Format(precision=4, scheme=Scheme.fixed)}
for c in df.columns],
Symbol
columns=[{'id': c, 'name': c}
if c != 'pop' else
{'id': c, 'name': c+'_', 'type':'numeric', 'format':Format(symbol=Symbol.yes, symbol_prefix='@')}
for c in df.columns],
Interaction Operations
sort_action='native' # sorting by columns
filter_action='native' # filtering by columns
editable=True # editing the cells
row_deletable=True # deleting rows
row_selectable='single' | 'multi' # Selecting rows
page_action='native' | 'custom' # paging
Column/Columns Selection
column_selectable, 'single', or 'multi'
- enable the table to be selectable
columns[i].selectable, boolean
- make a specific column selectable
selected_columns, list of strings
- the ids of columns that are selected
derived_viewport_selected_columns, list of strings
- the ids of the selected_columns that are not currently hidden
import dash
import pandas as pd
from dash import html
from dash import dcc
from dash import dash_table
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
app = dash.Dash(__name__)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([dash_table.DataTable(
id = 'table',
data=df.to_dict('records'),
columns=[{'id': c, 'name': c, 'selectable': True} for c in df.columns],
column_selectable='multi',
selected_columns = ['year'],
hidden_columns = ['year'],
page_size = 20
),
html.Div(id = 'output')
])
@app.callback(
Output('output', 'children'),
Input('table', 'selected_columns'),
Input('table', 'derived_viewport_selected_columns'))
def update_table(columns, view_columns):
print(type(columns), columns)
print(type(view_columns), view_columns)
return columns
if __name__ == '__main__':
app.run_server(debug=True)
Column/Columns Hidding
automatically add a toggle button to switch columns shown/hidden
hidden_columns, list of strings
columns[i].hideable, boolean
- make a specific column hideable
import dash
import pandas as pd
from dash import html
from dash import dcc
from dash import dash_table
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
app = dash.Dash(__name__)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([dash_table.DataTable(
id = 'table',
data=df.to_dict('records'),
columns=[{'id': c, 'name': c, 'hideable':True} for c in df.columns],
hidden_columns = ['year'],
page_size = 20
),
html.Div(id = 'output')
])
@app.callback(
Output('output', 'children'),
Input('table', 'hidden_columns'))
def update_table(columns):
return str(columns)
if __name__ == '__main__':
app.run_server(debug=True)
Column/Columns Deletion
deletable, boolean
- enable column deletion
- the deleted columns are removed from data
import dash
import pandas as pd
from dash import html
from dash import dcc
from dash import dash_table
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
app = dash.Dash(__name__)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([dash_table.DataTable(
id = 'table',
data=df.to_dict('records'),
columns=[{'id': c, 'name': c, 'deletable': True} for c in df.columns],
page_size = 20
),
html.Div(id = 'output')
])
@app.callback(
Output('output', 'children'),
Input('table', 'columns'),
Input('table', 'data'))
def update_table(columns, data):
print(len(data[0]))
column_names = [column['name'] for column in columns]
return str(column_names)
if __name__ == '__main__':
app.run_server(debug=True)
Column/Columns Clearing
clearable, boolean
- be able to remove the content of columns
- the cleared columns are removed from data
import dash
import pandas as pd
from dash import html
from dash import dcc
from dash import dash_table
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
app = dash.Dash(__name__)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([dash_table.DataTable(
id = 'table',
data=df.to_dict('records'),
columns=[{'id': c, 'name': c, 'clearable': True} for c in df.columns],
page_size = 20
),
html.Div(id = 'output')
])
@app.callback(
Output('output', 'children'),
Input('table', 'columns'),
Input('table', 'data'))
def update_table(columns, data):
print(data[0])
column_names = [column['name'] for column in columns]
return str(column_names)
if __name__ == '__main__':
app.run_server(debug=True)
Column/Columns Renaming
renamable, boolean
- columns, the column names are changed
- data, the column names of data are not changed
import dash
import pandas as pd
from dash import html
from dash import dcc
from dash import dash_table
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
app = dash.Dash(__name__)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([dash_table.DataTable(
id = 'table',
data=df.to_dict('records'),
columns=[{'id': c, 'name': c, 'renamable': True} for c in df.columns],
page_size = 20
),
html.Div(id = 'output')
])
@app.callback(
Output('output', 'children'),
Input('table', 'columns'),
Input('table', 'data'))
def update_table(columns, data):
print(data[0])
column_names = [column['name'] for column in columns]
return str(column_names)
if __name__ == '__main__':
app.run_server(debug=True)
Native Row/Rows Selection
row_selectable, 'single', 'multi', False, enable row selection
selected_rows, list of integers
- select, the indices of selected rows in table data
- sort, sorting does not impact the indices of selected rows
- delete, delete rows from table data, the indices of selected rows are the indices after deletion
- filter, display only, not change table data and selected row
derived_viewport_indices, list of integers, the original indices of rows in the current page
- sort, the indices of rows in the current page in original table data, not change indices of table data
- delete, the indices of rows in the current page, which are the indices after deletion
- filter, the indices of rows in the current page after filtering, which are the indices in the current table data, not change table data
derived_viewport_selected_rows, list of integers
- select, the indices of the selected rows in the current page, starts from zero for each page
- sort, the indices of the selected rows in the current page after sorting, starts from zero for each page
- delete, the indices of the selected rows in the current page after deletion, starts from zero for each page
- filter, the indices of the selected rows in the current page after filtering, starts from zero for each page, not change table data
derived_viewport_data, list of dicts, the data on the current page
- sort, the data in the current page after sorting
- delete, the data in the current page after deletion
- filter, the data in the current page after filtering
derived_virtual_indices, list of integers, the indices across all pages
- sort, the indices of the sorted rows across all pages
- delete, the indices of the rows across all pages after deletion
- filter, the indices of the filtered rows across all pages
derived_virtual_selected_rows, list of integers
- select, the indices of the selected_rows across all pages
- sort, the indices of the sorted rows across all pages
- delete, the indices after deletion across all pages
- filter, the indices of the filtered rows across all pages
derived_virtual_data, list of dicts, the visible data across all pages
- sort, sorted rows across all pages
- delete, rows after deletion across all pages
- filter, rows after filtering across all pages
filter_action
- 'native', the filtering logic is handled by the table
- 'custom', program the filtering through a callback
Operators
- =
- contains
- datestartswith
- >, <, >=, <=, !=
import dash
import pandas as pd
from dash import html
from dash import dcc
from dash import dash_table
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
app = dash.Dash(__name__)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([dash_table.DataTable(
id = 'table',
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns],
row_selectable = 'multi',
row_deletable = True,
filter_action = 'native', # native filter
page_size = 20,
sort_action="native", # native sort
sort_mode="multi",
page_action='native', # native paging
),
html.Div(id = 'output')
])
@app.callback(
Output('output', 'children'),
Input('table', 'selected_rows'),
Input('table', 'derived_viewport_indices'),
Input('table', 'derived_virtual_indices'),
Input('table', 'derived_viewport_selected_rows'),
Input('table', 'derived_virtual_selected_rows'),
Input('table', 'data'),
Input('table', 'derived_viewport_data'),
Input('table', 'derived_virtual_data'))
def update_table(indices, viewport_indices, virtual_indices, selected_indices, virtual_selected_indices, data, viewport_data, virtual_data):
#if not indices:
#raise PreventUpdate
#print(indices)
#print(viewport_indices)
#print(virtual_indices)
#print(selected_indices)
#print(virtual_selected_indices)
#if viewport_data:
#print(len(viewport_data))
#return str(viewport_data)
if virtual_data:
print(virtual_data[10])
print(len(virtual_data))
return len(data)
#return str([data[index] for index in indices])
if __name__ == '__main__':
app.run_server(debug=True)
Custom Row/Rows Selection
# backend paging
import dash
from dash.dependencies import Input, Output
from dash import dash_table
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')
df[' index'] = range(1, len(df) + 1)
app = dash.Dash(__name__)
PAGE_SIZE = 5
app.layout = dash_table.DataTable(
id='datatable-paging',
columns=[
{"name": i, "id": i} for i in sorted(df.columns)
],
page_current=0,
page_size=PAGE_SIZE,
page_action='custom'
)
@app.callback(
Output('datatable-paging', 'data'),
Output('datatable-paging', 'page_count'),
Input('datatable-paging', "page_current"),
Input('datatable-paging', "page_size"))
def update_table(page_current,page_size):
num = int(df.shape[0]/PAGE_SIZE)
if df.shape[0]%PAGE_SIZE > 0:
num += 1
return df.iloc[
page_current*page_size:(page_current+ 1)*page_size
].to_dict('records'), num
if __name__ == '__main__':
app.run_server(debug=True)
# backend paging with sorting
import dash
from dash import html
from dash.dependencies import Input, Output, State
from dash import dash_table
from dash.exceptions import PreventUpdate
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')
df[' index'] = range(1, len(df) + 1)
app = dash.Dash(__name__)
PAGE_SIZE = 5
app.layout = html.Div([dash_table.DataTable(
id='datatable-paging',
columns=[
{"name": i, "id": i} for i in sorted(df.columns)
],
row_selectable='single',
cell_selectable=False,
page_current=0,
page_size=PAGE_SIZE,
page_action='custom',
sort_action='custom',
sort_mode='multi',
sort_by=[]
),
html.Div(id='display')])
@app.callback(
Output('datatable-paging', 'data'),
Output('datatable-paging', 'page_count'),
Input('datatable-paging', "page_current"),
Input('datatable-paging', "page_size"),
Input('datatable-paging', "sort_by"))
def update_table(page_current,page_size, sort_by):
num = int(df.shape[0]/PAGE_SIZE)
if df.shape[0]%PAGE_SIZE > 0:
num += 1
print(sort_by)
if len(sort_by):
dff = df.sort_values(
[col['column_id'] for col in sort_by],
ascending=[
col['direction'] == 'asc'
for col in sort_by
],
inplace=False
)
print('Sorted ...')
else:
# No sort is applied
dff = df
return dff.iloc[
page_current*page_size:(page_current+ 1)*page_size
].to_dict('records'), num
@app.callback(
Output('display', 'children'),
Input('datatable-paging', 'derived_viewport_selected_rows'),
State('datatable-paging', 'data'))
def display_output(index, rows):
print(index)
if not index:
raise PreventUpdate
if len(index) == 0:
raise PreventUpdate
return str(rows[index[0]])
if __name__ == '__main__':
app.run_server(debug=True)
# backend paging with filtering and sorting
import dash
from dash.dependencies import Input, Output
from dash import dash_table
import pandas as pd
app = dash.Dash(__name__)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')
PAGE_SIZE = 5
app.layout = dash_table.DataTable(
id='table-filtering',
columns=[
{"name": i, "id": i} for i in sorted(df.columns)
],
# backend paging parameters
page_current=0,
page_size=PAGE_SIZE,
page_action='custom',
# filtering parameters
filter_action='custom',
filter_query='',
# sorting parameters
sort_action='custom',
sort_mode='multi',
sort_by=[]
)
operators = [['ge ', '>='],
['le ', '<='],
['lt ', '<'],
['gt ', '>'],
['ne ', '!='],
['eq ', '='],
['contains '],
['datestartswith ']]
def split_filter_part(filter_part):
for operator_type in operators:
for operator in operator_type:
if operator in filter_part:
name_part, value_part = filter_part.split(operator, 1)
name = name_part[name_part.find('{') + 1: name_part.rfind('}')]
value_part = value_part.strip()
v0 = value_part[0]
if (v0 == value_part[-1] and v0 in ("'", '"', '`')):
value = value_part[1: -1].replace('\\' + v0, v0)
else:
try:
value = float(value_part)
except ValueError:
value = value_part
# word operators need spaces after them in the filter string,
# but we don't want these later
return name, operator_type[0].strip(), value
return [None] * 3
@app.callback(
Output('table-filtering', "data"),
Output('table-filtering', "page_count"),
Input('table-filtering', "page_current"),
Input('table-filtering', "page_size"),
Input('table-filtering', 'sort_by'),
Input('table-filtering', "filter_query"))
def update_table(page_current,page_size, sort_by, filter):
# filtering
filtering_expressions = filter.split(' && ')
dff = df
for filter_part in filtering_expressions:
col_name, operator, filter_value = split_filter_part(filter_part)
if operator in ('eq', 'ne', 'lt', 'le', 'gt', 'ge'):
dff = dff.loc[getattr(dff[col_name], operator)(filter_value)]
elif operator == 'contains':
dff = dff.loc[dff[col_name].str.contains(filter_value)]
elif operator == 'datestartswith':
dff = dff.loc[dff[col_name].str.startswith(filter_value)]
# get number of pages
num = int(dff.shape[0]/PAGE_SIZE)
if dff.shape[0]%PAGE_SIZE > 0:
num += 1
# sorting
print(sort_by)
if len(sort_by):
dff = dff.sort_values(
[col['column_id'] for col in sort_by],
ascending=[
col['direction'] == 'asc'
for col in sort_by
],
inplace=False
)
# backend paging
return dff.iloc[
page_current*page_size:(page_current+ 1)*page_size].to_dict('records'), num
if __name__ == '__main__':
app.run_server(debug=True)
Cell
active_cell
- the active data cell selected, contains row, column, and column id of the cell in the current page
start_cell
- the start cell of the selected area, usually is the active_cell
end_cell
- the end cell of the selected area
selected_cells, a list of dict
import dash
import pandas as pd
from dash import html
from dash import dcc
from dash import dash_table
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
app = dash.Dash(__name__)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([dash_table.DataTable(
id = 'table',
data=df.to_dict('records'),
columns=[{'id': c, 'name': c, 'selectable': True} for c in df.columns],
page_action='native',
page_size = 20
),
html.Div(id = 'output')
])
@app.callback(
Output('output', 'children'),
Input('table', 'data'),
Input('table', 'active_cell'),
Input('table', 'selected_cells'),
Input('table', 'start_cell'),
Input('table', 'end_cell')
)
def update_table(columns, active_cell, selected_cells, start_cell, end_cell):
print('active_cell: ', active_cell)
#print(selected_cells)
print('start_cell: ', start_cell)
print('end_cell: ', end_cell)
return str(selected_cells)
if __name__ == '__main__':
app.run_server(debug=True)
Editable
import dash
from dash import html
from dash import dash_table
from dash.dependencies import Output, Input, State
from dash.exceptions import PreventUpdate
import pandas as pd
import numpy as np
app = dash.Dash(__name__)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/Emissions%20Data.csv').reset_index()
df['Emission'] = df['Emission'].map(lambda x: '{0:.2f}'.format(x))
app.layout = html.Div([dash_table.DataTable(
id='table',
data=df.to_dict('records'),
columns=[
{'name': i, 'id': i} if i != 'Emission' else {'name': i, 'id': i, 'editable': True} for i in df.columns # create editable column/columns
],
fixed_rows={ 'headers': True, 'data': 0 },
#editable=True, # make whole table editable
page_action='native'
), html.Button('Click', id = 'button'), html.Div(id = 'output')
])
@app.callback(
Output('output', 'children'),
State('table', 'data'),
Input('button', 'n_clicks'))
def update_table(data, n_clicks):
if not n_clicks:
raise PreventUpdate
return str(data)
if __name__ == '__main__':
app.run_server(debug=True)
Tooltips
tooltip, dict
- column based tooltip configuration applied to all rows
tooltip_conditional, dict
- column based tooltip configuration applied to all rows meet certain conditions
tooltip_data, list of dicts
- delay, int, delay in milliseconds before the tooltip is shown
- duration, int, duration in milliseconds during which the tooltip
- type, string, 'text' (default) or 'markdown'
- value, string, content of the tooltip
tooltip_header, dict
- value, string, content of the tooltip
- type, string, 'text' (default) or 'markdown'
tooltip_delay, int
- delay in milliseconds before the tooltip is displayed
tooltip_duration, int
- duration in milliseconds
- None, continue to display
import dash
import pandas as pd
from dash import html
from dash import dcc
from dash import dash_table
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([dash_table.DataTable(
id = 'table',
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns],
tooltip_header={i: {'value':'**{}**'.format(i), 'type': 'markdown'} for i in df.columns},
tooltip_data=[
{
column: {'value': '**{}** \n Comments'.format(str(value)), 'type': 'markdown'}
for column, value in row.items()
} for row in df.to_dict('records')
],
tooltip_delay=0,
tooltip_duration=None
),
])
if __name__ == '__main__':
app.run_server(debug=True)
import dash
import pandas as pd
from dash import html
from dash import dcc
from dash import dash_table
from dash.dependencies import Output, Input
from dash.exceptions import PreventUpdate
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv')
app = dash.Dash(__name__)
app.layout = html.Div([dash_table.DataTable(
id = 'table',
data=df.to_dict('records'),
columns=[{'id': c, 'name': c} for c in df.columns],
tooltip ={i: {
'value': '**{}**'.format(i),
'use_with': 'both', # both refers to header & data cell
'type': 'markdown'
} for i in df.columns},
tooltip_conditional=[
{
'if': {
'filter_query': '{year} > 2000'
},
'type': 'markdown',
'value': '![Recent]({})'.format(app.get_relative_path('/assets/Air-Force-Logo.png'))
}
],
tooltip_delay=0,
tooltip_duration=None
),
])
if __name__ == '__main__':
app.run_server(debug=True)
Virtualization
Rendering a subset of the data at any instant to improve the performance
Automatically decide the table height
import dash
from dash import dash_table
import pandas as pd
app = dash.Dash(__name__)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/Emissions%20Data.csv').reset_index()
df['Emission'] = df['Emission'].map(lambda x: '{0:.2f}'.format(x))
app.layout = dash_table.DataTable(
id='table-virtualization',
data=df.to_dict('records'),
columns=[
{'name': i, 'id': i} for i in df.columns
],
fixed_rows={ 'headers': True, 'data': 0 },
virtualization=True,
page_action='none'
)
if __name__ == '__main__':
app.run_server(debug=True)
Dropdowns
import dash
from dash import html
from dash import dash_table
from dash.dependencies import Output, Input, State
from dash.exceptions import PreventUpdate
import pandas as pd
import numpy as np
app = dash.Dash(__name__)
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/Emissions%20Data.csv').reset_index()
df['Emission'] = df['Emission'].map(lambda x: '{0:.2f}'.format(x))
temp = np.zeros((df.shape[0], 1)).astype(int)
df['label'] = temp
app.layout = html.Div([dash_table.DataTable(
id='table',
data=df.to_dict('records'),
columns=[
{'name': i, 'id': i} if i != 'label' else {'name': i, 'id': i, 'presentation': 'dropdown', 'editable': True} for i in df.columns
],
fixed_rows={ 'headers': True, 'data': 0 },
#editable=True,
dropdown={
'label': {'options': [{'label':'0', 'value':0}, {'label':'1', 'value':1}]},
},
virtualization=True,
page_action='native'
), html.Button('Click', id = 'button'), html.Div(id = 'output')
])
@app.callback(
Output('output', 'children'),
State('table', 'data'),
Input('button', 'n_clicks'))
def update_table(data, n_clicks):
if not n_clicks:
raise PreventUpdate
return str(data)
if __name__ == '__main__':
app.run_server(debug=True)
Persistence
persistence = True,
# define persistent properties
persisted_props = [ 'columns.name', 'filter_query', 'hidden_columns', 'selected_columns', 'selected_rows', 'sort_by'],
# local, keep after browser quit
# session, keep on page reset, clear after browser quit
# memory, reset on page reset
persistence_type = 'local',
Reference