Callback and datatable

Hello,

I have the following datatable listing everything I have in my base.

I would like to create a callback that follows the same principles as the charts, the big problem is that I’m a little confused.

This below is a datatable:

tabelas = html.Div(
    [   
        dash_table.DataTable(
            columns=[{"name": str(i), 
                        "id": str(i), 
                    "type": "numeric", 
                    "format": formatted} for i in df_pivot.columns],
            data=df_pivot.to_dict("records"),
            #row_selectable="single",
            #row_deletable=True,
            editable=True,
            filter_action="native",
            sort_action="native",
            style_table={"overflowX": "auto"},
            page_size=15,
        )
    ], className="dbc dbc-row-selectable",
)

This below is my callback

@app.callback(
    Output('datatable-paging', 'data'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value'))
def update_table(date, dropdown_cidade, mes, toggle, dropdown_bairro):

    template = template_theme1 if toggle else template_theme2

    if 'TODAS' in dropdown_cidade:
        mask = (df_dados_gerais['ANO'] == date)  & (df_dados_gerais['OPERACAO']=='V') & (df_dados_gerais['MES'].isin(mes)) 
    else:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO']=='V') & (df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & (df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & (df_dados_gerais['MES'].isin(mes))    

    df = df_dados_gerais.loc[mask]

    df_pivot = pd.pivot_table(
        df, index=['CODIGO', 'DESCRICAO', 
                                'QT_PRATELEIRA', 'QT_DEPOSITO', 'GRUPO',
                                'FAMILIA', 'UNIDADE', 'CLIENTE_FORNECEDOR'], 
                        values='QUANTIDADE', 
                        columns='MES', 
                        aggfunc=sum).reset_index().fillna(0)
    df_pivot = df_pivot.rename({1: 'JAN', 2: 'FEV', 3: 'MAR', 4: 'ABR', 5: 'MAI', 6: 'JUN', 7: 'JUL', 8: 'AGO', 9: 'SET', 10: 'OUT', 11: 'NOV', 12: 'DEZ'}, axis=1)

    return df_pivot.to_dict('records')

I can’t update my data.

1 Like

Hello @EliasCoutinho,

It looks like you are missing the id='datatable-paging' from your dash_table. Try adding that, and see if it starts working.

It’s true, before posting I had done it correctly and it presented this error as below:

Traceback (most recent call last):
** File “c:\Users\EliasPai\Documents\RIKA\ProjetoDashRika\app_bkp.py”, line 166, in **
** “format”: formatted} for i in df_pivot.columns],**
NameError: name ‘df_pivot’ is not defined

To improve understanding I will post my code here: :innocent: :blush:

'''
*** Projeto dentro da pasta ProjetoDash ***
pip install openpyxl
pip3 install psycopg2
pip3 install peewee
pip3 install dash
pip3 install pandas
pip install dash-bootstrap-components
pip install dash-bootstrap-templates
https://docs.microsoft.com/en-GB/cpp/windows/latest-supported-vc-redist?view=msvc-170

No PowerShell rode o comando:
Set-ExecutionPolicy Unrestricted

'''
import plotly.graph_objs as go
import dash
from dash import html, dcc, Input, Output, State
from dash import html, dash_table
import dash_bootstrap_components as dbc
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd

from dash_bootstrap_templates import ThemeSwitchAIO

# Importei meu dataframe do arquivo movimento_geral.py
from movimento_geral import df_dados_gerais#, df_pivot

# Formatação das tabelas
formatted = {'specifier': ',.2f', 'locale': {'group': '.', 'decimal': ',',}}

# Note que são muitos os dados, isso deve ser fitrado por ANO mas por enquanto limito o número de linhas com .head(15)
# este não é um gráfico adequado para mostrar nomes de produtos.
# print(df_dados_gerais_bar.head(15))

# import theme changer
from dash_bootstrap_templates import ThemeSwitchAIO

# ================================================================== #
from flask import Flask


dbc_css = "https://cdn.jsdelivr.net/gh/AnnMarieW/dash-bootstrap-templates/dbc.min.css"

server = Flask(__name__)

app = dash.Dash(__name__,  server=server, suppress_callback_exceptions=True, external_stylesheets=[dbc.themes.BOOTSTRAP, dbc_css])

# ============================Styles================================ #
tab_card = {'height': '100%'}

main_config = {
    'hovermode': 'x unified',
    'legend': {
        'yanchor':'top',
        'y':0.9,
        'xanchor':'left',
        'x':0.1,
        'title': {'text':None},
        'font': {'color': 'white'},
        'bgcolor':'rgba(0,0,0,0.0)'},
    'margin':{'l':0, 'r':0, 't':20, 'b':0}
}

# Aparência do sistema, cuidado com a ordem do Template_theme1 e 2
# em relação a url_teme
template_theme1 = 'cyborg'
template_theme2 = 'spacelab'
url_theme1 = dbc.themes.CYBORG
url_theme2 = dbc.themes.SPACELAB

# Separando Cidades + Global
s1_cidade_bairros = df_dados_gerais.groupby(['CIDADE','BAIRRO'])['TOTAL_OPERACAO'].sum().reset_index()
s2_todos = pd.DataFrame()
s2_todos['CIDADE'] = ['TODAS']
s2_todos['BAIRRO'] = ['TODOS']
s2_todos['TOTAL_OPERACAO'] = [0]
cidade_bairros = pd.concat([s1_cidade_bairros, s2_todos], ignore_index=True)


# To dict - Para salvar no dcc.store
df_store = df_dados_gerais.to_dict()

