Interactive Venn Diagram Creator

Diagram (Counts)

Please enter elements into the sets to generate a diagram.

"; } else { // Handle cases like fully disjoint sets if venn.js didn't draw anything diagramDiv.innerHTML = "

Diagram could not be drawn (sets might be disjoint or empty). See element breakdown below.

"; } // --- 5. Display Textual Results --- let resultsHTML = ''; const addResultLine = (label, setData) => { const elements = [...setData]; resultsHTML += `
${label}: (${elements.length}) ${elements.length > 0 ? elements.join(', ') : '(empty)'}
`; }; if (numSets === 2) { addResultLine(`Elements only in ${nameA}`, results.A_only); addResultLine(`Elements only in ${nameB}`, results.B_only); addResultLine(`Elements in ${nameA} and ${nameB}`, results.A_B); } else { addResultLine(`Elements only in ${nameA}`, results.A_only); addResultLine(`Elements only in ${nameB}`, results.B_only); addResultLine(`Elements only in ${nameC}`, results.C_only); addResultLine(`Elements in ${nameA} and ${nameB} (but not ${nameC})`, results.A_B_only); addResultLine(`Elements in ${nameA} and ${nameC} (but not ${nameB})`, results.A_C_only); addResultLine(`Elements in ${nameB} and ${nameC} (but not ${nameA})`, results.B_C_only); addResultLine(`Elements in ${nameA}, ${nameB}, and ${nameC}`, results.A_B_C); } listResultsContainer.innerHTML = resultsHTML; resultsListDiv.style.display = 'block'; // --- 6. Enable PDF Download --- currentResults = results; // Save for PDF downloadBtn.style.display = 'block'; } catch (error) { console.error("Error generating Venn Diagram:", error); displayError("An error occurred: " + error.message); } }); // --- PDF Generation --- downloadBtn.addEventListener('click', () => { if (!currentResults || typeof jspdf === 'undefined') { alert("Please generate a diagram first, or jsPDF library is not loaded."); return; } try { const { jsPDF } = window.jspdf; const doc = new jsPDF(); const computedStyle = getComputedStyle(creatorDiv); const primaryColor = computedStyle.getPropertyValue('--vdc-primary-color').trim(); const textColor = computedStyle.getPropertyValue('--vdc-text-color').trim(); const secondaryColor = computedStyle.getPropertyValue('--vdc-secondary-color').trim(); let yPos = 20; const lineSpacing = 7; // Smaller spacing for lists const sectionSpacing = 12; const indent = 15; const pageWidth = doc.internal.pageSize.getWidth(); const wrapWidth = pageWidth - indent * 2; // Title doc.setFontSize(18); doc.setTextColor(primaryColor); doc.text("Venn Diagram Analysis Results", pageWidth / 2, yPos, { align: 'center' }); yPos += sectionSpacing; // Input Sets doc.setFontSize(14); doc.setTextColor(textColor); doc.text("Input Sets:", indent, yPos); yPos += lineSpacing * 1.5; doc.setFontSize(11); doc.setFont(undefined, 'bold'); doc.text(`${currentResults.nameA}:`, indent, yPos); doc.setFont(undefined, 'normal'); let elementsText = currentResults.rawSetA.length > 0 ? currentResults.rawSetA.join(', ') : '(empty)'; let lines = doc.splitTextToSize(elementsText, wrapWidth - 30); // Adjust width for label doc.text(lines, indent + 30, yPos); yPos += lines.length * lineSpacing; doc.setFont(undefined, 'bold'); doc.text(`${currentResults.nameB}:`, indent, yPos); doc.setFont(undefined, 'normal'); elementsText = currentResults.rawSetB.length > 0 ? currentResults.rawSetB.join(', ') : '(empty)'; lines = doc.splitTextToSize(elementsText, wrapWidth - 30); doc.text(lines, indent + 30, yPos); yPos += lines.length * lineSpacing; if (numSets === 3 && currentResults.nameC) { doc.setFont(undefined, 'bold'); doc.text(`${currentResults.nameC}:`, indent, yPos); doc.setFont(undefined, 'normal'); elementsText = currentResults.rawSetC.length > 0 ? currentResults.rawSetC.join(', ') : '(empty)'; lines = doc.splitTextToSize(elementsText, wrapWidth - 30); doc.text(lines, indent + 30, yPos); yPos += lines.length * lineSpacing; } yPos += sectionSpacing / 2; // Space before breakdown // Element Breakdown Section doc.setFontSize(14); doc.setTextColor(textColor); doc.text("Element Breakdown:", indent, yPos); yPos += lineSpacing * 1.5; doc.setFontSize(10); // Smaller font for the list const addPdfLine = (label, setData) => { if (yPos > doc.internal.pageSize.getHeight() - 20) { // Add new page if needed doc.addPage(); yPos = 20; } const elements = [...setData]; const count = elements.length; doc.setFont(undefined, 'bold'); doc.text(`${label}: (${count})`, indent, yPos); yPos += lineSpacing; doc.setFont(undefined, 'normal'); if (count > 0) { let elementListStr = elements.join(', '); let elementLines = doc.splitTextToSize(elementListStr, wrapWidth - 5); // Indent slightly doc.setTextColor(secondaryColor); // Use secondary color for elements doc.text(elementLines, indent + 5, yPos); doc.setTextColor(textColor); // Reset text color yPos += elementLines.length * (lineSpacing - 1); // Slightly tighter spacing for list items } else { doc.setTextColor(secondaryColor); doc.text('(empty)', indent + 5, yPos); doc.setTextColor(textColor); yPos += lineSpacing - 1; } yPos += 3; // Small gap between items }; // Generate lines based on numSets if (numSets === 2) { addPdfLine(`Only in ${currentResults.nameA}`, currentResults.A_only); addPdfLine(`Only in ${currentResults.nameB}`, currentResults.B_only); addPdfLine(`In ${currentResults.nameA} and ${currentResults.nameB}`, currentResults.A_B); } else { addPdfLine(`Only in ${currentResults.nameA}`, currentResults.A_only); addPdfLine(`Only in ${currentResults.nameB}`, currentResults.B_only); addPdfLine(`Only in ${currentResults.nameC}`, currentResults.C_only); addPdfLine(`In ${currentResults.nameA} & ${currentResults.nameB} (not ${currentResults.nameC})`, currentResults.A_B_only); addPdfLine(`In ${currentResults.nameA} & ${currentResults.nameC} (not ${currentResults.nameB})`, currentResults.A_C_only); addPdfLine(`In ${currentResults.nameB} & ${currentResults.nameC} (not ${currentResults.nameA})`, currentResults.B_C_only); addPdfLine(`In ${currentResults.nameA} & ${currentResults.nameB} & ${currentResults.nameC}`, currentResults.A_B_C); } // Footer (Optional) const pageCount = doc.internal.getNumberOfPages(); for (let i = 1; i <= pageCount; i++) { doc.setPage(i); const footerY = doc.internal.pageSize.getHeight() - 10; doc.setFontSize(9); doc.setTextColor(secondaryColor); doc.text(`Page ${i} of ${pageCount}`, pageWidth / 2, footerY, { align: 'center' }); doc.text(`Generated: ${new Date().toLocaleString()}`, indent, footerY); } // Save PDF doc.save('venn-diagram-analysis.pdf'); } catch (error) { console.error("Error generating PDF:", error); alert("An error occurred while generating the PDF. Check console."); } }); })(); // End IIFE
Scroll to Top