'Dash use html.button for export csv with filter

i'm quite new in dash. I try to create a simple dash with a filter, and an export button.

My data are simple: I have two Bank, with two app (one Android, one Apple) each. I have a score every month in 2021.

My graph works perfectly well. My dropdown is working.

I have a html.Button for export data as csv. It works but not as I would like.

I would like to export only the data filtered with the button. But with the code bellow, every time i change the filter after 1 click i'm style exporting a csv. I tried to use and change the value of dash.callback_context.triggered or how to reset the value but it doesn't work (or i'm too noob to understand why^^).

But even if i change the value of the callback_context i think it will not help me for the filtered part, isn't it?

I would like to use the button as a one shot export (whatever is the n_click number and how many time i change the filter) but reusable.

Could you help me?

    sidebar = html.Div(
    [
        html.H2('Parameter', style=TEXT_STYLE),
        html.Hr(),
        html.P('Bank :', style={'textAlign':'center'
        }),
        dcc.Dropdown(
            id="ticker",
            options=['Bank A',' Bank B'],
            value="Bank A",
            clearable=False
        ),
        html.Button('Export as csv',id="download-csv"),
        
        dcc.Download(id='first_output')
    ],
    style=SIDEBAR_STYLE,
)
### body of the app
content=html.Div(
    [
        html.H2('Dashboard ', style=TEXT_STYLE),
        html.Hr(),
        dcc.Graph(id="time-series-chart")
    ],
    style=CONTENT_STYLE
)
### App gestion 
external_stylesheets=[dbc.themes.BOOTSTRAP]#['https://codepen.io/chriddyp/pen/bWLwgP.css']
tickFont = {'size':12, 'color':"rgb(30,30,30)", 'family':"Courier New, monospace"}

app = Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div([sidebar,content])

def display_time_series(unautreticker):
    df2 =df
    df2 = df.sort_values(by='date')
    df_Brand = df2.loc[df2['Brand'] == unautreticker]
    fig = px.line(df_Brand, x=df_Brand['date'], y=df_Brand['note'] \
        , title= f'Rate of{unautreticker} for month',\
        markers=True, text = 'note', color = 'app_name', color_discrete_map=COLOR_DISCRETE_MAP)
    fig.update_traces(textposition = "top right")
    return fig

@app.callback(
    Output("first_output","data"),
    [Input('download-csv','n_clicks'),Input("ticker", "value")], 
    prevent_initial_call = True,
)
def dl_un_csv(n_clicks,ticker):
    print(n_clicks)
    while n_clicks == 1:
        df2 =df
        df2 = df2.loc[df2['Brand'] == ticker]
        n_clicks +=1
        print(dash.callback_context.triggered[0]['value'])
        return dcc.send_data_frame(df2.to_csv, filename=f'export_{ticker}.csv',sep=';',header=True,index=False,encoding='utf-8')

server = app.server
if __name__=="__main__":
    app.run_server(debug=False, port =8080)

Thanks guys. (I just did not put the variables like CONTENT_STYLE which take too much space)



Solution 1:[1]

I found an answer on this link with example :https://community.plotly.com/t/download-raw-data/4700/8.

You have to know that urllib.quote() is now urllib.parse.quote() for python 3. So you have to import urllibe.parse

I add some modification (like a dash_bootstrap_components) Here my solution based on the link:

    html.Div(
        [
            html.H2('Parametre', style=TEXT_STYLE),
            html.Hr(),
            html.P('Bank :', style={'textAlign':'center'
            }),
            dcc.Dropdown(
                id="ticker",
                options=['Bank A','Bank B'],
                value="Bank A",
                clearable=False
            ),
            dbc.Button('Export as csv',id="download-csv",class_name="m-5", color='secondary'),
        ],
        style=SIDEBAR_STYLE,
    )
@app.callback(
    dash.dependencies.Output('download-csv', 'href'), [dash.dependencies.Input('ticker','value')]
)

def dl_csv(ticker):
    df2=df
    df2 = df2.loc[df2['Brand'] == ticker]
    csv_string = df2.to_csv(index=False, encoding='utf-8',sep=';',header=True,)
    csv_string="data:text/csv;charset=utf-8,%EF%BB%BF" + urllib.parse.quote(csv_string)
    return csv_string

Edit: a working example here https://community.plotly.com/t/download-raw-data/4700/49

I hope this will help someone. Have a nice day,

So Ode

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 So ode