更新数据 Table 在 Dash 上使用日期选择器范围
Update Data Table Using Date Picker Range on Dash
我想根据用户选择的开始日期和结束日期更新我的数据table。但是,我不能link回调上的两个。我知道我的布局使用两个 dcc 组件 DatePickerRange
和 DataTable
。我该如何编写函数,以便在用户选择日期时更新我的数据 table。这是我目前所拥有的:
df = pd.read_csv('Test_Time_Series.csv')
df['Date'] = pd.to_datetime(df.Date,errors='coerce')
df.index = df['Date']
app = dash.Dash()
app.layout = html.Div([
dcc.DatePickerRange(
id='my-date-picker-range',
min_date_allowed=dt(2019, 1, 1),
max_date_allowed=dt(2019, 1, 4),
initial_visible_month=dt(2019, 1, 1),
end_date=dt(2019, 1, 4)
),
app.layout = html.Div([
dash_table.DataTable(
id='datatable-interactivity',
columns=[
{"name": i, "id": i, "deletable": True, "selectable": True, "hideable": True}
if i == "iso_alpha3" or i == "year" or i == "id"
else {"name": i, "id": i, "deletable": True, "selectable": True}
for i in df.columns
],
data=df.to_dict('records'), # the contents of the table
editable=True, # allow editing of data inside all cells
filter_action="native", # allow filtering of data by user ('native') or not ('none')
sort_action="native", # enables data to be sorted per-column by user or not ('none')
sort_mode="single", # sort across 'multi' or 'single' columns
column_selectable="multi", # allow users to select 'multi' or 'single' columns
row_selectable="multi", # allow users to select 'multi' or 'single' rows
row_deletable=True, # choose if user can delete a row (True) or not (False)
selected_columns=[], # ids of columns that user selects
selected_rows=[], # indices of rows that user selects
page_action="native", # all data is passed to the table up-front or not ('none')
page_current=0, # page number that user is on
page_size=6, # number of rows visible per page
style_cell={ # ensure adequate header width when text is shorter than cell's text
'minWidth': 95, 'maxWidth': 95, 'width': 95
},
style_cell_conditional=[ # align text columns to left. By default they are aligned to right
{
'if': {'column_id': c},
'textAlign': 'left'
} for c in ['country', 'iso_alpha3']
],
style_data={ # overflow cells' content into multiple lines
'whiteSpace': 'normal',
'height': 'auto'
}
)
])
# Link calendar to data table
@app.callback(
dash.dependencies.Output('datatable-interactivity', 'data'),
[dash.dependencies.Input('my-date-picker-range', 'start_date'),
dash.dependencies.Input('my-date-picker-range', 'end_date')])
def update_data(start_date, end_date):
df = df.loc[start_date: end_date]
columns =[{"name": i, "id": i} for i in df.columns]
return data
@app.callback(
dash.dependencies.Output('datatable-interactivity', 'columns'),
[dash.dependencies.Input('my-date-picker-range', 'start_date'),
dash.dependencies.Input('my-date-picker-range', 'end_date')])
def update_columns(start_date, end_date):
df = df.loc[start_date: end_date]
columns =[{"name": i, "id": i} for i in df.columns]
return columns
if __name__ == '__main__':
app.run_server(debug=True)
很难给你一个确切的答案,因为你遗漏了你的数据是什么样子和一些其他细节,但你可以这样做:
import pandas as pd
import dash
import dash_table
from dash.dependencies import Input, Output
from datetime import datetime as dt
import dash_core_components as dcc
import dash_html_components as html
df = pd.read_csv("Test_Time_Series.csv")
df["Date"] = pd.to_datetime(df.Date, errors="coerce")
df.index = df["Date"]
app = dash.Dash()
app.layout = html.Div(
[
dcc.DatePickerRange(
id="my-date-picker-range",
min_date_allowed=dt(2019, 1, 1),
max_date_allowed=dt(2019, 1, 4),
initial_visible_month=dt(2019, 1, 1),
end_date=dt(2019, 1, 4),
),
dash_table.DataTable(
id="datatable-interactivity",
columns=[
{
"name": i,
"id": i,
"deletable": True,
"selectable": True,
"hideable": True,
}
if i == "iso_alpha3" or i == "year" or i == "id"
else {"name": i, "id": i, "deletable": True, "selectable": True}
for i in df.columns
],
data=df.to_dict("records"), # the contents of the table
editable=True, # allow editing of data inside all cells
filter_action="native", # allow filtering of data by user ('native') or not ('none')
sort_action="native", # enables data to be sorted per-column by user or not ('none')
sort_mode="single", # sort across 'multi' or 'single' columns
column_selectable="multi", # allow users to select 'multi' or 'single' columns
row_selectable="multi", # allow users to select 'multi' or 'single' rows
row_deletable=True, # choose if user can delete a row (True) or not (False)
selected_columns=[], # ids of columns that user selects
selected_rows=[], # indices of rows that user selects
page_action="native", # all data is passed to the table up-front or not ('none')
page_current=0, # page number that user is on
page_size=6, # number of rows visible per page
style_cell={ # ensure adequate header width when text is shorter than cell's text
"minWidth": 95,
"maxWidth": 95,
"width": 95,
},
style_cell_conditional=[ # align text columns to left. By default they are aligned to right
{"if": {"column_id": c}, "textAlign": "left"}
for c in ["country", "iso_alpha3"]
],
style_data={ # overflow cells' content into multiple lines
"whiteSpace": "normal",
"height": "auto",
},
),
]
)
def date_string_to_date(date_string):
return pd.to_datetime(date_string, infer_datetime_format=True)
@app.callback(
dash.dependencies.Output("datatable-interactivity", "data"),
[
dash.dependencies.Input("my-date-picker-range", "start_date"),
dash.dependencies.Input("my-date-picker-range", "end_date"),
],
)
def update_data(start_date, end_date):
data = df.to_dict("records")
if start_date and end_date:
mask = (date_string_to_date(df["Date"]) >= date_string_to_date(start_date)) & (
date_string_to_date(df["Date"]) <= date_string_to_date(end_date)
)
data = df.loc[mask].to_dict("records")
return data
if __name__ == "__main__":
app.run_server(debug=True)
您的示例中的主要问题是您重新定义了 app.layout
,这意味着您不能同时使用 DatePickerRange
组件和数据表。
您没有显示工作表中使用的日期格式,但我已经针对此格式的日期测试了上述代码 2019-01-01
(ymd)。可能适用于更多,但我还没有测试其他人。
我想根据用户选择的开始日期和结束日期更新我的数据table。但是,我不能link回调上的两个。我知道我的布局使用两个 dcc 组件 DatePickerRange
和 DataTable
。我该如何编写函数,以便在用户选择日期时更新我的数据 table。这是我目前所拥有的:
df = pd.read_csv('Test_Time_Series.csv')
df['Date'] = pd.to_datetime(df.Date,errors='coerce')
df.index = df['Date']
app = dash.Dash()
app.layout = html.Div([
dcc.DatePickerRange(
id='my-date-picker-range',
min_date_allowed=dt(2019, 1, 1),
max_date_allowed=dt(2019, 1, 4),
initial_visible_month=dt(2019, 1, 1),
end_date=dt(2019, 1, 4)
),
app.layout = html.Div([
dash_table.DataTable(
id='datatable-interactivity',
columns=[
{"name": i, "id": i, "deletable": True, "selectable": True, "hideable": True}
if i == "iso_alpha3" or i == "year" or i == "id"
else {"name": i, "id": i, "deletable": True, "selectable": True}
for i in df.columns
],
data=df.to_dict('records'), # the contents of the table
editable=True, # allow editing of data inside all cells
filter_action="native", # allow filtering of data by user ('native') or not ('none')
sort_action="native", # enables data to be sorted per-column by user or not ('none')
sort_mode="single", # sort across 'multi' or 'single' columns
column_selectable="multi", # allow users to select 'multi' or 'single' columns
row_selectable="multi", # allow users to select 'multi' or 'single' rows
row_deletable=True, # choose if user can delete a row (True) or not (False)
selected_columns=[], # ids of columns that user selects
selected_rows=[], # indices of rows that user selects
page_action="native", # all data is passed to the table up-front or not ('none')
page_current=0, # page number that user is on
page_size=6, # number of rows visible per page
style_cell={ # ensure adequate header width when text is shorter than cell's text
'minWidth': 95, 'maxWidth': 95, 'width': 95
},
style_cell_conditional=[ # align text columns to left. By default they are aligned to right
{
'if': {'column_id': c},
'textAlign': 'left'
} for c in ['country', 'iso_alpha3']
],
style_data={ # overflow cells' content into multiple lines
'whiteSpace': 'normal',
'height': 'auto'
}
)
])
# Link calendar to data table
@app.callback(
dash.dependencies.Output('datatable-interactivity', 'data'),
[dash.dependencies.Input('my-date-picker-range', 'start_date'),
dash.dependencies.Input('my-date-picker-range', 'end_date')])
def update_data(start_date, end_date):
df = df.loc[start_date: end_date]
columns =[{"name": i, "id": i} for i in df.columns]
return data
@app.callback(
dash.dependencies.Output('datatable-interactivity', 'columns'),
[dash.dependencies.Input('my-date-picker-range', 'start_date'),
dash.dependencies.Input('my-date-picker-range', 'end_date')])
def update_columns(start_date, end_date):
df = df.loc[start_date: end_date]
columns =[{"name": i, "id": i} for i in df.columns]
return columns
if __name__ == '__main__':
app.run_server(debug=True)
很难给你一个确切的答案,因为你遗漏了你的数据是什么样子和一些其他细节,但你可以这样做:
import pandas as pd
import dash
import dash_table
from dash.dependencies import Input, Output
from datetime import datetime as dt
import dash_core_components as dcc
import dash_html_components as html
df = pd.read_csv("Test_Time_Series.csv")
df["Date"] = pd.to_datetime(df.Date, errors="coerce")
df.index = df["Date"]
app = dash.Dash()
app.layout = html.Div(
[
dcc.DatePickerRange(
id="my-date-picker-range",
min_date_allowed=dt(2019, 1, 1),
max_date_allowed=dt(2019, 1, 4),
initial_visible_month=dt(2019, 1, 1),
end_date=dt(2019, 1, 4),
),
dash_table.DataTable(
id="datatable-interactivity",
columns=[
{
"name": i,
"id": i,
"deletable": True,
"selectable": True,
"hideable": True,
}
if i == "iso_alpha3" or i == "year" or i == "id"
else {"name": i, "id": i, "deletable": True, "selectable": True}
for i in df.columns
],
data=df.to_dict("records"), # the contents of the table
editable=True, # allow editing of data inside all cells
filter_action="native", # allow filtering of data by user ('native') or not ('none')
sort_action="native", # enables data to be sorted per-column by user or not ('none')
sort_mode="single", # sort across 'multi' or 'single' columns
column_selectable="multi", # allow users to select 'multi' or 'single' columns
row_selectable="multi", # allow users to select 'multi' or 'single' rows
row_deletable=True, # choose if user can delete a row (True) or not (False)
selected_columns=[], # ids of columns that user selects
selected_rows=[], # indices of rows that user selects
page_action="native", # all data is passed to the table up-front or not ('none')
page_current=0, # page number that user is on
page_size=6, # number of rows visible per page
style_cell={ # ensure adequate header width when text is shorter than cell's text
"minWidth": 95,
"maxWidth": 95,
"width": 95,
},
style_cell_conditional=[ # align text columns to left. By default they are aligned to right
{"if": {"column_id": c}, "textAlign": "left"}
for c in ["country", "iso_alpha3"]
],
style_data={ # overflow cells' content into multiple lines
"whiteSpace": "normal",
"height": "auto",
},
),
]
)
def date_string_to_date(date_string):
return pd.to_datetime(date_string, infer_datetime_format=True)
@app.callback(
dash.dependencies.Output("datatable-interactivity", "data"),
[
dash.dependencies.Input("my-date-picker-range", "start_date"),
dash.dependencies.Input("my-date-picker-range", "end_date"),
],
)
def update_data(start_date, end_date):
data = df.to_dict("records")
if start_date and end_date:
mask = (date_string_to_date(df["Date"]) >= date_string_to_date(start_date)) & (
date_string_to_date(df["Date"]) <= date_string_to_date(end_date)
)
data = df.loc[mask].to_dict("records")
return data
if __name__ == "__main__":
app.run_server(debug=True)
您的示例中的主要问题是您重新定义了 app.layout
,这意味着您不能同时使用 DatePickerRange
组件和数据表。
您没有显示工作表中使用的日期格式,但我已经针对此格式的日期测试了上述代码 2019-01-01
(ymd)。可能适用于更多,但我还没有测试其他人。