# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#               Esse arquivo possui algumas modificações em relação ao arquivo apresentado no vídeo do YouTube
#                          Não deixe de assistir o vídeo e estudar pela documentação ofical Dash
# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# importando as bibliotecas necessárias
import dash
import dash_core_components as dcc
import dash_html_components as html

# importando as funções que auxiliam no funcionamento das callbacks do subpacote dependencies do pacote dash 
from dash.dependencies import Input, Output

# importando o módulo graph_objects da biblioteca plotly
import plotly.graph_objects as go

# adicionando um estilo externo através do link abaixo
    # esse link é o recomendado pela documentação da biblioteca Dash e ao acessar esse link no seu navegador,
    # você perceberá que ele possui a estrutura de um arquivo CSS

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

# criando a aplicação por meio da função Dash do pacote dash e atribuindo a variável app

app = dash.Dash(
    __name__,
    external_stylesheets=external_stylesheets
)

# criando uma função para gerar um gráfico com a biblioteca plotly.graph_objects
def gera_grafico(tipo):

    # criando uma figura
    # caso você faça print(fig), um dicionário será apresentado uma vez que as figuras podem ser representadas dessa forma, necessitando de módulos da biblioteca plotly para trabalhar com as informações
    fig = go.Figure()
    # https://plotly.com/python/creating-and-updating-figures/

    # adicionando um traço a figura
    fig.add_trace(
        go.Scatter(
            x=[0,1,2,3,4,5,6],
            y=[0,1,2,3,4,5,6],
            mode=tipo,
            name='Reta',
            )
        )

    fig.add_trace(
        go.Scatter(
            x=[0,1,2,3,4,5,6],
            y=[0,1,4,9,16,25,36],
            mode=tipo,
            name='Parábola',
            )
        )
    
    # adicionando um título ao gráfico
    fig.update_layout(title='Gráfico Exemplo')

    # variável retornada pela função gera_grafico(tipo)
    return fig


# criando um layout para a variável app
# adicionando ao layout um componente html.Div que irá conter os demais componentes que dão forma 

app.layout = html.Div([

    # inserindo um componente da biblioteca dash HTML components como título/cabeçalho do layout
    html.H2(
        ['Painel de Visualização de Gráficos'],
        
         # o parâmetro style define estilos css para o componente
        style={
            'textAlign':'center', # texto alinhado
            'font-weight':'bold' # texto em negrito
        }
    ),

    # adicionando uma linha horizontal no layout
    html.Hr(),

    # criando abas pai dentro do layout
    dcc.Tabs(

        # identidade/nome do componente
        id='tabs',

        # criando as abas filhas dentro do parâmetro children da função Tabs()
        children=[
            dcc.Tab(label='Gráfico de linha',value='tab-1'),
            dcc.Tab(label='Gráfico de Barra',value='tab-2'),
            dcc.Tab(label='Gráfico de Linha e Pontos',value='tab-3')
        ]
    ),

    # onde será apresentado o conteúdo das abas logo após a callback ser ativada
    html.Div(id='tabs-content'),

    html.Hr(),
])

# Callback

# estruturando a callback com as entradas (input) e saídas (output)
@app.callback(
    # Output(component_id,component_property)
    Output('tabs-content','children'),
    [
        # Input(component_id,component_property)
        Input('tabs','value')
    ]
)

# função que será chamada pela callback
def update_tab(tab):

    # quando a aba com valor igual a 'tab-1' for selecionada, a propriedade children do componente 'tabs-content'
    # receberá o gráfico de linha retornado abaixo pela função gera_gráfico(tipo='lines')
    if tab == 'tab-1':
        return html.Div([
            dcc.Graph(figure = gera_grafico('lines'))
        ])


    # quando a aba com valor igual a 'tab-2' for selecionada, a propriedade children do componente 'tabs-content'
    # receberá o gráfico de barras construído e retornado abaixo
    elif tab == 'tab-2':
        fig_bar = go.Figure()

        fig_bar.add_trace(
            go.Bar(
                x=[0,1,2,3,4,5,6],
                y=[0,1,2,3,4,5,6],
                )
            )

        fig_bar.add_trace(
            go.Bar(
                x=[0,1,2,3,4,5,6],
                y=[0,1,4,9,16,25,36],
                )
            )

        fig_bar.update_layout(title='Gráfico em Barras Exemplo')
        
        return html.Div([
            dcc.Graph(figure = fig_bar)
        ])

    # quando a aba com valor igual a 'tab-3' for selecionada, a propriedade children do componente 'tabs-content'
    # receberá o gráfico de linha retornado abaixo pela função gera_gráfico(tipo='lines+markers')
    elif tab == 'tab-3':
        return html.Div([
            dcc.Graph(figure = gera_grafico('lines+markers'))
        ])
    
    # caso nenhuma das condições acima sejam aceitas, significa que existe um erro, e assim, retornamos a mensagem de erro
    else:
        return html.Div(['Erro!'])


# servindo a aplicação em dash como versão para teste
if __name__ == "__main__":
    app.run_server(debug=True)
