harshapitla/github-actions-analytics
0
1import React, { useMemo } from "react";2import {3 BarChart,4 Bar,5 XAxis,6 YAxis,7 CartesianGrid,8 Tooltip,9 ResponsiveContainer,10} from "recharts";11import ChartCard from "../components/charts/ChartCard";12import InsightsBox from "../components/insights/InsightsBox";13 14/* ---------- Tooltip ---------- */15function CustomTooltip({ active, payload, label }) {16 if (active && payload && payload.length) {17 const d = payload[0].payload;18 return (19 <div20 style={{21 background: "#ffffff",22 color: "#0f172a",23 boxShadow: "0 8px 24px rgba(0,0,0,0.15)",24 border: "1px solid #e5e7eb",25 26 padding: "8px 12px",27 borderRadius: 6,28 29 maxWidth: 280,30 }}31 >32 <div style={{ fontWeight: "bold", marginBottom: 6 }}>{label}</div>33 <div style={{ fontSize: 12 }}>34 ⭐ Stars: <strong>{d.no_of_stars}</strong>35 </div>36 <div style={{ fontSize: 12 }}>37 👥 Contributors: <strong>{d.no_of_contributors}</strong>38 </div>39 <div style={{ fontSize: 12, marginTop: 4 }}>40 Stars per Contributor:{" "}41 <strong>{d.starsPerContributor.toFixed(1)}</strong>42 </div>43 </div>44 );45 }46 return null;47}48 49/* ---------- Chart ---------- */50export default function ContributorAdequacyChart({ rows = [] }) {51 const data = useMemo(() => {52 if (!Array.isArray(rows)) return [];53 54 return rows55 .filter(56 (r) =>57 Number(r.no_of_stars) > 500 && // only meaningful popularity58 Number(r.no_of_contributors) > 059 )60 .map((r) => ({61 action_title: r.action_title || "Unknown",62 no_of_stars: Number(r.no_of_stars),63 no_of_contributors: Number(r.no_of_contributors),64 starsPerContributor:65 Number(r.no_of_stars) / Number(r.no_of_contributors),66 }))67 .sort((a, b) => b.starsPerContributor - a.starsPerContributor)68 .slice(0, 15); // Top 15 highest risk69 }, [rows]);70 71 if (!data.length) {72 return (73 <ChartCard74 title="Contributor Adequacy"75 subtitle="No valid contributor data available"76 >77 <p className="small">Unable to compute maintainer load.</p>78 </ChartCard>79 );80 }81 82 return (83 <ChartCard84 title="Contributor Adequacy"85 subtitle="Do popular actions have enough maintainers?"86 >87 <div style={{ height: 520 }}>88 <ResponsiveContainer>89 <BarChart90 data={data}91 layout="vertical"92 margin={{ top: 20, right: 30, left: 220, bottom: 40 }}93 >94 <CartesianGrid strokeDasharray="3 3" stroke="#334155" />95 96 <YAxis97 type="category"98 dataKey="action_title"99 tick={{ fill: "#94a3b8", fontSize: 11 }}100 width={200}101 />102 103 <XAxis104 type="number"105 tick={{ fill: "#94a3b8", fontSize: 12 }}106 label={{107 value: "Stars per Contributor",108 position: "insideBottom",109 offset: -10,110 fill: "#94a3b8",111 }}112 />113 114 <Tooltip content={<CustomTooltip />} />115 116 <Bar117 dataKey="starsPerContributor"118 fill="#f59e0b"119 radius={[0, 6, 6, 0]}120 />121 </BarChart>122 </ResponsiveContainer>123 </div>124 125 <div126 style={{127 marginTop: 12,128 fontSize: 12,129 color: "#94a3b8",130 textAlign: "center",131 borderTop: "1px solid #334155",132 paddingTop: 10,133 }}134 >135 <p>136 Higher values mean fewer maintainers supporting more users, increasing137 bus-factor and burnout risk.138 </p>139 </div>140 <InsightsBox141 points={[142 "Several highly popular actions are maintained by very few contributors.",143 "High stars per contributor indicate increased workload and burnout risk.",144 "Actions with low maintainer support are more vulnerable to abandonment.",145 "A higher number of maintainers improves stability and long-term reliability.",146 ]}147 />148 </ChartCard>149 );150}151 