更新数据 Table 在 Dash 上使用日期选择器范围

Update Data Table Using Date Picker Range on Dash

我想根据用户选择的开始日期和结束日期更新我的数据table。但是,我不能link回调上的两个。我知道我的布局使用两个 dcc 组件 DatePickerRangeDataTable。我该如何编写函数,以便在用户选择日期时更新我的​​数据 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)。可能适用于更多,但我还没有测试其他人。