Team Ai
Apppublic

harshapitla/github-actions-analytics

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
ContributorUtilizationChart.jsx286 linesDownload Raw Back to charts
1import React, { useMemo } from "react";2import {3  BarChart,4  Bar,5  XAxis,6  YAxis,7  CartesianGrid,8  Tooltip,9  ResponsiveContainer,10  Cell,11  Label,12} from "recharts";13import ChartCard from "../components/charts/ChartCard";14 15function CustomTooltip({ active, payload }) {16  if (active && payload && payload.length) {17    const data = payload[0].payload;18    return (19      <div20        style={{21          background: "rgba(5, 18, 35, 0.9)",22          padding: "8px 12px",23          borderRadius: 6,24          border: "1px solid #334155",25          maxWidth: "350px",26        }}27      >28        <div style={{ marginBottom: 4, fontWeight: "bold" }}>29          {data.action_title}30        </div>31        <div style={{ color: data.verificationColor, fontWeight: "bold" }}>32          {data.isVerified ? "โœ“ Verified" : "โš  Non-Verified"}33        </div>34        <div style={{ color: "#8884d8" }}>35          Contributors: {data.no_of_contributors}36        </div>37        <div style={{ color: "#82ca9d" }}>PRs: {data.no_of_PRs}</div>38        <div style={{ color: "#fbbf24", marginTop: 4 }}>39          Efficiency Ratio: {data.efficiencyRatio}40        </div>41        <div style={{ color: "#f59e0b" }}>42          Stars: {data.no_of_stars.toLocaleString()}43        </div>44        <div style={{ fontSize: 12, color: "#94a3b8", marginTop: 4 }}>45          Publisher: {data.publisher}46        </div>47        {data.tags && (48          <div style={{ fontSize: 12, color: "#94a3b8" }}>49            Tags: {data.tags}50          </div>51        )}52      </div>53    );54  }55  return null;56}57 58export default function ContributorUtilizationChart({ rows = [] }) {59  const utilizationData = useMemo(() => {60    if (!Array.isArray(rows)) return [];61 62    // Filter for valid data63    const validRows = rows.filter((row) => {64      const contributors = parseInt(row.no_of_contributors) || 0;65      const prs = parseInt(row.no_of_PRs) || 0;66      const stars = parseInt(row.no_of_stars) || 0;67      return contributors >= 0 && prs >= 0 && stars >= 0;68    });69 70    const processedData = validRows.map((row) => {71      const contributors = parseInt(row.no_of_contributors) || 0;72      const prs = parseInt(row.no_of_PRs) || 0;73      const stars = parseInt(row.no_of_stars) || 0;74      const isVerified =75        String(row.is_action_verified).toLowerCase() === "true";76 77      // Calculate efficiency ratio: PRs per contributor78      const efficiencyRatio =79        contributors > 0 ? Math.round((prs / contributors) * 10) / 10 : 0;80 81      const verificationColor = isVerified ? "#10b981" : "#f59e0b";82 83      return {84        no_of_contributors: contributors,85        no_of_PRs: prs,86        no_of_stars: stars,87        efficiencyRatio,88        isVerified,89        verificationColor,90        action_title: row.action_title || row.name || "Unknown Action",91        publisher: row.publisher || "(unknown)",92        tags: row.tags || "",93      };94    });95 96    // Filter for actions with at least 1 contributor and sort by efficiency ratio descending97    const efficientActions = processedData98      .filter((action) => action.no_of_contributors >= 1)99      .sort((a, b) => b.efficiencyRatio - a.efficiencyRatio)100      .slice(0, 10); // Top 10 most efficient actions101 102    return efficientActions;103  }, [rows]);104 105  if (!utilizationData.length) {106    return (107      <ChartCard108        title="Top Contributor Utilization Efficiency"109        subtitle="Actions with highest PR-to-contributor ratios"110      >111        <p className="small">112          No valid data found for contributor utilization analysis.113        </p>114      </ChartCard>115    );116  }117 118  return (119    <ChartCard120      title="Top Contributor Utilization Efficiency"121      subtitle="Actions with highest PR-to-contributor ratios"122    >123      <div style={{ height: 500 }}>124        <ResponsiveContainer>125          <BarChart126            data={utilizationData}127            layout="horizontal"128            margin={{ top: 20, right: 30, left: 150, bottom: 20 }}129          >130            <CartesianGrid strokeDasharray="3 3" stroke="#334155" />131            <XAxis132              type="number"133              domain={[0, "dataMax"]}134              tick={{ fill: "#94a3b8", fontSize: 12 }}135            >136              <Label137                value="Efficiency Ratio (PRs per Contributor)"138                offset={-5}139                position="insideBottom"140                fill="#94a3b8"141              />142            </XAxis>143            <YAxis144              type="category"145              dataKey="action_title"146              tick={{ fill: "#94a3b8", fontSize: 11 }}147              width={140}148            />149            <Tooltip content={<CustomTooltip />} />150 151            <Bar dataKey="efficiencyRatio" radius={[0, 4, 4, 0]}>152              {utilizationData.map((entry, index) => (153                <Cell154                  key={`cell-${index}`}155                  fill={entry.verificationColor}156                  fillOpacity={0.8}157                />158              ))}159            </Bar>160          </BarChart>161        </ResponsiveContainer>162      </div>163 164      <div style={{ marginTop: 20, fontSize: 14, color: "#94a3b8" }}>165        <div166          style={{167            display: "grid",168            gridTemplateColumns: "1fr 1fr",169            gap: "12px",170            marginBottom: 16,171          }}172        >173          <div174            style={{175              textAlign: "center",176              padding: "10px",177              backgroundColor: "rgba(16, 185, 129, 0.1)",178              borderRadius: "6px",179            }}180          >181            <div182              style={{183                width: 12,184                height: 12,185                backgroundColor: "#10b981",186                borderRadius: "50%",187                margin: "0 auto 6px",188                border: "2px solid white",189              }}190            ></div>191            <div style={{ fontWeight: "bold", color: "#10b981", fontSize: 12 }}>192              Verified Actions193            </div>194            <div style={{ fontSize: 11 }}>Official verification badge</div>195          </div>196 197          <div198            style={{199              textAlign: "center",200              padding: "10px",201              backgroundColor: "rgba(245, 158, 11, 0.1)",202              borderRadius: "6px",203            }}204          >205            <div206              style={{207                width: 12,208                height: 12,209                backgroundColor: "#f59e0b",210                borderRadius: "50%",211                margin: "0 auto 6px",212                border: "2px solid white",213              }}214            ></div>215            <div style={{ fontWeight: "bold", color: "#f59e0b", fontSize: 12 }}>216              Non-Verified Actions217            </div>218            <div style={{ fontSize: 11 }}>Community maintained</div>219          </div>220        </div>221 222        <div223          style={{224            display: "grid",225            gridTemplateColumns: "1fr 1fr",226            gap: "12px",227            marginBottom: 16,228          }}229        >230          <div231            style={{232              textAlign: "center",233              padding: "10px",234              backgroundColor: "rgba(16, 185, 129, 0.1)",235              borderRadius: "6px",236            }}237          >238            <div style={{ fontSize: 18, marginBottom: 8 }}>๐Ÿ“ˆ</div>239            <div style={{ fontWeight: "bold", color: "#10b981", fontSize: 12 }}>240              High Efficiency241            </div>242            <div style={{ fontSize: 11 }}>243              Contributors producing many PRs - healthy collaboration244            </div>245          </div>246 247          <div248            style={{249              textAlign: "center",250              padding: "10px",251              backgroundColor: "rgba(239, 68, 68, 0.1)",252              borderRadius: "6px",253            }}254          >255            <div style={{ fontSize: 18, marginBottom: 8 }}>๐Ÿ˜</div>256            <div style={{ fontWeight: "bold", color: "#ef4444", fontSize: 12 }}>257              Low Efficiency258            </div>259            <div style={{ fontSize: 11 }}>260              Contributors producing few PRs - potential bottlenecks261            </div>262          </div>263        </div>264 265        <div266          style={{267            textAlign: "center",268            fontSize: 12,269            borderTop: "1px solid #334155",270            paddingTop: 12,271          }}272        >273          <p>274            <strong>Efficiency Ratio:</strong> PRs รท Contributors275            <br />276            <em>277              Showing top 10 most efficient actions โ€ข Higher ratios indicate278              better contributor utilization279            </em>280          </p>281        </div>282      </div>283    </ChartCard>284  );285}286