label-studio icon indicating copy to clipboard operation
label-studio copied to clipboard

fix: emit sync events when clicking on region annotations

Open cloudmark opened this issue 3 months ago • 7 comments

Here's a comprehensive PR description for the region synchronization fix:


PR Description

Reason for Change

Problem: When clicking on region annotations (either directly on the plot or in the Regions sidebar/outliner), the view scrolls to show the region but does NOT synchronize with other synced media components. This breaks multi-modal data exploration workflows where users expect all synchronized components (Audio, TimeSeries, etc.) to seek to the same time position.

For example:

  • Click on a TimeSeries region labeled "Walking" → Only TimeSeries view scrolls
  • Audio player stays at current position
  • Other TimeSeries (velocity, acceleration, etc.) don't update
  • User cannot navigate synchronized data by clicking annotations

Root Cause: The selectRegion() method in TimeSeriesRegion.js only calls scrollToRegion() which adjusts the view but does not:

  1. Update the cursor position (setCursor())
  2. Emit a sync event (syncSend()) to notify other components

This is inconsistent with how clicking directly on empty plot areas works, which DOES emit sync events.

Solution: Modified TimeSeriesRegion.selectRegion() to emit sync events after scrolling to the region. The method now:

  1. Scrolls the TimeSeries view to show the region (existing behavior)
  2. Updates the cursor/playhead position using setCursor()
  3. Calculates relative time from the region's start time
  4. Emits a sync event via syncSend() to notify all components in the same sync group
  5. Handles both date-formatted and numeric time columns properly

Videos

  • Bug demonstration: https://www.loom.com/share/2584716884114820a7e4b5b76a3316b3

    • Shows clicking on regions only scrolls that component
    • Audio and other TimeSeries don't synchronize
  • Fix demonstration: https://www.loom.com/share/9a6421fca42d424bb068779d9a4d7021

    • Shows clicking on regions now syncs all components
    • Audio, TimeSeries, and other synced components seek together

Rollout Strategy

No special rollout needed - This fix is gated by existing feature flag:

  • Requires FF_TIMESERIES_SYNC feature flag to be enabled
  • No new environment variables needed
  • No API changes
  • Backward compatible - only improves existing behavior
  • Change applies automatically when feature flag is active

Testing

Manual Testing Performed:

  1. Basic Region Click Test

    • Created TimeSeries task with Audio and multiple TimeSeries (acceleration, velocity)
    • Created region annotations on TimeSeries
    • Clicked on regions directly on the plot
    • Verified all synced components seek to region's start time (see fix demo video)
    • Tested with both numeric and date-formatted time columns
  2. Regions Sidebar Test

    • Clicked on regions in the Regions sidebar/outliner
    • Verified all synced components synchronize
    • Confirmed behavior is identical to clicking on plot
  3. Edge Cases

    • Regions at the very start/end of timeseries
    • Multiple regions selected in sequence
    • Instant regions (zero duration)
    • Date-formatted time columns with millisecond precision
  4. Interaction Consistency

    • Clicking empty plot → syncs all components (existing behavior - works)
    • Clicking region on plot → syncs all components (NEW - works)
    • Clicking region in sidebar → syncs all components (NEW - works)
  5. Multi-Component Synchronization

    • Audio + multiple TimeSeries (acceleration, velocity, gyroscope)
    • Verified sync works in all directions:
      • TimeSeries region → Audio seeks
      • Audio region → TimeSeries seek (if applicable)
      • All TimeSeries update together

Code Quality:

  • No linting errors introduced
  • Follows existing code patterns and conventions
  • Uses existing setCursor() and syncSend() methods
  • Properly checks feature flag before emitting sync

Risks

Risk Level: LOW

Performance:

  • No performance impact - only adds two method calls when regions are clicked
  • Sync events are already used throughout the system
  • No additional data processing or computations

Backward Compatibility:

  • No breaking changes
  • Only affects behavior when FF_TIMESERIES_SYNC is enabled
  • Users without the feature flag see no change
  • All existing TimeSeries functionality preserved

Security:

  • No security implications
  • No new dependencies added
  • No changes to data handling or storage
  • Uses existing sync infrastructure

User Experience:

  • Fixes broken behavior - strictly an improvement
  • Makes region clicks consistent with plot clicks
  • Improves multi-modal data exploration workflows

Reviewer Notes

Key Points to Review:

  1. Implementation Location (web/libs/editor/src/regions/TimeSeriesRegion.js)

    • Changes are in selectRegion() method (lines ~72-93)
    • Feature flag check ensures safe rollout
    • Time conversion handles both date and numeric formats
  2. Code Logic:

    // After existing scrollToRegion() call:
    if (isFF(FF_TIMESERIES_SYNC) && self.parent.sync) {
      const regionStartTime = self.start;
      self.parent.setCursor(regionStartTime);
    
      const [minKey] = self.parent.keysRange;
      if (minKey !== undefined) {
        let relativeTime;
        if (self.parent.isDate) {
          relativeTime = (regionStartTime - minKey) / 1000;
        } else {
          relativeTime = regionStartTime - minKey;
        }
        self.parent.syncSend({ time: relativeTime, playing: false }, "seek");
      }
    }
    
  3. Consistency with Existing Code:

    • Uses same pattern as handleMainAreaClick() and plotClickHandler()
    • Reuses existing setCursor() and syncSend() methods
    • Follows same time conversion logic as other seek operations
  4. Testing the Fix:

    • Watch both demonstration videos to see before/after behavior
    • Load any TimeSeries task with sync enabled
    • Click on regions (plot or sidebar) and verify all components sync

