import Papa from "papaparse"; export async function loadStackOverflowCSV(path, fetchOptions = {}) { const url = path + (path.includes("?") ? "&" : "?") + "t=" + Date.now(); const res = await fetch(url, fetchOptions); if (!res.ok) throw new Error(`Failed to load CSV: ${res.status} ${res.statusText}`); const text = await res.text(); const { data } = Papa.parse(text, { header: true, skipEmptyLines: true, transformHeader: (header) => header.trim(), }); return { rows: data.map(normalizeRow) }; } function normalizeRow(r) { const clone = { ...r }; // Normalize numeric fields for Stack Overflow data clone.Age = safeNumber(r.Age); clone.YearsCode = safeNumber(r.YearsCode); clone.YearsCodePro = safeNumber(r.YearsCodePro); clone.ConvertedCompYearly = safeNumber(r.ConvertedCompYearly); clone.WorkWeekHrs = safeNumber(r.WorkWeekHrs); clone.CompTotal = safeNumber(r.CompTotal); // Keep string fields as is clone.Country = r.Country || ""; clone.Gender = r.Gender || ""; clone.EdLevel = r.EdLevel || ""; clone.DevType = r.DevType || ""; clone.RemoteWork = r.RemoteWork || ""; clone.JobSat = r.JobSat || ""; clone.LanguageHaveWorkedWith = r.LanguageHaveWorkedWith || ""; clone.LanguageWantToWorkWith = r.LanguageWantToWorkWith || ""; clone.DatabaseHaveWorkedWith = r.DatabaseHaveWorkedWith || ""; clone.DatabaseWantToWorkWith = r.DatabaseWantToWorkWith || ""; clone.PlatformHaveWorkedWith = r.PlatformHaveWorkedWith || ""; clone.PlatformWantToWorkWith = r.PlatformWantToWorkWith || ""; clone.OrgSize = r.OrgSize || ""; clone.LearnCode = r.LearnCode || ""; clone.AISelect = r.AISelect || ""; clone.AIAccompany = r.AIAccompany || ""; clone.AIWantToWorkWith = r.AIWantToWorkWith || ""; return clone; } function safeNumber(v) { if (v === null || v === undefined || v === "") return 0; const cleaned = String(v).replace(/,/g, "").replace(/\s+/g, "").trim(); // Handle K for thousands if (cleaned.endsWith("K")) { const num = parseFloat(cleaned.slice(0, -1)); return Number.isFinite(num) ? num * 1000 : 0; } const n = Number(cleaned); return Number.isFinite(n) ? n : 0; }