chart/app/analysis
Chris Amow 078bc8f42c Fix trendline anchors jumping away from where they were drawn
Two faults, both of which made a finished line disagree with its own preview.

A placed anchor was being discarded by a twitch. finishToolGesture recomputed
`dragged` from the second click's own pointerdown/up, so a few pixels of
movement while pressing was read as a fresh press-drag-release: the anchor from
the first click was thrown away and the line began at the second click instead,
to the right of where it was meant to start. The preview had been rubber-banding
from the real anchor the whole time, which is why the result jumped on commit. A
pending anchor now wins over the current click's drag.

Snapping ignored where you pointed. snapPoint took the nearer of the bar's high
and low but only within 8px, so a cursor between the two snapped to neither and
returned a raw mid-bar price — and the side quietly fell back to the dropdown.
The gate is gone: with snapping on, an anchor always lands on the nearer extreme
of the nearest bar, and that choice *is* the side, a high being resistance and a
low support. app.js already preferred snappedSide over the dropdown, so the
inference was written and simply never fired.

snapPoint also guards against being handed an already-snapped point, which
carries no cursor y and previously compared against NaN.

Verified by driving the gesture in a browser: click, move, then a second click
with 4px of movement while pressed now yields anchor_t equal to the first
click's time and anchor_p exactly equal to the bar's high.

Also lands the groundwork for chart comments, inert until the UI is wired: a
`kind` on ManualLine with `pinned`, `x`, `y` and `collapsed`, a POST /comments
endpoint, GET /drawings, and the chart's DOM comment layer. Comments are stored
with the lines so they share numbering, filtering and deletion, and
ManualLineStore.levels() excludes them — a comment reaching the level list would
join a confluence cluster and push a notification about a piece of text. Tests
cover the exclusion, the derived kind for lines saved before comments existed,
and that numbering is shared.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 15:18:40 -05:00
..
__init__.py Implement M3 projected daily moving averages 2026-08-09 20:44:11 -05:00
alerts.py Price trendlines across bars, add one-shot alerts, collapse layers, drop 1h MAs 2026-08-10 04:15:05 -05:00
bar_space.py Price trendlines across bars, add one-shot alerts, collapse layers, drop 1h MAs 2026-08-10 04:15:05 -05:00
confluence.py Price trendlines across bars, add one-shot alerts, collapse layers, drop 1h MAs 2026-08-10 04:15:05 -05:00
horizontals.py Add prior-day levels and session VWAP; fix alert repetition they exposed 2026-08-10 00:36:21 -05:00
indicators.py Implement M3 projected daily moving averages 2026-08-09 20:44:11 -05:00
levels.py Price trendlines across bars, add one-shot alerts, collapse layers, drop 1h MAs 2026-08-10 04:15:05 -05:00
manual_lines.py Fix trendline anchors jumping away from where they were drawn 2026-08-10 15:18:40 -05:00
moving_averages.py Implement M3 projected daily moving averages 2026-08-09 20:44:11 -05:00
vwap.py Add prior-day levels and session VWAP; fix alert repetition they exposed 2026-08-10 00:36:21 -05:00