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() directly

  • Decorate 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 the GONET_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 of dict) – User-defined filters to apply to the dataset. Each filter includes a label, operator, and value.

  • channels (list of str) – 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 or None) – 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 by load_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 or dash.no_update – Updated heatmap figure or dash.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:
  • _ (Any) – Dummy input from the button click (not used).

  • filter_div (list) – Current list of filter components in the container.

  • labels (list of dict) – List of label options for dropdowns.

Returns:

filter_div – Updated list of filter components with one new filter added.

Return type:

list

GONet_Wizard.GONet_dashboard.src.callbacks.add_or_filter(_, id, labels)[source]

Add an additional (OR-based) condition to an existing filter block.

Parameters:
  • _ (Any) – Dummy input from the OR-button click (not used).

  • id (dict) – Dictionary containing the index of the filter block to update.

  • labels (list of dict) – List of label options for the dropdowns.

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 or None

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 or None

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 is None, when triggered the show-filtered-data-switch is reset to default status.

Parameters:
  • switches (list of bool) – States of the main filter switches indicating whether each filter is active.

  • ops (list of str) – 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 of str) – Comparison operators for each secondary filter.

  • second_values (list) – Values selected or entered for each secondary filter.

  • labels (list of str) – Labels (field names) selected for each main filter.

  • second_labels (list of str) – Labels selected for each secondary filter.

  • second_ids (list of dict) – IDs of the secondary filter value fields, containing the filter index.

  • selections_ids (list of dict) – IDs of the selection-based filters, containing the filter index.

  • filters_before (list of dict) – Previously active filters, used to check whether an update is necessary.

Returns:

Updated list of active filters, or no_update if unchanged.

Return type:

list of dict or dash.no_update

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:
  • _ (Any) – Unused placeholder for the n_clicks input from the export button.

  • fig (dict) – The Plotly figure dictionary containing plotted data and metadata.

  • data (dict) – The full dataset loaded into the application, including all measurements and metadata for each point.

Returns:

A dictionary containing:

  • ’content’: JSON string representing the filtered and formatted dataset.

  • ’filename’: Suggested filename for the download (“filtered_data.json”).

Return type:

dict

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:

dict

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:
  • contents (str) –

    Base64-encoded string representing the uploaded file contents from the Dash upload component.

  • filter_div (list) – List of existing filter components already present in the dashboard.

  • labels (list) – List of available labels used to populate new filters.

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:
  • relayout_data (dict) – The relayout metadata from the Plotly plot, which may include a ‘selections’ field.

  • fig (dict) – The current figure displayed in the main plot (unused, but passed for context).

  • all_data (dict) – The full dataset shown in the dashboard (unused, but passed for context).

Returns:

False if a valid selection exists (enabling the button), True otherwise (disabling it).

Return type:

bool

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:

  • filter_div (list) – Updated list of filter components, now including the new selection-based filter.

  • relayoutData (dict) – An empty dictionary to reset plot selection state.

  • figure (dict) – The updated figure with the selection metadata removed.

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.