Dash DataTable - Sorting and Filtering doesn't fire the callback


#1

Hi there,
I have tried to implement the functions included in the dash-table-experiments/usage.py file and customise it for my purposes.
However, one problem I am experiencing is that the interaction between table and linked chart is only limited to marker color (which I copied from the example). This means that sorting or filtering data in the table does not trigger any action in the chart.

My callbacks are as follows (the objects 'datatable-gapminder' and 'graph-gapminder' from the usage.py example have been replaced by 'acr_table' and 'acr_chart respectively):

@app.callback(
    Output('acr_table', 'selected_row_indices'),
    [Input('acr_graph', 'clickData')],
    [State('acr_table', 'selected_row_indices')])
def update_selected_row_indices(clickData, selected_row_indices):
    if clickData:
        for point in clickData['points']:
            if point['pointNumber'] in selected_row_indices:
                selected_row_indices.remove(point['pointNumber'])
            else:
                selected_row_indices.append(point['pointNumber'])
    return selected_row_indices

@app.callback(
    Output('acr_graph', 'figure'),
    [Input('acr_table', 'rows'), Input('acr_table', 'selected_row_indices')])
def update_figure(rows, selected_row_indices):
    dff = pd.DataFrame(rows)
    data=go.Data([])
    marker = {'color': ['#0074D9']*len(dff)}
    for i in (selected_row_indices or []):
        marker['color'][i] = '#FF851B'
    data.append(
        go.Bar(
            x = df_acr['BD1_HA26p_occ'],
            y = df_acr['job_id_short'],
            orientation='h',
            marker = marker,
            ),
        ),

    figure = go.Figure(
        data=data,
        # layout=layout,
        )
    return figure

#2

@andrea.botti - Hm, I’m not sure if I follow what you are saying. When I run usage.py, sorting and filtering does update the chart:


Could you elaborate?


#3

@chriddyp apologies, I appreciate my message could be clearer.
What I meant is that the sorting and filtering works brilliantly in the example, but not in the code I wrote adapting it. As such I was inquiring about which @app.callback function achieves that. I pasted the callbacks as per my amended file, which is such that filtering the table only results in highlighting certain markers from the bar chart (colour from #0074D9 to #FF851B) - with no sorting / filtering.


#4

Hi again @chriddyp.
Here is the code I’ve written and which is currently not performing as your example. What am I doing wrong?

# Set import paths
F = 'CP_P1201'
filepath = 'https://www.dropbox.com/s/zb1v4c5dafgfpm7/{}_df_acr_large.csv?dl=1'.format(F)

# Imports data to be visualised
df = pd.read_csv(filepath)
# slice df to test visuals on smaller dataset
df = df.iloc[:200]


# Setup app
app = dash.Dash()

# CSS
external_css = ["https://fonts.googleapis.com/css?family=Overpass:300,300i",
                "https://cdn.rawgit.com/plotly/dash-app-stylesheets/dab6f937fd5548cebf4c6dc7e93a10ac438f5efb/dash-technical-charting.css",
                "https://codepen.io/chriddyp/pen/bWLwgP.css"]
[app.css.append_css({"external_url": css}) for css in external_css]
if 'DYNO' in os.environ:
    app.scripts.append_script({'external_url': 'https://cdn.rawgit.com/chriddyp/ca0d8f02a1659981a0ea7f013a378bbd/raw/e79f3f789517deec58f41251f7dbb6bee72c44ab/plotly_ga.js'})


##########
# ROASST App
app.layout = html.Div(
    [
        html.H1('ROASST App - Explore simulation results'),
        
        html.Div([
            html.H4('DataTable'),    
            dt.DataTable(
                rows=df.to_dict('records'),
                # columns=col_sel,     # optional - sets the order of columns
                filterable=True,
                sortable=True,
                row_selectable=True,
                selected_row_indices=[],
                id='acr_table'
                ),
            ], className='six columns',
            ),
        html.Div(id='selected-indexes',children=[
            html.H4('Chart'),             
            dcc.Graph(
                id='acr_graph'
                )
            ], className='five columns',
            ),
    ], className='row',
    style={
        'fontSize':11,
        'background-color': '#F3F3F3',
        'font-family': 'overpass',
        'width': '90%', 'max-width': '1500',
        'margin-left': 'auto', 'margin-right': 'auto', 'padding': '20', 'padding-top': '20', 'padding-bottom': '20',
    },
)
@app.callback(
    Output('acr_table', 'selected_row_indices'),
    [Input('acr_graph', 'clickData')],
    [State('acr_table', 'selected_row_indices')])
def update_selected_row_indices(clickData, selected_row_indices):
    if clickData:
        for point in clickData['points']:
            if point['pointNumber'] in selected_row_indices:
                selected_row_indices.remove(point['pointNumber'])
            else:
                selected_row_indices.append(point['pointNumber'])
    return selected_row_indices


@app.callback(
    Output('acr_graph', 'figure'),
    [Input('acr_table', 'rows'), Input('acr_table', 'selected_row_indices')])
def update_figure(rows, selected_row_indices):
    dff = pd.DataFrame(rows)
    data=go.Data([])
    marker = {'color': ['#0074D9']*len(dff)}
    for i in (selected_row_indices or []):
        marker['color'][i] = '#FF851B'
    data.append(
        go.Bar(
            x = df['BD1_HA26p_occ'],
            y = df['job_s'],
            orientation='h',
            marker = marker,
            ),
        ),

    figure = go.Figure(
        data=data,
        # layout=layout,
        )
    return figure



if __name__ == '__main__':
    app.run_server(port=8053, debug=False)

#5

Hi @andrea.botti, did you ever find the solution for this? I recently ran into the same issue when modifying usage.py for my own purposes. I believe Im at the same point you are, where filtering and selection seems to work, but it does not update the order of bar chart, or adjustments to bar width when datatable is filtering the data.