Skip to content

Aozora7/darkhour

Repository files navigation

darkhour

https://25h.aozora.one/

screenshot

A client-side React application that visualizes Google Health sleep data in a way that's helpful for people with non-24-hour sleep-wake disorder (N24). The main feature is an actogram with sleep stage data (when available), and an overlay that displays estimated circadian night on each day, calculated based on the entire visible data set.

In many aspects inspired by fitbit-sleep-vis as I've been using it for years, but this project is written completely from scratch due to vastly different objectives and implementation besides fetching.

This repository is a reimplementation of fitbit-n24 for Google Health API as Fitbit API will be deprecated this year.

Features

Visualization

  • Canvas actogram with sleep stage coloring, one row per day
  • Periodogram for circadian frequency analysis
  • Optional double-plot mode for patterns crossing row boundaries
  • Adjustable row height
  • Adjustable row width to match the data's circadian period, allowing sleep records to line up
  • Interactive tooltips with date, times, duration, efficiency, stage breakdown

Circadian analysis

  • Estimated circadian night overlay (purple) computed from sleep data
  • Forecast circadian night 2/7/30 days ahead using recent trend
  • Schedule overlay (green) to compare circadian night against weekly commitments

Data

  • Fetch from Google Health API with progressive loading and IndexedDB caching
  • Import/export JSON
  • Date range filter for all visualizations and calculations
  • Export what you see as PNG

Tech stack

Layer Choice
Build Vite
UI React 19 + TypeScript
CSS Tailwind CSS v4
Visualization HTML Canvas + d3-scale
Auth OAuth 2.0 PKCE

Quick start

npm install
npm run dev

Open http://localhost:5173.

Google Health API setup

To fetch data directly from the Google Health API:

  1. Create OAuth credentials in Google Cloud Console
    • OAuth client type: Web application
    • Authorized redirect URI: http://localhost:5173/
  2. Copy .env.example to .env and fill in your client ID:
    VITE_GOOGLE_HEALTH_CLIENT_ID=your_client_id_here
    VITE_GOOGLE_HEALTH_CLIENT_SECRET=your_client_secret_here
    
  3. Start the dev server and click "Sign in"

Data sources

The app starts empty. You can:

  • Fetch from Google Health: Sign in via OAuth and fetch all historical sleep data. Data is cached in IndexedDB; subsequent fetches only retrieve new records.
  • Import JSON: Load a previously exported file or raw API response data.
  • Import Google Takeout data: Multiple sleep-YYYY-MM-DD.json files from Takeout can be imported at the same time.
  • Export JSON: Save the current dataset as a JSON file that can be re-imported later.

Supported import formats:

  • Google Health sleep dataPoints
  • Fitbit API v1.2 response
  • Previously exported data from this app

Project structure

src/
  main.tsx              Entry point, provider hierarchy
  App.tsx               Layout shell (no logic)
  AppContext.tsx        Global state, derived values, context provider
  index.css             Tailwind directives + global styles

  api/                  API types, fetch wrappers, paging implementations
  auth/                 OAuth 2.0 PKCE flow, auth context provider
  data/                 Data loading, IndexedDB caching, fetch orchestration
  models/               Actogram row transform, circadian estimation, sleep scoring, periodogram
  components/           UI components (header, toolbar, controls, actogram, periodogram, legend, schedule editor)

About

React application that visualizes sleep data for people with non-24-hour sleep-wake disorder (N24)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages