Adding form to dash app

Hi all,
Ok, So I want to go one step further. I don’t know if it is possible with a dash.
I want to create a form ( probably WTForm from Flask ).
The form should have date and annotation/comments section.
When someone submits a form, it will save to the database.
Then dash will read it and show on the graph.
My graph looks like that:


On the x-axis will be date from FlaskForm representing Event that it was stored in the database, and annotation will be showed in the graph itself when I hover to that exact date
Something similar to this one:

And now, can you please tell me if it’s possible? What tools should I use it? It’s just a concept, but I think will be helpful for everyone.

so anyone have the solution maybe?

I have no idea what a form is, but aaaanyhow.

It sounds like you want to have self-updating graphs plotting stuff™ from a database.
You could do this with a dcc.Intervals component which reads the last N records from your database, and create whatever figures you want.

You can get this bu manipulating whatever you get from your database into a nice string to put on your x-axis ticks and by using the ‘text’ options for a standard plotly figure.

Thank you for your response @Blaceus, but Form i mean Forms, like this one54

And after submitting this form it should automatically update my graph.
So Event Date will be on Xaxis and comment should be somewhere on top of this.
It should look soooooomething like that:

Hello,

you can build this form using the different components from dash-core-components ( DatePickerSingle and Textarea) and dash-html-components (Button).

Then you can create a callback which is triggered upon the button click and do what you wanted to do with the “Event date” and “Comment”

from  dash.dependencies import Output, Input, State

@app.callback(
   Output('graph', 'figure'),
    [Input('button', 'n_clicks')],
    [
         State('comment-box', 'value'),
         State('date-picker','date')
    ]
)
def update_graph(n_clicks, event_comment, event_date):

     # highlight the graph, maybe methods described in https://dash.plot.ly/interactive-graphing
     # might be useful for that
     return fig

I would advice consulting https://dash.plot.ly/interactive-graphing because your solution might be within the examples presented here :slight_smile:

2 Likes

WOW, @Bachibouzouk I think you find a better solution for what I have been looking for, rather than doing routing and forms in flask…

I hope it solves the problem…
Because, I just need to create Textarea and DatePicker, and then put them in the callback, and text and date put in the annotations in the graph itself? correct?

1 Like

soo, I find a solution for what I was looking for, but anyway, I need to use CRUD’s to my problem, but I will share my code here.

so here is a simple “form” to add an event to the graph:

html.Div([
        html.Div([
            dcc.DatePickerSingle(
                id='date-picker',
                display_format='D/M/Y',
                date=dt.now(),
            ), ]),
        html.Div([
            dcc.Textarea(
                id='input_comments',
                placeholder='Add your Event here...',
                rows=5,
                style={'display': 'inline-block', 'verticalAlign': 'top', 'width': '30%'},
            ),
        ]),
        html.Div(
            [
                html.A(
                    html.Button(
                        id='add_event_btn',
                        children='Add a Event form!',
                        style={
                            'display': 'inline-block',
                            'verticalAlign': 'top',
                            'width': '30%'
                        }
                    )
                )
            ]),
    ]),

And here will automatically read from our “form” and saves it to the db, and then reads and plots to the graph

@app.callback(
    Output('closed_accounts', 'figure'),
    [Input('interval-component', 'n_intervals'),
     Input('closed_account_options', 'value'),
     Input('add_event_btn', 'n_clicks')],
    [
        State('input_comments', 'value'),
        State('date-picker', 'date')
    ]
)
def update_graph(n, selected_df, n_clicks, event_comment, event_date):
    selected = closed_account_options[selected_df]
    datetime_object = dt.strptime(event_date[:10], '%Y-%m-%d')
    conn = getConnection()
    if n_clicks is not None:
        try:
            with conn.cursor() as cursor:
                cursor.execute("INSERT INTO ***  (`event_date`, `event_comment`) VALUES(%s, %s);",
                               (datetime_object, event_comment))
                conn.commit()
        finally:
            conn.close()
    get_events = getting_events()
    dates = []
    comments = []
    for index, row in get_events.iterrows():
        dates.append(row.event_date)
        comments.append(row.event_comment)
    return {
        'data': [
            go.Scatter(
                x=selected.index,
                y=selected.xxx,
                name="selected.xxx,",
                opacity=0.8),
            go.Scatter(
                x=selected.index,
                y=selected.xxx,,
                name="selected.xxx,",
                opacity=0.8),
            go.Scatter(
                x=selected.index,
                y=selected.xxx,,
                name="selected.xxx,",
                opacity=0.8),
            go.Scatter(
                x=selected.index,
                y=selected.xxx,,
                name="selected.xxx,",
                opacity=0.8),
            go.Scatter(
                x=selected.index,
                y=selected.xxx,,
                name="selected.xxx,",
                opacity=0.8)
        ],
        'layout': go.Layout(
            annotations=[dict(
                x=xi,
                y=selected.max(),
                xref='x',
                yref='y',
                text="{0}\n{1}".format(xi, yi),
                align='center',
                arrowhead=2,
                arrowsize=1,
                arrowwidth=2,
                arrowcolor='#636363',
                ax=20,
                ay=-30,
                bordercolor='#c7c7c7',
                borderwidth=2,
                borderpad=4,
                bgcolor='#ff7f0e',
                opacity=0.8,
            ) for xi, yi in zip(dates, comments)],
            xaxis=dict(
                rangeselector=dict(
                    buttons=list([
                        dict(count=1, label='1 day', step='day', stepmode='backward'),
                        dict(count=7, label='1 week', step='day', stepmode='backward'),
                        dict(count=1, label='1 month', step='month', stepmode='backward'),
                        dict(step='all')
                    ])
                ),
                rangeslider=dict(), type='date'
            ), yaxis={'autorange': True}
        )
    }

and this is just test for this solution, but as you can see it works :slight_smile:

I think it can be written even better, but no time to clean the code, but if you like please do not hesitate to use and do better, and of course share later :slight_smile:
Still, a lot challenges more to come :slight_smile:

1 Like

Can you touch on how to connect DKash to the SQL database. I have Dash running on a Flask website connected with SQL Alchemy but I don’t know how Dash would connect with my wt-form to get this data