Skip to content

Conversation

@andrepimenta
Copy link
Member

@andrepimenta andrepimenta commented Nov 10, 2025

Interactive Chart for Predict Markets

Overview

This PR adds interactive drag-to-view functionality to the Predict market details chart, allowing users to explore historical price data by dragging their finger across the chart.

CHANGELOG entry: null

Simulator.Screen.Recording.-.iPhone.16.Pro.-.2025-11-10.at.12.25.35.mov

Features

1. Touch Interaction

  • Users can touch and drag on the chart to view values at different points in time
  • Crosshair line follows finger position from top to bottom of chart
  • Values update in real-time as user drags

2. Visual Feedback

  • Crosshair Line: Solid vertical line (theme-aware) extends from top to bottom
  • Time Label: Displayed at top of chart showing timestamp at dragged position
  • Data Point Indicators: Colored circles on each line at the active position
  • Value Labels: Colored badges showing series name and value at each data point

3. Smart Label Positioning

  • Collision Detection: Labels automatically adjust to prevent overlap when lines cross
  • Side Switching: Labels flip from right to left side when user drags past chart midpoint
  • Character Limit: Labels truncate to 25 characters to prevent overflow

4. Dynamic Legend Values

  • Legend above chart updates to show values at dragged position
  • Automatically reverts to latest values when user releases touch
  • Provides context for historical data exploration

5. Gesture Handling

  • Directional Detection: Distinguishes between horizontal drags (chart interaction) and vertical scrolls (page scrolling)
  • No Scroll Conflicts: Parent ScrollView continues to work for vertical scrolling
  • Smart gesture capture prevents interference between chart interaction and page navigation

6. Theme Support

  • All colors use design tokens for automatic light/dark mode support
  • Crosshair line: colors.border.muted (gray in light mode, white in dark mode)
  • Text: colors.text.alternative (gray in light mode, white in dark mode)
  • Labels: colors.background.default for text on colored backgrounds

Technical Implementation

Components Modified

  1. PredictDetailsChart.tsx

    • Added PanResponder for touch gesture handling
    • Implemented collision detection algorithm for label positioning
    • Created tooltip overlay with proper z-index stacking
    • Added directional gesture discrimination
  2. ChartLegend.tsx

    • Added activeIndex prop to display dragged position values
    • Updates dynamically during drag interaction
    • Reverts to latest values on release

Key Technical Decisions

  • Tooltip Rendering: Uses separate transparent LineChart overlay rendered last for proper z-index
  • Collision Detection: Sorts labels by Y position and applies minimum 4px spacing
  • Gesture Direction: Uses gestureState.dx and gestureState.dy to determine horizontal vs vertical movement
  • Label Truncation: 25-character limit with ellipsis for long outcome titles

Testing

Manual Testing Steps

  1. Navigate to any Predict market with price history
  2. Touch and drag horizontally on the chart
  3. Verify:
    • Crosshair line appears and follows touch
    • Time label shows at top of chart
    • Value labels appear next to data points
    • Legend values update to show dragged position
    • Labels flip to left side when dragging on right half
    • Labels don't overlap when lines cross
  4. Release touch and verify:
    • Tooltip disappears
    • Legend reverts to latest values
  5. Try vertical scrolling on chart area:
    • Verify page scrolls normally
    • Chart interaction only activates on horizontal drag

Edge Cases Tested

  • ✅ Multiple series with crossing lines (collision detection)
  • ✅ Long outcome titles (truncation to 25 chars)
  • ✅ Single vs multiple series charts
  • ✅ Empty data states
  • ✅ Loading states
  • ✅ Light and dark modes
  • ✅ Gesture conflicts with ScrollView

Screenshots/Demo

Add screenshots or screen recording demonstrating the interactive features

Performance Considerations

  • Uses useCallback for gesture handlers to prevent unnecessary re-renders
  • Tooltip component defined outside render to avoid recreation
  • Collision detection runs only during active drag (not on every render)
  • Proper cleanup on gesture release

Accessibility

  • Touch targets are appropriate size (chart fills available width)
  • Visual feedback is clear and theme-aware
  • Falls back to showing latest values when not interacting

Breaking Changes

None. All changes are additive and backward compatible.

Dependencies

No new dependencies added. Uses existing:

  • react-native-svg-charts (already in use)
  • react-native-svg (already in use)
  • React Native PanResponder (built-in)

Future Enhancements

Potential improvements for future PRs:

  • Haptic feedback on touch
  • Animation transitions for label movements
  • Pinch-to-zoom for chart data
  • Export chart data feature
  • Customizable tooltip appearance

Commits

  • ba2a015 - feat: add interactive chart with drag-to-view values in Predict
  • 3a40cd1 - refactor: improve chart tooltip styling and positioning
  • 93142d5 - feat: add label collision detection to chart tooltip
  • 2a6f32b - feat: update legend values dynamically based on dragged position
  • a9d37d6 - feat: add character limit to tooltip labels

Checklist

  • Code follows project coding guidelines
  • No linting errors
  • Changes are backward compatible
  • Manual testing completed
  • Works in both light and dark themes
  • Gesture handling doesn't conflict with ScrollView
  • Unit tests added (if applicable)
  • E2E tests updated (if applicable)
  • Documentation updated (if applicable)

Related Issues

Link any related issues or tickets here


Note

