Summary
pickInterval and drawGrid can fail to terminate when the Y domain is tiny or non-finite, hanging the main thread (browser “Page Unresponsive”).
This pairs with the minRange floor bug (#18): a denormal-scale domain makes fine so small that val += fine never advances. Even with a correct floor, hardening the grid is worthwhile so any pathological range cannot lock up the page.
Failure modes
pickInterval (src/draw/grid.ts)
- Invalid
valRange / pxPerUnit (≤0 or non-finite) → bad log10 / division.
- Divisor shrink loop:
span /= divs[...] does not strictly decrease → infinite while.
- Runaway iterations on slow shrink.
best === Infinity or non-positive best → unsafe fallback.
drawGrid fine-label loop
for (let val = first; val <= maxVal; val += fine) { ... }
fine ≤ 0 or non-finite → loop never reaches maxVal.
first non-finite.
fine smaller than ULP of val → val + fine === val → infinite loop.
Suggested guards (minimal)
pickInterval
- Reject non-positive / non-finite inputs early; return a finite default.
- Only shrink when
next < span && next > 0; break otherwise.
- Cap iterations (e.g.
1e4).
drawGrid
- Early-return if
fine is not finite / ≤ 0.
- Bail if
first is non-finite.
- Break when
val + fine does not strictly increase.
- Hard iteration cap (e.g.
4096) as a last resort.
Related
Environment
liveline@0.0.7, React web, micro price series (~1e-4–1e-5).
Summary
pickIntervalanddrawGridcan fail to terminate when the Y domain is tiny or non-finite, hanging the main thread (browser “Page Unresponsive”).This pairs with the
minRangefloor bug (#18): a denormal-scale domain makesfineso small thatval += finenever advances. Even with a correct floor, hardening the grid is worthwhile so any pathological range cannot lock up the page.Failure modes
pickInterval(src/draw/grid.ts)valRange/pxPerUnit(≤0 or non-finite) → badlog10/ division.span /= divs[...]does not strictly decrease → infinitewhile.best === Infinityor non-positive best → unsafe fallback.drawGridfine-label loopfine≤ 0 or non-finite → loop never reachesmaxVal.firstnon-finite.finesmaller than ULP ofval→val + fine === val→ infinite loop.Suggested guards (minimal)
pickIntervalnext < span && next > 0; break otherwise.1e4).drawGridfineis not finite / ≤ 0.firstis non-finite.val + finedoes not strictly increase.4096) as a last resort.Related
minRangefloor skipped for tiny nonzero spans (primary domain-side cause for micro series).Environment
liveline@0.0.7, React web, micro price series (~1e-4–1e-5).