0

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.

Erlaed
  • 1
  • 2

0 Answers0