I have an application that retrieves data from a db and then update some dropdowns and an AG Grid table.
The raw data was stored using the dcc.Store(id=‘session’)
# Callback to dynamically query the database based on the selected date range
@callback(
Output('session', 'raw_data'),
[Input('picker', 'start_date'),
Input('picker', 'end_date')]
# [State(store, 'data')] # State input to pass the result of the previous callback
)
def update_displayed_data(start_date, end_date):
# Parse the selected dates
try:
start_date = parser.parse(start_date).timestamp()
# start_date = datetime.strptime(start_date, date_format).timestamp()
# end_date = datetime.strptime(end_date, date_format).timestamp()
end_date = parser.parse(end_date).timestamp()
data = dashboard_input(machine_type, start_date, end_date)
# print(data.columns)
# Returning the result along with the previous result
# return [data.to_dict('records'), region_option, model_options, machine_options, region_value, model_value, machine_value, data.to_dict('records')]
return data.to_json(date_format='iso', orient='split')
except ValueError as e:
print(f"Error: {e}")
return []
@callback(
Output('regDrop', 'options'),
Output('regDrop', 'value'),
Input('session', 'raw_data'))
def set_location_options(data):
# more generally, this line would be
# json.loads(jsonified_cleaned_data)
df = pd.read_json(data, orient='split')
regions = df.Location.dropna().unique()
# Create a dropdown menu for all desired Regions
region_option = [{'label': 'Select All', 'value': 'all'}] \
+ [{'label': reg, 'value': reg} for reg in regions]
region_value=region_option[1]['value']
return region_option, region_value
@callback(
Output('modDrop', 'options'),
Output('modDrop', 'value'),
Input('session', 'raw_data'),
Input('regDrop', 'value'))
def set_model_options(data, regDrop):
# more generally, this line would be
# json.loads(jsonified_cleaned_data)
df = pd.read_json(data, orient='split')
if 'all' in regDrop:
models = df['Model Type'].dropna().unique()
else:
models = df.query("Location == @regDrop")['Model Type'].dropna().unique()
# # Create a dropdown menu for all desired Models
model_options = [{'label': model, 'value': model}
for model in models]
model_options.insert(0, {'label': 'Select All', 'value': 'ALL'})
model_value=model_options[1]['value']
return model_options, model_value
@callback(
Output('machineDrop', 'options'),
Output('machineDrop', 'value'),
Input('session', 'raw_data'),
Input('regDrop', 'value'),
Input('modDrop', 'value'))
def set_machine_options(data, regDrop, modDrop):
# more generally, this line would be
# json.loads(jsonified_cleaned_data)
df = pd.read_json(data, orient='split')
# machines = df['Machine Number'].dropna().unique()
if not 'all' in regDrop:
mask = (df.Location == regDrop)
machines = df[mask]['Machine Number'].dropna().unique()
elif not "ALL" in modDrop:
mask = (df['Model Type'] == modDrop)
machines = df[mask]['Machine Number'].dropna().unique()
elif 'all' in regDrop and "ALL" in modDrop:
machines = df['Machine Number'].dropna().unique()
else:
machines = df['Machine Number'].dropna().unique()
# Create a dropdown menu for all desired Machines (serial numbers)
machine_options = [{'label': 'Select All', 'value': 'all'}]
machine_options += [{'label': machine, 'value': machine}
for machine in machines]
machine_value=machine_options[1]['value']
return machine_options, machine_value
def filter_selection(df, regDrop, modDrop, machineDrop):
regMask = (df.Location == regDrop) if not 'all' in regDrop and regDrop is not None else (df.Location == df.Location)
modMask = (df['Model Type'] == modDrop) if not 'ALL' in modDrop and modDrop is not None else (df['Model Type'] == df['Model Type'])
macMask = (df['machine_number'] == machineDrop) if not 'all' in machineDrop and machineDrop is not None else (df['machine_number'] == df['machine_number'])
mask = regMask & modMask & macMask
print(regDrop, modDrop, machineDrop)
print(mask)
return df[mask]
# Update AG Grid based on different dropdown values and date range
@callback(
Output("dash-ag-grid", "rowData"),
Output("dash-ag-grid", "columnDefs"),
[Input("session", "raw_data"),
Input("regDrop", "value"),
Input("modDrop", "value"),
Input("machineDrop", "value"),
Input("graphDrop", "value")
]
)
def update_grid_wrapper(df, grRegDrop, grModDrop, grMachineDrop, selected_graphDrop):
"""
Update AG-grid (data table) for this page
"""
df = pd.read_json(df, orient='split')
filtered_df = filter_selection(df, grRegDrop, grModDrop, grMachineDrop)
return update_grid(df=filtered_df, grRegDrop=grRegDrop, grModDrop=grModDrop, grMachineDrop=grMachineDrop, selected_graphDrop=selected_graphDrop)
Everything works fine until I need to filter the data sent to AG Grid with the selected dropdown values. My filtered df was returning an empty df, I have debugged it for hours and logged the dropdown values which are coming through and I can’t seem to figure out why I can’t filter the df and pass the filtered data to AG Grid.
The application works if I switch to the raw data, however, it defeats the purpose of having the dropdown in place if it doesn’t sync with the selected values.