Skip to content

Commit 0724b35

Browse files
rdhyeeclaude
andauthored
Add rich HTML table UI for Eric's query results (#32)
Replace raw JSON output with styled, scrollable table featuring: **Features**: - Thumbnail images (clickable to full size) - Placeholder "No image" boxes for samples without thumbnails - Clickable sample PIDs linking to OpenContext records - Clickable site names linking to site pages - Formatted descriptions with proper line breaks - Geographic coordinates (lat/lon) - Zebra-striped rows for readability - Sticky header that stays visible while scrolling - Result count display **Layout**: - Max height: 600px with vertical scrolling - 5 columns: Thumbnail | Sample | Description | Site | Location - Responsive sizing with max-widths - Alternating row colors (#f8f9fa background) **Handles edge cases**: - Loading state: shows "Loading samples…" - Empty results: friendly message about Path 1 requirements - Missing thumbnails: grey placeholder box - Long descriptions: max-width with proper wrapping Significantly improves data exploration experience over raw JSON. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
1 parent 043db38 commit 0724b35

File tree

1 file changed

+80
-4
lines changed

1 file changed

+80
-4
lines changed

tutorials/parquet_cesium.qmd

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -897,10 +897,86 @@ This query implements Eric Kansa's authoritative `get_samples_at_geo_cord_locati
897897
```{ojs}
898898
//| echo: false
899899
samples_combined = selectedSamplesCombined
900-
combinedLoading ? md`(loading…)` : md`\`\`\`
901-
${JSON.stringify(samples_combined, null, 2)}
902-
\`\`\`
903-
`
900+
```
901+
902+
```{ojs}
903+
//| echo: false
904+
html`${
905+
combinedLoading ?
906+
html`<div class="loading">Loading samples…</div>`
907+
:
908+
samples_combined && samples_combined.length > 0 ?
909+
html`<div style="max-height: 600px; overflow-y: auto; border: 1px solid #ddd; border-radius: 4px;">
910+
<table style="width: 100%; border-collapse: collapse; font-size: 0.9em;">
911+
<thead style="position: sticky; top: 0; background: #f8f9fa; z-index: 1;">
912+
<tr style="border-bottom: 2px solid #dee2e6;">
913+
<th style="padding: 12px; text-align: left;">Thumbnail</th>
914+
<th style="padding: 12px; text-align: left;">Sample</th>
915+
<th style="padding: 12px; text-align: left;">Description</th>
916+
<th style="padding: 12px; text-align: left;">Site</th>
917+
<th style="padding: 12px; text-align: left;">Location</th>
918+
</tr>
919+
</thead>
920+
<tbody>
921+
${samples_combined.map((sample, i) => html`
922+
<tr style="border-bottom: 1px solid #eee; ${i % 2 === 0 ? 'background: #f8f9fa;' : ''}">
923+
<td style="padding: 8px; width: 100px;">
924+
${sample.has_thumbnail ?
925+
html`<a href="${sample.sample_thumbnail_url}" target="_blank">
926+
<img src="${sample.sample_thumbnail_url}"
927+
alt="${sample.sample_label}"
928+
style="max-width: 80px; max-height: 80px; border-radius: 4px; border: 1px solid #ddd;">
929+
</a>`
930+
:
931+
html`<div style="width: 80px; height: 80px; background: #e9ecef; border-radius: 4px; display: flex; align-items: center; justify-content: center; color: #6c757d; font-size: 0.8em;">No image</div>`
932+
}
933+
</td>
934+
<td style="padding: 8px;">
935+
<div style="margin-bottom: 4px;">
936+
<strong>${sample.sample_label}</strong>
937+
</div>
938+
<div style="font-size: 0.85em; color: #666;">
939+
<a href="${sample.sample_pid.startsWith('http') ? sample.sample_pid : sample.sample_alternate_identifiers?.[0] || '#'}"
940+
target="_blank"
941+
style="color: #007bff; text-decoration: none;">
942+
${sample.sample_pid.replace('ark:/28722/', 'ark:…/')}
943+
</a>
944+
</div>
945+
</td>
946+
<td style="padding: 8px; max-width: 300px;">
947+
<div style="font-size: 0.85em; color: #495057; line-height: 1.4;">
948+
${sample.sample_description || 'No description'}
949+
</div>
950+
</td>
951+
<td style="padding: 8px;">
952+
<div style="margin-bottom: 2px;">
953+
<strong>${sample.sample_site_label}</strong>
954+
</div>
955+
<div style="font-size: 0.75em;">
956+
<a href="${sample.sample_site_pid}"
957+
target="_blank"
958+
style="color: #007bff; text-decoration: none;">
959+
View site
960+
</a>
961+
</div>
962+
</td>
963+
<td style="padding: 8px; font-size: 0.85em; color: #666;">
964+
${sample.latitude.toFixed(5)}°N<br>
965+
${sample.longitude.toFixed(5)}°E
966+
</td>
967+
</tr>
968+
`)}
969+
</tbody>
970+
</table>
971+
</div>
972+
<div style="margin-top: 8px; font-size: 0.9em; color: #666;">
973+
Found ${samples_combined.length} sample${samples_combined.length !== 1 ? 's' : ''}
974+
</div>`
975+
:
976+
html`<div style="padding: 20px; background: #f8f9fa; border-radius: 4px; color: #6c757d;">
977+
No samples found at this location via Path 1 (direct sampling events).
978+
</div>`
979+
}`
904980
```
905981

906982
## Geographic Location Classification

0 commit comments

Comments
 (0)