callbacks
Callbacks for the GONet Dashboard.
This module defines all Dash callback functions that power the interactivity of the GONet Wizard dashboard. The callbacks handle core responsibilities such as:
Loading and parsing the GONet data archive
Applying and managing user-defined filters
Generating interactive plots and statistics
Managing UI state, selections, and saved configurations
Exporting data and application state to JSON
Callback Registration Decorators
Most callbacks in this module use the custom utils.gonet_callback()
decorator, which extends
Dash’s default callback mechanism to include:
Automatic alert handling (via the alert-container)
Inline warning and exception capture
Debug logging (including the triggering input and source line)
This greatly simplifies development and debugging, especially for callbacks that modify user-facing components like figures and tables.
⚠️ Important Exception: MATCH/ALL Pattern-Matching Callbacks
Dash requires all Outputs in a callback to use the same wildcard keys when using pattern-matching IDs
(MATCH, ALL, etc.). Since utils.gonet_callback()
automatically adds static alert outputs,
it cannot be used with callbacks that include pattern-matching outputs.
For these cases, such as:
Output({"type": "filter-value", "index": MATCH}, "value")
we used instead:
app.callback()
directlyDecorate the callback with
utils.debug_print()
for logging
This ensures compatibility with Dash’s output constraints and avoids runtime errors.
Functions
load()
: Load available data from the configured ROOT directory and prepare dropdown options.update_main_plot()
: Update the main plot based on the selected axes, filters, and other plot parameters.add_filter()
: Add a new empty filter block to the filter container in the UI.add_or_filter()
: Add an additional (OR-based) condition to an existing filter block.update_main_filters_value()
: Automatically update the value of the main filter when a filter label is selected.update_secondary_filters_value()
: Automatically update the value of the secondary (OR) filter when a label is selected.update_filters()
: Assemble and update the active filters list based on user-defined filter inputs.export_data()
: Export filtered data from the plot to a downloadable JSON file.save_status()
: Save the current dashboard state, including axis selections and filter configurations.load_status()
: Load a previously saved dashboard state from a base64-encoded JSON file.update_filter_selection_state()
: Enable or disable the “Add Selection Filter” button based on current selection in the plot.add_selection_filter()
: Create and add a new filter based on the current selection region in the plot.
Dash callbacks:
- GONet_Wizard.GONet_dashboard.src.callbacks.load(_)[source]
Dash callback to initialize the dashboard data store and dropdown options.
This function is triggered once when the layout is rendered. It delegates the actual data-loading logic to
load_data.load_data_from_json()
, which scans the directory specified by theGONET_ROOT
environment variable, loads GONet JSON files, and returns a flat dictionary of observations along with axis selection options.The callback is wrapped in
handle_errors()
to display any exceptions in the alert container and halt further callback execution if a failure occurs.- Parameters:
_ (Any) – Dummy input triggered by layout initialization; unused.
- Returns:
data (dict) – Flattened dictionary of GONet metadata and per-channel measurements, to be stored in a hidden dcc.Store component.
options_x (list of dict) – Dropdown options for selecting the x-axis quantity.
options_y (list of dict) – Dropdown options for selecting the y-axis quantity.
- GONet_Wizard.GONet_dashboard.src.callbacks.update_main_plot(x_label, y_label, active_filters, channels, show_filtered_points, clickdata, fig, gonet_fig, info_table, all_data)[source]
Update the main plot, statistics table, image preview, and info panel in response to user interaction.
This is the central callback for GONet dashboard interactivity. It responds to any change that affects how data should be visualized or interpreted, and coordinates all downstream updates accordingly. It ensures that the displayed figure remains synchronized with the current filter set, axis choices, selected channels, and clicked data point.
Triggers that activate this callback include:
Changing the selected x- or y-axis quantity
Adding, removing, or modifying any active filters
Toggling the visibility of filtered-out points
Enabling or disabling channels in the channel selector
Clicking a data point on the plot
This function manages the following visual components:
The main scatter plot (created or updated using
FigureWrapper
)The statistics summary table (mean ± std for x and y values)
The GONet image heatmap of the selected “big point” (if applicable)
The information table containing metadata for the selected data point
Depending on the triggering input, the function will:
Rebuild the entire figure from scratch (on axis change)
Reapply filters and update trace visibility (on filter change)
Show or hide filtered-out points (on toggle)
Add or remove traces corresponding to visible channels (on channel change)
Highlight and load image + metadata for the selected point (on click)
- Parameters:
x_label (
str
) – Selected label for the x-axis (e.g., ‘sky_brightness’).y_label (
str
) – Selected label for the y-axis (e.g., ‘temperature’).active_filters (
list
ofdict
) – User-defined filters to apply to the dataset. Each filter includes a label, operator, and value.channels (
list
ofstr
) – List of active channels to display (e.g., [‘red’, ‘green’, ‘blue’]).show_filtered_points (
bool
) – Whether to display data points that fail the filter criteria with reduced opacity.clickdata (
dict
orNone
) – Plotly clickData object containing information about the clicked point (if any).fig (
dict
) – Current Plotly figure, passed in from the Dash state.gonet_fig (
dict
) – Current heatmap image figure, passed in from the Dash state.info_table (
list
) – Current info table rows, passed in from the Dash state.all_data (
dict
) – Complete flattened dataset returned byload_data_from_json()
.
- Returns:
dict
– Updated Plotly figure reflecting current filters, axes, and channels.list
– Updated statistics table rows with mean and standard deviation summaries.dict
ordash.no_update
– Updated heatmap figure ordash.no_update
if no change is needed.list
– Updated rows of the data point information table.
- GONet_Wizard.GONet_dashboard.src.callbacks.add_filter(_, filter_div, labels)[source]
Add a new empty filter block to the filter container in the UI.
- Parameters:
- Returns:
filter_div – Updated list of filter components with one new filter added.
- Return type:
- GONet_Wizard.GONet_dashboard.src.callbacks.add_or_filter(_, id, labels)[source]
Add an additional (OR-based) condition to an existing filter block.
- Parameters:
- Returns:
new_filter – A new filter component to be added to the filter block.
- Return type:
dash component
- GONet_Wizard.GONet_dashboard.src.callbacks.update_main_filters_value(label)[source]
Automatically update the value of the main filter when a filter label is selected.
- Parameters:
label (
str
) – The selected label from the main filter dropdown.- Returns:
value – Default value corresponding to the label, or None if not found.
- Return type:
Any
orNone
- GONet_Wizard.GONet_dashboard.src.callbacks.update_secondary_filters_value(label)[source]
Automatically update the value of the secondary (OR) filter when a label is selected.
- Parameters:
label (
str
) – The selected label from the secondary filter dropdown.- Returns:
value – Default value corresponding to the label, or None if not found.
- Return type:
Any
orNone
- GONet_Wizard.GONet_dashboard.src.callbacks.update_filters(_, switches, ops, values, selections, second_ops, second_values, labels, second_labels, second_ids, selections_ids, filters_before)[source]
Assemble and update the active filters list based on user-defined filter inputs.
This function collects the current state of all active filters, including their labels, operators, and values, and constructs a list of active filters. If a secondary (OR) filter is present, it is added as a nested dictionary.
This function is also triggered at load up. Since initially
active_filters
isNone
, when triggered the show-filtered-data-switch is reset to default status.- Parameters:
switches (
list
ofbool
) – States of the main filter switches indicating whether each filter is active.ops (
list
ofstr
) – Comparison operators for each main filter (e.g., ‘>’, ‘<=’, ‘==’).values (
list
) – Values selected or entered for each main filter.selections (
list
) – Lasso or box selection data used to override value-based filters.second_ops (
list
ofstr
) – Comparison operators for each secondary filter.second_values (
list
) – Values selected or entered for each secondary filter.labels (
list
ofstr
) – Labels (field names) selected for each main filter.second_labels (
list
ofstr
) – Labels selected for each secondary filter.second_ids (
list
ofdict
) – IDs of the secondary filter value fields, containing the filter index.selections_ids (
list
ofdict
) – IDs of the selection-based filters, containing the filter index.filters_before (
list
ofdict
) – Previously active filters, used to check whether an update is necessary.
- Returns:
Updated list of active filters, or no_update if unchanged.
- Return type:
- GONet_Wizard.GONet_dashboard.src.callbacks.export_data(_, fig, data)[source]
Export filtered data from the plot to a downloadable JSON file.
This function retrieves all points currently visible in the main plot that are not filtered or marked as big points. It extracts relevant metadata and fit parameters for each unique index across all channels, organizing the data into a structured JSON format for export.
- Parameters:
- Returns:
A dictionary containing:
’content’: JSON string representing the filtered and formatted dataset.
’filename’: Suggested filename for the download (“filtered_data.json”).
- Return type:
- GONet_Wizard.GONet_dashboard.src.callbacks.save_status(_, *args)[source]
Save the current dashboard state, including axis selections and filter configurations.
This function collects the current state of all dashboard controls—such as axis dropdowns, filters, channel selections, and switches—and assembles them into a dictionary suitable for export or persistent storage. It supports both primary and secondary filters.
- Parameters:
_ (
Any
) – Unused placeholder for the n_clicks input from the “save status” button.*args (
list
) – Interleaved list of (id, value) pairs for all input states. Each id can either be a string (for global components like axis dropdowns and switches) or a dictionary (for indexed filters).
- Returns:
A dictionary representing the current state of the dashboard, including:
Axis selection values.
All filters and their properties.
Active channels and switch states.
The structure is compatible with later reloading via the
load_status()
function.- Return type:
- GONet_Wizard.GONet_dashboard.src.callbacks.load_status(contents, filter_div, labels)[source]
Load a previously saved dashboard state from a base64-encoded JSON file.
This function decodes and parses the uploaded status file and restores the application state, including axis selections, active channels, switches, and filters. It dynamically reconstructs each filter (both primary and secondary) and injects them into the dashboard.
- Parameters:
- Returns:
x_axis_value (
str
) – Restored value for the x-axis dropdown.y_axis_value (
str
) – Restored value for the y-axis dropdown.channels (
list
) – Restored list of selected channels.show_filtered (
bool
) – Whether to show filtered points, as restored from the saved state.filter_div (
list
) – Updated list of filter UI components reflecting the saved configuration.
- GONet_Wizard.GONet_dashboard.src.callbacks.update_filter_selection_state(relayout_data, fig, all_data)[source]
Enable or disable the “Add Selection Filter” button based on current selection in the plot.
This function checks whether a valid lasso or box selection exists in the main plot. If such a selection is detected (i.e., a non-empty path is present), the filter button becomes enabled; otherwise, it remains disabled.
- Parameters:
- Returns:
False if a valid selection exists (enabling the button), True otherwise (disabling it).
- Return type:
- GONet_Wizard.GONet_dashboard.src.callbacks.add_selection_filter(_, filter_div, relayout_data, figure)[source]
Create and add a new filter based on the current selection region in the plot.
This function checks if a valid lasso or box selection exists in the plot’s
relayoutData
. If so, it generates a new filter corresponding to the selected data points and appends it to the list of existing filters. The selection is then removed from the plot layout to avoid reprocessing.- Parameters:
_ (
Any
) – Placeholder for the button click triggering the addition of a selection-based filter.filter_div (
list
) –Existing list of Dash filter components displayed in the UI.
relayout_data (
dict
) – Plotly relayout data containing information about lasso/box selections.figure (
dict
) – The current figure dictionary shown in the main plot.
- Returns:
Clientside Callback: Export Dashboard Status
This clientside callback enables users to export the current dashboard state as a JSON file. The data is serialized in the browser and downloaded via a temporary Blob URL.
- Inputs:
status-data.data
: A dictionary containing the current UI state, including axis selections, filters, and switches.
- Outputs:
dummy-div.children
: Used solely to trigger the callback.
- Behavior:
Prompts the user to enter a filename (default:
status.json
).Converts the status dictionary into a formatted JSON string.
Creates a Blob and object URL.
Initiates the download using a temporary anchor tag.
Cleans up all temporary DOM elements and object URLs afterward.
- Usage Notes:
This approach is quick and convenient for small data payloads.
It uses browser-native functionality and does not require server interaction.
The callback is designed to be self-contained and avoids the need for backend downloads.
A more robust alternative using the File System Access API is commented in the code, but is currently disabled due to limited UI polish and cross-browser compatibility.
- Future Improvements:
For larger payloads or enhanced control, this behavior may eventually be migrated to the Django backend.