DataFrame Visualization Tool

DataFrame Visualization Tool

Your DataFrame

View, sort, and visualize your tabular data.

Configure Your Data

Add, edit, and manage your DataFrame rows.

Add/Edit Data Row

ID Category Metric 1 ($) Metric 2 ($) Description Actions

No data available for charting. Add data in "Data Configuration".

'; return; } const selectedColumn = chartColumnSelect.value; if (!selectedColumn) { chartContainer.innerHTML = '

Select a numerical column to visualize.

'; return; } // Filter out rows where the selected metric is null or invalid const chartData = dataframe.filter(d => d[selectedColumn] !== null && !isNaN(d[selectedColumn])); if (chartData.length === 0) { chartContainer.innerHTML = `

No valid data for '${selectedColumn === 'metric1' ? 'Metric 1' : 'Metric 2'}' to chart.

`; return; } const margin = { top: 30, right: 30, bottom: 60, left: 60 }; const width = chartContainer.clientWidth - margin.left - margin.right; const height = chartContainer.clientHeight - margin.top - margin.bottom; const svg = d3.select(chartContainer) .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", `translate(${margin.left},${margin.top})`); // X scale for categories const x = d3.scaleBand() .domain(chartData.map(d => d.category)) .range([0, width]) .padding(0.1); // Y scale const y = d3.scaleLinear() .domain([0, d3.max(chartData, d => d[selectedColumn]) * 1.1]) // 10% buffer .range([height, 0]); // Add X axis svg.append("g") .attr("class", "axis x-axis") .attr("transform", `translate(0,${height})`) .call(d3.axisBottom(x)) .selectAll("text") .style("text-anchor", "end") .attr("dx", "-.8em") .attr("dy", ".15em") .attr("transform", "rotate(-45)"); // Add Y axis svg.append("g") .attr("class", "axis y-axis") .call(d3.axisLeft(y).tickFormat(d3.format("$,.0f"))); // Format as currency // Tooltip const tooltip = d3.select("body").append("div") .attr("class", "chart-tooltip") .style("opacity", 0); // Add bars svg.selectAll(".bar") .data(chartData) .enter().append("rect") .attr("class", "bar") .attr("x", d => x(d.category)) .attr("y", d => y(d[selectedColumn])) .attr("width", x.bandwidth()) .attr("height", d => height - y(d[selectedColumn])) .on("mouseover", function(event, d) { d3.select(this).attr("fill", d3.rgb("steelblue").darker(0.5)); tooltip.transition() .duration(200) .style("opacity", .9); tooltip.html(`Category: ${d.category}
${selectedColumn === 'metric1' ? 'Metric 1' : 'Metric 2'}: $${d[selectedColumn].toLocaleString('en-US')}`) .style("left", (event.pageX + 10) + "px") .style("top", (event.pageY - 28) + "px"); }) .on("mouseout", function(d) { d3.select(this).attr("fill", "steelblue"); tooltip.transition() .duration(500) .style("opacity", 0); }); }; // --- PDF Download Function --- /** * Generates and downloads a PDF of the current dashboard content. */ window.downloadPdf = async function() { if (!dashboardTab) { console.error('Error: Dashboard tab content not found for PDF generation.'); return; } // Temporarily hide elements not needed in PDF const elementsToHide = document.querySelectorAll('.tab-nav, .nav-buttons, #downloadPdfButton, .chart-tooltip'); elementsToHide.forEach(el => el.style.display = 'none'); // Ensure the dashboard tab is active for capture dashboardTab.classList.add('active'); // Use html2canvas to capture the dataframe table const tableCanvas = await html2canvas(document.getElementById('dataframe-table-container'), { scale: 2, // Increase scale for better resolution in PDF useCORS: true, logging: false }); const tableImgData = tableCanvas.toDataURL('image/png'); // Use html2canvas to capture the chart const chartCanvas = await html2canvas(document.getElementById('chart-container'), { scale: 2, // Increase scale for better resolution in PDF useCORS: true, logging: false }); const chartImgData = chartCanvas.toDataURL('image/png'); // Re-show hidden elements immediately after capture elementsToHide.forEach(el => el.style.display = ''); const { jsPDF } = window.jspdf; const pdf = new jsPDF({ orientation: 'portrait', unit: 'px', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); let yOffset = 40; // Add title to PDF pdf.setFontSize(22); pdf.text("DataFrame Visualization Report", pdfWidth / 2, yOffset, { align: 'center' }); yOffset += 20; // Add current date/time to PDF pdf.setFontSize(10); pdf.text(`Generated on: ${new Date().toLocaleString()}`, pdfWidth / 2, yOffset, { align: 'center' }); yOffset += 40; // Add DataFrame Table pdf.setFontSize(18); pdf.text("DataFrame Table", pdfWidth / 2, yOffset, { align: 'center' }); yOffset += 10; const tableImgHeight = (tableCanvas.height * (pdfWidth - 40)) / tableCanvas.width; pdf.addImage(tableImgData, 'PNG', 20, yOffset, pdfWidth - 40, tableImgHeight); yOffset += tableImgHeight + 30; // Add Chart Visualization pdf.setFontSize(18); pdf.text("Chart Visualization", pdfWidth / 2, yOffset, { align: 'center' }); yOffset += 10; const chartImgHeight = (chartCanvas.height * (pdfWidth - 40)) / chartCanvas.width; pdf.addImage(chartImgData, 'PNG', 20, yOffset, pdfWidth - 40, chartImgHeight); yOffset += chartImgHeight + 30; // Add a section for detailed data (tabular format) pdf.addPage(); pdf.setFontSize(18); pdf.text("Detailed Data Table", pdf.internal.pageSize.getWidth() / 2, 40, { align: 'center' }); const tableData = dataframe.map(row => [ row.id, row.category, `$${row.metric1.toLocaleString('en-US')}`, row.metric2 !== null ? `$${row.metric2.toLocaleString('en-US')}` : 'N/A', row.text || 'N/A' ]); pdf.autoTable({ head: [['ID', 'Category', 'Metric 1 ($)', 'Metric 2 ($)', 'Description']], body: tableData, startY: 60, theme: 'grid', styles: { fontSize: 8, cellPadding: 4 }, headStyles: { fillColor: [242, 242, 242], textColor: [51, 51, 51], fontStyle: 'bold' }, alternateRowStyles: { fillColor: [251, 251, 251] }, margin: { top: 70, left: 10, right: 10 } // Adjust margins for more columns }); pdf.save('dataframe_visualization_report.pdf'); }; // --- Event Listeners and Initial Render --- downloadPdfButton.addEventListener('click', downloadPdf); // Initial setup updateConfigDataTable(); renderDataFrameTable(); populateChartColumnSelect(); renderChart(); updateNavigationButtons(); // Set initial button states });
Scroll to Top