graficos = [
    # Row 1

    # Row 4
    # Row Single Card
    dbc.Row([
        dbc.Col([
            dbc.Card([
                dbc.CardBody([
                    dcc.Graph(id='graph0', className='dbc', config={"displayModeBar": False, "showTips": False})
                ])
            ], style=tab_card)
        ], sm=12, lg=12)        
    ], className='g-2 my-auto', style={'margin-top': '7px'}),


    # Row 3
    dbc.Row([
        dbc.Col([
            dbc.Card([
                dbc.CardBody([
                    html.H4("Top 10 em valor de venda, em Reais", style={"font-weight": "bold"}),
                    dcc.Graph(id='graph1', className='dbc', config={"displayModeBar": False, "showTips": False})
                ])
            ], style=tab_card)
        ], sm=12, lg=4, style={'margin-top': '7px'}),
        # Card 2
        dbc.Col([
            dbc.Row([
                dbc.Col([
                    dbc.Card([
                        dbc.CardBody([
                            dcc.Graph(id='graph2', className='dbc', config={"displayModeBar": False, "showTips": False})
                        ])
                    ], style=tab_card)
                ])
            ]),
            dbc.Row([
                dbc.Col([
                    dbc.Card([
                        dbc.Row([
                            dbc.Col([
                                dcc.Graph(id='graph3', className='dbc', config={"displayModeBar": False, "showTips": False})
                            ])
                        ])
                    ], style=tab_card)
                ], sm=12, lg=4),
                dbc.Col([
                    dbc.Card([
                        dbc.Row([
                            dbc.Col([
                                dcc.Graph(id='graph4', className='dbc',  config={"displayModeBar": False, "showTips": False})
                            ])
                        ])
                    ], style=tab_card)
                ], sm=12, lg=4),
                dbc.Col([
                    dbc.Card([
                        dbc.CardBody([
                            #dbc.Row([
                            #    dbc.Col([
                            #        html.H5('Filtro por Gênero'),
                            #        dcc.Graph(id='graph44', className='dbc',  config={"displayModeBar": False, "showTips": False})
                            #   ])
                            #])
                        ])
                    ], style=tab_card)
                ], sm=12, lg=4)
            ], className='g-2 my-auto')
        ], sm=12, lg=8)
    ], justify='center', className='g-2 my-auto'),    
]

tabelas = html.Div(
    [   
        dash_table.DataTable(
            id='datatable-data',
            columns=[{"name": str(i), 
                        "id": str(i), 
                    "type": "numeric", 
                    "format": formatted} for i in df_pivot.columns], # <<<<==== HERE
            data= df_pivot.to_dict("records"), # <<<<==== HERE
            #row_selectable="single",
            #row_deletable=True,
            editable=True,
            filter_action="native",
            sort_action="native",
            style_table={"overflowX": "auto"},
            page_size=15,
        )
    ], className="dbc dbc-row-selectable",
)

# Layout
app.layout = dbc.Container([
    dcc.Store(id='dataset', data=df_store),

    dbc.Row([
        dbc.Col([
            dbc.Card([
                dbc.CardBody([
                    dbc.Row([
                        dbc.Col([  
                            html.Legend("Bag Sales Metrics")
                        ], sm=9),
                        #dbc.Col([         
                        #    html.I(className='fa fa-gamepad', style={'font-size': '300%'})
                        #], sm=3, align="left")
                    ]),
                    dbc.Row([
                        dbc.Col([
                            ThemeSwitchAIO(aio_id="theme", themes=[url_theme1, url_theme2]),
                            html.Legend("Rika Embalagens")
                        ])
                    ], style={'margin-top': '10px'}),
                    dbc.Row([
                        dbc.Button("Visite o Site", href="https://ajuda.alterdata.com.br/suporteexpress", target="_blank")
                    ], style={'margin-top': '10px'})
                ])
            ], style=tab_card)
        ], sm=12, lg=3),

        dbc.Col([
            dbc.Row([
                dbc.Col([
                    dbc.Card([
                        dbc.CardBody([
                            dbc.Col([
                                # html.H5('Escolha o ano da sua pesquisa.', style={"font-weight": "bold"}),
                                dbc.Label("Escolha o ano da sua pesquisa."),
                                dcc.Slider(id='year-slider',
                                    min=int(df_dados_gerais['ANO'][1]),
                                    max=int(df_dados_gerais['ANO'].max()),
                                    marks={str(year): str(year) for year in sorted(df_dados_gerais['ANO'].unique())},
                                    value=int(df_dados_gerais['ANO'].max())-1,
                                    step=None,
                                    tooltip={'always_visible':False, 'placement':'bottom'}, 
                                    className="mb-2"),                        
                            ], sm=12, style={'margin-top': '7px'}),
                        ])
                    ], style=tab_card)
                ])
            ]),
            
            dbc.Row([
                dbc.Col([
                    dbc.Card([
                        dbc.CardBody([
                            dbc.Col([
                                dbc.Label("Marque os mezes de sua pesquisa."),
                                dbc.Checklist(
                                    options=[
                                        {"label": "JAN", "value": 1},
                                        {"label": "FEV", "value": 2},
                                        {"label": "MAR", "value": 3},
                                        {"label": "ABR", "value": 4},
                                        {"label": "MAI", "value": 5},
                                        {"label": "JUN", "value": 6},
                                        {"label": "JUL", "value": 7},
                                        {"label": "AGO", "value": 8},
                                        {"label": "SET", "value": 9},
                                        {"label": "OUT", "value": 10},
                                        {"label": "NOV", "value": 11},
                                        {"label": "DEZ", "value": 12},
                                    ],
                                    value=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
                                    id="check-inline-mes",
                                    inline=True,
                                    #switch=True,
                                ),
                            ], style={'margin-top': '7px'})                            
                        ])

                    ], style=tab_card)
                ], sm=12, lg=12),
            ], className='g-2 my-auto')
        ], sm=12, lg=9)

    ], className='g-2 my-auto', style={'margin-top': '7px'}),

    # Row 2
    dbc.Row([

        dbc.Col([
            dbc.Card([
                dbc.CardBody([
                    dbc.Row([
                        dbc.Col([
                            html.H5('Filtro por Cidade', style={"font-weight": "bold"}),
                            dcc.Dropdown(id='drop-cidade', multi=True, value=['TODAS',], options=[{'label':name, 'value':name} for name in cidade_bairros['CIDADE'].unique()], className='dbc'),
                        ])
                    ])
                ])
            ], style=tab_card)
        ], sm=12, lg=6),

        dbc.Col([
            dbc.Card([
                dbc.CardBody([
                    dbc.Row([
                        dbc.Col([
                            html.H5('Filtro por Bairro', style={"font-weight": "bold"}),
                            dcc.Dropdown(id='drop-bairro', multi=True, value=['TODOS',], className='dbc'),                            
                        ])
                    ])
                ])
            ], style=tab_card)
        ], sm=12, lg=6),                        

    ], className='g-2 my-auto', style={'margin-top': '7px'}),


    dbc.Row([
        dbc.Col([

            dbc.Tabs(
                [
                    dbc.Tab(
                        label="Gráficos", activeTabClassName="fw-bold fst-italic",
                        #active_tab_style={"textTransform": "uppercase"},
                        children=html.Div(graficos, className="p-4 border"),
                    ),
                    dbc.Tab(
                        label="Tabelas", activeTabClassName="fw-bold fst-italic",
                        #active_tab_style={"textTransform": "uppercase"},                        
                        #label="tab 2", active_label_style={"color": "#FB79B3"}
                        children=html.Div(tabelas, className="p-4 border"),
                    ),
                ], className="dbc",
            ),         
        ], sm=12, lg=12)
    ], className='g-2 my-auto', style={'margin-top': '7px'})



], fluid=True, style={'height': '100vh'})

