SHIELD is a lightweight web dashboard for exploring how stress-hardening treatments perform across Pacific Northwest shellfish outplant sites. It brings together real RobertsLab field observations, in-situ temperature logger records, and near-live public environmental feeds so users can compare growth, survival, temperature, site conditions, and treatment outcomes in one browser-based view.
The app is built with React, Vite, Recharts, Leaflet, and React Router. It is deployed as a static single-page app, with data prepared ahead of time by build scripts rather than by a runtime application server.
- Public dashboard: https://robertslab.github.io/SHIELD/
- Research overview: https://robertslab.github.io/SHIELD/research
The website now includes four main views:
| Route | View | Purpose |
|---|---|---|
/ |
Dashboard | Filter field observations, compare treatments and sites, inspect time-series charts, and export field summaries |
/map |
Site Map | Explore outplant locations, site summaries, and links back into filtered dashboard views |
/live-data |
Live Data | Review near-live environmental observations, source metadata, maps, and OSEL-score context |
/research |
Research Overview | Share project objectives, collaborators, Washington Sea Grant support, and research context |
The dashboard is intended as a shareable research and collaboration interface for the RobertsLab Crassostrea gigas stress-hardening outplant program. It helps users:
- Compare survival and growth across hardening treatments and farm sites
- Inspect long-running HOBO logger temperature records by site
- View geographic site summaries on an interactive map
- Check near-live environmental context from nearby observing stations
- Export the currently filtered field summary for reporting
- Share a direct research overview page with project objectives, personnel, and funding context
SHIELD has no browser-facing backend. The deployed site loads committed JSON
bundles from src/data/ and renders them entirely in the React app.
The backend-like work happens before deployment:
scripts/build_real_observations.pyreads RobertsLab observation files and writessrc/data/realObservations.json.scripts/buildArchivalTemperature.mjsdownloads high-frequency HOBO logger CSVs, aggregates them to daily mean/min/max water temperature, and writessrc/data/archivalTemperatureData.json.scripts/build_live_temperature.pyfetches recent public environmental observations from nearby NOAA, USGS, and NANOOS-matched sources and writessrc/data/liveTemperature.json..github/workflows/live-temperature.ymlrefreshes the live environmental snapshot hourly and commits it only when the JSON changes..github/workflows/deploy.ymlbuilds the static app and deploys thedist/artifact to GitHub Pages.
This design keeps the public site simple to host on GitHub Pages while still allowing scheduled server-side data refreshes for sources that cannot be fetched directly from the browser because of CORS or credential constraints.
The historical placeholder dataset has been replaced with real observation
records. The mockShellfishData export name remains for component compatibility,
but it now points to src/data/realObservations.json.
Current committed data summary:
| Dataset | File | Description |
|---|---|---|
| Field observations | src/data/realObservations.json |
74 site x treatment x assessment-date records generated from RobertsLab outplant data and Baywater 10K-Seed survival anchors |
| Archival temperature | src/data/archivalTemperatureData.json |
Daily water-temperature summaries aggregated from approximately 15-minute HOBO logger records |
| Near-live environment | src/data/liveTemperature.json |
Recent matched observations and source metadata for temperature, tide, wind, pressure, streamflow, and chlorophyll source matches |
| Site metadata | src/data/mockShellfishData.js |
Site coordinates, regions, descriptions, colors, filter helpers, and chart aggregation helpers |
- Baywater, Thorndyke Bay / Hood Canal, Washington
- Sequim Bay, Washington
- Goose Point, Palix River / Willapa Bay, Washington
- Westcott, Westcott Bay / San Juan Island, Washington
- Dabob Bay is included in the near-live environmental panel as an environmental-only context site
- Control
- Heat primed
- Freshwater primed
- Immune primed
- Combined stress primed
- Growth, in millimeters shell height where measured
- Survival, as percent surviving where measured
- Water temperature, in degrees Celsius from in-situ logger monthly means for field observation rows and daily means for the archival temperature chart
- Near-live environmental context, including water temperature, air temperature, air pressure, wind, tide height, tide predictions, salinity/conductivity where available, streamflow, and chlorophyll source matches
See docs/DATA_FORMAT.md for the observation schema and integration notes.
SHIELD combines data from the following sources. Please preserve these credits when reusing the dashboard or derived data products.
| Source | Used for | Where used |
|---|---|---|
RobertsLab project-gigas-conditioning |
Goose Point, Sequim Bay, and Westcott outplant survival/growth inputs; environmental temperature CSVs for Sequim Bay, Goose Point, and Westcott | scripts/build_real_observations.py, scripts/buildArchivalTemperature.mjs |
RobertsLab 10K-seed-Cgigas |
Baywater 10K-Seed survival anchors and Baywater temperature CSV | scripts/build_real_observations.py, scripts/buildArchivalTemperature.mjs |
| NOAA National Data Buoy Center (NDBC) realtime feeds | Nearby buoy meteorological and water-condition observations | scripts/build_live_temperature.py |
| NOAA CO-OPS Tides and Currents API | Water temperature, air temperature, pressure, humidity, salinity, conductivity, wind, water level, and tide predictions from nearby stations | scripts/build_live_temperature.py |
| USGS National Water Information System (NWIS) Instantaneous Values API | Nearby watershed streamflow context for Dabob Bay | scripts/build_live_temperature.py |
| NANOOS Shellfish Growers portal, including matched UW ORCA, Padilla Bay NERR, WA Ecology, and Pacific Shellfish Institute sources | Shellfish-focused chlorophyll and water-quality source matches; some imports are marked as source-matched until automated access is configured | scripts/build_live_temperature.py |
| OpenStreetMap contributors | Base map tiles and map attribution | src/components/SiteMap.jsx, src/components/LiveTemperaturePanel.jsx |
Direct public source URLs are stored in the generated JSON metadata where
available, especially src/data/archivalTemperatureData.json and
src/data/liveTemperature.json.
- Interactive filters for site, treatment, metric, and study year
- Summary statistic cards for filtered records
- Time-series chart for growth, temperature, or survival
- Archival water-temperature chart from HOBO logger data
- Treatment comparison and site comparison charts
- Sortable, searchable, paginated data table
- Field report export for the current filter state
- Geographic site map with interactive markers
- Near-live environmental dashboard with source map and source ledger
- Research overview page for objectives, collaborators, Washington Sea Grant support, and project summary language
- Node.js 18 or later
- npm, included with Node.js
- Python 3 with
pandasif regeneratingrealObservations.json
npm installnpm run devOpen the URL shown in the terminal, typically
http://localhost:5173/SHIELD/.
Local route shortcuts:
- Dashboard:
http://localhost:5173/SHIELD/ - Site map:
http://localhost:5173/SHIELD/map - Live data:
http://localhost:5173/SHIELD/live-data - Research overview:
http://localhost:5173/SHIELD/research
Build the static site:
npm run buildOutput is written to dist/.
Refresh the near-live environmental snapshot locally:
npm run build:live-environmentRegenerate the archival temperature bundle:
npm run build:temperatureRegenerate real observations manually:
python3 scripts/build_real_observations.pyPreview the production build locally:
npm run previewThis project is configured for GitHub Pages with base path
/SHIELD/, which must match the repository name.
Deployment uses the official GitHub Pages Actions flow in
.github/workflows/deploy.yml. Do not use branch-based deploy from main or
docs/; that serves source files and can cause blank pages or workflow
conflicts.
- In the repository, go to Settings -> Pages.
- Under Build and deployment -> Source, choose GitHub Actions.
- Push to
main; the workflow buildsdist/and deploys automatically.
The site will be available at:
https://<your-username>.github.io/SHIELD/
For this repository, the direct research page is:
https://robertslab.github.io/SHIELD/research
You can also trigger a deploy manually from the Actions tab: Deploy to GitHub Pages -> Run workflow.
| Symptom | Cause | Fix |
|---|---|---|
| Workflow fails on "Deploy to docs/" | Old branch-based workflow conflicting with GitHub Actions | Use the current Pages workflow and set Pages source to GitHub Actions |
| Blank white page | Pages serving the repository root or /docs instead of the Actions artifact |
Set Pages source to GitHub Actions |
| 404 on JS/CSS files | Wrong base path in vite.config.js |
base must match repo name: /SHIELD/ |
/map, /live-data, or /research route 404 |
Missing SPA fallback | Build copies index.html to 404.html automatically |
| Intermittent deploy failures | Concurrent pushes racing to deploy | The workflow uses concurrency control; re-run the failed job if needed |
The Vite base path must match the GitHub repository name. It is currently set
to /SHIELD/. If you rename the repo, update base in
vite.config.js:
base: '/your-repo-name/',The React Router basename is derived automatically from this setting.
shield-dashboard/
├── README.md
├── docs/
│ └── DATA_FORMAT.md
├── package.json
├── index.html
├── vite.config.js
├── scripts/
│ ├── build_real_observations.py
│ ├── buildArchivalTemperature.mjs
│ └── build_live_temperature.py
└── src/
├── main.jsx
├── App.jsx
├── styles.css
├── data/
│ ├── archivalTemperatureData.json
│ ├── liveTemperature.json
│ ├── mockShellfishData.js
│ └── realObservations.json
├── pages/
│ ├── DashboardPage.jsx
│ ├── LiveDataPage.jsx
│ ├── MapPage.jsx
│ └── ResearchPage.jsx
└── components/
├── ArchivalTemperatureChart.jsx
├── DataTable.jsx
├── FieldReportExport.jsx
├── Filters.jsx
├── Header.jsx
├── LiveTemperaturePanel.jsx
├── SiteComparisonChart.jsx
├── SiteMap.jsx
├── SummaryCards.jsx
├── TimeSeriesChart.jsx
└── TreatmentComparisonChart.jsx
| Script | Description |
|---|---|
npm run dev |
Start the Vite development server |
npm run build |
Build the static app and create GitHub Pages SPA fallback files |
npm run preview |
Preview the production build locally |
npm run deploy |
Alias for the production build |
npm run build:live-environment |
Refresh src/data/liveTemperature.json from public observing feeds |
npm run build:temperature |
Regenerate src/data/archivalTemperatureData.json from source temperature CSVs |
Research dashboard prototype for collaboration and data exploration. Check upstream source repositories and public data provider terms before redistributing raw or derived datasets.
