Commit Graph
27 Commits
Author SHA1 Message Date
jaredandClaude Sonnet 5 cf8e65bb8e Fix chart bugs found on deployed site, redesign Chart 2 as box-and-whisker
Deploy to git-pages / deploy (push) Successful in 12s
Chart 4 (model predictions vs. observed) was picking the first row for a
given wave/model instead of summing across selected groups, so any district
whose first-returned group had zero counts (e.g. a suppressed race group)
showed a collapsed, flat modeled marker instead of the real aggregate
interval. Also fixes the rightmost wave label ("2021-22") clipping off the
edge of the small-multiple panels by anchoring edge ticks away from the
viewBox boundary instead of centering on it.

Chart 6's y-axis group labels (e.g. "American Indian / Alaska Native
Female") were wider than their margin and clipped past the left edge of the
SVG. Adds a shared shortGroupLabel() to colors.js and uses it here, matching
the convention already used in charts 2 and 5.

Chart 2 previously drew a plain bar to the modeled median next to an
observed diamond that often sat well past the bar's end, reading as if the
bar itself were an uncertainty range when it wasn't. Replaces it with an
actual horizontal box-and-whisker: whisker = the API's reported 90%
interval, box = the fitted approximation's 25th/75th percentiles (via a new
fit.quantile() inverse-CDF, exact round-trip of fitSkewedInterval's own
construction), median tick, observed diamond overlaid.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 18:58:35 -04:00
jaredandClaude Sonnet 5 67caa02fe2 Redesign chart visualizations to match Civilytics white-paper style
Deploy to git-pages / deploy (push) Successful in 18s
Rebuilds all 6 charts around a validated categorical race palette, row-based
sex encoding, and a consistent observed-vs-modeled mark convention (diamond
vs. filled bar/density) instead of ad hoc per-chart color schemes. Adds a
shared student-group filter (defaults to all 8 groups) that scopes every
chart's data from one place in ChartPanel.

Drops the D3 dependency entirely in favor of plain SVG, removing the
imperative-DOM bug class behind this app's repeated "fix the fix" commits.
Replaces the fake symmetric-normal posterior approximation with a skewed,
median-preserving fit to the API's interval bounds, clearly labeled as an
approximation. Fixes two broken SVG fill attributes, a decorative model
dropdown that never affected its chart, dead code, an orphaned component,
and a broken CSS token reference.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 18:45:37 -04:00
jared 6c8e1e8409 docs: refresh AGENTS.md, HANDOFF.md, and README with recent work
- Create AGENTS.md: comprehensive agent guide covering architecture,
  data flow, error bar convention (90% intervals), D3 usage patterns,
  null safety pitfalls, deployment checklist, and related repos
- Update HANDOFF.md: mark CORS as resolved, document chart improvements
  (Chart 5 ridgeline rewrite with synthetic draws + smooth rendering)
- Refresh README.md: accurate tech stack (D3 v7), updated file structure
  with new chart files, corrected API endpoint table
2026-08-10 17:10:35 -04:00
jared 3fe004356e Fix ridgeline chart to render smooth density curves instead of individual columns
Deploy to git-pages / deploy (push) Successful in 13s
- Rewrite RateDensityRidgeline.jsx with proper histogram-to-density conversion
- Build top-edge points from binned draws, then smooth with d3.curveBasis
- Construct complete area path: bottom edge + smoothed top + close
- Position observed rate diamonds above the ridge peak
2026-08-10 17:05:38 -04:00
jared fc0b7e9b6d Fix: remove broken .replace() call causing TypeError in RateDensityRidgeline
Deploy to git-pages / deploy (push) Successful in 12s
2026-08-10 16:56:29 -04:00
jared c32aa46f7c Fix: null check before accessing modelDraws[q.key]
Deploy to git-pages / deploy (push) Successful in 12s
2026-08-10 16:51:53 -04:00
jared c64682228d Fix: null checks for quadData in ChartPanel and child components
Deploy to git-pages / deploy (push) Successful in 14s
2026-08-10 16:43:30 -04:00
jared 83417368f2 Fix: handle null modelDraws gracefully
Deploy to git-pages / deploy (push) Successful in 13s
2026-08-10 16:37:40 -04:00
jared be647d0882 Fix: remove draws fetch (API endpoint not available for browser)
Deploy to git-pages / deploy (push) Successful in 12s
The /estimates/{leaid}/draws endpoint doesn't exist - only bulk Parquet
shard access is available. Falls back to interval-based rendering.
2026-08-10 16:32:40 -04:00
jared 54814564a9 Hook up raw posterior draws from API to ModelDrawsComparison
Deploy to git-pages / deploy (push) Successful in 11s
- Add fetchDistrictDraws call in ChartPanel for all 4 quadrant models
- Pass modelDraws to ModelDrawsComparison component
- Rewrite Chart 4 with D3 showing:
  - Density histogram from raw draws when available (per-year distribution)
  - Fall back to interval-based rendering otherwise
  - 90% credible intervals from quantile calculation
  - Legend explaining colors (red=observed, teal=one-year, navy=three-year)
