From 8b3d48b308be7753d9ef5414875253240f5a17a3 Mon Sep 17 00:00:00 2001 From: Dobricean Ioan Dorian <50819975+dobri1408@users.noreply.github.com> Date: Thu, 7 Aug 2025 10:12:29 +0300 Subject: [PATCH 1/2] fix download --- src/Utils/Download.jsx | 64 +++++++++++++--- src/helpers/csvString.js | 161 +++++++++++++++++++++++++++------------ 2 files changed, 165 insertions(+), 60 deletions(-) diff --git a/src/Utils/Download.jsx b/src/Utils/Download.jsx index 65bde840..98fa136b 100644 --- a/src/Utils/Download.jsx +++ b/src/Utils/Download.jsx @@ -160,7 +160,7 @@ export default function Download(props) { // If no dataset information exists, download only the complete CSV if (!hasDatasetInfo) { - handleDownloadSingleCSV(); + await handleDownloadSingleCSV(); return; } @@ -176,14 +176,14 @@ export default function Download(props) { } // Add the complete CSV with all data - const completeCSVData = generateOriginalCSV(); + const completeCSVData = await generateOriginalCSV(); zip.file(`${title}.csv`, completeCSVData); const zipBlob = await zip.generateAsync({ type: 'blob' }); const zipArrayBuffer = await zipBlob.arrayBuffer(); exportZipFile(zipArrayBuffer, title); } catch (error) { - handleDownloadSingleCSV(); + await handleDownloadSingleCSV(); } }; @@ -235,24 +235,66 @@ export default function Download(props) { return generateFinalCSV(array, readme, metadataFlags, metadataArrays); }; - const generateOriginalCSV = () => { + const generateOriginalCSV = async () => { let array = []; let readme = provider_metadata?.readme ? [provider_metadata?.readme] : []; - Object.entries(dataSources).forEach(([key, items]) => { - items.forEach((item, index) => { - if (!array[index]) array[index] = {}; - array[index][key] = item; + // Check if dataSources has any data + const hasDataSources = + dataSources && + Object.keys(dataSources).some( + (key) => Array.isArray(dataSources[key]) && dataSources[key].length > 0, + ); + + if (hasDataSources) { + // Use existing dataSources logic + Object.entries(dataSources).forEach(([key, items]) => { + items.forEach((item, index) => { + if (!array[index]) array[index] = {}; + array[index][key] = item; + }); }); - }); + } else if (chartData?.data && Array.isArray(chartData.data)) { + // Extract data from traces when dataSources is empty + const allTraceData = []; + for (const trace of chartData.data) { + const traceData = await processTraceData(trace, dataSources || {}); + allTraceData.push(traceData); + } + + // Process all trace data + if ( + allTraceData.length > 0 && + !allTraceData.every((data) => data.length === 0) + ) { + const maxLength = Math.max(...allTraceData.map((data) => data.length)); + + for (let i = 0; i < maxLength; i++) { + if (!array[i]) array[i] = {}; + + allTraceData.forEach((traceData) => { + if (traceData[i]) { + Object.keys(traceData[i]).forEach((key) => { + if ( + traceData[i][key] !== null && + traceData[i][key] !== undefined + ) { + array[i][key] = traceData[i][key]; + } + }); + } + }); + } + } + } const metadataFlags = getMetadataFlags(); const metadataArrays = processMetadataArrays(metadataFlags); return generateFinalCSV(array, readme, metadataFlags, metadataArrays); }; - const handleDownloadSingleCSV = () => { - const csvData = generateOriginalCSV(); + const handleDownloadSingleCSV = async () => { + const csvData = await generateOriginalCSV(); exportCSVFile(csvData, title); }; diff --git a/src/helpers/csvString.js b/src/helpers/csvString.js index 54a92724..0ff57ac7 100644 --- a/src/helpers/csvString.js +++ b/src/helpers/csvString.js @@ -236,72 +236,135 @@ function groupDataByDataset(chartData) { async function processTraceData(trace, dataSources) { let processedData = []; - // Collect all columns used by the trace - const usedColumns = new Set(); - const { getAttrsPath, constants, getSrcAttr } = await import( '@eeacms/react-chart-editor/lib' ); - // Get all data attributes from constants.TRACE_SRC_ATTRIBUTES - const traceDataAttrs = getAttrsPath(trace, constants.TRACE_SRC_ATTRIBUTES); + // Check if dataSources has any data + const hasDataSources = + dataSources && + Object.keys(dataSources).some( + (key) => Array.isArray(dataSources[key]) && dataSources[key].length > 0, + ); - // For each data attribute, get the corresponding src attribute using getSrcAttr - Object.entries(traceDataAttrs).forEach(([dataAttrPath, dataValue]) => { - const srcAttr = getSrcAttr(trace, dataAttrPath); + if (hasDataSources) { + // Use existing logic when dataSources is available + const usedColumns = new Set(); - if (srcAttr && srcAttr.value && dataSources[srcAttr.value]) { - usedColumns.add(srcAttr.value); - } - }); + // Get all data attributes from constants.TRACE_SRC_ATTRIBUTES + const traceDataAttrs = getAttrsPath(trace, constants.TRACE_SRC_ATTRIBUTES); - // Add columns from transforms - if (trace.transforms && Array.isArray(trace.transforms)) { - trace.transforms.forEach((transform) => { - if (transform.targetsrc && dataSources[transform.targetsrc]) { - usedColumns.add(transform.targetsrc); - } - }); - } + // For each data attribute, get the corresponding src attribute using getSrcAttr + Object.entries(traceDataAttrs).forEach(([dataAttrPath, dataValue]) => { + const srcAttr = getSrcAttr(trace, dataAttrPath); - // If no specific columns found, use all available data sources - if (usedColumns.size === 0) { - Object.keys(dataSources).forEach((key) => { - if (Array.isArray(dataSources[key])) { - usedColumns.add(key); + if (srcAttr && srcAttr.value && dataSources[srcAttr.value]) { + usedColumns.add(srcAttr.value); } }); - } - const maxLength = Math.max( - ...Array.from(usedColumns).map((col) => - dataSources[col] ? dataSources[col].length : 0, - ), - ); + // Add columns from transforms + if (trace.transforms && Array.isArray(trace.transforms)) { + trace.transforms.forEach((transform) => { + if (transform.targetsrc && dataSources[transform.targetsrc]) { + usedColumns.add(transform.targetsrc); + } + }); + } + + // If no specific columns found, use all available data sources + if (usedColumns.size === 0) { + Object.keys(dataSources).forEach((key) => { + if (Array.isArray(dataSources[key])) { + usedColumns.add(key); + } + }); + } + + const maxLength = Math.max( + ...Array.from(usedColumns).map((col) => + dataSources[col] ? dataSources[col].length : 0, + ), + ); + + for (let i = 0; i < maxLength; i++) { + const row = {}; + usedColumns.forEach((col) => { + if (dataSources[col] && dataSources[col][i] !== undefined) { + row[col] = dataSources[col][i]; + } + }); + processedData.push(row); + } - for (let i = 0; i < maxLength; i++) { - const row = {}; - usedColumns.forEach((col) => { - if (dataSources[col] && dataSources[col][i] !== undefined) { - row[col] = dataSources[col][i]; + // Ensure all rows have the same columns (fill missing columns with empty values) + const allColumns = new Set(); + processedData.forEach((row) => { + Object.keys(row).forEach((col) => allColumns.add(col)); + }); + + processedData.forEach((row) => { + allColumns.forEach((col) => { + if (!(col in row)) { + row[col] = ''; + } + }); + }); + } else { + // Extract data directly from trace using constants when no dataSources + const traceDataAttrs = getAttrsPath(trace, constants.TRACE_SRC_ATTRIBUTES); + + // Extract data directly from trace properties + const dataColumns = new Set(); + const traceDataValues = {}; + + Object.entries(traceDataAttrs).forEach(([dataAttrPath, dataValue]) => { + if (dataValue && Array.isArray(dataValue)) { + const columnName = dataAttrPath.replace(/\./g, '_'); + dataColumns.add(columnName); + traceDataValues[columnName] = dataValue; } }); - processedData.push(row); - } - // Ensure all rows have the same columns (fill missing columns with empty values) - const allColumns = new Set(); - processedData.forEach((row) => { - Object.keys(row).forEach((col) => allColumns.add(col)); - }); + // If no data found in standard attributes, try common plotly data attributes + if (dataColumns.size === 0) { + const commonAttributes = ['x', 'y', 'z', 'text', 'hovertext']; + commonAttributes.forEach((attr) => { + if (trace[attr] && Array.isArray(trace[attr])) { + dataColumns.add(attr); + traceDataValues[attr] = trace[attr]; + } + }); + } - processedData.forEach((row) => { - allColumns.forEach((col) => { - if (!(col in row)) { - row[col] = ''; + if (dataColumns.size > 0) { + const maxLength = Math.max( + ...Array.from(dataColumns).map((col) => + traceDataValues[col] ? traceDataValues[col].length : 0, + ), + ); + + for (let i = 0; i < maxLength; i++) { + const row = {}; + dataColumns.forEach((col) => { + if (traceDataValues[col] && traceDataValues[col][i] !== undefined) { + row[col] = traceDataValues[col][i]; + } + }); + if (Object.keys(row).length > 0) { + processedData.push(row); + } } - }); - }); + } + + // Add trace metadata if available + if (processedData.length > 0) { + processedData.forEach((row) => { + if (trace.name) row.trace_name = trace.name; + if (trace.type) row.trace_type = trace.type; + }); + } + } // Apply transforms if they exist if (trace.transforms && Array.isArray(trace.transforms)) { From 5646011ad736fde059d26c5599d6dc0d9e55bc27 Mon Sep 17 00:00:00 2001 From: Dobricean Ioan Dorian <50819975+dobri1408@users.noreply.github.com> Date: Thu, 7 Aug 2025 10:15:40 +0300 Subject: [PATCH 2/2] fix download --- src/helpers/csvString.js | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/helpers/csvString.js b/src/helpers/csvString.js index 0ff57ac7..c9e9168b 100644 --- a/src/helpers/csvString.js +++ b/src/helpers/csvString.js @@ -326,17 +326,6 @@ async function processTraceData(trace, dataSources) { } }); - // If no data found in standard attributes, try common plotly data attributes - if (dataColumns.size === 0) { - const commonAttributes = ['x', 'y', 'z', 'text', 'hovertext']; - commonAttributes.forEach((attr) => { - if (trace[attr] && Array.isArray(trace[attr])) { - dataColumns.add(attr); - traceDataValues[attr] = trace[attr]; - } - }); - } - if (dataColumns.size > 0) { const maxLength = Math.max( ...Array.from(dataColumns).map((col) => @@ -356,14 +345,6 @@ async function processTraceData(trace, dataSources) { } } } - - // Add trace metadata if available - if (processedData.length > 0) { - processedData.forEach((row) => { - if (trace.name) row.trace_name = trace.name; - if (trace.type) row.trace_type = trace.type; - }); - } } // Apply transforms if they exist