问题
I have a data set that looks like this:
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
I want to turn this into a table in plotly dash. I have most of the code that I want set up:
#!/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)
There is just three things that I’m struggling with if someone could help I would appreciate it:
I want to create a dropdown menu for each column, without pre-defining the dropdown options and allowing for multiple selection. for example using the table here, in publisher, there are two choices (D and D, and S and K); i want those to automatically appear as a dropdown option to filter by, without having to hardcode them in, because for example if I edit the input table and add a row, and there’s another publisher added (e.g. A and D), i want A and D to automatically be added to the dropdown options? (so ultimately, the idea would be to mimic excel, where I could select from a dropdown e.g. D and D and S and K from a dropdown for this column, and the entries would be filtered based on this).
is it possible to select multiple rows, and delete them with one action? at the minute, I can delete single rows.
Is it possible to export the table? e.g. say I read in a table, and then someone deletes some columns/rows, can I export the resulting table?
If anyone could help me figure out the code for these I’d appreciate it. As a a side note, since I’m just starting out, if anyone has any other suggestions for improvements to this script I’d appreciate it.
回答1:
What you would probably want to do here is create a callback for each dropdown (or a multi-output callback for all of them) that outputs to the
options
prop. Maybe triggered by updates to the table. You can initialize the dropdowns in the layout with a dummy dropdown option to start, and let the callback take it from there.I'm not sure whether the table does that on its own, but you could make your callback for the table do this. Because you can only have one callback per unique output, anything that involves updating the table's
data
prop would have to be run under the seam callback. You could probably add a button like "delete rows" to listen for asInput
, and use the data and selected rows asState
. When that button is clicked and fires the callback, you simply rebuild the dataframe for the table without rows in therows_selected
value, and then output to the table's data again.Sure. Export it how? You could set up a callback from a button, "export data" which could export it however you want. You could have the function dump the data to a file, or print it to the console, save it in a database, email it, or whatever you want basically. Anything you could do with Python really. The callback would need an output, so maybe just open a dialog or a snackbar letting the user know that the export request was received and started/completed.
来源:https://stackoverflow.com/questions/55871311/dash-plotly-create-a-dropdown-menu-dynamically-selection-of-multiple-rows-ta