dash plotly - 动态创建下拉菜单,选择多行,table 导出?

dash plotly - create a dropdown menu dynamically, selection of multiple rows, table export?

我有一个如下所示的数据集:

cat_id  author  year    publisher   country value (dollars)
name1   kunga   1998    D and D Australia   10
name2   siba    2001    D and D UK  20
name3   siba    2001    D and D US  20
name3   shevara 2001    D and D UK  10
name3   dougherty   1992    D and D Australia   20
name4   ken 2011    S and K Australia   10

我想把它变成一个 table 的 plotly dash。我有我想要设置的大部分代码:

#!/usr/bin/env python
import dash
from dash.dependencies import Input, Output, State
import dash_table
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd

app = dash.Dash(__name__)
df = pd.read_excel('dash_test_doc.xlsx')


app.layout = html.Div([
    html.Div([
        dcc.Input(
            id='adding-rows-name',
            placeholder='Enter a column name...',
            value='',
            style={'padding': 10},
        ),
        html.Button('Add Column', id='adding-rows-button', n_clicks=0)
    ], style={'height': 50}),



     dash_table.DataTable(
         id='adding-rows-table',
         columns=[{"name": i, "id": i} for i in df.columns],
         data = df.to_dict('rows'),
         editable=True,
         filtering=True,
         sorting=True,
         sorting_type="multi",
         row_selectable="multi",
         row_deletable=True,
         selected_rows=[],
         pagination_mode="fe",
         style_cell_conditional=[
         {
             'if': {'row_index': 'odd'},
             'backgroundColor': 'rgb(230, 255, 230)'
         }
     ] + [
         {
             'if': {'column_id': c},
             'textAlign': 'left'
        } for c in ['Date', 'Region']
    ],
    style_header={
        'backgroundColor': 'white',
        'fontWeight': 'bold'
    }
    ),

    html.Button('Add Row', id='editing-rows-button', n_clicks=0),
    dcc.Graph(id='adding-rows-graph'),
])

@app.callback(
    Output('adding-rows-table', 'data'),
    [Input('editing-rows-button', 'n_clicks')],
    [State('adding-rows-table', 'data'),
     State('adding-rows-table', 'columns')])
def add_row(n_clicks, rows, columns):
    if n_clicks > 0:
        rows.append({c['id']: '' for c in columns})
    return rows


@app.callback(
    Output('adding-rows-table', 'columns'),
    [Input('adding-rows-button', 'n_clicks')],
    [State('adding-rows-name', 'value'),
     State('adding-rows-table', 'columns')])
def update_columns(n_clicks, value, existing_columns):
    if n_clicks > 0:
        existing_columns.append({
            'id': value, 'name': value,
            'editable_name': True, 'deletable': True
        })
    return existing_columns


@app.callback(
    Output('adding-rows-graph', 'figure'),
    [Input('adding-rows-table', 'data'),
     Input('adding-rows-table', 'columns')])
def display_output(rows, columns):
    return {
        'data': [{
            'type': 'heatmap',
            'z': [[row.get(c['id'], None) for c in columns] for row in rows],
            'x': [c['name'] for c in columns]
        }]
    }


if __name__ == '__main__':
    app.run_server(debug=True)

只有三件事让我苦恼,如果有人能提供帮助,我将不胜感激:

  1. 我想为每一列创建一个下拉菜单,无需预先定义下拉选项并允许多个 selection。例如这里使用table,在publisher中,有两种选择(D和D,S和K);我希望它们自动显示为下拉选项以供过滤,而不必将它们硬编码,因为例如,如果我编辑输入 table 并添加一行,并且添加了另一个发布者(例如 A 和 D) , 我希望 A 和 D 自动添加到下拉选项中? (所以最终,我的想法是模仿 excel,我可以从下拉列表中 select 例如,从该列的下拉列表中选择 D 和 D 以及 S 和 K,然后将根据以下条件过滤条目这个).

  2. 是否可以select多行,然后一次删除?目前,我可以删除单行。

  3. 是否可以导出 table?例如假设我读入了 table,然后有人删除了一些 columns/rows,我可以导出结果 table 吗?

如果有人能帮我找出这些代码,我将不胜感激。附带说明一下,由于我刚刚起步,如果有人对此脚本有任何其他改进建议,我将不胜感激。

  1. 您可能想在这里做的是为输出到 options 道具的每个下拉菜单(或所有下拉菜单的多输出回调)创建一个回调。可能由 table 的更新触发。您可以使用虚拟下拉选项初始化布局中的下拉菜单,然后让回调从那里开始。

  2. 我不确定 table 是否会自行执行此操作,但您可以让 table 的回调执行此操作。因为每个唯一输出只能有一个回调,所以任何涉及更新 table 的 data 属性的东西都必须是接缝回调下的 运行。您可能会添加一个像 "delete rows" 这样的按钮来监听 Input,并使用数据和选定的行作为 State。单击该按钮并触发回调时,您只需重建 table 的数据框,而 rows_selected 值中没有行,然后再次输出到 table 的数据。

  3. 好的。怎么导出呢?您可以从按钮 "export data" 设置回调,它可以根据需要导出它。您可以让函数将数据转储到文件,或将其打印到控制台,将其保存在数据库中,通过电子邮件发送,或者基本上您想要的任何内容。 Python 真的可以做任何事情。回调需要一个输出,所以可能只是打开一个对话框或一个小吃店让用户知道导出请求已收到并且 started/completed.