Как получить данные для одного и того же графика из текстового поля или раскрывающегося списка? - PullRequest
0 голосов
/ 04 октября 2018

Я хочу создать простое приложение для черточки, в котором на входе указан символ акции, а на выходе - его цена за определенный период времени.Тем не менее, я хочу дать пользователю 2 способа выбора ввода: либо наберите его в текстовом поле, либо выберите из выпадающего списка некоторые общие акции.

Это мой код, чтобы сделать это:

import pandas_datareader.data as web
import datetime
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

app = dash.Dash()

app.layout = html.Div(children=[
    html.Div(children='Symbol to graph:'),
    dcc.Input(id='input', value='', type='text'),

    html.Div(children='Frequent options:'),
    dcc.Dropdown(
    options=[
        {'label': 'Apple (AAPL)', 'value': 'AAPL'},
        {'label': 'Microsoft (MSFT)', 'value': 'MSFT'},
        {'label': 'Amazon (AMZN)', 'value': 'AMZN'},
        {'label': 'Tesla (TSLA)', 'value': 'TSLA'}
    ],
    style={'width': '40%'},
    id='freq-inputs'
    ),

    html.Div(id='output-graph'),

    html.Div(id='freq-input-graph'),
])

@app.callback(
    Output(component_id='output-graph', component_property='children'),
    [Input(component_id='input', component_property='value')]
)
def update_value(input_data):
    start = datetime.datetime(2015, 1, 1)
    end = datetime.datetime.now()
    df = web.DataReader(input_data, 'iex', start, end)
    df.reset_index(inplace=True)
    df.set_index("date", inplace=True)

    return dcc.Graph(
        id='example-graph',
        figure={
            'data': [
                {'x': df.index, 'y': df.close, 'type': 'line', 'name': input_data},
            ],
            'layout': {
                'title': input_data
            }
        }
    )

@app.callback(
    Output(component_id='output-graph', component_property='children'),
    [Input(component_id='freq-inputs', component_property='value')]
)
def update_value(input_data):
    start = datetime.datetime(2015, 1, 1)
    end = datetime.datetime(2018, 9, 24) #datetime.datetime.now()
    df = web.DataReader(input_data, 'iex', start, end)
    df.reset_index(inplace=True)
    df.set_index("date", inplace=True)

    return dcc.Graph(
        id='example-graph',
        figure={
            'data': [
                {'x': df.index, 'y': df.close, 'type': 'line', 'name': input_data},
            ],
            'layout': {
                'title': input_data
            }
        }
    )

if __name__ == '__main__':
    app.run_server(debug=True)

Как видите, мне пришлось написать 2 деления для каждого типа ввода (html.Div(id='output-graph') и html.Div(id='freq-input-graph')) и, следовательно, 2 функции-оболочки обратного вызова, которые идентичны, за исключением идентификаторов компонентов ввода и вывода.Это потому, что когда я пытался использовать тот же компонент div для вывода, я получал сообщение об ошибке:

You have already assigned a callback to the output
with ID "output-graph" and property "children". An output can only have
a single callback function. Try combining your inputs and
callback functions together into one function.

Помимо избыточного кода, есть еще одна проблема, с которой я сталкиваюсь в этом коде.Если я наберу символ акции, он построит график;если я затем выберу опцию из выпадающего списка, последний график будет отображен на том же элементе div, что и предыдущий, поэтому мы можем видеть только один график в любой момент времени.Однако, если я сначала выберу опцию из выпадающего списка, а затем напечатал символ, он строит 2 разных графика.

Это потому, что html.Div(id='output-graph') объявлено / определено выше html.Div(id='freq-input-graph') в определении макета приложения,Если я поменяю порядок, будет замечено противоположное поведение.

Как мне это исправить?

1 Ответ

0 голосов
/ 04 октября 2018

Лучшее решение - использовать State, а не Input, и тогда у вас будет только один обратный вызов функции.это состояние может быть назначено кнопке отправки, а затем, когда пользователь выберет один ввод между раскрывающимся списком или текстовым полем и нажмет кнопку, обновление будет выполнено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...