3D Scatter Plot

3D Plot Controls

Your 3D plot will be displayed here

Enter your data and click "Generate Plot" to begin.

Error: Charting libraries could not be loaded. Please refresh.

`; return; } // --- Event Listeners --- plotBtn.addEventListener('click', generatePlot); pdfBtn.addEventListener('click', generatePdf); // Initial plot on load with example data generatePlot(); // --- Core Functions --- function parseData() { const lines = dataInput.value.split('\n').filter(line => line.trim() !== '' && !line.trim().startsWith('#')); const data = { x: [], y: [], z: [], raw: [] }; lines.forEach(line => { const parts = line.split(',').map(val => parseFloat(val.trim())); if (parts.length === 3 && !parts.some(isNaN)) { data.x.push(parts[0]); data.y.push(parts[1]); data.z.push(parts[2]); data.raw.push(parts); } }); return data; } function generatePlot() { const data = parseData(); if (data.x.length === 0) { alert('No valid data found. Please ensure data is in X,Y,Z format.'); return; } placeholder.style.display = 'none'; const trace = { x: data.x, y: data.y, z: data.z, mode: 'markers', type: 'scatter3d', marker: { color: colorInput.value, size: parseInt(sizeInput.value, 10), }, hoverinfo: 'x+y+z', hovertemplate: `${xLabelInput.value}: %{x}
${yLabelInput.value}: %{y}
${zLabelInput.value}: %{z}` }; const layout = { title: { text: titleInput.value, font: { family: 'Roboto, sans-serif', size: 20 } }, scene: { xaxis: { title: xLabelInput.value }, yaxis: { title: yLabelInput.value }, zaxis: { title: zLabelInput.value } }, margin: { l: 0, r: 0, b: 0, t: 40 } }; Plotly.newPlot(plotArea, [trace], layout, { responsive: true }); pdfBtn.disabled = false; } async function generatePdf() { pdfBtn.textContent = 'Generating PDF...'; pdfBtn.disabled = true; const { jsPDF } = window.jspdf; const doc = new jsPDF('p', 'mm', 'a4'); const primaryColor = getComputedStyle(document.documentElement).getPropertyValue('--plot-primary-color').trim(); // --- Page 1: Plot Image --- doc.setFontSize(22); doc.setFont('helvetica', 'bold'); doc.setTextColor(primaryColor); doc.text('3D Scatter Plot Report', doc.internal.pageSize.getWidth() / 2, 20, { align: 'center' }); doc.setFontSize(14); doc.setFont('helvetica', 'normal'); doc.setTextColor('#333333'); doc.text(titleInput.value, doc.internal.pageSize.getWidth() / 2, 30, { align: 'center' }); try { const imgData = await Plotly.toImage(plotArea, { format: 'png', width: 800, height: 600 }); doc.addImage(imgData, 'PNG', 15, 40, 180, 135); } catch(e) { console.error("PDF Image generation failed:", e); doc.text("Could not generate plot image.", 15, 60); } // --- Page 2: Data Table --- doc.addPage(); doc.setFontSize(18); doc.setFont('helvetica', 'bold'); doc.setTextColor(primaryColor); doc.text('Raw Data Table', doc.internal.pageSize.getWidth() / 2, 20, { align: 'center' }); const data = parseData(); const tableHeaders = [xLabelInput.value, yLabelInput.value, zLabelInput.value]; doc.autoTable({ head: [tableHeaders], body: data.raw, startY: 30, theme: 'grid', headStyles: { fillColor: primaryColor, textColor: '#ffffff', fontStyle: 'bold' }, styles: { font: 'Roboto', cellPadding: 3, fontSize: 10 } }); doc.save(`${titleInput.value.replace(/ /g, '_')}_Report.pdf`); pdfBtn.textContent = 'Download PDF Report'; pdfBtn.disabled = false; } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', setupScatterPlotter); } else { setupScatterPlotter(); }
Scroll to Top