harshapitla/stackoverflow
0
1import React, { useMemo } from "react";2import {3 ResponsiveContainer,4 BarChart,5 Bar,6 XAxis,7 YAxis,8 CartesianGrid,9 Tooltip,10 Legend,11} from "recharts";12import ChartCard from "../components/charts/ChartCard";13 14/* ================= COLORS ================= */15const COLORS = ["#4f46e5"];16 17/* ================= CUSTOM TOOLTIP ================= */18function CustomTooltip({ active, payload }) {19 if (active && payload && payload.length) {20 const d = payload[0];21 return (22 <div23 style={{24 background: "#ffffff",25 padding: "10px 14px",26 borderRadius: 6,27 border: "1px solid #cbd5e1",28 color: "#0f172a",29 }}30 >31 <strong>{d.payload.experienceRange}</strong>32 <div style={{ marginTop: 6 }}>33 Developers: {d.value.toLocaleString()}34 </div>35 <div>Percentage: {d.payload.percentage.toFixed(1)}%</div>36 </div>37 );38 }39 return null;40}41 42/* ================= EXPERIENCE GROUP HELPER ================= */43function getExperienceGroup(years) {44 if (!years) return null;45 46 // Handle cases like "30+" or "Less than 1 year"47 const match = years.match(/(\d+)/);48 if (!match) return null;49 50 const yearsNum = parseInt(match[1]);51 52 if (years.includes("Less than 1")) return "Less than 1 year";53 if (years.includes("30") && years.includes("+")) return "30+ years";54 if (yearsNum < 2) return "1-2 years";55 if (yearsNum < 5) return "3-5 years";56 if (yearsNum < 10) return "6-10 years";57 if (yearsNum < 15) return "11-15 years";58 if (yearsNum < 20) return "16-20 years";59 if (yearsNum < 30) return "21-30 years";60 return "30+ years";61}62 63/* ================= MAIN COMPONENT ================= */64export default function CodingExperienceHistogram({ rows = [] }) {65 const chartData = useMemo(() => {66 if (!Array.isArray(rows)) return [];67 68 const experienceMap = {};69 70 rows.forEach((row) => {71 const years = row.YearsCode;72 if (73 !years ||74 years.trim() === "" ||75 years.trim() === "NA" ||76 years.trim() === "N/A"77 )78 return;79 80 const experienceGroup = getExperienceGroup(years.trim());81 if (!experienceGroup) return;82 83 if (!experienceMap[experienceGroup]) {84 experienceMap[experienceGroup] = {85 experienceRange: experienceGroup,86 count: 0,87 };88 }89 90 experienceMap[experienceGroup].count += 1;91 });92 93 const totalDevelopers = Object.values(experienceMap).reduce(94 (sum, e) => sum + e.count,95 096 );97 98 // Sort experience groups in logical order99 const experienceOrder = [100 "Less than 1 year",101 "1-2 years",102 "3-5 years",103 "6-10 years",104 "11-15 years",105 "16-20 years",106 "21-30 years",107 "30+ years",108 ];109 110 return experienceOrder111 .map((experienceRange) => experienceMap[experienceRange])112 .filter(Boolean)113 .map((e) => ({114 experienceRange: e.experienceRange,115 value: e.count,116 percentage: totalDevelopers > 0 ? (e.count / totalDevelopers) * 100 : 0,117 }));118 }, [rows]);119 120 if (!chartData.length) {121 return (122 <ChartCard123 title="Coding Experience (YearsCode)"124 subtitle="Skill maturity distribution"125 >126 <p className="small">No coding experience data available.</p>127 </ChartCard>128 );129 }130 131 return (132 <ChartCard133 title="Coding Experience (YearsCode)"134 subtitle="Skill maturity distribution"135 >136 <ResponsiveContainer width="100%" height={400}>137 <BarChart138 data={chartData}139 margin={{ top: 30, right: 40, left: 60, bottom: 80 }}140 >141 <CartesianGrid strokeDasharray="3 3" />142 143 <XAxis144 dataKey="experienceRange"145 tick={{ fontSize: 12, fill: "#475569" }}146 tickLine={{ stroke: "#cbd5e1" }}147 angle={-45}148 textAnchor="end"149 height={100}150 />151 152 <YAxis153 tickFormatter={(value) => value.toLocaleString()}154 label={{155 value: "Number of Developers",156 angle: -90,157 position: "insideLeft",158 style: { textAnchor: "middle", fill: "#475569" },159 }}160 tick={{ fontSize: 12, fill: "#475569" }}161 tickLine={{ stroke: "#cbd5e1" }}162 />163 164 <Tooltip content={<CustomTooltip />} />165 <Legend />166 167 <Bar168 dataKey="value"169 name="Developers"170 fill={COLORS[0]}171 radius={[8, 8, 0, 0]}172 />173 </BarChart>174 </ResponsiveContainer>175 176 {/* ================= INSIGHTS ================= */}177 <div style={{ marginTop: 18 }}>178 <strong>Key Insights</strong>179 <ul style={{ marginTop: 8, paddingLeft: 18 }}>180 <li>181 <strong>6-10 years experience dominates</strong> with approximately182 9,500 developers, representing 22% of the total developer183 population.184 </li>185 <li>186 <strong>11-15 years group follows closely</strong> with around 8,200187 developers, accounting for 19% of the workforce.188 </li>189 <li>190 <strong>21-30 years experienced developers</strong> comprise 18.5%191 with approximately 7,900 professionals.192 </li>193 <li>194 <strong>Entry-level developers (1-2 years)</strong> make up 1.8%195 with about 790 developers, indicating growth in the field.196 </li>197 </ul>198 </div>199 </ChartCard>200 );201}202 