Reputation: 1005
I have a data-table displayed on screen and I built a litle dropdown menu because I want to filter the table based on the value selected on this widget. While no error gets outputed, the table does not update. It just remains the same. I have followed this post for help Plotly Dash table callback. I feel like I am super close but cannot figure out what is wrong.
here is what I have been able to do so far: html code:
app.layout = html.Div(children=[
html.Br(),
html.Br(),
html.Br(),
#,style={'border':'solid 0.1em','border-color': 'transparent transparent #ff5402','font-size':'1em', 'color':'#ff5402'}),
html.Div(children=[
html.Div(
html.Div(html.H1("Demand planning"),
className="col-sm-12 inline-block")),
html.Br(),
html.Br(),
html.Div(children=[
html.Div([
dcc.Dropdown(
id='item',
options=[{'label': name, 'value': name} for name in available_items],
value='choose an item')
]),
html.Br(),
html.Div(children=[
html.Br(),
html.Div(children=[
html.Div(html.H4("Forecast"),style={'padding-left':10}),
dash_table.DataTable(
id='table',
columns=[{"name": i, "id": i} for i in forecast.columns],
style_cell={'whiteSpace': 'normal','height': 'auto',},
data=forecast.to_dict('rows'),
sort_action='native',
filter_action='none',
export_format='csv',
page_action = 'native',
page_current = 0,
page_size = 10,
style_cell_conditional = [
{'if': {'column_id': 'Id'},
'width': '30%', 'textAlign':'left'},
{'if': {'column_id': 'QuantityMin'},
'width': '30%', 'textAlign':'left'},
{'if': {'column_id': 'QuantityMax'},
'width': '30%', 'textAlign':'left'},
{'if': {'column_id': 'Probability'},
'width': '30%', 'textAlign':'left'},
],
style_data_conditional=[
{'backgroundColor': 'rgba(0, 0, 0,0)'}],
style_header={'backgroundColor': 'rgb(230, 230, 230)','font-size' : '10px'})
],
className= "mx-auto justify-content-left", style={'display': 'inline-block', "width":800,"height":475,"margin": 5}),##ca va avec le children du datatable
],className="row justify-content-center",style={'display': 'flex','align': 'center','heigh':475,'textAlign': 'center','border':'solid 0.05em','border-color': 'lightgray'}
), #celui la cest celui au dessus du Br()
],className='container', style={'padding-top':10, 'padding-bottom':50}), #ca c;est le children entre les deux br
])
])
and callback
@app.callback(
Output('table-container', 'children'),
[Input('item', 'name')],)
def update_figure(forecast):
print('name')
forecast = forecast[forecast['Id'] == 'name']
print(forecast)
return html.Div(
[
dash_table.DataTable(id='table', columns=[{'id': name, 'value': name} for name in forecast.columns.values])
]
)
here is the error output in the log:
forecast = forecast[forecast['Id'] == 'name']
TypeError: 'NoneType' object is not subscriptable
I would be grateful if someone could help me find out why the table is not updating?
Upvotes: 1
Views: 2512
Reputation: 15722
I'm guessing you don't see the errors, because you have suppress_callback_exceptions
set to True
.
The problem with your callback is that is that your output looks like this:
Output('table', 'figure')
table
is a DataTable
and has no property figure
.
What you could do instead is surround the table by a div, let's call this table-container
and change the output in the callback to this:
Output("table-container", "children")
Adjusted layout:
app.layout = html.Div(
children=[
html.Br(),
html.Br(),
html.Br(),
# ,style={'border':'solid 0.1em','border-color': 'transparent transparent #ff5402','font-size':'1em', 'color':'#ff5402'}),
html.Div(
children=[
html.Div(
html.Div(
html.H1("Demand planning"), className="col-sm-12 inline-block"
)
),
html.Br(),
html.Br(),
html.Div(
children=[
html.Div(
[
dcc.Dropdown(
id="item",
options=[
{"label": name, "value": name}
for name in available_items
],
value="choose an item",
)
]
),
html.Br(),
html.Div(
children=[
html.Br(),
html.Div(
children=[
html.Div(
html.H4("Forecast"),
style={"padding-left": 10},
),
html.Div(
id="table-container",
children=[
dash_table.DataTable(
id="table",
columns=[
{"name": i, "id": i}
for i in forecast.columns
],
style_cell={
"whiteSpace": "normal",
"height": "auto",
},
data=forecast.to_dict("rows"),
sort_action="native",
filter_action="none",
export_format="csv",
page_action="native",
page_current=0,
page_size=10,
style_cell_conditional=[
{
"if": {"column_id": "Id"},
"width": "30%",
"textAlign": "left",
},
{
"if": {
"column_id": "QuantityMin"
},
"width": "30%",
"textAlign": "left",
},
{
"if": {
"column_id": "QuantityMax"
},
"width": "30%",
"textAlign": "left",
},
{
"if": {
"column_id": "Probability"
},
"width": "30%",
"textAlign": "left",
},
],
style_data_conditional=[
{
"backgroundColor": "rgba(0, 0, 0,0)"
}
],
style_header={
"backgroundColor": "rgb(230, 230, 230)",
"font-size": "10px",
},
),
],
),
],
className="mx-auto justify-content-left",
style={
"display": "inline-block",
"width": 800,
"height": 475,
"margin": 5,
},
), ##ca va avec le children du datatable
],
className="row justify-content-center",
style={
"display": "flex",
"align": "center",
"heigh": 475,
"textAlign": "center",
"border": "solid 0.05em",
"border-color": "lightgray",
},
), # celui la cest celui au dessus du Br()
],
className="container",
style={"padding-top": 10, "padding-bottom": 50},
), # ca c;est le children entre les deux br
]
),
]
)
Also 'value'
is not a valid key for columns
, I think you're looking for 'name'
instead.
For a minimal example, see the documentation here.
An general example of how a callback that filters the DataTable
data based on the input value could look like:
@app.callback(
Output("table-container", "children"),
[Input("item", "value")],
)
def update_figure(input_value):
dff = forecast[forecast["species"] == input_value]
return html.Div(
[
dash_table.DataTable(
id="table",
columns=[{"id": name, "name": name} for name in dff.columns.values],
data=dff.to_dict("records"),
)
]
)
In the example above I've set forecast
equal to the iris
data set and changed the filter slightly, because I don't know what your data looks like.
Upvotes: 1