UNPKG

edeap

Version:

Euler Diagrams Drawn with Ellipses Area-Proportionally (Edeap)

77 lines (76 loc) 2.52 kB
export function parse(str) { return str .trim() .split("\n") .map((row) => { const sets = row.trim().split(/\s+/); const size = parseFloat(sets.pop()); return { sets, size }; }); } export function check(sets, silent = true) { const seenBefore = new Set(); return sets .filter((row) => { const test = row.sets.length > 0; if (!test && !silent) throw new Error("Each row need to contain at least 2 elements"); return test; }) .filter((row) => { const proportion = row.size; const test = !isNaN(proportion) && proportion > 0; if (!test && !silent) throw new Error("Set proportion suppose to be positive"); return test; }) .filter((row) => { const combination = row.sets; const combinationUnique = [...new Set(combination)]; const test1 = combination.length === combinationUnique.length; if (!test1 && !silent) throw new Error("Duplicates in combination"); if (!test1) return test1; const key = combinationUnique.join(" "); const test2 = !seenBefore.has(key); seenBefore.add(key); if (!test2 && !silent) throw new Error("Duplicate combinations"); return test2; }); } export function transform(sets) { const contours = new Set(); const zones = []; const proportions = []; sets.forEach((row) => { const zone = row.sets; const proportion = row.size; zone.forEach((contour) => contours.add(contour)); zones.push(zone); proportions.push(proportion); }); return { contours: [...contours].sort(), zones, proportions, }; } export function calculateInitial(sets) { const totalArea = sets.proportions.reduce((acc, x) => acc + x, 0); const scalingValue = 1 / totalArea; const proportions = sets.proportions.map((x) => x * scalingValue); const contoursIndex = Object.fromEntries(sets.contours.map((value, index) => [value, index])); const contourAreas = sets.contours.map(() => 0); sets.zones.forEach((zone, i) => zone.forEach((contour) => { const j = contoursIndex[contour]; contourAreas[j] += proportions[i]; })); return { originalProportions: [...sets.proportions], proportions, contourAreas, zoneStrings: sets.zones.map((zone) => [...zone].sort().toString()), }; }