CM-2 UI: Chart viewport resets to full-history view on every 30s candle refresh; user zoom/scroll position is not preserved #336
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:implement
agent:implement
agent:open_issues
agent:ready
agent:research
agent:security_audit
agent:verify
architecture
backend
blocker:hybrid
blocker:launch
blocker:limit-orders
blocker:v2
block:log_only
block:security
bug
ci
contracts
correctness
deploy
dev
devops
docs
documentation
duplicate
e2e
enhancement
epic
feature
frontend
functional-completion
gas
good first issue
governance
help wanted
high-risk
hooks
hybrid
indexer
infra
infrastructure
integrators
invalid
launch-blocker
limit-orders
localnet
localterra
low priority
missing-implementation
needs-design
ops
performance
priority
high
priority
medium
product
qa
QA
question
ready
ready
research
scripts
security
security-hardening
smartcontracts
tech-debt
testing
ux
UX
v2
verification
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
code/cl8y-dex-terraclassic#336
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Every 30 seconds the candle query refetches and
PriceChartLightweightCanvascallstimeScale().fitContent()immediately after writing the new data. This snaps the chart viewport back to "show all candles" regardless of where the user has scrolled or zoomed. A user inspecting a specific time window (e.g. zoomed into the last 4 hours on a 1h chart) will be kicked back to the full-history view 30 seconds later with no warning.The headline "Last" price updates every 15 seconds via the trades tape and does not cause any visual flicker — that part of CM-2 passes.
Root cause (code verified)
PriceChartLightweightCanvas.tsx:227–234— data-refreshuseEffect:This effect runs whenever
candlePointschanges — which happens on everycandlesQueryrefetch (refetchInterval: 30_000inPriceChart.tsx:60). BecausesetDatareplaces all candle data andfitContent()fits the time scale to the full dataset, the user's viewport is unconditionally reset to the full candle range on each refresh cycle.The correct pattern for live chart updates is:
series.update(latestCandle)to append or update only the most recent bar (no viewport side effect)fitContent()only on initial mount or on deliberate interval/pair switch — not on every background refetchfitContent()is also called at:Steps to reproduce
/trade/:pairAddror/charts, connect Keplr walletRepeatable every 30 seconds as long as the chart is on screen.
Expected behavior
Background candle data refreshes should update the chart data without affecting the user's viewport. If a new candle is appended,
series.update()should be used instead ofseries.setData().timeScale().fitContent()should only be called on initial mount, pair switch, or interval switch — not during routine background refetches.Actual behavior
Every 30-second background refetch calls
setDataon all series and thenfitContent(), resetting the viewport to show the full candle history and discarding any user-set zoom or scroll position.Environment
/trade/:pairAddr(embedded chart),/charts(standalone chart page)Severity: P2(Polish) : chart data updates correctly; the viewport reset is a UX regression that makes the chart unusable for any analysis that requires holding a zoom level for more than 30 seconds.
cc: @PlasticDigits
mentioned in commit
9c27c35016mentioned in merge request !822
Implementation complete — MR !822: https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/104
Root cause:
PriceChartLightweightCanvascalledtimeScale().fitContent()on every candle data refresh (30srefetchInterval), resetting zoom/scroll.Fix: New
priceChartLightweightSeriesSync.tsusesseries.update()for incremental refreshes;fitContent()limited to initial mount and indicator toggles.Acceptance
PriceChartLightweightCanvas.test.tsx— background data refresh does not call fitContentseries.update()priceChartLightweightSeriesSync.test.ts(8 cases)setDataPriceChart.test.tsx— reuses one chart instance across many interval switchesAutomated commands (all PASS):
mentioned in commit
f95ffd174amentioned in merge request !834
mentioned in issue #337
mentioned in commit
f875d5388amentioned in commit
50cf53e2cfmentioned in commit
0e3afcaef3mentioned in commit
5a961085c1mentioned in commit
9377f88b68mentioned in commit
65876e17c7mentioned in issue #543
mentioned in issue #705
mentioned in merge request !1197
mentioned in issue #717