Add 24h/7d sparklines to the crypto grid cards - #18
Merged
Merged
Conversation
Each card now draws an inline SVG price line with a 24h/7d toggle, the change
across that window beside the session change, and the selection persisted.
The series has its own endpoint rather than reusing /crypto/bars, for two
reasons found by measuring rather than assuming:
- Alpaca's multi-symbol bars endpoint paginates and truncates per symbol. A
single request for two pairs over 7d returned 168 bars for BTC but only 34
for ETH plus a page token; twelve pairs is several round trips.
- Twelve cards do not need ~2,000 OHLCV objects to draw twelve lines a couple
of hundred pixels wide.
So the series is built and downsampled server-side — 24 points for 24h, 56 for
7d — and cached as a unit per period, with concurrent misses collapsed into one
fetch. A whole grid costs one set of upstream requests per minute rather than
one per visitor, and 14KB on the wire for all twelve.
Three details that are deliberate:
- The downsampler always keeps the first and last point. The line's endpoint
sits directly beside the printed price, and dropping it would make the card
contradict itself.
- The line is coloured by ITS OWN window, not the session. A pair can be down
today inside a rising week; painting the 7d line red because the day was red
would misreport it. Mutation-checked — colouring by session fails the test.
- A pair with fewer than two points is drawn without a line rather than as a
flat one, which would assert a stability never observed. MATIC/USD is
exactly this case in production, so the grid says "1 without 24h history"
rather than leaving a card that looks broken.
Losing the sparklines never costs the prices: the two requests are issued
together but the chart one is allowed to fail on its own.
490 tests pass (19 new), tsc clean. Verified live in a real DOM against real
Alpaca data: 12 cards, 11 lines, the toggle redrawing +0.8% -> +3.1%, no page
errors.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ThreatCrush Security Scan56 finding(s) HIGH/CRITICAL: 6 | MEDIUM: 50
…and 6 more. Full results in the Security tab. Snippets are redacted; ThreatCrush never prints matched credential material. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Each grid card now draws an inline SVG price line, with a 24h / 7d toggle, the change across that window beside the session change, and the selection persisted across reloads.
Why a dedicated endpoint
I measured before building on
/crypto/bars, and it would not have worked well:So
/crypto/sparklines?symbols=&period=24h|7dbuilds and downsamples server-side — 24 points for 24h, 56 for 7d — caches per period, and collapses concurrent misses into one fetch. A whole grid costs one set of upstream requests per minute rather than one per visitor, and 14KB on the wire for all twelve.Three deliberate details
The downsampler always keeps the first and last point. The line's endpoint sits directly beside the printed price; dropping it would make the card contradict itself.
The line is coloured by its own window, not the session. A pair can be down today inside a rising week — painting the 7d line red because the day was red would misreport it. This one is mutation-checked: colouring by session direction fails the test.
A pair with fewer than two points gets no line, not a flat one. A flat line asserts a stability that was never observed.
MATIC/USDis exactly this case in production (the migrated token, no recent hourly bars), so the grid reports "1 without 24h history" rather than leaving a card that looks broken.Losing the sparklines never costs the prices — both requests are issued together, but the chart one is allowed to fail on its own.
Verification
tsc --noEmitclean🤖 Generated with Claude Code