← back to Stock Vshape Viewer
yoloforever cycle 1: 3D encodings legend (height/volume/verdict/peak-glow/MA key), default-collapsed per Cody (avoids occluding 3D ticker labels)
b40722e05516a29f21e841a82a7f5e376f1710fc · 2026-08-28 00:50:10 -0700 · Steve
Files touched
M public/app.jsM public/index.html
Diff
commit b40722e05516a29f21e841a82a7f5e376f1710fc
Author: Steve <steve@designerwallcoverings.com>
Date: Fri Aug 28 00:50:10 2026 -0700
yoloforever cycle 1: 3D encodings legend (height/volume/verdict/peak-glow/MA key), default-collapsed per Cody (avoids occluding 3D ticker labels)
---
public/app.js | 4 ++++
public/index.html | 18 ++++++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/public/app.js b/public/app.js
index e58635a..6711a90 100644
--- a/public/app.js
+++ b/public/app.js
@@ -580,6 +580,10 @@ const volnormBtn = document.getElementById('volnorm');
const syncVolNorm = () => { volnormBtn.textContent = state.volNorm === 'global' ? '⬍ Vol: comparable' : '⬍ Vol: per-stock'; volnormBtn.classList.toggle('on', state.volNorm === 'global'); };
syncVolNorm();
volnormBtn.onclick = () => { state.volNorm = state.volNorm === 'global' ? 'per-stock' : 'global'; save(LS.volNorm, state.volNorm); syncVolNorm(); rebuildScene(); applyFilters(); };
+document.querySelector('#legend3d .lg-title').onclick = () => {
+ const hidden = document.getElementById('lg-body').classList.toggle('hidden');
+ document.getElementById('lg-toggle').textContent = hidden ? '▸' : '▾';
+};
addEventListener('keydown', e => { if (e.key === 'Escape') { clearSelect(); document.getElementById('left').classList.remove('open'); } });
addEventListener('resize', () => {
camera.aspect = innerWidth / innerHeight; camera.updateProjectionMatrix(); renderer.setSize(innerWidth, innerHeight);
diff --git a/public/index.html b/public/index.html
index 7461fed..c22438f 100644
--- a/public/index.html
+++ b/public/index.html
@@ -107,6 +107,13 @@
/* ===== bottom controls ===== */
#ctl{position:fixed;bottom:14px;left:50%;transform:translateX(-50%);z-index:15;display:flex;gap:8px;padding:8px}
#hint{position:fixed;bottom:60px;left:50%;transform:translateX(-50%);color:var(--dim);font-size:12px;z-index:5;pointer-events:none;opacity:.8}
+ #legend3d{position:fixed;bottom:14px;left:14px;z-index:12;padding:8px 10px;font-size:10.5px;color:var(--dim);opacity:.9}
+ #legend3d .lg-title{font-weight:700;color:var(--ink);font-size:11px;margin-bottom:4px;cursor:pointer;user-select:none}
+ #legend3d #lg-body{display:flex;flex-direction:column;gap:3px}
+ #legend3d #lg-body.hidden{display:none}
+ #legend3d .sw{display:inline-block;width:9px;height:9px;border-radius:2px;vertical-align:middle;margin-right:2px}
+ #legend3d .ln{display:inline-block;width:13px;height:2px;vertical-align:middle;margin-right:2px}
+ #legend3d .glowdot{display:inline-block;width:9px;height:9px;border-radius:50%;background:#fff;box-shadow:0 0 5px #9fd8ff;vertical-align:middle;margin-right:2px}
/* ===== detail panel ===== */
#detail{position:fixed;bottom:14px;right:14px;width:min(470px,46vw);max-height:calc(100vh - 80px);
@@ -254,6 +261,17 @@
</div>
<div id="hint">drag to orbit · scroll to zoom · click a layer for its chart · ☰ to screen</div>
+<div id="legend3d" class="glass">
+ <div class="lg-title">3D key <span id="lg-toggle">▸</span></div>
+ <div id="lg-body" class="hidden">
+ <div><b>height</b> = price · <b>thicker + brighter</b> = more volume</div>
+ <div><i class="sw" style="background:var(--pass)"></i>PASS <i class="sw" style="background:var(--fail)"></i>fails screen</div>
+ <div><span class="glowdot"></span> highest-volume day</div>
+ <div><i class="sw" style="background:var(--high)"></i>high <i class="sw" style="background:var(--trough)"></i>trough <i class="sw" style="background:var(--newhigh)"></i>recent high</div>
+ <div><i class="ln" style="background:var(--ma50)"></i>50-DMA <i class="ln" style="background:var(--ma200)"></i>200-DMA</div>
+ </div>
+</div>
+
<div id="detail" class="glass">
<div class="dh"><b id="d-tk"></b><span class="x" id="d-x">✕</span></div>
<div class="sub" id="d-sub"></div>
← 5ff5470 3D volume reads: per-vertex volume color (bright=heavy/dim=l
·
back to Stock Vshape Viewer
·
yoloforever cycle 2: buy-score is CAP-DEPENDENT. Backtest no 7a16bf9 →