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)