Skip to content

Fix chart zoom reset on data refresh#36

Open
krandder wants to merge 1 commit into
mainfrom
fix/spot-price-shivering
Open

Fix chart zoom reset on data refresh#36
krandder wants to merge 1 commit into
mainfrom
fix/spot-price-shivering

Conversation

@krandder

@krandder krandder commented Mar 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Split the monolithic useEffect in SubgraphChart.jsx into two separate effects: chart creation (structural changes only) and data updates (in-place via setData())
  • fitContent() now only runs once on initial data load, tracked by a hasInitiallyFit ref
  • Auto-resync (every 60s), spot price updates, and line visibility toggles no longer destroy/rebuild the chart, preserving user zoom/pan state

Fixes #7

Test plan

  • Load a market page with subgraph chart
  • Zoom into a specific time range
  • Wait for auto-resync (60s) — chart should update data without resetting zoom
  • Toggle dark mode — chart rebuilds but fits content once (structural change)
  • Toggle line visibility (click YES/NO/SPOT labels) — should not reset zoom

Split monolithic useEffect into chart-creation and data-update effects
so auto-resync and spot updates use setData() in-place instead of
destroying and rebuilding the chart. fitContent() now only runs once
on initial data load, preserving user zoom/pan state.
@netlify

netlify Bot commented Mar 4, 2026

Copy link
Copy Markdown

Deploy Preview for futarchy ready!

Name Link
🔨 Latest commit 87f44c6
🔍 Latest deploy log https://app.netlify.com/projects/futarchy/deploys/69a825288740c50008e140bd
😎 Deploy Preview https://deploy-preview-36--futarchy.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

krandder added a commit that referenced this pull request May 10, 2026
Catalogue completion: discovered the repo has only 42 PRs total (range
#23..#65 with one gap at #38), not the assumed ~65. The 3 missing from
the previous count are all currently OPEN: #36 (chart zoom reset), #40
(position tab indicator), #41 (footer docs hub). Catalogued under a
new "Open PRs" section. Catalogue is now 42/42 (full coverage).

Snapshot field corrected from "40 / ~65" to "42 / 42" + stale "still
need to be catalogued" footer note replaced.

Test: footer-links.test.mjs (6 cases) — static lint of NAV_LINKS in
src/components/common/Footer.jsx. Pins:

  - Every entry has label + href
  - external: true ↔ absolute http(s) href
  - non-external entries are path-relative
  - Documentation href is in an accepted set covering BOTH the current
    external URL AND the post-PR-#41 in-app routes — stays green
    through the transition, surfaces typos / accidental redirects
  - Status link pinned at canonical https://status.futarchy.fi

Tests: 79 → 85 (interface), 146 → 152 cross-repo. All green.
krandder added a commit that referenced this pull request May 11, 2026
…haos row)

Opens a new row of the chaos matrix: "rate-limited 429".
Distinct from #2 (hard 502) and #7 (malformed body) — clients
with auto-retry-on-429 take a different code path than for 5xx
errors, and the Retry-After header is actionable.

Registry returns 429 + Retry-After: 1 + JSON-shape error body
(keeps body parseable to isolate the status-code-only handling
from the body-parse-also-fails handling #7 covers).

Catches NEW bug-shapes:
  - page crashes on 429 (treats response.json() as valid registry
    data — fetch .then fires for 4xx)
  - page silently empties orgs list (no telemetry / retry / signal)
  - page hammers upstream with retries (no Retry-After respect;
    thundering-herd)
  - page renders raw "rate limited" error in UI
  - page hangs in loading from downstream consumer crashing on
    error envelope where data.organizations expected

Chaos matrix script + smoke test updated:
  - scenarios:chaos-matrix recognizes -rate-limited filenames
  - smoke test pin relaxed to regex range so test surfaces drops
    without breaking on growth

Catalog: 36 scenarios. Matrix: /companies 13/14, /markets 12/14.
Smoke 80/80. Passed in 8.7s.
krandder added a commit that referenced this pull request May 11, 2026
…nies row complete 14/14)

Mirror of #36 on candles side. Registry happy (carousel mounts) +
candles returns 429 + Retry-After: 1 + JSON-shape error body.

