harshapitla/github-actions-analytics
0
1import React, { useMemo } from "react";2import {3 ScatterChart,4 Scatter,5 XAxis,6 YAxis,7 CartesianGrid,8 Tooltip,9 ResponsiveContainer,10 ReferenceLine,11} from "recharts";12import ChartCard from "../components/charts/ChartCard";13 14/* ---------- Tooltip ---------- */15function CustomTooltip({ active, payload }) {16 if (active && payload && payload.length) {17 const d = payload[0].payload;18 return (19 <div20 style={{21 background: "#ffffff",22 padding: "8px 12px",23 borderRadius: 6,24 border: "1px solid #334155",25 fontSize: 12,26 maxWidth: 260,27 }}28 >29 <div style={{ fontWeight: "bold", marginBottom: 6 }}>30 {d.action_title}31 </div>32 <div>33 ๐ Open Issues: <strong>{d.no_of_open_issues}</strong>34 </div>35 <div>36 ๐ Open Pull Requests: <strong>{d.no_of_PRs}</strong>37 </div>38 </div>39 );40 }41 return null;42}43 44/* ---------- Chart ---------- */45export default function IssueResolutionBalanceChart({ rows = [] }) {46 const data = useMemo(() => {47 if (!Array.isArray(rows)) return [];48 49 return rows50 .map((row) => ({51 action_title: row.action_title || "Unknown Action",52 no_of_open_issues: Number(row.no_of_open_issues) || 0,53 no_of_PRs: Number(row.no_of_PRs) || 0,54 }))55 .filter((r) => r.no_of_open_issues > 0 || r.no_of_PRs > 0)56 .slice(0, 300); // safety cap for performance57 }, [rows]);58 59 if (!data.length) {60 return (61 <ChartCard62 title="Issue Resolution Balance"63 subtitle="No issue or pull request activity found"64 >65 <p className="small">Nothing to analyze for maintenance balance.</p>66 </ChartCard>67 );68 }69 70 return (71 <ChartCard72 title="Issue Resolution Balance"73 subtitle="Are maintainers keeping pace with incoming issues?"74 >75 <div style={{ height: 520 }}>76 <ResponsiveContainer>77 <ScatterChart margin={{ top: 20, right: 30, bottom: 60, left: 70 }}>78 <CartesianGrid strokeDasharray="3 3" stroke="#e2e8f0" />79 80 <XAxis81 type="number"82 dataKey="no_of_open_issues"83 tick={{ fill: "#475569", fontSize: 12 }}84 label={{85 value: "Open Issues",86 position: "insideBottom",87 offset: -10,88 fill: "#475569",89 }}90 />91 92 <YAxis93 type="number"94 dataKey="no_of_PRs"95 tick={{ fill: "#475569", fontSize: 12 }}96 label={{97 value: "Open Pull Requests",98 angle: -90,99 position: "insideLeft",100 fill: "#475569",101 }}102 />103 104 {/* Balance reference */}105 <ReferenceLine106 y={10}107 stroke="#94a3b8"108 strokeDasharray="4 4"109 label={{110 value: "Active maintenance zone",111 position: "right",112 fill: "#64748b",113 fontSize: 11,114 }}115 />116 117 <Tooltip content={<CustomTooltip />} />118 119 <Scatter data={data} fill="#60a5fa" fillOpacity={0.65} />120 </ScatterChart>121 </ResponsiveContainer>122 </div>123 124 <div125 style={{126 marginTop: 12,127 fontSize: 12,128 color: "#64748b",129 textAlign: "center",130 borderTop: "1px solid #e2e8f0",131 paddingTop: 10,132 }}133 >134 <p>135 Actions with many open issues but few pull requests show growing136 maintenance backlog and risk of maintainer overload.137 </p>138 </div>139 </ChartCard>140 );141}142 