[object Object]

← back to Stock Vshape Viewer

Sliders recompute ALL stocks live on drag (rAF-coalesced) + dispose geometry to prevent GPU leak on rebuild

abac055b8549bf1b32f97d901d51bd0034d782e6 · 2026-08-27 08:57:26 -0700 · Steve

Files touched

Diff

commit abac055b8549bf1b32f97d901d51bd0034d782e6
Author: Steve <steve@designerwallcoverings.com>
Date:   Thu Aug 27 08:57:26 2026 -0700

    Sliders recompute ALL stocks live on drag (rAF-coalesced) + dispose geometry to prevent GPU leak on rebuild
---
 public/app.js | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/public/app.js b/public/app.js
index 4a39736..cb8bd23 100644
--- a/public/app.js
+++ b/public/app.js
@@ -106,7 +106,13 @@ function priceToY(d, price) { const lo = d.min * 0.985, hi = d.max; return ((pri
 function idxToX(n, i) { return (i / (n - 1)) * LANE_LEN - LANE_LEN / 2; }
 
 function rebuildScene() {
-  for (const g of groups) scene.remove(g.group);
+  for (const g of groups) {
+    g.group.traverse(o => {           // dispose to avoid GPU leak on repeated rebuilds
+      if (o.geometry) o.geometry.dispose();
+      if (o.material) { const m = o.material; (Array.isArray(m) ? m : [m]).forEach(x => { x.map && x.map.dispose(); x.dispose(); }); }
+    });
+    scene.remove(g.group);
+  }
   groups = []; laneMeshes.length = 0;
   for (const t of state.tickers) {
     const D = state.data[t]; if (!D) continue;
@@ -403,14 +409,19 @@ function syncFilterUI() {
   }
   for (const [key, id] of TOGGLES) document.getElementById(id).checked = !!state.filters[key];
 }
+let processQueued = false;
+function scheduleProcess() {           // coalesce a burst of slider events into 1 rebuild/frame
+  if (processQueued) return; processQueued = true;
+  requestAnimationFrame(() => { processQueued = false; process(); });
+}
 function wireFilters() {
-  for (const [key, id, vid, fmt, reprocess] of SLIDERS) {
+  for (const [key, id, vid, fmt] of SLIDERS) {
     const el = document.getElementById(id);
     el.oninput = () => {
       state.filters[key] = +el.value; document.getElementById(vid).textContent = fmt(+el.value);
       save(LS.filters, state.filters);
-      if (reprocess) process(); else { applyFilters(); if (state.selected) showDetail(state.selected); }
       updateCriteriaChips();
+      scheduleProcess();               // every criterion recomputes ALL stocks, live
     };
   }
   for (const [key, id] of TOGGLES) {

← 8c16d08 Live parametric V-shape screener: local three.js, criteria b  ·  back to Stock Vshape Viewer  ·  Market scanner: NASDAQ+DJIA universe scan (buy-score ranked, 23089cb →