|
|
|
|
|
let csvData = []; |
|
|
let headers = []; |
|
|
|
|
|
|
|
|
const dropZone = document.getElementById('dropZone'); |
|
|
const csvFileInput = document.getElementById('csvFile'); |
|
|
const previewSection = document.getElementById('previewSection'); |
|
|
const tableHeaders = document.getElementById('tableHeaders'); |
|
|
const tableBody = document.getElementById('tableBody'); |
|
|
const generateVizBtn = document.getElementById('generateViz'); |
|
|
const vizGallery = document.getElementById('vizGallery'); |
|
|
const chartContainer = document.getElementById('chartContainer'); |
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() { |
|
|
initializeEventListeners(); |
|
|
}); |
|
|
|
|
|
function initializeEventListeners() { |
|
|
|
|
|
csvFileInput.addEventListener('change', handleFileSelect); |
|
|
|
|
|
|
|
|
dropZone.addEventListener('dragover', handleDragOver); |
|
|
dropZone.addEventListener('dragleave', handleDragLeave); |
|
|
dropZone.addEventListener('drop', handleDrop); |
|
|
|
|
|
|
|
|
generateVizBtn.addEventListener('click', generateVisualizations); |
|
|
} |
|
|
|
|
|
function handleDragOver(e) { |
|
|
e.preventDefault(); |
|
|
dropZone.classList.add('drop-zone-active'); |
|
|
} |
|
|
|
|
|
function handleDragLeave(e) { |
|
|
e.preventDefault(); |
|
|
dropZone.classList.remove('drop-zone-active'); |
|
|
} |
|
|
|
|
|
function handleDrop(e) { |
|
|
e.preventDefault(); |
|
|
dropZone.classList.remove('drop-zone-active'); |
|
|
|
|
|
const files = e.dataTransfer.files; |
|
|
if (files.length > 0) { |
|
|
processCSVFile(files[0]); |
|
|
} |
|
|
} |
|
|
|
|
|
function handleFileSelect(e) { |
|
|
const file = e.target.files[0]; |
|
|
if (file) { |
|
|
processCSVFile(file); |
|
|
} |
|
|
} |
|
|
|
|
|
function processCSVFile(file) { |
|
|
if (file.type !== 'text/csv' && !file.name.endsWith('.csv')) { |
|
|
alert('Please upload a valid CSV file.'); |
|
|
return; |
|
|
} |
|
|
|
|
|
const reader = new FileReader(); |
|
|
reader.onload = function(e) { |
|
|
const csvText = e.target.result; |
|
|
parseCSV(csvText); |
|
|
}; |
|
|
reader.readAsText(file); |
|
|
} |
|
|
|
|
|
function parseCSV(csvText) { |
|
|
const lines = csvText.split('\n').filter(line => line.trim() !== ''); |
|
|
if (lines.length === 0) return; |
|
|
|
|
|
|
|
|
headers = lines[0].split(',').map(header => header.trim()); |
|
|
|
|
|
|
|
|
csvData = lines.slice(1).map(line => { |
|
|
const values = line.split(',').map(value => value.trim()); |
|
|
return values; |
|
|
}); |
|
|
|
|
|
displayPreview(); |
|
|
} |
|
|
|
|
|
function displayPreview() { |
|
|
|
|
|
previewSection.classList.remove('hidden'); |
|
|
|
|
|
|
|
|
tableHeaders.innerHTML = headers.map(header => |
|
|
`<th class="px-6 py-4 text-left font-semibold">${header}</th>` |
|
|
).join(''); |
|
|
|
|
|
|
|
|
const previewData = csvData.slice(0, 10); |
|
|
tableBody.innerHTML = previewData.map(row => |
|
|
`<tr class="hover:bg-cyan-500/10">${row.map(cell => |
|
|
`<td class="px-6 py-4 border-b border-gray-700">${cell}</td>` |
|
|
).join('')}</tr>` |
|
|
).join(''); |
|
|
|
|
|
|
|
|
previewSection.scrollIntoView({ behavior: 'smooth' }); |
|
|
} |
|
|
|
|
|
function generateVisualizations() { |
|
|
if (csvData.length === 0) return; |
|
|
|
|
|
|
|
|
vizGallery.classList.remove('hidden'); |
|
|
chartContainer.innerHTML = ''; |
|
|
|
|
|
|
|
|
generateBarChart(); |
|
|
generateLineChart(); |
|
|
generatePieChart(); |
|
|
generateScatterPlot(); |
|
|
|
|
|
|
|
|
vizGallery.scrollIntoView({ behavior: 'smooth' }); |
|
|
} |
|
|
|
|
|
function generateBarChart() { |
|
|
const canvas = document.createElement('canvas'); |
|
|
canvas.className = 'glass-card p-4'; |
|
|
chartContainer.appendChild(canvas); |
|
|
|
|
|
|
|
|
const ctx = canvas.getContext('2d'); |
|
|
new Chart(ctx, { |
|
|
type: 'bar', |
|
|
data: { |
|
|
labels: headers.slice(0, 5), |
|
|
datasets: [{ |
|
|
label: 'Sample Data', |
|
|
data: [65, 59, 80, 81, 56], |
|
|
backgroundColor: [ |
|
|
'rgba(0, 255, 255, 0.7)', |
|
|
'rgba(168, 85, 247, 0.7)', |
|
|
'rgba(34, 211, 238, 0.7)', |
|
|
'rgba(139, 92, 246, 0.7)', |
|
|
'rgba(45, 212, 191, 0.7)' |
|
|
], |
|
|
borderColor: [ |
|
|
'rgba(0, 255, 255, 1)', |
|
|
'rgba(168, 85, 247, 1)', |
|
|
'rgba(34, 211, 238, 1)', |
|
|
'rgba(139, 92, 246, 1)', |
|
|
'rgba(45, 212, 191, 1)' |
|
|
], |
|
|
borderWidth: 2 |
|
|
}] |
|
|
}, |
|
|
options: { |
|
|
responsive: true, |
|
|
plugins: { |
|
|
title: { |
|
|
display: true, |
|
|
text: 'Bar Chart Visualization', |
|
|
color: 'white', |
|
|
font: { size: 16 } |
|
|
}, |
|
|
legend: { |
|
|
labels: { color: 'white' } |
|
|
} |
|
|
}, |
|
|
scales: { |
|
|
y: { |
|
|
beginAtZero: true, |
|
|
ticks: { color: 'white' } |
|
|
}, |
|
|
x: { |
|
|
ticks: { color: 'white' } |
|
|
} |
|
|
} |
|
|
}); |
|
|
} |
|
|
|
|
|
function generateLineChart() { |
|
|
const canvas = document.createElement('canvas'); |
|
|
canvas.className = 'glass-card p-4'; |
|
|
chartContainer.appendChild(canvas); |
|
|
|
|
|
const ctx = canvas.getContext('2d'); |
|
|
new Chart(ctx, { |
|
|
type: 'line', |
|
|
data: { |
|
|
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'], |
|
|
datasets: [{ |
|
|
label: 'Trend Line', |
|
|
data: [12, 19, 3, 5, 2], |
|
|
borderColor: 'rgba(0, 255, 255, 1)', |
|
|
backgroundColor: 'rgba(0, 255, 255, 0.1)', |
|
|
borderWidth: 3, |
|
|
tension: 0.4, |
|
|
fill: true |
|
|
}] |
|
|
}, |
|
|
options: { |
|
|
responsive: true, |
|
|
plugins: { |
|
|
title: { |
|
|
display: true, |
|
|
text: 'Line Chart Trend', |
|
|
color: 'white', |
|
|
font: { size: 16 } |
|
|
}, |
|
|
legend: { |
|
|
labels: { color: 'white' } |
|
|
} |
|
|
}, |
|
|
scales: { |
|
|
y: { |
|
|
beginAtZero: true, |
|
|
ticks: { color: 'white' } |
|
|
}, |
|
|
x: { |
|
|
ticks: { color: 'white' } |
|
|
} |
|
|
} |
|
|
}); |
|
|
} |
|
|
|
|
|
function generatePieChart() { |
|
|
const canvas = document.createElement('canvas'); |
|
|
canvas.className = 'glass-card p-4'; |
|
|
chartContainer.appendChild(canvas); |
|
|
|
|
|
const ctx = canvas.getContext('2d'); |
|
|
new Chart(ctx, { |
|
|
type: 'pie', |
|
|
data: { |
|
|
labels: ['Category A', 'Category B', 'Category C', 'Category D'], |
|
|
datasets: [{ |
|
|
data: [30, 25, 20, 25], |
|
|
backgroundColor: [ |
|
|
'rgba(0, 255, 255, 0.8)', |
|
|
'rgba(168, 85, 247, 0.8)', |
|
|
'rgba(34, 211, 238, 0.8)', |
|
|
'rgba(139, 92, 246, 0.8)' |
|
|
], |
|
|
borderColor: 'rgba(255, 255, 255, 0.3)', |
|
|
borderWidth: 2 |
|
|
}] |
|
|
}, |
|
|
options: { |
|
|
responsive: true, |
|
|
plugins: { |
|
|
title: { |
|
|
display: true, |
|
|
text: 'Pie Chart Distribution', |
|
|
color: 'white', |
|
|
font: { size: 16 } |
|
|
}, |
|
|
legend: { |
|
|
labels: { color: 'white' } |
|
|
} |
|
|
} |
|
|
}); |
|
|
} |
|
|
|
|
|
function generateScatterPlot() { |
|
|
const canvas = document.createElement('canvas'); |
|
|
canvas.className = 'glass-card p-4'; |
|
|
chartContainer.appendChild(canvas); |
|
|
|
|
|
const ctx = canvas.getContext('2d'); |
|
|
new Chart(ctx, { |
|
|
type: 'scatter', |
|
|
data: { |
|
|
datasets: [{ |
|
|
label: 'Data Points', |
|
|
data: [ |
|
|
{ x: 10, y: 20 }, { x: 15, y: 25 }, { x: 20, y: 30 }, |
|
|
{ x: 25, y: 35 }, { x: 30, y: 40 }, { x: 35, y: 45 } |
|
|
], |
|
|
backgroundColor: 'rgba(168, 85, 247, 0.7)', |
|
|
borderColor: 'rgba(168, 85, 247, 1)', |
|
|
borderWidth: 2, |
|
|
pointRadius: 6 |
|
|
}] |
|
|
}, |
|
|
options: { |
|
|
responsive: true, |
|
|
plugins: { |
|
|
title: { |
|
|
display: true, |
|
|
text: 'Scatter Plot Correlation', |
|
|
color: 'white', |
|
|
font: { size: 16 } |
|
|
}, |
|
|
legend: { |
|
|
labels: { color: 'white' } |
|
|
} |
|
|
}, |
|
|
scales: { |
|
|
y: { |
|
|
beginAtZero: true, |
|
|
ticks: { color: 'white' } |
|
|
}, |
|
|
x: { |
|
|
ticks: { color: 'white' } |
|
|
} |
|
|
} |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
function downloadChart(chartId, filename) { |
|
|
const canvas = document.getElementById(chartId); |
|
|
const link = document.createElement('a'); |
|
|
link.download = filename; |
|
|
link.href = canvas.toDataURL(); |
|
|
link.click(); |
|
|
} |
|
|
|
|
|
console.log('DataViz Liquid Glass Studio loaded successfully!'); |