// components/DemographicAnalysis.jsx - Complete Updated File "use client"; import React, { useState, useMemo, useEffect, useRef } from "react"; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip as RechartsTooltip, Legend, ResponsiveContainer, Cell, LabelList, } from "recharts"; import { getSignificanceIndicator, formatDisplayKey, getMetricTooltip, } from "../lib/utils"; // Adjust path as needed import { Tooltip } from "./Tooltip"; // Your custom Tooltip component // Helper component for info tooltips with fixed positioning const InfoTooltip = ({ text }) => { const [isVisible, setIsVisible] = useState(false); const [position, setPosition] = useState({ top: 0, left: 0 }); const buttonRef = useRef(null); // Update position when tooltip becomes visible useEffect(() => { if (isVisible && buttonRef.current) { const rect = buttonRef.current.getBoundingClientRect(); setPosition({ top: rect.top - 10, // Position above the icon with a small gap left: rect.left + 12, // Center with the icon }); } }, [isVisible]); return (
{label}
{sortedPayload.map((entry, index) => ({data.model}
Select a metric to view analysis.
)} {currentMetricDisplayKeys.length === 0 && (No {metricLevel} metrics available.
)}{!selectedDemographicFactor ? "Please select a demographic factor." : !selectedMetricDisplayKey ? "Please select a metric." : "No score data found."}
{!selectedDemographicFactor ? "Select factor." : !selectedMetricDisplayKey ? "Select metric." : "No equity gaps found."}
Chart ranks models by equity gap size (lower is better).
)}Rank | Model | Equity Gap | Effect Size | Significance | Concern? | Lowest Group (Score) | Highest Group (Score) |
---|---|---|---|---|---|---|---|
{gap.rank} |
{gap.model}
|
{/* Equity Gap as plain text */} {gap.gap !== undefined && gap.gap !== null ? gap.gap.toFixed(1) : "N/A"} |
{gap.effect_size !== undefined &&
gap.effect_size !== null ? (
{gap.effect_size_class || "N/A"}
) : (
N/A
)}
|
{gap.is_statistically_significant ? (
Significant ✔
) : (
Not Significant ✘
)}
{gap.p_value !== undefined && gap.p_value !== null
? formatPValue(gap.p_value)
: ""}
|
{gap.is_equity_concern ? "Yes" : "No"} |
{gap.min_level ? (
{gap.min_level}
{minScoreDisplay}
) : (
-
)}
|
{gap.max_level ? (
{gap.max_level}
{maxScoreDisplay}
) : (
-
)}
|
Rank: Based on lowest Equity Gap value for this metric/factor
Equity Gap: Score difference (0-100 points) between highest and lowest scoring groups
Effect Size: Gap magnitude relative to score variation (hover for details)
Significance:Whether the gap is statistically significant after adjusting for multiple tests (Benjamini-Hochberg FDR correction, q<0.05)
Concern?: 'Yes' flags potential equity concerns (Large Effect Size AND Statistically Significant)