У меня есть набор данных, который выглядит следующим образом:
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
Цель - создать выпадающее меню с несколькими вариантами выбора на столбец, а не на все столбцы (потому что фильтр на столбец, который я в данный моментdo не достаточно, мне нужно иметь возможность фильтровать по нескольким элементам на столбец за один раз).
Используя приведенный выше пример, это добавило бы ячейку сразу под cat_id с именем1,2,3,4;у автора будет выпадающий список с кунга, сиба, шевара и душерти;год будет иметь выпадение с 1992,1998,2001,2011 и т. д.
Я написал следующий код:
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}),
#Need to move this to being within each column?
html.Label('Multi-Select Dropdown'),
dcc.Dropdown(options=[{'label':i,'value':i} for i in df.columns],
value = [i for i in df.columns],
multi=True),
dash_table.DataTable(
id='adding-rows-table',
columns=[{"name": i, "id": i,"deletable":True} for i in df.columns],
# column_conditional_dropdowns=[{'id':i,'dropdowns':df[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)
У этого метода есть две специфические проблемы:
- Раскрывающийся список выполняется на уровне таблицы, а не на уровне столбца.
- Я хочу затем отфильтровать таблицу, чтобы отобразить только то, что находится в выпадающей панели, что в данный момент не выполняется..
Я знаю, что части кода, которые являются проблемой:
#Need to move this to being within each column?
html.Label('Multi-Select Dropdown'),
dcc.Dropdown(options=[{'label':i,'value':i} for i in df.columns],
value = [i for i in df.columns],
multi=True),
и что нет обратного вызова, но я новичок в тире, и яЯ изо всех сил пытаюсь понять, что конкретно я должен делать.Если бы кто-то мог показать мне, как исправить эти две проблемы в этом коде, я был бы признателен.
В качестве примечания / отказа от ответственности я изначально задавал этот вопрос как часть гораздо большего вопроса здесь, но я понял, что мне нужно сделать свои вопросы более специфичными для кода и более конкретными в целом, поэтому я собираюсь проработать каждую проблему в отдельности.