← back to Dead Agentabrams
room: interactive touring-history year map for archive browse
0c6d91e5d6d3af48f71ac2190b5af3a859671ee5 · 2026-09-02 07:50:37 -0700 · Steve Abrams
Files touched
Diff
commit 0c6d91e5d6d3af48f71ac2190b5af3a859671ee5
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Sep 2 07:50:37 2026 -0700
room: interactive touring-history year map for archive browse
---
room/index.html | 55 +++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 49 insertions(+), 6 deletions(-)
diff --git a/room/index.html b/room/index.html
index 05c9f58..d08161d 100644
--- a/room/index.html
+++ b/room/index.html
@@ -154,6 +154,18 @@
.mr-search{width:100%;background:rgba(40,12,16,.8);color:var(--ink);border:1px solid var(--panel-edge);border-radius:9px;padding:8px 10px;font-size:12px;margin-bottom:8px}
.mr-search::placeholder{color:var(--ink-dim)}
.mr-year{width:100%;background:rgba(40,12,16,.8);color:var(--ink);border:1px solid var(--panel-edge);border-radius:9px;padding:7px 9px;font-size:12px;margin-bottom:8px;cursor:pointer}
+ /* interactive touring-history year map */
+ .mr-map-head{display:flex;justify-content:space-between;align-items:center;font-size:10px;color:var(--ink-dim);margin:2px 0 3px;gap:8px}
+ #mrMapLabel{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
+ .mr-allbtn{flex:none;background:rgba(70,20,26,.6);color:var(--ink);border:1px solid var(--panel-edge);border-radius:6px;font-size:10px;padding:2px 8px;cursor:pointer}
+ .mr-allbtn.on{background:var(--gold);color:#2a0d10;border-color:var(--gold)}
+ .mr-map{display:flex;align-items:flex-end;gap:2px;height:60px;overflow-x:auto;overflow-y:hidden;padding:3px 2px 0;margin-bottom:8px;border-bottom:1px solid var(--panel-edge);scrollbar-width:thin}
+ .mr-yr{flex:0 0 auto;width:11px;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;height:100%;cursor:pointer;background:none;border:0;padding:0}
+ .mr-yr .bar{width:8px;min-height:3px;border-radius:2px 2px 0 0;background:linear-gradient(180deg,var(--gold),#7a2a1e);opacity:.5;transition:opacity .15s,box-shadow .15s}
+ .mr-yr:hover .bar{opacity:.9}
+ .mr-yr.on .bar{opacity:1;background:linear-gradient(180deg,#ffd97a,var(--gold));box-shadow:0 0 8px rgba(240,190,90,.85)}
+ .mr-yr .yl{font-size:7px;line-height:1;color:var(--ink-dim);margin-top:2px;writing-mode:vertical-rl;transform:rotate(180deg);font-variant-numeric:tabular-nums;letter-spacing:-.5px;height:14px}
+ .mr-yr.on .yl{color:var(--gold)}
.mr-results{max-height:150px;overflow:auto;margin-bottom:8px;display:flex;flex-direction:column;gap:2px}
.mr-results:empty{display:none}
.mr-result{display:flex;gap:9px;align-items:baseline;width:100%;text-align:left;background:none;border:0;color:var(--ink-dim);font-family:var(--sans);font-size:11.5px;padding:5px 6px;cursor:pointer;border-radius:6px}
@@ -243,7 +255,9 @@
</header>
<div class="mrbody" id="mrbody">
<input class="mr-search" id="mrSearch" type="search" placeholder="🔍 Search the whole Dead archive — date, city, song…" aria-label="Search the Grateful Dead archive">
- <select class="mr-year" id="mrYear" aria-label="Browse by year"></select>
+ <div class="mr-map-head"><span id="mrMapLabel">Touring history — tap a year</span><button type="button" class="mr-allbtn on" id="mrAll">All years</button></div>
+ <div class="mr-map" id="mrMap" role="listbox" aria-label="Browse shows by year"></div>
+ <input type="hidden" id="mrYear" value="">
<div class="mr-results" id="mrResults" role="list"></div>
<div class="mr-picks">Curated nights:</div>
<select class="mr-show" id="mrShow" aria-label="Choose a recording from the Live Music Archive"></select>
@@ -1646,11 +1660,40 @@ sel.addEventListener('change',()=>loadShow(+sel.value,{play:true}));
// archive search wiring — type anything, debounced; Enter searches immediately
const searchEl=$('mrSearch'), yearEl=$('mrYear');
-if(yearEl){
- let opts='<option value="">All years · most played</option>';
- for(let y=1965;y<=1995;y++) opts+=`<option value="${y}">${y}</option>`;
- yearEl.innerHTML=opts;
- yearEl.addEventListener('change',()=>searchArchive(searchEl?searchEl.value:''));
+// Interactive touring-history map: one bar per year, height ∝ shows surviving that year.
+const mapEl=$('mrMap'), mapLabel=$('mrMapLabel'), allBtn=$('mrAll');
+if(mapEl && yearEl){
+ const YEARS=[]; for(let y=1965;y<=1995;y++) YEARS.push(y);
+ const counts={};
+ function setYear(y){
+ yearEl.value=y?String(y):'';
+ [...mapEl.children].forEach(c=>c.classList.toggle('on', c.dataset.y===String(y)));
+ allBtn.classList.toggle('on', !y);
+ mapLabel.textContent = y ? `${y} · ${(counts[y]||0).toLocaleString()} shows` : 'Touring history — tap a year';
+ searchArchive(searchEl?searchEl.value:'');
+ }
+ YEARS.forEach(y=>{
+ const b=document.createElement('button'); b.type='button'; b.className='mr-yr'; b.dataset.y=String(y); b.setAttribute('role','option');
+ b.title=y+' — counting…';
+ b.innerHTML=`<span class="bar" style="height:3px"></span><span class="yl">${y%5===0?y:''}</span>`;
+ b.addEventListener('click',()=>setYear(y));
+ b.addEventListener('mouseenter',()=>{ if(counts[y]!=null) mapLabel.textContent=`${y} · ${counts[y].toLocaleString()} shows`; });
+ mapEl.appendChild(b);
+ });
+ mapEl.addEventListener('mouseleave',()=>{ const on=yearEl.value; mapLabel.textContent = on?`${on} · ${(counts[on]||0).toLocaleString()} shows`:'Touring history — tap a year'; });
+ allBtn.addEventListener('click',()=>setYear(0));
+ // Fetch per-year show counts in parallel, then scale bars (sqrt to tame the '77–'90 spikes).
+ Promise.all(YEARS.map(y=>
+ fetch('https://archive.org/advancedsearch.php?q='+encodeURIComponent('collection:GratefulDead AND year:'+y)+'&rows=0&output=json',{mode:'cors'})
+ .then(r=>r.json()).then(j=>({y,n:(j.response&&j.response.numFound)||0})).catch(()=>({y,n:0}))
+ )).then(rows=>{
+ const max=Math.max(1,...rows.map(r=>Math.sqrt(r.n)));
+ rows.forEach(({y,n})=>{ counts[y]=n; const el=mapEl.querySelector('[data-y="'+y+'"]'); if(!el) return;
+ el.querySelector('.bar').style.height=Math.round(3+(Math.sqrt(n)/max)*40)+'px';
+ el.title=y+' — '+n.toLocaleString()+' shows';
+ });
+ const cur=yearEl.value; if(cur) mapLabel.textContent=`${cur} · ${(counts[cur]||0).toLocaleString()} shows`;
+ }).catch(()=>{});
}
if(searchEl){
searchEl.addEventListener('input',()=>{ clearTimeout(searchTimer); searchTimer=setTimeout(()=>searchArchive(searchEl.value),450); });
← cb10224 Sync ROOM 01: full Grateful Dead archive browse (popular + b
·
back to Dead Agentabrams
·
snapshot before orb UFO/celestial + roaming-animal build 0feb28b →