02b2aebbb7edcca2d99adcfec6a382a969d8e9a4
User report: the dashed vertical line + "MACRO BOTTOM" label could be
visually "dragged" — it wasn't actually draggable, but it stayed glued
to a fixed pixel column on screen while the candles slid out from under
it on pan, so the label ended up pointing at unrelated candles.
Root cause: the line + label are absolutely-positioned DOM nodes (the
lightweight-charts library has no first-class vertical-marker primitive).
The data effect set their `left` ONCE via timeScale.timeToCoordinate()
and then never updated again. Every user interaction that changes the
visible range — pan, wheel zoom, programmatic setVisibleRange, window
resize — invalidates that pixel coordinate.
Fix:
- Store the signal's bucketTime + label text in refs.
- Hoist the "project bucketTime → pixel X" logic into a single
`reposition()` fn captured in repositionMacroRef.
- Subscribe to `timeScale().subscribeVisibleTimeRangeChange(reposition)`
so it fires on every pan / zoom / data update.
- Wire it into the ResizeObserver too (width change ⇒ new pixel space).
- Re-run from the data effect whenever the signal changes.
- Hide (opacity: 0) instead of clamping when the signal candle scrolls
outside the visible range — a clamped label glued to the chart edge
is actively misleading.
- Drop `transition: left 160ms` on both nodes — that transition fires
on every pan frame and makes the marker LAG behind the candles,
reproducing the original visual bug for fast pans.
Verified via DOM scripting:
pan right ⇒ label_left 744px → 344px (follows candles ✓)
big right-pan past signal ⇒ opacity 1 → 0 (hides cleanly ✓)
zoom out ⇒ opacity 0 → 1, label re-projects to new pixel space ✓
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Description
No description provided
Languages
TypeScript
81.5%
CSS
18.4%
JavaScript
0.1%