[((1211, 1273), 'dash.Dash', 'dash.Dash', (['__name__'], {'external_stylesheets': 'external_stylesheets'}), '(__name__, external_stylesheets=external_stylesheets)\n', (1220, 1273), False, 'import dash\n'), ((1629, 1640), 'plotly.graph_objects.Figure', 'go.Figure', ([], {}), '()\n', (1638, 1640), True, 'import plotly.graph_objects as go\n'), ((3561, 3595), 'dash.dependencies.Output', 'Output', (['"""tabs-content"""', '"""children"""'], {}), "('tabs-content', 'children')\n", (3567, 3595), False, 'from dash.dependencies import Input, Output\n'), ((1768, 1856), 'plotly.graph_objects.Scatter', 'go.Scatter', ([], {'x': '[0, 1, 2, 3, 4, 5, 6]', 'y': '[0, 1, 2, 3, 4, 5, 6]', 'mode': 'tipo', 'name': '"""Reta"""'}), "(x=[0, 1, 2, 3, 4, 5, 6], y=[0, 1, 2, 3, 4, 5, 6], mode=tipo,\n    name='Reta')\n", (1778, 1856), True, 'import plotly.graph_objects as go\n'), ((1942, 2037), 'plotly.graph_objects.Scatter', 'go.Scatter', ([], {'x': '[0, 1, 2, 3, 4, 5, 6]', 'y': '[0, 1, 4, 9, 16, 25, 36]', 'mode': 'tipo', 'name': '"""Parábola"""'}), "(x=[0, 1, 2, 3, 4, 5, 6], y=[0, 1, 4, 9, 16, 25, 36], mode=tipo,\n    name='Parábola')\n", (1952, 2037), True, 'import plotly.graph_objects as go\n'), ((2526, 2631), 'dash_html_components.H2', 'html.H2', (["['Painel de Visualização de Gráficos']"], {'style': "{'textAlign': 'center', 'font-weight': 'bold'}"}), "(['Painel de Visualização de Gráficos'], style={'textAlign':\n    'center', 'font-weight': 'bold'})\n", (2533, 2631), True, 'import dash_html_components as html\n'), ((2848, 2857), 'dash_html_components.Hr', 'html.Hr', ([], {}), '()\n', (2855, 2857), True, 'import dash_html_components as html\n'), ((3367, 3394), 'dash_html_components.Div', 'html.Div', ([], {'id': '"""tabs-content"""'}), "(id='tabs-content')\n", (3375, 3394), True, 'import dash_html_components as html\n'), ((3401, 3410), 'dash_html_components.Hr', 'html.Hr', ([], {}), '()\n', (3408, 3410), True, 'import dash_html_components as html\n'), ((3659, 3681), 'dash.dependencies.Input', 'Input', (['"""tabs"""', '"""value"""'], {}), "('tabs', 'value')\n", (3664, 3681), False, 'from dash.dependencies import Input, Output\n'), ((4294, 4305), 'plotly.graph_objects.Figure', 'go.Figure', ([], {}), '()\n', (4303, 4305), True, 'import plotly.graph_objects as go\n'), ((4346, 4402), 'plotly.graph_objects.Bar', 'go.Bar', ([], {'x': '[0, 1, 2, 3, 4, 5, 6]', 'y': '[0, 1, 2, 3, 4, 5, 6]'}), '(x=[0, 1, 2, 3, 4, 5, 6], y=[0, 1, 2, 3, 4, 5, 6])\n', (4352, 4402), True, 'import plotly.graph_objects as go\n'), ((4496, 4555), 'plotly.graph_objects.Bar', 'go.Bar', ([], {'x': '[0, 1, 2, 3, 4, 5, 6]', 'y': '[0, 1, 4, 9, 16, 25, 36]'}), '(x=[0, 1, 2, 3, 4, 5, 6], y=[0, 1, 4, 9, 16, 25, 36])\n', (4502, 4555), True, 'import plotly.graph_objects as go\n'), ((5251, 5270), 'dash_html_components.Div', 'html.Div', (["['Erro!']"], {}), "(['Erro!'])\n", (5259, 5270), True, 'import dash_html_components as html\n'), ((3085, 3133), 'dash_core_components.Tab', 'dcc.Tab', ([], {'label': '"""Gráfico de linha"""', 'value': '"""tab-1"""'}), "(label='Gráfico de linha', value='tab-1')\n", (3092, 3133), True, 'import dash_core_components as dcc\n'), ((3146, 3194), 'dash_core_components.Tab', 'dcc.Tab', ([], {'label': '"""Gráfico de Barra"""', 'value': '"""tab-2"""'}), "(label='Gráfico de Barra', value='tab-2')\n", (3153, 3194), True, 'import dash_core_components as dcc\n'), ((3207, 3264), 'dash_core_components.Tab', 'dcc.Tab', ([], {'label': '"""Gráfico de Linha e Pontos"""', 'value': '"""tab-3"""'}), "(label='Gráfico de Linha e Pontos', value='tab-3')\n", (3214, 3264), True, 'import dash_core_components as dcc\n'), ((4722, 4747), 'dash_core_components.Graph', 'dcc.Graph', ([], {'figure': 'fig_bar'}), '(figure=fig_bar)\n', (4731, 4747), True, 'import dash_core_components as dcc\n')]