I'm doing a dash application. This is my first one.
I have a dropdown (id='demo-dropdown') and a dash_table.DataTable
tab : dash_table.DataTable = dash_table.DataTable(
id='datatable-interactivity',
columns=[
{"name": 'systemName', "id": 'systemName', "deletable": False, "selectable": False},
...
{"name": 'x', "id": 'x', "deletable": False, "selectable": False, "hideable": True, "type": "numeric"},
{"name": 'y', "id": 'y', "deletable": False, "selectable": False, "hideable": True, "type": "numeric"},
{"name": 'z', "id": 'z', "deletable": False, "selectable": False, "hideable": True, "type": "numeric"},
...
{"name": 'distance', "id": 'distance', "deletable": False, "selectable": False, "type": "numeric"},
],
data=df.to_dict('records'),
editable=False,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable=False, # "single",
row_selectable=False, # "multi",
row_deletable=False,
selected_columns=[ ],
selected_rows=[ ],
page_action="native",
page_current=0,
page_size=100,
)
The dropdown specifies a location (x0,y0,z0), and I want to fill the distance column with regular euclidean distance values from that point. For the moment, I'd be happy to increment the values in the distance column by 5 when the user clicks the dropdown.
Here's my callback:
@app.callback(
[dash.dependencies.Output('datatable-interactivity', 'data'),
dash.dependencies.Output('datatable-interactivity', 'columns')],
[dash.dependencies.Input('demo-dropdown', 'value')])
def update_output(value):
columns = [{"name": 'distance', "id": 'distance'}]
nrows = df.shape[ 0 ]
for ind in df.index:
x1: float = df.at[ind, 'x']
y1: float = df.at[ind, 'y']
z1: float = df.at[ind, 'z']
dis: float = math.sqrt((x - x1) ** 2 + (y - y1) ** 2 + (z - z1) ** 2)
df.at[ind, 'distance'] = dis
return [df['distance'].to_dict(), columns] #tried "records" "rows"
My problem seems similar to How can we create data columns in Dash Table dynamically using callback with a function providing the dataframe - but I can't seem to make it work.
The error message I get is:
Invalid argument `data` passed into DataTable with ID "datatable-interactivity".
Expected an array.
Was supplied type `object`.
Value provided:
{
"0": 37.0625,
"1": 94.53125,
"2": 62.03125,
"3": 33.65625,
"4": 33.65625,
...
"185": 63.59375
}
at propTypeErrorHandler (http://127.0.0.1:8050/_dash-component-suites/dash_renderer/dash_renderer.v1_4_1m1588701826.dev.js:37662:9)
at CheckedComponent (http://127.0.0.1:8050/_dash-component-suites/dash_renderer/dash_renderer.v1_4_1m1588701826.dev.js:32489:77)
...
I've tried various combinations of lists and dicts for the return with no luck. Also, I think, but am not sure, that updating the dataframe in place is the right thing to do.
(Just to sum up - this is what I think I'm doing: notifying the view that data in the model has changed by returning a list with two dicts, the first one has row indices and the new values, and the second identifies the column(s) that are changed.)
Thanks!
Update As far as I can tell, changing the last two lines of the callback to the following works:
_cols = [{"name": i, "id": i} for i in df.columns]
return df.to_dict('records'), _cols
i.e. replacing all the values in the table, instead of just the last column.