import { useState } from 'react' /** * Chart 6: Probability the district exceeds the national rate for each student group. * Uses posterior draws (approximated via interval bounds + median) to compute * P(district_rate > national_rate) per race×sex group. */ export default function ExceedanceProbability({ rateByGroup, nationalRates }) { const [selectedModel, setSelectedModel] = useState('unified_m2_mod') // Compute exceedance probability for each group using normal approximation: // P(district_rate > national) ≈ Φ((modeled_median - national) / modeled_sd) // where sd is derived from the interval width (upper - lower) / (2 * z_{0.95}) const computed = rateByGroup.map(d => { const natKey = `${d.race}_${d.sex}` const nationalRate = nationalRates[natKey] || 0 // Use modeled median and interval from the estimate data if available // (rate_median is per student; multiply by 1000 for per-1k) const modeledMedianPerK = ((d.modeledRateMedian || d.observedRate * (d.enroll || 1) / 1000)) // Actually: rate_median is already a probability (per-student). Convert to per-1k. const modeledRatePerK = ((d.rate_median || 0) * 1000) || d.observedRate // Derive SD from interval width if available, else use observed as proxy const lowerPerK = ((d.rate_lower || 0) * 1000) || (modeledRatePerK * 0.7) const upperPerK = ((d.rate_upper || 0) * 1000) || (modeledRatePerK * 1.3) // sd ≈ (upper - lower) / (2 * 1.645) for a 90% interval under normality const modeledSd = Math.max((upperPerK - lowerPerK) / 3.29, 0.05) // P(district > national) using normal CDF approximation const z = (modeledRatePerK - nationalRate) / modeledSd const probExceeds = normalCDF(z) return { ...d, natKey, nationalRate, modeledRate: modeledRatePerK, modeledSd, probExceeds: Math.max(0.01, Math.min(0.99, probExceeds)), // clamp to avoid extremes } }).sort((a, b) => b.probExceeds - a.probExceeds) const width = 400 const height = 320 const margin = { top: 50, right: 100, bottom: 90, left: 70 } const innerWidth = width - margin.left - margin.right return (
Based on the {selectedModel === 'unified_m2_mod' ? 'one-year + covariate model (recommended)' : 'three-year + covariate model'}, which balances precision with current-year data. Green bars indicate groups where this district's rate is unlikely to exceed the national average; red indicates likely exceedance.