2026-08-10 16:27:47 -04:00
jared f65a70fc3e Add D3 and new ridgeline chart matching R aesthetic
Deploy to git-pages / deploy (push) Successful in 19s
- Install d3@7
- Add fetchDistrictDraws API function (for future use with raw draws)
- Create RateDensityRidgeline component using D3.js
  - Density ridges showing posterior distributions per race group
  - Diamond markers for observed rates (matching R design)
  - Dropdown to switch between model specifications
  - Matches Civilytics color palette (navy fill, danger diamonds)
2026-08-10 16:15:33 -04:00
jared c4c0aa63bd Use three-year model (unified_m3_mod) to fetch observed data for all waves
Deploy to git-pages / deploy (push) Successful in 11s
One-year models don't return historical arrest data; three-year models
include observed counts across all CRDC waves (15-16, 17-18, 21-22).
2026-08-10 13:19:39 -04:00
jared 0fa5844a16 Replace logo with Civilytics wordmark from civilyticsR package
Deploy to git-pages / deploy (push) Successful in 11s
2026-08-10 12:54:55 -04:00
jared b135f480c0 Fix chart sizing, model predictions, 90% intervals, and deep link district name
Deploy to git-pages / deploy (push) Successful in 17s
- Increase SVG dimensions in all 6 charts to prevent label truncation
- Fix ModelDrawsComparison: pass quadData so predictions render for three-year models
- Change error bars from 95% to 90% (legend text + SD calculation)
- Widen chart viewport: max-width 70rem vs default 60rem text width
- Fix deep link: fetch district name from API instead of showing 'Loading...'
2026-08-10 12:50:19 -04:00
jared eb396abce7 Restore first three charts (ArrestsOverTime, RateByGroupBar, DistrictVsNational) that were accidentally removed in previous edit
Deploy to git-pages / deploy (push) Successful in 11s
2026-08-10 12:27:04 -04:00
jared 77757348f8 Switch ChartPanel from 3-column grid to single vertical stack
Deploy to git-pages / deploy (push) Successful in 10s
Charts and their titles/captions need more horizontal space for readability. Single column layout ensures each chart renders at full container width without cramped side-by-side placement.
2026-08-10 12:25:31 -04:00
jared 26f72da6db Disable source map generation for cleaner production builds
Deploy to git-pages / deploy (push) Successful in 17s
Source maps cause harmless but noisy 404 errors in browser dev tools when deployed to git-pages, since the hashed filenames change between local and CI builds. Disabling them eliminates these warnings without affecting app functionality.
2026-08-10 12:23:27 -04:00
jared dd69bb6f8f Fix JS syntax error in ObservedRateDensity.jsx — const declarations were embedded inside JSX
Deploy to git-pages / deploy (push) Successful in 11s
The obsWidth, lowerX, upperWidth, and medX variables were declared inline within the SVG <g> element's children, which is invalid JavaScript/JSX. This caused 'ReferenceError: obsWidth is not defined' at runtime when rendering Chart 5.

Fix: Moved all const declarations to the top of the map callback, before the return statement.
2026-08-10 12:21:00 -04:00
jared 116730b685 Fix national_rates.json deployment — copy to public/ directory
Deploy to git-pages / deploy (push) Successful in 19s
- Add missing data/national_rates.json fixture (was only in src/data/, not served by Vite)
- LoadingAnimation.jsx: Use import.meta.env.BASE_URL for national rates path
- Ensures file is available at /crdc-demo/data/national_rates.json on git-pages
2026-08-10 12:17:42 -04:00
jared 2c900b003f Fix static asset paths for /crdc-demo subdirectory deployment
Deploy to git-pages / deploy (push) Successful in 10s
- App.jsx: Use import.meta.env.BASE_URL prefix for civilytics-logo.svg (was hardcoded as '/civilytics-logo.svg' → 404 on pages.civilytics.org/crdc-demo/)
- ChartPanel.jsx: Same fix for /data/national_rates.json path — was causing JSON.parse errors because the 404 HTML response couldn't be parsed
2026-08-10 11:44:26 -04:00
jared 8ba7440a34 Fix routing, data fetching, and rendering issues in CRDC demo app:
Deploy to git-pages / deploy (push) Successful in 10s
- App.jsx: Fix 'search another district' button href to use /crdc-demo/ instead of / (root)
- LoadingAnimation.jsx: Replace broken inline fetch helper with centralized api client from useApi.js — was bypassing envelope unwrapping ({status:'success',data:[...]}), causing all 43 API calls to fail silently
- ChartPanel.jsx: Same fix — replace raw fetch() calls with api.fetchDistrictEstimates(), fix national_rates.json path (remove hardcoded /crdc-demo/ prefix that breaks in dev), parallelize wave/model fetches with Promise.all for faster loading

Root causes fixed:
1. Navigation button linked to site root instead of app subdirectory → users lost their way after selecting a district
2. Dual API client implementations — inline fetch helpers didn't unwrap the JSON envelope structure, causing data parsing failures that made the page appear stuck on 'Organizing data...'
3. Sequential fetches in ChartPanel caused slow loading; parallelized for better UX
2026-08-10 11:42:31 -04:00
jared c475bfe50b Add handoff notes for CORS deployment fix 2026-08-10 11:27:03 -04:00
jared 4ce64c7839 Fix CORS: add proxy support for browser-based API calls on git-pages
Deploy to git-pages / deploy (push) Successful in 20s
- Add VITE_PROXY_URL env var to route requests through a CORS proxy when
  deployed as static site (CRDC API doesn't send Access-Control-Allow-Origin)
- Update useApi.js, LoadingAnimation.jsx, and ChartPanel.jsx to respect proxy
- Add nginx.conf with /api/v1/ reverse proxy + CORS headers for Docker deployment
- Include proxy.php — simple PHP CORS proxy for git-pages hosts that support PHP
- Document CORS workaround in README

Without this fix, browser fetch() calls are blocked by same-origin policy and
the app shows a blank white screen despite serving correct HTML.
2026-08-10 11:22:44 -04:00
jared 194208d817 Fix base URL for subdirectory deployment on pages.civilytics.org
Deploy to git-pages / deploy (push) Successful in 10s
- Set vite.config.mjs base to '/crdc-demo/' so asset paths resolve correctly
  when served from a subdirectory (not root)
- Add favicon.svg in public/ folder
- Update index.html with correct absolute paths including /crdc-demo/ prefix
2026-08-10 11:13:16 -04:00
jared ff4b2ac690 Update README: document Gitea Actions pages workflow
Replaces the GitHub Actions reference with .gitea/workflows/pages.yml,
following the sln-school-comparison deployment pattern. Documents the
git-pages.civilytics.org/crdc-demo/ URL and token configuration.
2026-08-10 11:08:00 -04:00
jared 7cf9777673 Add Gitea Actions workflow for git-pages deployment
Deploy to git-pages / deploy (push) Successful in 10s
Adapts the sln-school-comparison pattern: builds Vite static site in CI,
then copies dist/ to a pages branch served by the git-pages webhook at
pages.civilytics.org/crdc-demo/
2026-08-10 10:57:00 -04:00
jared 52a0c77e31 Initial commit: CRDC Arrests API demo app
Deploy to Git Pages / build-and-deploy (push) Failing after 19s
React + Vite static site demonstrating the CRDC School Arrest Rate API.
Features 6 interactive charts comparing observed arrest data against Bayesian
model estimates across U.S. school districts, with Civilytics visual identity.

- State selector and district search with 'interesting' suggestions (top arrests)
- Animated histogram loading grid showing posterior draw progress
- Charts: time series, rate by group, district vs national, model comparison quadrants, density proxy, exceedance probability
- Static JSON fixture for national rates (no API changes needed)
- Dockerfile + docker-compose.yml for self-hosted deployment
- GitHub Actions workflow and _config.yml for Git Pages
2026-08-10 10:54:51 -04:00