General Notes

Implementation Details:

The fix adds synchronization logic to TimeSeriesRegion.selectRegion():

  • Called when region is clicked on plot OR in sidebar
  • Scrolls view to region (existing behavior - preserved)
  • Updates cursor position to region start time (NEW)
  • Emits sync event to all synced components (NEW)

Time Conversion:

  • For date-formatted columns: converts milliseconds to seconds
  • For numeric columns: uses values directly
  • Matches existing time conversion patterns throughout TimeSeries

Feature Flag:

  • Protected by FF_TIMESERIES_SYNC feature flag
  • Safe to deploy with flag disabled
  • Can be enabled per-project or globally

Benefits:

  • Clicking any region (plot or sidebar) now syncs all components
  • Consistent behavior across all interaction methods
  • Critical for multi-modal workflows (IoT, wearables, autonomous vehicles)
  • Improved user experience for time-series annotation tasks

Files Changed:

  1. web/libs/editor/src/regions/TimeSeriesRegion.js - Added sync logic to selectRegion()

No Migration Required - This is a transparent bug fix that improves behavior without requiring any user action or configuration changes.


Related Context

Related to Issue: https://github.com/HumanSignal/label-studio/issues/8603

cloudmark avatar Oct 08 '25 10:10 cloudmark

Deploy request for heartex-docs pending review.

Visit the deploys page to approve it

Name Link
Latest commit 38f829b703970afd20146a9c8fb9a5fb18698c36

netlify[bot] avatar Oct 08 '25 10:10 netlify[bot]

Deploy request for label-studio-docs-new-theme pending review.

Visit the deploys page to approve it

Name Link
Latest commit 38f829b703970afd20146a9c8fb9a5fb18698c36

netlify[bot] avatar Oct 08 '25 10:10 netlify[bot]

Deploy Preview for label-studio-storybook ready!

Name Link
Latest commit 38f829b703970afd20146a9c8fb9a5fb18698c36
Latest deploy log https://app.netlify.com/projects/label-studio-storybook/deploys/68e636c9c9f3cf0008921652
Deploy Preview https://deploy-preview-8604--label-studio-storybook.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

netlify[bot] avatar Oct 08 '25 10:10 netlify[bot]

Deploy Preview for label-studio-playground ready!

Name Link
Latest commit 38f829b703970afd20146a9c8fb9a5fb18698c36
Latest deploy log https://app.netlify.com/projects/label-studio-playground/deploys/68e636c91b5d580008929794
Deploy Preview https://deploy-preview-8604--label-studio-playground.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

netlify[bot] avatar Oct 08 '25 10:10 netlify[bot]

/jira create

Workflow run Jira issue TRIAG-1683 is created

yyassi-heartex avatar Oct 17 '25 19:10 yyassi-heartex

you let me know what you want to do, if you want to remove Ill remove, alternatively feel free to remove it while you merge internally

On Tue, Oct 21, 2025 at 5:47 PM Raul Martin @.***> wrote:

@.**** commented on this pull request.

In web/package.json https://github.com/HumanSignal/label-studio/pull/8604#discussion_r2448834802 :

@@ -249,7 +249,7 @@ "moment": "2.29.4", "on-headers": "1.1.0", "form-data": "4.0.4",

  • "stylus": "0.0.1-security"
  • "stylus": "0.64.0"

Great catch, @cloudmark https://github.com/cloudmark! I think it's best to take it from this PR to avoid mixing concerns. Let's review this separately @yyassi-heartex https://github.com/yyassi-heartex, as @nass600 https://github.com/nass600 said this can probably be removed since it's coming from the npm incident.

— Reply to this email directly, view it on GitHub https://github.com/HumanSignal/label-studio/pull/8604#discussion_r2448834802, or unsubscribe https://github.com/notifications/unsubscribe-auth/AANKHJSCA6WHWV5CH37P6SL3YZIQ7AVCNFSM6AAAAACITM5YR2VHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZTGNRRGQ4DAMRZGQ . You are receiving this because you were mentioned.Message ID: @.***>

cloudmark avatar Oct 21 '25 17:10 cloudmark

This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days.

robot-ci-heartex avatar Dec 07 '25 02:12 robot-ci-heartex

This PR was closed because it has been stalled for 10 days with no activity.

robot-ci-heartex avatar Dec 18 '25 02:12 robot-ci-heartex