Skip to content

Fix: chart resets viewport on click and drawings trigger wrong data reload#104

Open
MalkinK wants to merge 1 commit into
deepentropy:mainfrom
MalkinK:fix/click-jump-and-state-desync
Open

Fix: chart resets viewport on click and drawings trigger wrong data reload#104
MalkinK wants to merge 1 commit into
deepentropy:mainfrom
MalkinK:fix/click-jump-and-state-desync

Conversation

@MalkinK
Copy link
Copy Markdown

@MalkinK MalkinK commented Feb 25, 2026

Problem

Two related bugs that degrade the user experience when interacting with the chart:

Bug 1: Chart jumps/resets zoom on every click

ChartRenderer.updateSeries() calls fitContent() unconditionally every time it runs. Since updateSeries() is
triggered by realtime data updates, any user interaction (click, scroll, zoom) that coincides with an update causes
the chart to snap back to the full-range view, losing the user's scroll/zoom position.

Root cause: fitContent() at line 360 of ChartRenderer.ts fires on every updateSeries() call with no guard.

Bug 2: Clicking a drawing triggers a full data reload with wrong interval

When a user clicks on a drawing (e.g., Parallel Channel), it triggers loadSymbolData() via event propagation.
Because the layout's interval property is hardcoded to "1D" in the template and loadSymbolData() doesn't sync
its interval parameter back to the component's reactive state, subsequent loads use the stale default interval
instead of the one actually displayed.

Root cause:

  1. oak-view-layout.ts has interval="1D" hardcoded in the toolbar template instead of binding to a reactive
    property
  2. oak-view-chart.ts loadSymbolData() doesn't sync the symbol/interval args back to
    this.symbol/this.interval or the Store, so internal state drifts from what's rendered

Fix

ChartRenderer.ts

  • Add _initialFitDone flag — fitContent() only fires once on first data load, not on every updateSeries() call
  • Add resetFitState() method — called when symbol/interval changes so new data gets one auto-fit
  • Reset flag in dispose() for clean lifecycle

oak-view-layout.ts

  • Add interval as a @property() reactive attribute (was missing entirely)
  • Bind template to ${this.interval} instead of hardcoded "1D"

oak-view-chart.ts

  • In loadSymbolData(): sync symbol and interval back to reactive properties and Store before loading data
  • Call resetFitState() when configuring timescale for new interval

Testing

  • Verified with 12/12 Playwright headless tests (page load, chart clicks without viewport jump, indicator modal,
    pane toggles)
  • Manual testing: repeated clicks on chart + drawings no longer cause zoom reset or data reload with wrong timeframe
  • Build passes with npm run build (no new errors introduced)

Changes

  • 3 files changed, 31 insertions, 2 deletions
  • Zero new dependencies

…eload

Bug 1: ChartRenderer.updateSeries() calls fitContent() unconditionally
on every update. Any user interaction (click, scroll, zoom) that
coincides with a realtime update causes the chart to snap back to
full-range view, losing the user's scroll/zoom position.

Fix: Add _initialFitDone flag so fitContent() only fires once on first
data load. Add resetFitState() for symbol/interval changes.

Bug 2: Clicking a drawing triggers loadSymbolData() but the layout's
interval is hardcoded to "1D" in the template, and loadSymbolData()
doesn't sync its interval arg back to reactive state. This causes
subsequent loads to use the stale default interval.

Fix: Add interval as a reactive @Property() on oak-view-layout.ts,
bind template to it instead of hardcoded "1D". In loadSymbolData(),
sync symbol/interval back to reactive properties and Store.

Files changed:
- src/components/ChartRenderer.ts: _initialFitDone guard + resetFitState()
- src/oak-view-layout.ts: interval reactive property + template binding
- src/oak-view-chart.ts: state sync in loadSymbolData() + resetFitState() call

Tested: 12/12 Playwright headless tests pass, build succeeds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant