Skip to content

Commit 1078fe4

Browse files
rdhyeeclaude
andcommitted
Fix progressive globe: render stats bar from OJS cells
DOM elements created in raw HTML aren't available when OJS cells execute. Move legend, stats bar, and phase indicator into OJS cells and add null guards on all getElementById calls. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c96c384 commit 1078fe4

1 file changed

Lines changed: 33 additions & 15 deletions

File tree

tutorials/progressive_globe.qmd

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -119,24 +119,34 @@ db = {
119119
}
120120
```
121121

122-
<div class="legend">
122+
```{ojs}
123+
//| echo: false
124+
// Render legend and stats bar from OJS so they're in the DOM before phase1 runs
125+
legend_html = html`<div class="legend">
123126
<strong>Source:</strong>
124127
<span class="legend-item"><span class="legend-dot" style="background:#3366CC"></span> SESAR</span>
125128
<span class="legend-item"><span class="legend-dot" style="background:#DC3912"></span> OpenContext</span>
126129
<span class="legend-item"><span class="legend-dot" style="background:#109618"></span> GEOME</span>
127130
<span class="legend-item"><span class="legend-dot" style="background:#FF9900"></span> Smithsonian</span>
128-
</div>
131+
</div>`
132+
```
129133

130-
<div id="statsBar" class="stats-bar">
134+
```{ojs}
135+
//| echo: false
136+
statsBar = html`<div class="stats-bar">
131137
<span class="stat"><span class="stat-label">Phase:</span> <span id="statPhase" class="stat-value">Loading...</span></span>
132138
<span class="stat"><span class="stat-label">Points:</span> <span id="statPoints" class="stat-value">0</span></span>
133139
<span class="stat"><span class="stat-label">Samples:</span> <span id="statSamples" class="stat-value">0</span></span>
134140
<span class="stat"><span class="stat-label">Time:</span> <span id="statTime" class="stat-value">-</span></span>
135-
</div>
141+
</div>`
142+
```
136143

137-
<div id="phaseIndicator" class="phase-indicator" style="background: #e3f2fd; color: #1565c0;">
144+
```{ojs}
145+
//| echo: false
146+
phaseIndicatorEl = html`<div id="phaseIndicator" class="phase-indicator" style="background: #e3f2fd; color: #1565c0;">
138147
Phase 1: Loading H3 global overview (580 KB)...
139-
</div>
148+
</div>`
149+
```
140150

141151
::: {.panel-tabset}
142152

@@ -343,13 +353,18 @@ viewer = {
343353
344354
// === PHASE 1: Load H3 res4 aggregates (instant) ===
345355
phase1 = {
356+
// Ensure OJS-rendered DOM elements are available
357+
void statsBar;
358+
void phaseIndicatorEl;
359+
346360
performance.mark('phase1-start');
347361
348362
const updateStats = (phase, points, samples, time) => {
349-
document.getElementById('statPhase').textContent = phase;
350-
document.getElementById('statPoints').textContent = points.toLocaleString();
351-
document.getElementById('statSamples').textContent = samples.toLocaleString();
352-
document.getElementById('statTime').textContent = time;
363+
const el = (id) => document.getElementById(id);
364+
if (el('statPhase')) el('statPhase').textContent = phase;
365+
if (el('statPoints')) el('statPoints').textContent = points.toLocaleString();
366+
if (el('statSamples')) el('statSamples').textContent = samples.toLocaleString();
367+
if (el('statTime')) el('statTime').textContent = time;
353368
};
354369
355370
const indicator = document.getElementById('phaseIndicator');
@@ -420,8 +435,10 @@ phase1 = {
420435
// === PHASE 2: Zoom-triggered detail loading ===
421436
// Monitor camera height and load finer resolution when zoomed in
422437
zoomWatcher = {
423-
// Wait for phase 1 to complete
438+
// Wait for phase 1 to complete and DOM to be ready
424439
if (!phase1) return;
440+
void statsBar;
441+
void phaseIndicatorEl;
425442
426443
let currentResolution = 4;
427444
let loadingRes = false;
@@ -501,10 +518,11 @@ zoomWatcher = {
501518
performance.measure(`res${res}-total`, `res${res}-start`, `res${res}-end`);
502519
const elapsed = performance.getEntriesByName(`res${res}-total`)[0].duration;
503520
504-
document.getElementById('statPhase').textContent = `H3 Res${res}`;
505-
document.getElementById('statPoints').textContent = data.length.toLocaleString();
506-
document.getElementById('statSamples').textContent = totalSamples.toLocaleString();
507-
document.getElementById('statTime').textContent = `${(elapsed/1000).toFixed(1)}s`;
521+
const el = (id) => document.getElementById(id);
522+
if (el('statPhase')) el('statPhase').textContent = `H3 Res${res}`;
523+
if (el('statPoints')) el('statPoints').textContent = data.length.toLocaleString();
524+
if (el('statSamples')) el('statSamples').textContent = totalSamples.toLocaleString();
525+
if (el('statTime')) el('statTime').textContent = `${(elapsed/1000).toFixed(1)}s`;
508526
509527
if (indicator) {
510528
indicator.style.background = '#e8f5e9';

0 commit comments

Comments
 (0)