# * * * * * A FAZER * * * * *
# 1 - Adicionar filtro de canceladas.
# 2 - Adicionar check "Marca todas" nos meses.
# 3 - Adicionar Painel de valores:
#     a) Vendas
#     b) Devolução
#     c) Compras
#     a) Entradas


# ======== Callbacks ========== #
@app.callback(
    Output('drop-bairro', 'options'),
    Input('drop-cidade', 'value'))
def set_cities_options(selected_country):
    mask = cidade_bairros['CIDADE'].isin(selected_country)
    df_cidade_bairros = cidade_bairros.loc[mask]

    return [{'label': i, 'value': i} for i in df_cidade_bairros['BAIRRO'].unique()]


# Pie Charts
@app.callback(
    Output('graph0', 'figure'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value')
    )
def graph0(date, dropdown_cidade, mes, toggle, dropdown_bairro):
    template = template_theme1 if toggle else template_theme2

    if 'TODAS' in dropdown_cidade:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['MES'].isin(mes)) 
    else:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & (df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & (df_dados_gerais['MES'].isin(mes))
            
    df_subplot = df_dados_gerais.loc[mask]
    # Cria o mask de df_dados_gerais e faz os filtros
    # procura em df_dados_gerais as cidades do dropdown
    # cria novo objeto df_subplot recebendo o que aparecer de df_dados_gerais.loc[mask]    

    df_groups_v = df_subplot[df_subplot['OPERACAO']=='V'].groupby(['GRUPO'])[['TOTAL_OPERACAO']].sum()
    df_groups_v = df_groups_v.reset_index()
    df_groups_v.sort_values(by=['TOTAL_OPERACAO'],  ascending=False, inplace=True)
    # df_subplot.to_excel('C:/Users/EliasPai/Desktop/df_groups.xlsx')

    df_groups_s = df_subplot[df_subplot['OPERACAO']=='S'].groupby(['GRUPO'])[['TOTAL_OPERACAO']].sum()
    df_groups_s = df_groups_s.reset_index()
    df_groups_s.sort_values(by=['TOTAL_OPERACAO'],  ascending=False, inplace=True)

    df_groups_c = df_subplot[df_subplot['OPERACAO']=='C'].groupby(['GRUPO'])[['TOTAL_OPERACAO']].sum()
    df_groups_c = df_groups_c.reset_index()
    df_groups_c.sort_values(by=['TOTAL_OPERACAO'],  ascending=False, inplace=True)

    df_groups_e = df_subplot[df_subplot['OPERACAO']=='E'].groupby(['GRUPO'])[['TOTAL_OPERACAO']].sum()
    df_groups_e = df_groups_e.reset_index()
    df_groups_e.sort_values(by=['TOTAL_OPERACAO'],  ascending=False, inplace=True)            

    
    subplot_topgames = make_subplots(rows=1, cols=4, specs=[[{"type": "pie"}, {"type": "pie"}, {"type": "pie"}, {"type": "pie"}]],  subplot_titles=("<b>Vendas</b>", "<b>Saídas</b>", "<b>Compras</b>", "<b>Entradas</b>"))
    
    values_v = df_groups_v['TOTAL_OPERACAO']
    subplot_topgames.add_trace(go.Pie(
        labels=df_groups_v['GRUPO'], values=values_v, hole=.2), row=1, col=1)

    
    subplot_topgames.add_trace(go.Pie(
        labels=df_groups_s['GRUPO'], values=df_groups_s['TOTAL_OPERACAO'], hole=.2), row=1, col=2)

    
    subplot_topgames.add_trace(go.Pie(
        labels=df_groups_c['GRUPO'], values=df_groups_c['TOTAL_OPERACAO'], hole=.2), row=1, col=3)

    
    subplot_topgames.add_trace(go.Pie(
        labels=df_groups_e['GRUPO'], values=df_groups_e['TOTAL_OPERACAO'], hole=.2), row=1, col=4)


    subplot_topgames.update_layout(margin={"l":0, "r":0, "t":20, "b":0}, height=200, template=template)

    return subplot_topgames
# --------------------------------------------------------------------------------------------

# Graph1 - Horizontal Bars
@app.callback(
    Output('graph1', 'figure'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value')
    )

def fig1(date, dropdown_cidade, mes, toggle, dropdown_bairro):
    template = template_theme1 if toggle else template_theme2
    if 'TODAS' in dropdown_cidade:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO']=='V') & (df_dados_gerais['MES'].isin(mes)) 
    else:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO']=='V') & (df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & (df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & (df_dados_gerais['MES'].isin(mes))

    df_topglobal = df_dados_gerais.loc[mask]


    df_topglobal = df_topglobal.groupby(['DESCRICAO'])[['TOTAL_OPERACAO']].sum()
    df_topglobal = df_topglobal.reset_index()
    df_topglobal.sort_values(by=['TOTAL_OPERACAO'],  ascending=False, inplace=True)
    df_topglobal = df_topglobal.head(10).sort_values(by=['TOTAL_OPERACAO'])

#    df_topglobal.to_excel('C:/Users/EliasPai/Desktop/2021.xlsx')

    text = [f'{x} - R${y:_.2f} '.replace('.', ',').replace('_', '.') for x,y in zip(df_topglobal['DESCRICAO'].unique(), df_topglobal['TOTAL_OPERACAO'].unique())]

    fig = go.Figure(go.Bar(x=df_topglobal['TOTAL_OPERACAO'], y=df_topglobal['DESCRICAO'], orientation='h', text=text))
    fig.update_layout(main_config, height=310, xaxis={'title': None, 'showticklabels':False}, yaxis={'title': None, 'showticklabels':False}, template=template)
    return fig


# Graph 2 - Line Chart
@app.callback(
    Output('graph2', 'figure'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value')
    )
def long(date, dropdown_cidade, mes, toggle, dropdown_bairro):
    template = template_theme1 if toggle else template_theme2
    if 'TODAS' in dropdown_cidade:
        mask = (df_dados_gerais['ANO'] == date)  & (df_dados_gerais['OPERACAO']=='V') & (df_dados_gerais['MES'].isin(mes)) 
    else:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO']=='V') & (df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & (df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & (df_dados_gerais['MES'].isin(mes))

    df_anos = df_dados_gerais.loc[mask]

    trace = df_anos.groupby('MES')['TOTAL_OPERACAO'].sum().reset_index()

    trace['MES'] = trace['MES'].map({1: 'JAN',
                                    2: 'FEV',
                                    3: 'MAR',
                                    4: 'ABR',
                                    5: 'MAI',
                                    6: 'JUN',
                                    7: 'JUL',
                                    8: 'AGO',
                                    9: 'SET',
                                    10: 'OUT',
                                    11: 'NOV',
                                    12: 'DEZ'},
                                    na_action=None)    

    fig_anos = go.Figure(go.Scatter(x=trace['MES'], y=trace['TOTAL_OPERACAO'], mode='lines+markers', fill='tonexty', name='Global Sales'))
    
    fig_anos.update_layout(main_config, height=200, xaxis={'title': 'None'}, yaxis={'title': None}, template=template)

    fig_anos.add_annotation(text=f'Vendas em Reais de {date}',
        xref="paper", yref="paper",
        font=dict(
            size=20,
            color='white'
            ),
        align="center", bgcolor="rgba(0,0,0,0.8)", opacity=0.8,
        x=0.5, y=0.5, showarrow=False)

    return fig_anos



# Indicator 1 and 2
@app.callback(
    Output('graph3', 'figure'),
    Output('graph4', 'figure'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value')
)
def ind1(date, dropdown_cidade, mes, toggle, dropdown_bairro):
    template = template_theme1 if toggle else template_theme2

    if 'TODAS' in dropdown_cidade:
        mask = (df_dados_gerais['ANO'] == date)  & (df_dados_gerais['OPERACAO']=='V') & (df_dados_gerais['MES'].isin(mes)) 
    else:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO']=='V') & (df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & (df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & (df_dados_gerais['MES'].isin(mes))    

    df_graph3 = df_graph4 = df_dados_gerais.loc[mask]

    df_graph3 = df_graph3.groupby('MES')['TOTAL_OPERACAO'].sum().reset_index()
    df_graph4 = df_graph4.groupby('CIDADE')['TOTAL_OPERACAO'].sum().reset_index()
    
    value1 = df_graph3['TOTAL_OPERACAO'].max()
    name1 = df_graph3.loc[df_graph3['TOTAL_OPERACAO'].idxmax()]['MES']

    value2 = df_graph4['TOTAL_OPERACAO'].max()
    name2 = df_graph4.loc[df_graph4['TOTAL_OPERACAO'].idxmax()]['CIDADE']

    fig1 = go.Figure()
    fig2 = go.Figure()
    # R${y:_.2f} '.replace('.', ',').replace('_', '.') ***** FORMATO DOS NÚMEROS *****
    fig1.add_trace(go.Indicator(
        mode = "number",
        title = {"text": f"<span style='font-size:100%'>{name1} - Melhor venda</span><br><span style='font-size:70%'>Em Reais</span><br><span style='font-size:0.7em'>{df_dados_gerais['ANO'][1]} - {df_dados_gerais['ANO'].max()}</span>"},
        value = value1,
        number = {'valueformat': '.2f'}
    ))

    fig2.add_trace(go.Indicator(
        mode = "number",
        title = {"text": f"<span style='font-size:100%'>{name2} - Melhor Grupo</span><br><span style='font-size:70%'>Em Reais</span><br><span style='font-size:0.7em'>{df_dados_gerais['ANO'][1]} - {df_dados_gerais['ANO'].max()}</span>"},
        value = value2,
        number = {'valueformat': '.2f'}
    ))

    fig1.update_layout(main_config, height=273, template=template)
    fig2.update_layout(main_config, height=273, template=template)

    return fig1, fig2


@app.callback(
    Output('datatable-data', 'data'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value'))
def update_table(date, dropdown_cidade, mes, toggle, dropdown_bairro):

    template = template_theme1 if toggle else template_theme2

    if 'TODAS' in dropdown_cidade:
        mask = (df_dados_gerais['ANO'] == date)  & (df_dados_gerais['OPERACAO']=='V') & (df_dados_gerais['MES'].isin(mes)) 
    else:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO']=='V') & (df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & (df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & (df_dados_gerais['MES'].isin(mes))    

    df = df_dados_gerais.loc[mask]

    df_pivot = pd.pivot_table(
        df, index=['CODIGO', 'DESCRICAO', 
                                'QT_PRATELEIRA', 'QT_DEPOSITO', 'GRUPO',
                                'FAMILIA', 'UNIDADE', 'CLIENTE_FORNECEDOR'], 
                        values='QUANTIDADE', 
                        columns='MES', 
                        aggfunc=sum).reset_index().fillna(0)
    df_pivot = df_pivot.rename({1: 'JAN', 2: 'FEV', 3: 'MAR', 4: 'ABR', 5: 'MAI', 6: 'JUN', 7: 'JUL', 8: 'AGO', 9: 'SET', 10: 'OUT', 11: 'NOV', 12: 'DEZ'}, axis=1)

    return df_pivot.to_dict('records')

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

The error happens at the points I entered the comment # <<<<==== HERE.
And the callback is the last one where there is the def update_table function.

Hello @EliasCoutinho,

Your df_pivot is undefined at initialization. That is why it is breaking.

If you can define the df_pivot at the top, then everything should be fine. If not, then you’ll have to also pass the columns during your callback and use an empty datatable in your layout initially.

It even worked without errors, but it didn’t show any data.

Hmm…

Try this:

'''
*** Projeto dentro da pasta ProjetoDash ***
pip install openpyxl
pip3 install psycopg2
pip3 install peewee
pip3 install dash
pip3 install pandas
pip install dash-bootstrap-components
pip install dash-bootstrap-templates
https://docs.microsoft.com/en-GB/cpp/windows/latest-supported-vc-redist?view=msvc-170

No PowerShell rode o comando:
Set-ExecutionPolicy Unrestricted

'''
import plotly.graph_objs as go
import dash
from dash import html, dcc, Input, Output, State
from dash import html, dash_table
import dash_bootstrap_components as dbc
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd

from dash_bootstrap_templates import ThemeSwitchAIO

# Importei meu dataframe do arquivo movimento_geral.py
from movimento_geral import df_dados_gerais  # , df_pivot

# Formatação das tabelas
formatted = {'specifier': ',.2f', 'locale': {'group': '.', 'decimal': ',', }}

# Note que são muitos os dados, isso deve ser fitrado por ANO mas por enquanto limito o número de linhas com .head(15)
# este não é um gráfico adequado para mostrar nomes de produtos.
# print(df_dados_gerais_bar.head(15))

# import theme changer
from dash_bootstrap_templates import ThemeSwitchAIO

# ================================================================== #
from flask import Flask

dbc_css = "https://cdn.jsdelivr.net/gh/AnnMarieW/dash-bootstrap-templates/dbc.min.css"

server = Flask(__name__)

app = dash.Dash(__name__, server=server, suppress_callback_exceptions=True,
                external_stylesheets=[dbc.themes.BOOTSTRAP, dbc_css])

# ============================Styles================================ #
tab_card = {'height': '100%'}

main_config = {
    'hovermode': 'x unified',
    'legend': {
        'yanchor': 'top',
        'y': 0.9,
        'xanchor': 'left',
        'x': 0.1,
        'title': {'text': None},
        'font': {'color': 'white'},
        'bgcolor': 'rgba(0,0,0,0.0)'},
    'margin': {'l': 0, 'r': 0, 't': 20, 'b': 0}
}

# Aparência do sistema, cuidado com a ordem do Template_theme1 e 2
# em relação a url_teme
template_theme1 = 'cyborg'
template_theme2 = 'spacelab'
url_theme1 = dbc.themes.CYBORG
url_theme2 = dbc.themes.SPACELAB

# Separando Cidades + Global
s1_cidade_bairros = df_dados_gerais.groupby(['CIDADE', 'BAIRRO'])['TOTAL_OPERACAO'].sum().reset_index()
s2_todos = pd.DataFrame()
s2_todos['CIDADE'] = ['TODAS']
s2_todos['BAIRRO'] = ['TODOS']
s2_todos['TOTAL_OPERACAO'] = [0]
cidade_bairros = pd.concat([s1_cidade_bairros, s2_todos], ignore_index=True)

# To dict - Para salvar no dcc.store
df_store = df_dados_gerais.to_dict()

graficos = [
    # Row 1

    # Row 4
    # Row Single Card
    dbc.Row([
        dbc.Col([
            dbc.Card([
                dbc.CardBody([
                    dcc.Graph(id='graph0', className='dbc', config={"displayModeBar": False, "showTips": False})
                ])
            ], style=tab_card)
        ], sm=12, lg=12)
    ], className='g-2 my-auto', style={'margin-top': '7px'}),

    # Row 3
    dbc.Row([
        dbc.Col([
            dbc.Card([
                dbc.CardBody([
                    html.H4("Top 10 em valor de venda, em Reais", style={"font-weight": "bold"}),
                    dcc.Graph(id='graph1', className='dbc', config={"displayModeBar": False, "showTips": False})
                ])
            ], style=tab_card)
        ], sm=12, lg=4, style={'margin-top': '7px'}),
        # Card 2
        dbc.Col([
            dbc.Row([
                dbc.Col([
                    dbc.Card([
                        dbc.CardBody([
                            dcc.Graph(id='graph2', className='dbc', config={"displayModeBar": False, "showTips": False})
                        ])
                    ], style=tab_card)
                ])
            ]),
            dbc.Row([
                dbc.Col([
                    dbc.Card([
                        dbc.Row([
                            dbc.Col([
                                dcc.Graph(id='graph3', className='dbc',
                                          config={"displayModeBar": False, "showTips": False})
                            ])
                        ])
                    ], style=tab_card)
                ], sm=12, lg=4),
                dbc.Col([
                    dbc.Card([
                        dbc.Row([
                            dbc.Col([
                                dcc.Graph(id='graph4', className='dbc',
                                          config={"displayModeBar": False, "showTips": False})
                            ])
                        ])
                    ], style=tab_card)
                ], sm=12, lg=4),
                dbc.Col([
                    dbc.Card([
                        dbc.CardBody([
                            # dbc.Row([
                            #    dbc.Col([
                            #        html.H5('Filtro por Gênero'),
                            #        dcc.Graph(id='graph44', className='dbc',  config={"displayModeBar": False, "showTips": False})
                            #   ])
                            # ])
                        ])
                    ], style=tab_card)
                ], sm=12, lg=4)
            ], className='g-2 my-auto')
        ], sm=12, lg=8)
    ], justify='center', className='g-2 my-auto'),
]

tabelas = html.Div(
    [
        dash_table.DataTable(
            id='datatable-data',
            # columns=[{"name": str(i),
            #           "id": str(i),
            #           "type": "numeric",
            #           "format": formatted} for i in df_pivot.columns],  # <<<<==== HERE
            # data=df_pivot.to_dict("records"),  # <<<<==== HERE
            # row_selectable="single",
            # row_deletable=True,
            editable=True,
            filter_action="native",
            sort_action="native",
            style_table={"overflowX": "auto"},
            page_size=15,
        )
    ], className="dbc dbc-row-selectable",
)

# Layout
app.layout = dbc.Container([
    dcc.Store(id='dataset', data=df_store),

    dbc.Row([
        dbc.Col([
            dbc.Card([
                dbc.CardBody([
                    dbc.Row([
                        dbc.Col([
                            html.Legend("Bag Sales Metrics")
                        ], sm=9),
                        # dbc.Col([         
                        #    html.I(className='fa fa-gamepad', style={'font-size': '300%'})
                        # ], sm=3, align="left")
                    ]),
                    dbc.Row([
                        dbc.Col([
                            ThemeSwitchAIO(aio_id="theme", themes=[url_theme1, url_theme2]),
                            html.Legend("Rika Embalagens")
                        ])
                    ], style={'margin-top': '10px'}),
                    dbc.Row([
                        dbc.Button("Visite o Site", href="https://ajuda.alterdata.com.br/suporteexpress",
                                   target="_blank")
                    ], style={'margin-top': '10px'})
                ])
            ], style=tab_card)
        ], sm=12, lg=3),

        dbc.Col([
            dbc.Row([
                dbc.Col([
                    dbc.Card([
                        dbc.CardBody([
                            dbc.Col([
                                # html.H5('Escolha o ano da sua pesquisa.', style={"font-weight": "bold"}),
                                dbc.Label("Escolha o ano da sua pesquisa."),
                                dcc.Slider(id='year-slider',
                                           min=int(df_dados_gerais['ANO'][1]),
                                           max=int(df_dados_gerais['ANO'].max()),
                                           marks={str(year): str(year) for year in
                                                  sorted(df_dados_gerais['ANO'].unique())},
                                           value=int(df_dados_gerais['ANO'].max()) - 1,
                                           step=None,
                                           tooltip={'always_visible': False, 'placement': 'bottom'},
                                           className="mb-2"),
                            ], sm=12, style={'margin-top': '7px'}),
                        ])
                    ], style=tab_card)
                ])
            ]),

            dbc.Row([
                dbc.Col([
                    dbc.Card([
                        dbc.CardBody([
                            dbc.Col([
                                dbc.Label("Marque os mezes de sua pesquisa."),
                                dbc.Checklist(
                                    options=[
                                        {"label": "JAN", "value": 1},
                                        {"label": "FEV", "value": 2},
                                        {"label": "MAR", "value": 3},
                                        {"label": "ABR", "value": 4},
                                        {"label": "MAI", "value": 5},
                                        {"label": "JUN", "value": 6},
                                        {"label": "JUL", "value": 7},
                                        {"label": "AGO", "value": 8},
                                        {"label": "SET", "value": 9},
                                        {"label": "OUT", "value": 10},
                                        {"label": "NOV", "value": 11},
                                        {"label": "DEZ", "value": 12},
                                    ],
                                    value=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
                                    id="check-inline-mes",
                                    inline=True,
                                    # switch=True,
                                ),
                            ], style={'margin-top': '7px'})
                        ])

                    ], style=tab_card)
                ], sm=12, lg=12),
            ], className='g-2 my-auto')
        ], sm=12, lg=9)

    ], className='g-2 my-auto', style={'margin-top': '7px'}),

    # Row 2
    dbc.Row([

        dbc.Col([
            dbc.Card([
                dbc.CardBody([
                    dbc.Row([
                        dbc.Col([
                            html.H5('Filtro por Cidade', style={"font-weight": "bold"}),
                            dcc.Dropdown(id='drop-cidade', multi=True, value=['TODAS', ],
                                         options=[{'label': name, 'value': name} for name in
                                                  cidade_bairros['CIDADE'].unique()], className='dbc'),
                        ])
                    ])
                ])
            ], style=tab_card)
        ], sm=12, lg=6),

        dbc.Col([
            dbc.Card([
                dbc.CardBody([
                    dbc.Row([
                        dbc.Col([
                            html.H5('Filtro por Bairro', style={"font-weight": "bold"}),
                            dcc.Dropdown(id='drop-bairro', multi=True, value=['TODOS', ], className='dbc'),
                        ])
                    ])
                ])
            ], style=tab_card)
        ], sm=12, lg=6),

    ], className='g-2 my-auto', style={'margin-top': '7px'}),

    dbc.Row([
        dbc.Col([

            dbc.Tabs(
                [
                    dbc.Tab(
                        label="Gráficos", activeTabClassName="fw-bold fst-italic",
                        # active_tab_style={"textTransform": "uppercase"},
                        children=html.Div(graficos, className="p-4 border"),
                    ),
                    dbc.Tab(
                        label="Tabelas", activeTabClassName="fw-bold fst-italic",
                        # active_tab_style={"textTransform": "uppercase"},                        
                        # label="tab 2", active_label_style={"color": "#FB79B3"}
                        children=html.Div(tabelas, className="p-4 border"),
                    ),
                ], className="dbc",
            ),
        ], sm=12, lg=12)
    ], className='g-2 my-auto', style={'margin-top': '7px'})

], fluid=True, style={'height': '100vh'})


# * * * * * A FAZER * * * * *
# 1 - Adicionar filtro de canceladas.
# 2 - Adicionar check "Marca todas" nos meses.
# 3 - Adicionar Painel de valores:
#     a) Vendas
#     b) Devolução
#     c) Compras
#     a) Entradas


# ======== Callbacks ========== #
@app.callback(
    Output('drop-bairro', 'options'),
    Input('drop-cidade', 'value'))
def set_cities_options(selected_country):
    mask = cidade_bairros['CIDADE'].isin(selected_country)
    df_cidade_bairros = cidade_bairros.loc[mask]

    return [{'label': i, 'value': i} for i in df_cidade_bairros['BAIRRO'].unique()]


# Pie Charts
@app.callback(
    Output('graph0', 'figure'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value')
)
def graph0(date, dropdown_cidade, mes, toggle, dropdown_bairro):
    template = template_theme1 if toggle else template_theme2

    if 'TODAS' in dropdown_cidade:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['MES'].isin(mes))
    else:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & (
            df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & (df_dados_gerais['MES'].isin(mes))

    df_subplot = df_dados_gerais.loc[mask]
    # Cria o mask de df_dados_gerais e faz os filtros
    # procura em df_dados_gerais as cidades do dropdown
    # cria novo objeto df_subplot recebendo o que aparecer de df_dados_gerais.loc[mask]    

    df_groups_v = df_subplot[df_subplot['OPERACAO'] == 'V'].groupby(['GRUPO'])[['TOTAL_OPERACAO']].sum()
    df_groups_v = df_groups_v.reset_index()
    df_groups_v.sort_values(by=['TOTAL_OPERACAO'], ascending=False, inplace=True)
    # df_subplot.to_excel('C:/Users/EliasPai/Desktop/df_groups.xlsx')

    df_groups_s = df_subplot[df_subplot['OPERACAO'] == 'S'].groupby(['GRUPO'])[['TOTAL_OPERACAO']].sum()
    df_groups_s = df_groups_s.reset_index()
    df_groups_s.sort_values(by=['TOTAL_OPERACAO'], ascending=False, inplace=True)

    df_groups_c = df_subplot[df_subplot['OPERACAO'] == 'C'].groupby(['GRUPO'])[['TOTAL_OPERACAO']].sum()
    df_groups_c = df_groups_c.reset_index()
    df_groups_c.sort_values(by=['TOTAL_OPERACAO'], ascending=False, inplace=True)

    df_groups_e = df_subplot[df_subplot['OPERACAO'] == 'E'].groupby(['GRUPO'])[['TOTAL_OPERACAO']].sum()
    df_groups_e = df_groups_e.reset_index()
    df_groups_e.sort_values(by=['TOTAL_OPERACAO'], ascending=False, inplace=True)

    subplot_topgames = make_subplots(rows=1, cols=4,
                                     specs=[[{"type": "pie"}, {"type": "pie"}, {"type": "pie"}, {"type": "pie"}]],
                                     subplot_titles=(
                                     "<b>Vendas</b>", "<b>Saídas</b>", "<b>Compras</b>", "<b>Entradas</b>"))

    values_v = df_groups_v['TOTAL_OPERACAO']
    subplot_topgames.add_trace(go.Pie(
        labels=df_groups_v['GRUPO'], values=values_v, hole=.2), row=1, col=1)

    subplot_topgames.add_trace(go.Pie(
        labels=df_groups_s['GRUPO'], values=df_groups_s['TOTAL_OPERACAO'], hole=.2), row=1, col=2)

    subplot_topgames.add_trace(go.Pie(
        labels=df_groups_c['GRUPO'], values=df_groups_c['TOTAL_OPERACAO'], hole=.2), row=1, col=3)

    subplot_topgames.add_trace(go.Pie(
        labels=df_groups_e['GRUPO'], values=df_groups_e['TOTAL_OPERACAO'], hole=.2), row=1, col=4)

    subplot_topgames.update_layout(margin={"l": 0, "r": 0, "t": 20, "b": 0}, height=200, template=template)

    return subplot_topgames


# --------------------------------------------------------------------------------------------

# Graph1 - Horizontal Bars
@app.callback(
    Output('graph1', 'figure'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value')
)
def fig1(date, dropdown_cidade, mes, toggle, dropdown_bairro):
    template = template_theme1 if toggle else template_theme2
    if 'TODAS' in dropdown_cidade:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO'] == 'V') & (
            df_dados_gerais['MES'].isin(mes))
    else:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO'] == 'V') & (
            df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & (df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & (
                   df_dados_gerais['MES'].isin(mes))

    df_topglobal = df_dados_gerais.loc[mask]

    df_topglobal = df_topglobal.groupby(['DESCRICAO'])[['TOTAL_OPERACAO']].sum()
    df_topglobal = df_topglobal.reset_index()
    df_topglobal.sort_values(by=['TOTAL_OPERACAO'], ascending=False, inplace=True)
    df_topglobal = df_topglobal.head(10).sort_values(by=['TOTAL_OPERACAO'])

    #    df_topglobal.to_excel('C:/Users/EliasPai/Desktop/2021.xlsx')

    text = [f'{x} - R${y:_.2f} '.replace('.', ',').replace('_', '.') for x, y in
            zip(df_topglobal['DESCRICAO'].unique(), df_topglobal['TOTAL_OPERACAO'].unique())]

    fig = go.Figure(go.Bar(x=df_topglobal['TOTAL_OPERACAO'], y=df_topglobal['DESCRICAO'], orientation='h', text=text))
    fig.update_layout(main_config, height=310, xaxis={'title': None, 'showticklabels': False},
                      yaxis={'title': None, 'showticklabels': False}, template=template)
    return fig


# Graph 2 - Line Chart
@app.callback(
    Output('graph2', 'figure'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value')
)
def long(date, dropdown_cidade, mes, toggle, dropdown_bairro):
    template = template_theme1 if toggle else template_theme2
    if 'TODAS' in dropdown_cidade:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO'] == 'V') & (
            df_dados_gerais['MES'].isin(mes))
    else:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO'] == 'V') & (
            df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & (df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & (
                   df_dados_gerais['MES'].isin(mes))

    df_anos = df_dados_gerais.loc[mask]

    trace = df_anos.groupby('MES')['TOTAL_OPERACAO'].sum().reset_index()

    trace['MES'] = trace['MES'].map({1: 'JAN',
                                     2: 'FEV',
                                     3: 'MAR',
                                     4: 'ABR',
                                     5: 'MAI',
                                     6: 'JUN',
                                     7: 'JUL',
                                     8: 'AGO',
                                     9: 'SET',
                                     10: 'OUT',
                                     11: 'NOV',
                                     12: 'DEZ'},
                                    na_action=None)

    fig_anos = go.Figure(go.Scatter(x=trace['MES'], y=trace['TOTAL_OPERACAO'], mode='lines+markers', fill='tonexty',
                                    name='Global Sales'))

    fig_anos.update_layout(main_config, height=200, xaxis={'title': 'None'}, yaxis={'title': None}, template=template)

    fig_anos.add_annotation(text=f'Vendas em Reais de {date}',
                            xref="paper", yref="paper",
                            font=dict(
                                size=20,
                                color='white'
                            ),
                            align="center", bgcolor="rgba(0,0,0,0.8)", opacity=0.8,
                            x=0.5, y=0.5, showarrow=False)

    return fig_anos


# Indicator 1 and 2
@app.callback(
    Output('graph3', 'figure'),
    Output('graph4', 'figure'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value')
)
def ind1(date, dropdown_cidade, mes, toggle, dropdown_bairro):
    template = template_theme1 if toggle else template_theme2

    if 'TODAS' in dropdown_cidade:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO'] == 'V') & (
            df_dados_gerais['MES'].isin(mes))
    else:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO'] == 'V') & (
            df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & (df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & (
                   df_dados_gerais['MES'].isin(mes))

    df_graph3 = df_graph4 = df_dados_gerais.loc[mask]

    df_graph3 = df_graph3.groupby('MES')['TOTAL_OPERACAO'].sum().reset_index()
    df_graph4 = df_graph4.groupby('CIDADE')['TOTAL_OPERACAO'].sum().reset_index()

    value1 = df_graph3['TOTAL_OPERACAO'].max()
    name1 = df_graph3.loc[df_graph3['TOTAL_OPERACAO'].idxmax()]['MES']

    value2 = df_graph4['TOTAL_OPERACAO'].max()
    name2 = df_graph4.loc[df_graph4['TOTAL_OPERACAO'].idxmax()]['CIDADE']

    fig1 = go.Figure()
    fig2 = go.Figure()
    # R${y:_.2f} '.replace('.', ',').replace('_', '.') ***** FORMATO DOS NÚMEROS *****
    fig1.add_trace(go.Indicator(
        mode="number",
        title={
            "text": f"<span style='font-size:100%'>{name1} - Melhor venda</span><br><span style='font-size:70%'>Em Reais</span><br><span style='font-size:0.7em'>{df_dados_gerais['ANO'][1]} - {df_dados_gerais['ANO'].max()}</span>"},
        value=value1,
        number={'valueformat': '.2f'}
    ))

    fig2.add_trace(go.Indicator(
        mode="number",
        title={
            "text": f"<span style='font-size:100%'>{name2} - Melhor Grupo</span><br><span style='font-size:70%'>Em Reais</span><br><span style='font-size:0.7em'>{df_dados_gerais['ANO'][1]} - {df_dados_gerais['ANO'].max()}</span>"},
        value=value2,
        number={'valueformat': '.2f'}
    ))

    fig1.update_layout(main_config, height=273, template=template)
    fig2.update_layout(main_config, height=273, template=template)

    return fig1, fig2


@app.callback(
    Output('datatable-data', 'data'),
    Output('datatable-data', 'columns'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value'))
def update_table(date, dropdown_cidade, mes, toggle, dropdown_bairro):
    template = template_theme1 if toggle else template_theme2

    if 'TODAS' in dropdown_cidade:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO'] == 'V') & (
            df_dados_gerais['MES'].isin(mes))
    else:
        mask = (df_dados_gerais['ANO'] == date) & (df_dados_gerais['OPERACAO'] == 'V') & (
            df_dados_gerais['CIDADE'].isin(dropdown_cidade)) & (df_dados_gerais['BAIRRO'].isin(dropdown_bairro)) & (
                   df_dados_gerais['MES'].isin(mes))

    df = df_dados_gerais.loc[mask]

    df_pivot = pd.pivot_table(
        df, index=['CODIGO', 'DESCRICAO',
                   'QT_PRATELEIRA', 'QT_DEPOSITO', 'GRUPO',
                   'FAMILIA', 'UNIDADE', 'CLIENTE_FORNECEDOR'],
        values='QUANTIDADE',
        columns='MES',
        aggfunc=sum).reset_index().fillna(0)
    df_pivot = df_pivot.rename(
        {1: 'JAN', 2: 'FEV', 3: 'MAR', 4: 'ABR', 5: 'MAI', 6: 'JUN', 7: 'JUL', 8: 'AGO', 9: 'SET', 10: 'OUT', 11: 'NOV',
         12: 'DEZ'}, axis=1)

    return df_pivot.to_dict('records'), [{"name": str(i),
                      "id": str(i),
                      "type": "numeric",
                      "format": formatted} for i in df_pivot.columns]


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

Got responding now!
It’s just bringing everything repeated, I’ll do a grouping to try to solve it.

I thank you very much.

1 Like

Hi @EliasCoutinho

Here’s a tip when using the ThemeSwitchAIO component. When the theme changes, it’s necessary to do a callback to update the figure with the correct theme. However a callback is not necessary to update the theme of dash core components and the DataTable when you use the stylesheet from the dash-bootstrap-templates library.

Since this callback only updates the table, it does not need to have the value of the ThemeSwitchAIO as an input:

@app.callback(
    Output('datatable-data', 'data'),
    Output('datatable-data', 'columns'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    Input('check-inline-mes', 'value'),
    Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('drop-bairro', 'value'))
def update_table(date, dropdown_cidade, mes, toggle, dropdown_bairro):
    template = template_theme1 if toggle else template_theme2

    if 'TODAS' in dropdown_cidade:
         
           ... rest of your callback

Your callback can be simplified to this:

@app.callback(
    Output('datatable-data', 'data'),
    Output('datatable-data', 'columns'),
    Input('year-slider', 'value'),
    Input('drop-cidade', 'value'),
    # remove this next line:
    #Input(ThemeSwitchAIO.ids.switch("theme"), "value"),
    Input('check-inline-mes', 'value'),    
    Input('drop-bairro', 'value'))
def update_table(date, dropdown_cidade, mes,  dropdown_bairro):
    
    # Remove this because figure templates are not used when updated the DataTable
    #template = template_theme1 if toggle else template_theme2

    if 'TODAS' in dropdown_cidade:
         
           ... rest of your callback
2 Likes

Hello guys.

Interestingly after this datatable, my filters only work if I search for the exact text, that is, if I write part of the text it doesn’t find it.

What could be wrong?

Hi @EliasCoutinho can you make a minimal example that reproduces the issue - with just a DataTable and some sample data where the filters are not working?

I ended up finding out that the problem is in this line:

 return df_pivot.to_dict('records'), [{"name": str(i),
                   "id": str(i),
                   "type": "numeric",
                   "format": formatted} for i in df_pivot.columns]

Where I transform all the fields into numeric (To keep the decimal places as I need).
I’ll try to pass different types to different columns.
If friends help me I appreciate it.

My solution was pretty primitive, if anyone has a cleaner solution I’d appreciate it:

return df_pivot.to_dict('records'), [
            {
                'name': 'CODE',
                'id': 'CODE',
                'type': 'text',
            },

            {
                'name': 'DESCRIPTION',
                'id': 'DESCRIPTION',
                'type': 'text',
            },

            {
                'name': 'STOCK',
                'id': 'STOCK',
                'type': 'numeric',
                'format': formatted,
            },

            {
                'name': 'GROUP',
                'id': 'GROUP',
                'type': 'text',
            },

            {
                'name': 'FAMILY',
                'id': 'FAMILY',
                'type': 'text',
            },

            {
                'name': 'UNIT',
                'id': 'UNIT',
                'type': 'text',
            },

            {
                'name': 'JAN',
                'id': 'JAN',
                'type': 'numeric',
                'format': formatted,
            },

            {
                'name': 'FEB',
                'id': 'FEB',
                'type': 'numeric',
                'format': formatted,
            },

            {
                'name': 'MAR',
                'id': 'MAR',
                'type': 'numeric',
                'format': formatted,
            },

            {
                'name': 'ABR',
                'id': 'ABR',
                'type': 'numeric',
                'format': formatted,
            },

            {
                'name': 'MAY',
                'id': 'MAY',
                'type': 'numeric',
                'format': formatted,
            },

            {
                'name': 'JUN',
                'id': 'JUN',
                'type': 'numeric',
                'format': formatted,
            },

            {
                'name': 'JUL',
                'id': 'JUL',
                'type': 'numeric',
                'format': formatted,
            },

            {
                'name': 'AUG',
                'id': 'AUG',
                'type': 'numeric',
                'format': formatted,
            },

            {
                'name': 'SET',
                'id': 'SET',
                'type': 'numeric',
                'format': formatted,
            },

            {
                'name': 'OUT',
                'id': 'OUT',
                'type': 'numeric',
                'format': formatted,
            },

            {
                'name': 'NOV',
                'id': 'NOV',
                'type': 'numeric',
                'format': formatted,
            },

            {
                'name': 'TEN',
                'id': 'TEN',
                'type': 'numeric',
                'format': formatted,
            },
        ]

Hello @EliasCoutinho,

Since not all of your columns are numeric, you can save the names in a list of the numeric columns and do this:

cols = []

numCols = [] # <--numeric columns here

for i in df_pivot.columns:
    if i in numCols:
        cols.append({"name": str(i),
                   "id": str(i),
                   "type": "numeric",
                   "format": formatted})
    else:
        cols.append({"name": str(i),
                     "id": str(i),
                     "type": "text"})



return df_pivot.to_dict('records'), cols
1 Like