Same terminal UX as #3 (hard 502 → "0.00 SDAI" fallback) but
DIFFERENT control flow (4xx-with-Retry-After vs 5xx). Status 429
is "successful" from a Promise standpoint so .then fires — clients
that don't check response.ok take a different path than for 5xx.

Catches NEW bug-shapes vs #3:
  - per-pool fetcher crashes on 429 (treats response.json() as
    valid pool data; downstream .map/.length throws)
  - per-pool fetcher hammers candles upstream with retries
    (no Retry-After respect; thundering-herd)
  - raw "rate limited" error rendered in price card
  - card forever-LoadingSpinner (429 doesn't trigger loading=false
    because .catch only handles 5xx not 4xx)
  - bulk-prefetch vs per-pool fallback race under partial
    rate-limiting

/companies chaos matrix now 14/14 COMPLETE (7 rows × 2 endpoints).
Catalog: 37 scenarios. Smoke 80/80. Passed in 9.9s.
krandder added a commit that referenced this pull request May 11, 2026
…mited (matrix 13/14)

Mirror of #36 applied to market page's distinct proposal-metadata-
fetch path. Registry returns 429 + Retry-After: 1 + JSON-shape
error body, candles happy.

Distinct from:
  - #24 (5xx → .catch on same page; different control flow)
  - #36 (same failure mode on /companies; different page contract
    because /companies has registry as foundation, market page has
    it as enrichment)

Catches NEW bug-shapes vs #24 and #36:
  - page crashes on 429 (treats response.json() as valid registry
    data; downstream crash on proposalentities.find/.length)
  - page-shell hangs forever (429 doesn't trigger loading=false;
    .catch handles 5xx not 4xx)
  - page hammers registry with retries (worse than /companies
    because market page polls on every state change)
  - raw "rate limited" rendered in proposal title or chart
  - "Market Not Found" false-positive from 429 wrong-code-path
    collapse

Market-page chaos matrix now 13/14. Catalog: 38 scenarios.
Smoke 80/80. Passed in 11.6s.
krandder added a commit that referenced this pull request May 11, 2026
… (NEW chaos row)

Adds 40-registry-504-gateway-timeout.scenario.mjs — opens the
EIGHTH row of the chaos matrix: "gateway timeout 504". First
cell filled (registry side on /companies); subsequent slices
fill the other 3 cells of the new row.

Distinct from prior 7 rows:
- vs #2 (502 + JSON envelope): 504 means upstream timed out,
  not "upstream sent a bad response"; AND #40 returns HTML body,
  so consumer's .json() throws SyntaxError (different bug-class
  than #2's structured-envelope path)
- vs #7 (200 + non-JSON body): #7 has status OK so failure
  surfaces only on parse; #40 has status ERROR + non-JSON so
  EITHER status OR parse path can fire depending on consumer
  code order
- vs #19 (slow-but-eventual valid): #19 returns 200 eventually;
  #40 says "wait already exceeded LB timeout" — consumers should
  retry once with jitter, not spin
- vs #36 (429 + Retry-After): 429 is client-fault (rate
  limiter); 504 is infra-fault (LB ↔ origin). Consumer that
  conflates them fails both — invisible regression class only
  chaos catches

REGISTRY responds 504 + Content-Type: text/html + nginx-style
HTML 504 page (no JSON). Models real LB defaults (AWS ALB,
nginx, Cloudflare, GCP HTTPS LB). Asserts /companies still
degrades to "No organizations found" — same terminal UX as #2
but via fundamentally different control-flow path.

Bug-shapes captured: page crashes on JSON.parse(html) throwing
SyntaxError, page renders raw HTML body in org list, page
treats 504 as success with empty data (silent broken state),
page immediately retries in tight loop without backoff, page
hangs in loading forever (parse error before loading-cleanup),
"Application error" from missing top-level error boundary.

Drift-resistant matrix tooling extended: new
FAILURE_MODE_KEYWORDS entry ('gateway timeout 504' →
['-504-gateway-timeout', '-504-']), new CANONICAL_FAILURE_MODES
row, smoke-test floor pin bumped from /14 to /16 (15 floor on
/companies, 14 on /markets/[address]).

Live re-validation: smoke 80/80, scenario #40 passes in 1.8s on
first run, catalog regenerated (40 scenarios), matrix script
shows /companies 15/16 + /markets/[address] 14/16.
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.

High zoom chart has sudden change in x-axis

1 participant