Adds touch-driven crosshair/tooltip overlay with dynamic legend updates to Predict details chart, plus extensive tests and minor type/mocks updates.

  • PredictDetailsChart (PredictDetailsChart.tsx):
    • Add interactive drag support via PanResponder with horizontal/vertical gesture discrimination.
    • Implement ChartTooltip overlay (crosshair, timestamp, per-series circles/labels) rendered via transparent LineChart layer.
    • Dynamic legend: pass activeIndex to ChartLegend to show values at the dragged position; revert when inactive.
    • Data/type updates: ChartSeries.data supports optional label; generate formatted label for timestamps; collision handling and side-switching for tooltip labels; theme-aware colors.
  • ChartLegend (components/ChartLegend.tsx):
    • Accept activeIndex to display contextual values; fallback to last point; formatting via formatTickValue.
  • Tests:
    • Expand PredictDetailsChart.test.tsx to cover interactions, overlays, label truncation/collisions, theme, multiple series, and axis labels; adjust LineChart mock to hide transparent overlay; add Circle/Rect to SVG mocks.
    • Add ChartLegend.test.tsx with value formatting, activeIndex behaviors, edge cases, and multi-series coverage.

Written by Cursor Bugbot for commit 98d1802. This will update automatically on new commits. Configure here.

- Add touch interaction to PredictDetailsChart component
- Display crosshair line when user drags on chart
- Show colored labels next to each data point following their line position
- Labels have series color as background with design token text color
- Implement smart label positioning (left/right) to prevent off-screen issues
- Add directional gesture detection to allow vertical scrolling
- Use PanResponder with horizontal/vertical gesture discrimination
- Render tooltip overlay on top of all chart lines for proper z-index
- Support multi-series charts with individual colored indicators
- Labels track data points vertically as user drags horizontally
- Move time label to top of chart with connecting line
- Replace dashed crosshair with solid line throughout
- Extend crosshair line from top to bottom of chart
- Use theme-aware colors for time label (gray/white)
- Use text.alternative color for better theme consistency
- Implement automatic label spacing when lines cross
- Sort labels by Y position to detect overlaps
- Shift overlapping labels down with 4px minimum spacing
- Preserve circle indicators at actual data points
- Labels remain readable when multiple series converge
- Use proper type guards instead of non-null assertions
- Add activeIndex prop to ChartLegend component
- Show values at dragged position while user interacts with chart
- Revert to latest values when user releases touch
- Legend updates in real-time as user drags across chart
- Provides better context for historical data exploration
- Truncate series labels to 25 characters maximum
- Append ellipsis (...) when labels exceed limit
- Prevent labels from overflowing off screen
- Calculate label width based on truncated text
- Improves readability for long outcome titles
@andrepimenta andrepimenta added No QA Needed Apply this label when your PR does not need any QA effort. team-predict Predict team labels Nov 10, 2025
@metamaskbot metamaskbot added team-mobile-platform Mobile Platform team INVALID-PR-TEMPLATE PR's body doesn't match template labels Nov 10, 2025
…overlay

- Update LineChart mock to filter out transparent tooltip overlay
- Add missing SVG component mocks (Circle and Rect)
- Fix test assertions to use regex for partial text matching in legend
- All 22 tests now passing
@andrepimenta andrepimenta marked this pull request as ready for review November 10, 2025 13:07
caieu
caieu previously approved these changes Nov 10, 2025
Copy link
Contributor

@caieu caieu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

- Add 23 tests covering component rendering, value display, and edge cases
- Test activeIndex behavior for interactive chart updates
- Test multiple series with different data lengths
- Test value formatting with different ranges
- Test empty data and out-of-bounds scenarios
- All tests passing with no linting errors
@github-actions
Copy link
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

- Add 18 new tests for PredictDetailsChart interactive functionality
- Test touch interactions and pan handler setup
- Test ChartTooltip SVG rendering and overlay layers
- Test label truncation with long labels and special characters
- Test active index behavior and legend updates during drag
- Test collision detection for crossing and close series values
- Test tooltip positioning across different data ranges
- Test theme support and color application
- Test multiple series rendering with overlays
- Test data point and timestamp formatting
- Total: 40 tests passing (22 original + 18 new)
- No linting errors
@github-actions github-actions bot added size-XL and removed size-L labels Nov 11, 2025
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
15.2% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

Copy link
Contributor

@caieu caieu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@andrepimenta andrepimenta added the skip-sonar-cloud Only used for bypassing sonar cloud when failures are not relevant to the changes. label Nov 11, 2025
@andrepimenta andrepimenta added this pull request to the merge queue Nov 11, 2025
Merged via the queue into main with commit e6d0632 Nov 11, 2025
219 of 225 checks passed
@andrepimenta andrepimenta deleted the feature/predict/chart-interactive branch November 11, 2025 15:11
@github-actions github-actions bot locked and limited conversation to collaborators Nov 11, 2025
@metamaskbot metamaskbot added the release-7.60.0 Issue or pull request that will be included in release 7.60.0 label Nov 11, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

INVALID-PR-TEMPLATE PR's body doesn't match template No QA Needed Apply this label when your PR does not need any QA effort. release-7.60.0 Issue or pull request that will be included in release 7.60.0 size-XL skip-sonar-cloud Only used for bypassing sonar cloud when failures are not relevant to the changes. team-mobile-platform Mobile Platform team team-predict Predict team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants