Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Legislation Dashboard

Open the dashboard →

A static, client-side dashboard over bill data from every tracked jurisdiction, filterable by state/territory, session, chamber, topic tag, and free-text search. It is plain HTML/JS with no external dependencies, deployed as part of this docs site by the existing GitHub Pages workflow.

What it shows

  • Stat tiles — bill count, jurisdictions, sessions, and share of bills with topic tags
  • Bills by jurisdiction and bills by topic bar charts (click a bar to filter)
  • Activity by month — bills by the month of their most recent recorded action
  • Bills table — sortable, with topic chips and links to each bill’s official source

All charts, tiles, and the table re-render against the same filtered slice, so the numbers always agree. A “Data as of” badge under the title shows when the snapshot was built.

Jurisdictions whose upstream scraper repo cloned but published no bills yet are listed as pending under the jurisdiction chart (rather than silently omitted), and appear automatically once their *-legislation repo starts carrying data.

Where the data comes from

The page reads a single data.json produced by scripts/build_dashboard_data.py, which scans cloned govbot dataset repos for bills in either format — govbot’s OCD-files layout (**/bills/<ID>/metadata.json) or raw OpenStates scraper output (_data/<locale>/bill_<uuid>.json) — and joins topic tags from govbot tag output (tags/*.tag.json).

On every Pages deploy (and on a daily 8am UTC schedule), the workflow shallow-clones every *-legislation repo from the govbot-openstates-scrapers organization and rebuilds data.json from all of them, so the published dashboard covers every tracked jurisdiction. If that step fails, the deploy falls back to the committed sample data rather than breaking the docs site.

The committed sample data is built from the offline mocks (actions/govbot/mocks/govbot_data — Wyoming and Guam), with demo topics derived from the keyword definitions in scripts/dashboard_tags.json (the same shape as the tags: section of govbot.yml, keyword-only mode):

python3 scripts/build_dashboard_data.py \
  --govbot-dir actions/govbot/mocks/govbot_data \
  --tags-config scripts/dashboard_tags.json \
  --output docs/src/dashboard/data.json

Regenerating locally with real data

govbot clone all        # clone the dataset repos (~/govbot_data/repos)
govbot tag              # optional: score bills against your govbot.yml tags
python3 scripts/build_dashboard_data.py --output docs/src/dashboard/data.json

When real tags/*.tag.json files exist for a session, they take precedence over the keyword fallback; a bill gets a tag when its final_score meets the tag’s configured threshold. Commit the regenerated data.json and the Pages workflow publishes it with the rest of the docs.