Skip to content

Conversation

@rdhyee
Copy link
Contributor

@rdhyee rdhyee commented Oct 31, 2025

Summary

Upgrade Path 1 and Path 2 queries to match Eric's authoritative query structure, and display all three with consistent rich HTML tables.

Motivation

Previously:

  • Path 1 and Path 2 returned minimal data (just PIDs, labels, event info)
  • Displayed as raw JSON dumps
  • Inconsistent with Eric's rich query results

Now:

  • All three queries return the same rich dataset
  • All three display with beautiful, consistent HTML tables
  • Users can compare results visually across different query paths

Enhanced Query Data

Both Path 1 and Path 2 now return:

  • 📷 Thumbnails: sample_thumbnail_url, has_thumbnail
  • 📝 Full metadata: sample_description, sample_alternate_identifiers
  • 📍 Site context: sample_site_label, sample_site_pid
  • 🌍 Coordinates: latitude, longitude
  • 🔗 Sample info: sample_pid, sample_label

Technical Changes

Query Improvements

  • Path 1 (get_samples_1):

    • Enhanced from 6 columns to 11 columns
    • Uses list_contains() for proper edge traversal
    • Orders by has_thumbnail DESC (images first)
  • Path 2 (get_samples_2):

    • Enhanced from 7 columns to 11 columns
    • Uses list_contains() for proper backward traversal
    • Orders by has_thumbnail DESC (images first)

UI Improvements

  • Replaced raw JSON with styled HTML tables
  • Same 5-column layout for all three queries:
    • Thumbnail: 80x80px images or "No image" placeholder
    • Sample: Name + clickable PID link
    • Description: Formatted text with wrapping
    • Site: Name + "View site" link
    • Location: Lat/lon coordinates

Consistency

All three query results now share:

  • Identical table structure and styling
  • Same data fields and formatting
  • Consistent loading/empty states
  • Result count displays

Before vs After

Path 1 Query - Before

{
  "sample_id": "ark:/28722/k2wq0b20z",
  "sample_label": "4061-17",
  "sample_name": "4061-17",
  "event_id": "...",
  "event_label": "...",
  "location_path": "direct_event_location"
}

Path 1 Query - After

Rich HTML table with thumbnails, full descriptions, clickable links, and geographic coordinates.

Benefits

  1. Visual Comparison: Users can now visually compare results across all three paths
  2. More Information: Thumbnails and descriptions aid in sample identification
  3. Better UX: Clickable links make navigation seamless
  4. Consistency: All query results follow the same visual pattern
  5. Discoverability: Rich data encourages exploration

Testing

  • Path 1 table displays with rich data
  • Path 2 table displays with rich data
  • Both match Eric's query UI pattern
  • Thumbnails load and link correctly
  • Sample and site links work
  • Empty states show friendly messages
  • Loading states display correctly

Test with: geoloc_04d6e816218b1a8798fa90b3d1d43bf4c043a57f (PKAP, has samples via multiple paths)

🤖 Generated with Claude Code

rdhyee and others added 3 commits October 31, 2025 13:37
Update both query paths to match Eric's authoritative query structure:

**Enhanced Queries**:
- Path 1 (get_samples_1): Now returns full sample metadata
- Path 2 (get_samples_2): Now returns full sample metadata
- Both now include: thumbnails, descriptions, alternate IDs, site info, coordinates
- Both use list_contains() for proper edge traversal
- Both order by has_thumbnail DESC (images first)

**Rich HTML Tables**:
- Replace raw JSON output with styled, scrollable tables
- Same 5-column layout as Eric's query: Thumbnail | Sample | Description | Site | Location
- Clickable thumbnail images or "No image" placeholders
- Clickable sample PIDs linking to OpenContext
- Clickable site names with "View site" links
- Formatted coordinates and descriptions
- Zebra-striped rows, sticky headers, result counts
- Loading and empty states

**Consistency**:
All three query result displays now use the same UI pattern:
- Eric's query (Path 1 only, authoritative)
- Path 1 query (direct event location)
- Path 2 query (via site location)

Users can now compare results across all three approaches with rich, visual data presentation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Establish comprehensive testing foundation for future UI evolution:

**Test Framework**:
- Playwright for E2E browser testing
- Configured for Chromium (extensible to Firefox/Safari)
- HTML reporting with traces and screenshots
- CI-ready with automatic retries

**Test Coverage** (`tests/playwright/cesium-queries.spec.js`):
- ✅ Page loading and geocode search box
- ✅ Camera movement on geocode search
- ✅ HTML table structure (5 columns: Thumbnail | Sample | Description | Site | Location)
- ✅ Clickable sample PID links to OpenContext
- ✅ "View site" links
- ✅ Thumbnail images and "No image" placeholders
- ✅ Result count displays
- ✅ Empty state friendly messages
- ✅ Scrollable tables with sticky headers
- ✅ Zebra-striped rows
- ✅ Visual consistency across all three tables

**Test Data**:
- PKAP location with samples: `geoloc_04d6e816218b1a8798fa90b3d1d43bf4c043a57f`
- Larnaka site marker (empty state): `geoloc_7a05216d388682536f3e2abd8bd2ee3fb286e461`

**Infrastructure Files**:
- `playwright.config.js`: Test configuration with extended timeouts
- `package.json`: NPM scripts (test, test:headed, test:ui, test:debug)
- `tests/README.md`: Comprehensive testing guide
- `tests/playwright/cesium-queries.spec.js`: Full test suite

**NPM Scripts**:
```bash
npm test              # Run all tests
npm run test:headed   # Run with browser visible
npm run test:ui       # Interactive UI mode
npm run test:debug    # Debug mode with inspector
npm run test:report   # View HTML report
```

**Gitignore Updates**:
- node_modules/
- test-results/
- playwright-report/
- package-lock.json

**Future-Ready**:
This infrastructure provides a solid foundation for:
- Adding new UI feature tests
- Visual regression testing
- Accessibility testing
- Performance monitoring
- Cross-browser testing
- Mobile responsive tests

Tests validate the enhanced query UI (Path 1, Path 2, Eric's query) to ensure consistent, high-quality user experience as the UI evolves.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…nhancement

**Performance Improvement**: 7+ seconds → ~2 seconds (71% faster!)

## Problem
The expensive CTE query with JOIN + GROUP BY took 7+ seconds to classify
each geocode as sample_location/site_location/both before rendering any dots.
This made the page feel frozen and unresponsive.

## Solution: Progressive Enhancement
1. **Fast initial load** (~2s): Simple SELECT DISTINCT query, all dots blue
2. **Optional refinement** (~7s): Button to classify and color-code by type
3. **Chunked rendering**: 500 points per batch with progress indicator
4. **Performance telemetry**: Console logs show timing for all operations

## Technical Changes

### Simplified Initial Query (lines 137-163)
**Before** (expensive):
```sql
WITH geo_classification AS (
    SELECT geo.pid, geo.latitude, geo.longitude,
           MAX(CASE WHEN e.p = 'sample_location' THEN 1 ELSE 0 END) as is_sample_location,
           MAX(CASE WHEN e.p = 'site_location' THEN 1 ELSE 0 END) as is_site_location
    FROM nodes geo
    JOIN nodes e ON (geo.row_id = e.o[1])
    WHERE geo.otype = 'GeospatialCoordLocation'
    GROUP BY geo.pid, geo.latitude, geo.longitude
)
SELECT pid, latitude, longitude, CASE ... END as location_type
FROM geo_classification
```

**After** (fast):
```sql
SELECT DISTINCT pid, latitude, longitude
FROM nodes
WHERE otype = 'GeospatialCoordLocation'
```

### Optional Classification Button (lines 50-56, 769-845)
- User can click button to run classification query
- Updates existing point colors/sizes in-place
- Same color scheme as before:
  - Blue (small): sample_location_only - field collection points
  - Purple (large): site_location_only - administrative markers
  - Orange (medium): both - dual-purpose locations

### Chunked Rendering (lines 169-218)
- Render 500 points per batch
- Yield to browser between chunks (keeps UI responsive)
- Dynamic progress: "Rendering geocodes... 500/198,433 (0%)"

### Performance Telemetry (lines 376-384, 438-446, 500-508)
- Console logs for all queries: locations, Path 1, Path 2, Eric's query
- Example output:
  ```
  Query executed in 1847ms - retrieved 198433 locations
  Rendering completed in 423ms
  Total time (query + render): 2270ms
  ```

## User Experience Improvements

**Before**:
- Page frozen for 7+ seconds with static "Loading..." text
- No feedback on progress
- User uncertain if page crashed

**After**:
- Interactive in ~2 seconds with all dots visible
- Progress indicator shows "Rendering geocodes... X/Y (Z%)"
- Optional color-coding button if user wants classification
- Console telemetry for debugging and optimization planning

## Files Changed
- `tutorials/parquet_cesium.qmd` (+86 lines): Optimized queries + telemetry
- `OPTIMIZATION_SUMMARY.md` (new): Performance analysis and results
- `LAZY_LOADING_IMPLEMENTATION.md` (new): Technical implementation details
- `PERFORMANCE_OPTIMIZATION_PLAN.md` (new): Future optimization roadmap

## Testing
Test at http://localhost:XXXX/tutorials/parquet_cesium.html
- Expect: Page loads in ~2 seconds with all blue dots
- Click "Color-code by type" button → dots recolor after ~7 seconds
- Console shows timing for all queries

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@rdhyee rdhyee merged commit 40d2792 into isamplesorg:main Nov 1, 2025
1 check passed
rdhyee added a commit to rdhyee/isamplesorg.github.io that referenced this pull request Nov 1, 2025
The optional classification button approach (from commit 4612339) never
rendered properly in the browser. Reverting to the working automatic
color-classification from commit 4a4b527 (PR isamplesorg#33).

**Reverted changes**:
- Removed non-functional classification button
- Restored automatic CTE query with JOIN + GROUP BY
- Dots now color-code automatically on load:
  - Blue (small): sample_location_only - field collection points
  - Purple (large): site_location_only - administrative markers
  - Orange (medium): both - dual-purpose locations

**Trade-off**: Slower initial load (~7s vs ~2s) but WORKING feature.

The button was never rendering due to Observable/Quarto interaction issues.
Rather than debug further, restoring proven working behavior.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant