From 1363df0e6a358bcd8a819932a0877bd47fe92c91 Mon Sep 17 00:00:00 2001 From: Tiberiu Ichim Date: Mon, 11 Aug 2025 12:16:15 +0300 Subject: [PATCH 01/22] WIP on embedding data --- src/Blocks/EmbedVisualization/View.jsx | 33 ++++ src/Utils/Download.jsx | 204 ++++--------------------- src/Utils/utils.js | 201 ++++++++++++++++++++++++ src/helpers/csvString.js | 6 +- src/index.js | 6 + 5 files changed, 269 insertions(+), 181 deletions(-) create mode 100644 src/Utils/utils.js diff --git a/src/Blocks/EmbedVisualization/View.jsx b/src/Blocks/EmbedVisualization/View.jsx index 35fd04d5..e3f95c5b 100644 --- a/src/Blocks/EmbedVisualization/View.jsx +++ b/src/Blocks/EmbedVisualization/View.jsx @@ -1,5 +1,37 @@ import React from 'react'; +import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable'; import PlotlyComponent from '@eeacms/volto-plotlycharts/PlotlyComponent'; +import { generateCSVForDataset } from '@eeacms/volto-plotlycharts/Utils/utils'; + +function EmbedData(props) { + const { reactChartEditorLib } = props; + const { dataSources } = props.data?.visualization || {}; + const url_source = ''; + + const completeCSVData = generateOriginalCSV( + dataSources, + provider_metadata, + url_source, + core_metadata, + ); + + // const csvData = generateCSVForDataset( + // dataSources, + // datasetData, + // provider_metadata, + // core_metadata, + // url_source, + // reactChartEditorLib, + // ); + + //eslint-disable-next-line no-console + console.log(csvData); + return null; +} + +const WithChartEditorLibEmbedData = injectLazyLibs(['reactChartEditorLib'])( + EmbedData, +); const View = (props) => { const { data = {} } = props; @@ -16,6 +48,7 @@ const View = (props) => { with_sources: true, }} /> + ); }; diff --git a/src/Utils/Download.jsx b/src/Utils/Download.jsx index 65bde840..e3844f65 100644 --- a/src/Utils/Download.jsx +++ b/src/Utils/Download.jsx @@ -1,3 +1,4 @@ +import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable'; import React from 'react'; import cx from 'classnames'; import { cloneDeep } from 'lodash'; @@ -6,19 +7,17 @@ import { useLocation } from 'react-router-dom'; import { Popup } from 'semantic-ui-react'; import { toPublicURL } from '@plone/volto/helpers'; import { - convertToCSV, exportCSVFile, exportZipFile, groupDataByDataset, - processTraceData, - spreadCoreMetadata, } from '@eeacms/volto-plotlycharts/helpers/csvString'; +import { generateOriginalCSV, generateCSVForDataset } from './utils'; const Plotly = loadable.lib(() => import('plotly.js/dist/plotly.min')); -export default function Download(props) { +function Download(props) { const location = useLocation(); - const { chartData, filters, provider_metadata } = props; + const { chartData, filters, provider_metadata, reactChartEditorLib } = props; const url_source = toPublicURL(location.pathname); @@ -43,111 +42,6 @@ export default function Download(props) { const [open, setOpen] = React.useState(false); - const getMetadataFlags = () => ({ - hasDataProvenance: core_metadata.data_provenance?.length > 0, - hasOtherOrganisation: core_metadata.other_organisations?.length > 0, - hasTemporalCoverage: core_metadata.temporal_coverage?.length > 0, - hasGeoCoverage: core_metadata.geo_coverage?.length > 0, - hasPublisher: core_metadata.publisher?.length > 0, - }); - - const processMetadataArrays = (metadataFlags) => { - const arrays = { - data_provenance_array: [], - other_organisation_array: [], - temporal_coverage_array: [], - geo_coverage_array: [], - publisher_array: [], - }; - - if ( - metadataFlags.hasDataProvenance || - metadataFlags.hasOtherOrganisation || - metadataFlags.hasTemporalCoverage || - metadataFlags.hasGeoCoverage || - metadataFlags.hasPublisher - ) { - Object.entries(spreadCoreMetadata(core_metadata)).forEach( - ([key, items]) => { - items.forEach((item, index) => { - if (key.includes('data_provenance') || key.includes('Sources')) { - if (!arrays.data_provenance_array[index]) - arrays.data_provenance_array[index] = {}; - arrays.data_provenance_array[index][key] = item; - } - if ( - key.includes('other_organisation') || - key.includes('Other organisations involved') - ) { - if (!arrays.other_organisation_array[index]) - arrays.other_organisation_array[index] = {}; - arrays.other_organisation_array[index][key] = item; - } - if ( - key.includes('temporal_coverage') || - key.includes('Temporal coverage') - ) { - if (!arrays.temporal_coverage_array[index]) - arrays.temporal_coverage_array[index] = {}; - arrays.temporal_coverage_array[index][key] = item; - } - if ( - key.includes('geo_coverage') || - key.includes('Geographical coverage') - ) { - if (!arrays.geo_coverage_array[index]) - arrays.geo_coverage_array[index] = {}; - arrays.geo_coverage_array[index][key] = item; - } - if (key.includes('publisher') || key.includes('Publisher')) { - if (!arrays.publisher_array[index]) - arrays.publisher_array[index] = {}; - arrays.publisher_array[index][key] = item; - } - }); - }, - ); - } - - return arrays; - }; - - const generateFinalCSV = (array, readme, metadataFlags, metadataArrays) => { - const data_csv = convertToCSV(array, readme); - - const data_provenance_csv = metadataFlags.hasDataProvenance - ? convertToCSV(metadataArrays.data_provenance_array, [], true) - : ''; - const other_organisation_csv = metadataFlags.hasOtherOrganisation - ? convertToCSV(metadataArrays.other_organisation_array, [], true) - : ''; - const temporal_coverage_csv = metadataFlags.hasTemporalCoverage - ? convertToCSV(metadataArrays.temporal_coverage_array, [], true) - : ''; - const geo_coverage_csv = metadataFlags.hasGeoCoverage - ? convertToCSV(metadataArrays.geo_coverage_array, [], true) - : ''; - const publisher_csv = metadataFlags.hasPublisher - ? convertToCSV(metadataArrays.publisher_array, [], true) - : ''; - - const download_source_csv = convertToCSV( - [{ 'Downloaded from: ': url_source }], - [], - true, - ); - - return ( - download_source_csv + - publisher_csv + - other_organisation_csv + - data_provenance_csv + - geo_coverage_csv + - temporal_coverage_csv + - data_csv - ); - }; - const handleDownloadData = async () => { const datasets = groupDataByDataset(chartData); @@ -170,13 +64,25 @@ export default function Download(props) { // Add individual CSV files for each dataset for (const [, datasetData] of Object.entries(datasets)) { - const csvData = await generateCSVForDataset(datasetData); + const csvData = generateCSVForDataset( + dataSources, + datasetData, + provider_metadata, + core_metadata, + url_source, + reactChartEditorLib, + ); const fileName = `${datasetData.name || 'data'}.csv`; zip.file(fileName, csvData); } // Add the complete CSV with all data - const completeCSVData = generateOriginalCSV(); + const completeCSVData = generateOriginalCSV( + dataSources, + provider_metadata, + url_source, + core_metadata, + ); zip.file(`${title}.csv`, completeCSVData); const zipBlob = await zip.generateAsync({ type: 'blob' }); @@ -187,72 +93,13 @@ export default function Download(props) { } }; - const generateCSVForDataset = async (datasetData) => { - let array = []; - let readme = provider_metadata?.readme ? [provider_metadata?.readme] : []; - - // Collect all trace data separately - const allTraceData = []; - for (const trace of datasetData.data) { - const traceData = await processTraceData(trace, dataSources); - allTraceData.push(traceData); - } - - // If no processed data from traces, fall back to original data sources - if ( - allTraceData.length === 0 || - allTraceData.every((data) => data.length === 0) - ) { - Object.entries(dataSources).forEach(([key, items]) => { - items.forEach((item, index) => { - if (!array[index]) array[index] = {}; - array[index][key] = item; - }); - }); - } else { - 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 generateOriginalCSV = () => { - 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; - }); - }); - - const metadataFlags = getMetadataFlags(); - const metadataArrays = processMetadataArrays(metadataFlags); - return generateFinalCSV(array, readme, metadataFlags, metadataArrays); - }; - const handleDownloadSingleCSV = () => { - const csvData = generateOriginalCSV(); + const csvData = generateOriginalCSV( + dataSources, + provider_metadata, + url_source, + core_metadata, + ); exportCSVFile(csvData, title); }; @@ -458,3 +305,6 @@ export default function Download(props) { /> ); } + +const WithLibsDownload = injectLazyLibs(['reactChartEditorLib'])(Download); +export default WithLibsDownload; diff --git a/src/Utils/utils.js b/src/Utils/utils.js new file mode 100644 index 00000000..6151a8e3 --- /dev/null +++ b/src/Utils/utils.js @@ -0,0 +1,201 @@ +import { + convertToCSV, + processTraceData, + spreadCoreMetadata, +} from '@eeacms/volto-plotlycharts/helpers/csvString'; + +export const generateFinalCSV = ( + array, + readme, + metadataFlags, + metadataArrays, + url_source, +) => { + const data_csv = convertToCSV(array, readme); + + const data_provenance_csv = metadataFlags.hasDataProvenance + ? convertToCSV(metadataArrays.data_provenance_array, [], true) + : ''; + const other_organisation_csv = metadataFlags.hasOtherOrganisation + ? convertToCSV(metadataArrays.other_organisation_array, [], true) + : ''; + const temporal_coverage_csv = metadataFlags.hasTemporalCoverage + ? convertToCSV(metadataArrays.temporal_coverage_array, [], true) + : ''; + const geo_coverage_csv = metadataFlags.hasGeoCoverage + ? convertToCSV(metadataArrays.geo_coverage_array, [], true) + : ''; + const publisher_csv = metadataFlags.hasPublisher + ? convertToCSV(metadataArrays.publisher_array, [], true) + : ''; + + const download_source_csv = convertToCSV( + [{ 'Downloaded from: ': url_source }], + [], + true, + ); + + return ( + download_source_csv + + publisher_csv + + other_organisation_csv + + data_provenance_csv + + geo_coverage_csv + + temporal_coverage_csv + + data_csv + ); +}; + +export const generateOriginalCSV = ( + dataSources, + provider_metadata, + url_source, + core_metadata, +) => { + 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; + }); + }); + + const metadataFlags = getMetadataFlags(core_metadata); + const metadataArrays = processMetadataArrays(core_metadata, metadataFlags); + return generateFinalCSV( + array, + readme, + metadataFlags, + metadataArrays, + url_source, + ); +}; + +const getMetadataFlags = (core_metadata) => ({ + hasDataProvenance: core_metadata.data_provenance?.length > 0, + hasOtherOrganisation: core_metadata.other_organisations?.length > 0, + hasTemporalCoverage: core_metadata.temporal_coverage?.length > 0, + hasGeoCoverage: core_metadata.geo_coverage?.length > 0, + hasPublisher: core_metadata.publisher?.length > 0, +}); + +const processMetadataArrays = (core_metadata, metadataFlags) => { + const arrays = { + data_provenance_array: [], + other_organisation_array: [], + temporal_coverage_array: [], + geo_coverage_array: [], + publisher_array: [], + }; + + if ( + metadataFlags.hasDataProvenance || + metadataFlags.hasOtherOrganisation || + metadataFlags.hasTemporalCoverage || + metadataFlags.hasGeoCoverage || + metadataFlags.hasPublisher + ) { + Object.entries(spreadCoreMetadata(core_metadata)).forEach( + ([key, items]) => { + items.forEach((item, index) => { + if (key.includes('data_provenance') || key.includes('Sources')) { + if (!arrays.data_provenance_array[index]) + arrays.data_provenance_array[index] = {}; + arrays.data_provenance_array[index][key] = item; + } + if ( + key.includes('other_organisation') || + key.includes('Other organisations involved') + ) { + if (!arrays.other_organisation_array[index]) + arrays.other_organisation_array[index] = {}; + arrays.other_organisation_array[index][key] = item; + } + if ( + key.includes('temporal_coverage') || + key.includes('Temporal coverage') + ) { + if (!arrays.temporal_coverage_array[index]) + arrays.temporal_coverage_array[index] = {}; + arrays.temporal_coverage_array[index][key] = item; + } + if ( + key.includes('geo_coverage') || + key.includes('Geographical coverage') + ) { + if (!arrays.geo_coverage_array[index]) + arrays.geo_coverage_array[index] = {}; + arrays.geo_coverage_array[index][key] = item; + } + if (key.includes('publisher') || key.includes('Publisher')) { + if (!arrays.publisher_array[index]) + arrays.publisher_array[index] = {}; + arrays.publisher_array[index][key] = item; + } + }); + }, + ); + } + + return arrays; +}; + +export const generateCSVForDataset = ( + dataSources, + datasetData, + provider_metadata, + core_metadata, + url_source, + reactChartEditorLib, +) => { + let array = []; + let readme = provider_metadata?.readme ? [provider_metadata?.readme] : []; + + // Collect all trace data separately + const allTraceData = []; + for (const trace of datasetData.data) { + const traceData = processTraceData(trace, dataSources, reactChartEditorLib); + allTraceData.push(traceData); + } + + // If no processed data from traces, fall back to original data sources + if ( + allTraceData.length === 0 || + allTraceData.every((data) => data.length === 0) + ) { + Object.entries(dataSources).forEach(([key, items]) => { + items.forEach((item, index) => { + if (!array[index]) array[index] = {}; + array[index][key] = item; + }); + }); + } else { + 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(core_metadata); + const metadataArrays = processMetadataArrays(metadataFlags); + return generateFinalCSV( + array, + readme, + metadataFlags, + metadataArrays, + url_source, + ); +}; diff --git a/src/helpers/csvString.js b/src/helpers/csvString.js index 54a92724..8da36880 100644 --- a/src/helpers/csvString.js +++ b/src/helpers/csvString.js @@ -233,15 +233,13 @@ function groupDataByDataset(chartData) { return datasets; } -async function processTraceData(trace, dataSources) { +function processTraceData(trace, dataSources, reactChartEditorLib) { let processedData = []; // Collect all columns used by the trace const usedColumns = new Set(); - const { getAttrsPath, constants, getSrcAttr } = await import( - '@eeacms/react-chart-editor/lib' - ); + const { getAttrsPath, constants, getSrcAttr } = reactChartEditorLib; // Get all data attributes from constants.TRACE_SRC_ATTRIBUTES const traceDataAttrs = getAttrsPath(trace, constants.TRACE_SRC_ATTRIBUTES); diff --git a/src/index.js b/src/index.js index 131c4add..87aea37f 100644 --- a/src/index.js +++ b/src/index.js @@ -1,3 +1,5 @@ +import loadable from '@loadable/component'; + import installBlocks from './Blocks'; import { VisualizationView } from './Views'; import { @@ -63,6 +65,10 @@ const applyConfig = (config) => { }, ]; + config.settings.loadables.reactChartEditorLib = loadable.lib( + () => import('@eeacms/react-chart-editor/lib'), + ); + return [installBlocks].reduce((acc, apply) => apply(acc), config); }; From 55c075cad10cf2fe65421af49a2644aad62d1f6e Mon Sep 17 00:00:00 2001 From: eea-jenkins Date: Mon, 11 Aug 2025 11:20:22 +0200 Subject: [PATCH 02/22] style: Automated code fix --- src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 87aea37f..9abc863f 100644 --- a/src/index.js +++ b/src/index.js @@ -65,8 +65,8 @@ const applyConfig = (config) => { }, ]; - config.settings.loadables.reactChartEditorLib = loadable.lib( - () => import('@eeacms/react-chart-editor/lib'), + config.settings.loadables.reactChartEditorLib = loadable.lib(() => + import('@eeacms/react-chart-editor/lib'), ); return [installBlocks].reduce((acc, apply) => apply(acc), config); From 27ebe1d58a44f08a2f64ae3bc61c7580b4bdf4db Mon Sep 17 00:00:00 2001 From: Tiberiu Ichim Date: Mon, 11 Aug 2025 12:41:05 +0300 Subject: [PATCH 03/22] WIP --- src/Blocks/EmbedVisualization/View.jsx | 31 +++++++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/src/Blocks/EmbedVisualization/View.jsx b/src/Blocks/EmbedVisualization/View.jsx index e3f95c5b..28b10bd7 100644 --- a/src/Blocks/EmbedVisualization/View.jsx +++ b/src/Blocks/EmbedVisualization/View.jsx @@ -1,12 +1,31 @@ import React from 'react'; import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable'; import PlotlyComponent from '@eeacms/volto-plotlycharts/PlotlyComponent'; -import { generateCSVForDataset } from '@eeacms/volto-plotlycharts/Utils/utils'; +import { + generateCSVForDataset, + generateOriginalCSV, +} from '@eeacms/volto-plotlycharts/Utils/utils'; function EmbedData(props) { - const { reactChartEditorLib } = props; - const { dataSources } = props.data?.visualization || {}; - const url_source = ''; + console.log(props); + const { provider_metadata } = props; // reactChartEditorLib, + const { dataSources = {} } = props.data?.visualization || {}; + const url_source = 'https://example.com'; + const { + data_provenance, + other_organisations, + temporal_coverage, + publisher, + geo_coverage, + } = props.data?.properties || {}; + + const core_metadata = { + data_provenance: data_provenance?.data, + other_organisations, + temporal_coverage: temporal_coverage?.temporal, + publisher, + geo_coverage: geo_coverage?.geolocation, + }; const completeCSVData = generateOriginalCSV( dataSources, @@ -25,7 +44,7 @@ function EmbedData(props) { // ); //eslint-disable-next-line no-console - console.log(csvData); + console.log({ completeCSVData }); return null; } @@ -48,7 +67,7 @@ const View = (props) => { with_sources: true, }} /> - + ); }; From e2e36b9e22e6498ac69befaae0fe34ee11de138c Mon Sep 17 00:00:00 2001 From: Tiberiu Ichim Date: Mon, 11 Aug 2025 12:49:56 +0300 Subject: [PATCH 04/22] WIP --- src/Blocks/EmbedVisualization/View.jsx | 52 ------------------------- src/PlotlyComponent/PlotlyComponent.jsx | 52 +++++++++++++++++++++++++ src/Utils/Download.jsx | 1 + 3 files changed, 53 insertions(+), 52 deletions(-) diff --git a/src/Blocks/EmbedVisualization/View.jsx b/src/Blocks/EmbedVisualization/View.jsx index 28b10bd7..35fd04d5 100644 --- a/src/Blocks/EmbedVisualization/View.jsx +++ b/src/Blocks/EmbedVisualization/View.jsx @@ -1,56 +1,5 @@ import React from 'react'; -import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable'; import PlotlyComponent from '@eeacms/volto-plotlycharts/PlotlyComponent'; -import { - generateCSVForDataset, - generateOriginalCSV, -} from '@eeacms/volto-plotlycharts/Utils/utils'; - -function EmbedData(props) { - console.log(props); - const { provider_metadata } = props; // reactChartEditorLib, - const { dataSources = {} } = props.data?.visualization || {}; - const url_source = 'https://example.com'; - const { - data_provenance, - other_organisations, - temporal_coverage, - publisher, - geo_coverage, - } = props.data?.properties || {}; - - const core_metadata = { - data_provenance: data_provenance?.data, - other_organisations, - temporal_coverage: temporal_coverage?.temporal, - publisher, - geo_coverage: geo_coverage?.geolocation, - }; - - const completeCSVData = generateOriginalCSV( - dataSources, - provider_metadata, - url_source, - core_metadata, - ); - - // const csvData = generateCSVForDataset( - // dataSources, - // datasetData, - // provider_metadata, - // core_metadata, - // url_source, - // reactChartEditorLib, - // ); - - //eslint-disable-next-line no-console - console.log({ completeCSVData }); - return null; -} - -const WithChartEditorLibEmbedData = injectLazyLibs(['reactChartEditorLib'])( - EmbedData, -); const View = (props) => { const { data = {} } = props; @@ -67,7 +16,6 @@ const View = (props) => { with_sources: true, }} /> - ); }; diff --git a/src/PlotlyComponent/PlotlyComponent.jsx b/src/PlotlyComponent/PlotlyComponent.jsx index 8678b3ec..f734c1c8 100644 --- a/src/PlotlyComponent/PlotlyComponent.jsx +++ b/src/PlotlyComponent/PlotlyComponent.jsx @@ -21,6 +21,10 @@ import { import { Toolbar } from '@eeacms/volto-plotlycharts/Utils'; import Plot from './Plot'; import Placeholder from './Placeholder'; +import { + // generateCSVForDataset, + generateOriginalCSV, +} from '@eeacms/volto-plotlycharts/Utils/utils'; function getFilterOptions(rows, rowsOrder = null) { if (!isArray(rows)) return []; @@ -298,10 +302,58 @@ function UnconnectedPlotlyComponent(props) { enlargeContent={} /> )} + + ); } +function EmbedData(props) { + console.log(props); + const { provider_metadata } = props; // reactChartEditorLib, + const { dataSources = {} } = props.data?.visualization || {}; + const url_source = 'https://example.com'; + const { + data_provenance, + other_organisations, + temporal_coverage, + publisher, + geo_coverage, + } = props.data?.properties || {}; + + const core_metadata = { + data_provenance: data_provenance?.data, + other_organisations, + temporal_coverage: temporal_coverage?.temporal, + publisher, + geo_coverage: geo_coverage?.geolocation, + }; + + const completeCSVData = generateOriginalCSV( + dataSources, + provider_metadata, + url_source, + core_metadata, + ); + + // const csvData = generateCSVForDataset( + // dataSources, + // datasetData, + // provider_metadata, + // core_metadata, + // url_source, + // reactChartEditorLib, + // ); + + //eslint-disable-next-line no-console + console.log({ completeCSVData }); + return null; +} + +const WithChartEditorLibEmbedData = injectLazyLibs(['reactChartEditorLib'])( + EmbedData, +); + const ConnectedPlotlyComponent = compose( connectBlockToVisualization(function getConfig(props) { const url = flattenToAppURL(props.data?.vis_url); diff --git a/src/Utils/Download.jsx b/src/Utils/Download.jsx index e3844f65..2cf522aa 100644 --- a/src/Utils/Download.jsx +++ b/src/Utils/Download.jsx @@ -37,6 +37,7 @@ function Download(props) { publisher, geo_coverage: geo_coverage?.geolocation, }; + console.log({ 'download props': props }); const { dataSources } = props.data?.visualization || {}; From 2a05efb213c99d3d45e6648c777401ab450e9d2e Mon Sep 17 00:00:00 2001 From: Tiberiu Ichim Date: Mon, 11 Aug 2025 15:12:39 +0300 Subject: [PATCH 05/22] WIP --- src/PlotlyComponent/PlotlyComponent.jsx | 113 ++++++++++++++++++++---- src/Utils/utils.js | 6 +- 2 files changed, 99 insertions(+), 20 deletions(-) diff --git a/src/PlotlyComponent/PlotlyComponent.jsx b/src/PlotlyComponent/PlotlyComponent.jsx index f734c1c8..ba84be3f 100644 --- a/src/PlotlyComponent/PlotlyComponent.jsx +++ b/src/PlotlyComponent/PlotlyComponent.jsx @@ -22,10 +22,13 @@ import { Toolbar } from '@eeacms/volto-plotlycharts/Utils'; import Plot from './Plot'; import Placeholder from './Placeholder'; import { - // generateCSVForDataset, - generateOriginalCSV, + getMetadataFlags, + processMetadataArrays, } from '@eeacms/volto-plotlycharts/Utils/utils'; +// generateCSVForDataset, +// generateOriginalCSV, + function getFilterOptions(rows, rowsOrder = null) { if (!isArray(rows)) return []; return sortBy( @@ -303,16 +306,60 @@ function UnconnectedPlotlyComponent(props) { /> )} - + ); } +function prepareEmbedData(dataSources, provider_metadata, core_metadata) { + let array = []; + Object.entries(dataSources).forEach(([key, items]) => { + items.forEach((item, index) => { + if (!array[index]) array[index] = {}; + array[index][key] = item; + }); + }); + + let readme = provider_metadata?.readme ? [provider_metadata?.readme] : []; + const metadataFlags = getMetadataFlags(core_metadata); + const metadataArrays = processMetadataArrays(core_metadata, metadataFlags); + + return { array, readme, metadataArrays, metadataFlags }; +} + +function Table({ rows }) { + const stableKeys = Object.keys(rows?.[0] || {}); + + return ( + + + + {stableKeys.map((key) => ( + + ))} + + + + {rows.map((row, index) => ( + + {stableKeys.map((key) => ( + + ))} + + ))} + +
{key}
{row[key]}
+ ); +} + function EmbedData(props) { - console.log(props); const { provider_metadata } = props; // reactChartEditorLib, const { dataSources = {} } = props.data?.visualization || {}; - const url_source = 'https://example.com'; + const { data_provenance, other_organisations, @@ -329,25 +376,55 @@ function EmbedData(props) { geo_coverage: geo_coverage?.geolocation, }; - const completeCSVData = generateOriginalCSV( + const embedData = prepareEmbedData( dataSources, provider_metadata, - url_source, core_metadata, ); - - // const csvData = generateCSVForDataset( - // dataSources, - // datasetData, - // provider_metadata, - // core_metadata, - // url_source, - // reactChartEditorLib, - // ); + const { array, readme, metadataArrays, metadataFlags } = embedData; //eslint-disable-next-line no-console - console.log({ completeCSVData }); - return null; + console.log(embedData); + + return ( +
+

Embed Data

+ + + {metadataFlags.hasDataProvenance && ( + <> +

Data Provenance

+
+ + )} + {metadataFlags.hasOtherOrganisation && ( + <> +

Other Organisations

+
+ + )} + {metadataFlags.hasTemporalCoverage && ( + <> +

Temporal Coverage

+
+ + )} + {metadataFlags.hasGeoCoverage && ( + <> +

Geographical Coverage

+
+ + )} + {metadataFlags.hasPublisher && ( + <> +

Publisher

+
+ + )} + +
{readme}
+ + ); } const WithChartEditorLibEmbedData = injectLazyLibs(['reactChartEditorLib'])( diff --git a/src/Utils/utils.js b/src/Utils/utils.js index 6151a8e3..5440e88b 100644 --- a/src/Utils/utils.js +++ b/src/Utils/utils.js @@ -64,6 +64,7 @@ export const generateOriginalCSV = ( const metadataFlags = getMetadataFlags(core_metadata); const metadataArrays = processMetadataArrays(core_metadata, metadataFlags); + return generateFinalCSV( array, readme, @@ -73,7 +74,7 @@ export const generateOriginalCSV = ( ); }; -const getMetadataFlags = (core_metadata) => ({ +export const getMetadataFlags = (core_metadata) => ({ hasDataProvenance: core_metadata.data_provenance?.length > 0, hasOtherOrganisation: core_metadata.other_organisations?.length > 0, hasTemporalCoverage: core_metadata.temporal_coverage?.length > 0, @@ -81,7 +82,7 @@ const getMetadataFlags = (core_metadata) => ({ hasPublisher: core_metadata.publisher?.length > 0, }); -const processMetadataArrays = (core_metadata, metadataFlags) => { +export const processMetadataArrays = (core_metadata, metadataFlags) => { const arrays = { data_provenance_array: [], other_organisation_array: [], @@ -191,6 +192,7 @@ export const generateCSVForDataset = ( const metadataFlags = getMetadataFlags(core_metadata); const metadataArrays = processMetadataArrays(metadataFlags); + return generateFinalCSV( array, readme, From 8073564a4698c1a961cd47989a6e332157f19910 Mon Sep 17 00:00:00 2001 From: Tiberiu Ichim Date: Mon, 11 Aug 2025 15:14:29 +0300 Subject: [PATCH 06/22] Remove console.log --- src/PlotlyComponent/PlotlyComponent.jsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/PlotlyComponent/PlotlyComponent.jsx b/src/PlotlyComponent/PlotlyComponent.jsx index ba84be3f..66531052 100644 --- a/src/PlotlyComponent/PlotlyComponent.jsx +++ b/src/PlotlyComponent/PlotlyComponent.jsx @@ -383,9 +383,6 @@ function EmbedData(props) { ); const { array, readme, metadataArrays, metadataFlags } = embedData; - //eslint-disable-next-line no-console - console.log(embedData); - return (

Embed Data

From ffed054854ac22af17738e0628296a05b6883dd9 Mon Sep 17 00:00:00 2001 From: Tiberiu Ichim Date: Thu, 14 Aug 2025 10:41:26 +0300 Subject: [PATCH 07/22] Lazy loading plotly --- src/Blocks/EmbedVisualization/View.jsx | 4 ++++ src/PlotlyComponent/PlotlyComponent.jsx | 2 +- src/PlotlyEditor/PlotlyEditor.jsx | 23 +++++++++++++++-------- src/Utils/Download.jsx | 1 - src/index.js | 12 +++++++++--- 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/Blocks/EmbedVisualization/View.jsx b/src/Blocks/EmbedVisualization/View.jsx index 35fd04d5..be08e394 100644 --- a/src/Blocks/EmbedVisualization/View.jsx +++ b/src/Blocks/EmbedVisualization/View.jsx @@ -3,6 +3,10 @@ import PlotlyComponent from '@eeacms/volto-plotlycharts/PlotlyComponent'; const View = (props) => { const { data = {} } = props; + console.log('View props:', props); + if (__SERVER__) { + console.log('searver'); + } return (
diff --git a/src/PlotlyComponent/PlotlyComponent.jsx b/src/PlotlyComponent/PlotlyComponent.jsx index 66531052..2cd8d5bd 100644 --- a/src/PlotlyComponent/PlotlyComponent.jsx +++ b/src/PlotlyComponent/PlotlyComponent.jsx @@ -384,7 +384,7 @@ function EmbedData(props) { const { array, readme, metadataArrays, metadataFlags } = embedData; return ( -
+

Embed Data

diff --git a/src/PlotlyEditor/PlotlyEditor.jsx b/src/PlotlyEditor/PlotlyEditor.jsx index 35605a64..27aeab78 100644 --- a/src/PlotlyEditor/PlotlyEditor.jsx +++ b/src/PlotlyEditor/PlotlyEditor.jsx @@ -9,8 +9,9 @@ import React, { import { compose } from 'redux'; import { useLocation } from 'react-router-dom'; import { cloneDeep, isEqual, isNil, sortBy, debounce } from 'lodash'; -import DefaultPlotlyEditor, { constants } from '@eeacms/react-chart-editor'; -import plotly from 'plotly.js/dist/plotly-with-meta'; +// import DefaultPlotlyEditor, { constants } from '@eeacms/react-chart-editor'; +// import plotly from 'plotly.js/dist/plotly-with-meta'; +import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable'; import { Api } from '@plone/volto/helpers'; @@ -46,6 +47,11 @@ const withValue = (WrappedComponent) => { }; const UnconnectedPlotlyEditor = forwardRef((props, ref) => { + const { DefaultPlotlyEditor, constants } = props.reactChartEditor; + const plotly = props.plotlyLib?.default || props.plotlyLib; + const { TRACE_SRC_ATTRIBUTES, LAYOUT_SRC_ATTRIBUTES, EDITOR_ACTIONS } = + constants; + const update = useRef({}); const flags = useRef({}); const editor = useRef(); @@ -87,21 +93,21 @@ const UnconnectedPlotlyEditor = forwardRef((props, ref) => { const updatedTrace = updateDataSources( updateTrace(trace), dataSources, - constants.TRACE_SRC_ATTRIBUTES, + TRACE_SRC_ATTRIBUTES, ); acc.push(updatedTrace); return acc; }, []); - }, [value.data, dataSources]); + }, [value.data, dataSources, TRACE_SRC_ATTRIBUTES]); const layout = useMemo(() => { return updateDataSources( value.layout || {}, dataSources, - constants.LAYOUT_SRC_ATTRIBUTES, + LAYOUT_SRC_ATTRIBUTES, ); - }, [value.layout, dataSources]); + }, [value.layout, dataSources, LAYOUT_SRC_ATTRIBUTES]); const ctx = useMemo( () => ({ @@ -192,7 +198,7 @@ const UnconnectedPlotlyEditor = forwardRef((props, ref) => { function updateTemplate(template) { editor.current.onUpdate({ - type: constants.EDITOR_ACTIONS.UPDATE_LAYOUT, + type: EDITOR_ACTIONS.UPDATE_LAYOUT, payload: { update: { template, @@ -213,7 +219,7 @@ const UnconnectedPlotlyEditor = forwardRef((props, ref) => { updateTemplate(theme); } } - }, [initialized, themes, layout.template]); + }, [initialized, themes, layout.template, EDITOR_ACTIONS.UPDATE_LAYOUT]); // Clean up @@ -297,6 +303,7 @@ const UnconnectedPlotlyEditor = forwardRef((props, ref) => { }); const ConnectedPlotlyEditor = compose( + injectLazyLibs(['reactChartEditor']), withValue, connectToProviderData((props) => ({ provider_url: props.value.provider_url, diff --git a/src/Utils/Download.jsx b/src/Utils/Download.jsx index 2cf522aa..e3844f65 100644 --- a/src/Utils/Download.jsx +++ b/src/Utils/Download.jsx @@ -37,7 +37,6 @@ function Download(props) { publisher, geo_coverage: geo_coverage?.geolocation, }; - console.log({ 'download props': props }); const { dataSources } = props.data?.visualization || {}; diff --git a/src/index.js b/src/index.js index 9abc863f..5ef8b6e6 100644 --- a/src/index.js +++ b/src/index.js @@ -65,9 +65,15 @@ const applyConfig = (config) => { }, ]; - config.settings.loadables.reactChartEditorLib = loadable.lib(() => - import('@eeacms/react-chart-editor/lib'), - ); + config.settings.loadables = { + ...config.settings.loadables, + reactChartEditorLib: loadable.lib( + () => import('@eeacms/react-chart-editor/lib'), + ), + reactChartEditor: loadable.lib(() => import('@eeacms/react-chart-editor')), + plotlyLib: loadable.lib(() => import('plotly.js/dist/plotly-with-meta')), + Plotly: loadable.lib(() => import('plotly.js/dist/plotly.min')), + }; return [installBlocks].reduce((acc, apply) => apply(acc), config); }; From 7f88384ddd9a4eab862298e9ce6d199d11e68c6d Mon Sep 17 00:00:00 2001 From: eea-jenkins Date: Thu, 14 Aug 2025 09:45:57 +0200 Subject: [PATCH 08/22] style: Automated code fix --- src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 5ef8b6e6..054c4095 100644 --- a/src/index.js +++ b/src/index.js @@ -67,8 +67,8 @@ const applyConfig = (config) => { config.settings.loadables = { ...config.settings.loadables, - reactChartEditorLib: loadable.lib( - () => import('@eeacms/react-chart-editor/lib'), + reactChartEditorLib: loadable.lib(() => + import('@eeacms/react-chart-editor/lib'), ), reactChartEditor: loadable.lib(() => import('@eeacms/react-chart-editor')), plotlyLib: loadable.lib(() => import('plotly.js/dist/plotly-with-meta')), From 058730005fffcec12e5f25579640ce9065b5bb91 Mon Sep 17 00:00:00 2001 From: Tiberiu Ichim Date: Thu, 14 Aug 2025 11:37:02 +0300 Subject: [PATCH 09/22] Lazy loading plotly --- src/PlotlyComponent/PlotlyComponent.jsx | 10 ++++--- src/PlotlyEditor/panels/GraphFilterPanel.jsx | 8 +++-- src/PlotlyEditor/widgets/TemplateSelector.jsx | 9 ++++-- src/Widgets/TemplatesWidget.jsx | 29 ++++++++++++------- 4 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/PlotlyComponent/PlotlyComponent.jsx b/src/PlotlyComponent/PlotlyComponent.jsx index 2cd8d5bd..ab63ea20 100644 --- a/src/PlotlyComponent/PlotlyComponent.jsx +++ b/src/PlotlyComponent/PlotlyComponent.jsx @@ -4,7 +4,7 @@ import { connect } from 'react-redux'; import { mapKeys, isArray, uniqBy, sortBy, isNil } from 'lodash'; import cx from 'classnames'; import { FormField } from 'semantic-ui-react'; -import { constants } from '@eeacms/react-chart-editor'; +// import { constants } from '@eeacms/react-chart-editor'; import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable'; import { flattenToAppURL } from '@plone/volto/helpers'; import { VisibilitySensor } from '@eeacms/volto-datablocks/components'; @@ -45,6 +45,8 @@ function getFilterOptions(rows, rowsOrder = null) { } function UnconnectedPlotlyComponent(props) { + const { reactChartEditor } = props; + const { constants } = reactChartEditor; const container = useRef(); const el = useRef(); const Select = props.reactSelect.default; @@ -128,7 +130,7 @@ function UnconnectedPlotlyComponent(props) { acc.push(updatedTrace); return acc; }, []); - }, [value.data, dataSources, filters]); + }, [value.data, dataSources, filters, constants.TRACE_SRC_ATTRIBUTES]); const layout = useMemo(() => { return updateDataSources( @@ -136,7 +138,7 @@ function UnconnectedPlotlyComponent(props) { dataSources, constants.LAYOUT_SRC_ATTRIBUTES, ); - }, [value.layout, dataSources]); + }, [value.layout, dataSources, constants.LAYOUT_SRC_ATTRIBUTES]); const toolbarData = useMemo(() => { return { @@ -449,7 +451,7 @@ const ConnectedPlotlyComponent = compose( selfProvided: props.data.visualization?.provider_url === props.data.properties?.['@id'], })), - injectLazyLibs(['reactSelect']), + injectLazyLibs(['reactSelect', 'reactChartEditor']), )(UnconnectedPlotlyComponent); export default function PlotlyComponent(props) { diff --git a/src/PlotlyEditor/panels/GraphFilterPanel.jsx b/src/PlotlyEditor/panels/GraphFilterPanel.jsx index dadcdb45..8ceec6ca 100644 --- a/src/PlotlyEditor/panels/GraphFilterPanel.jsx +++ b/src/PlotlyEditor/panels/GraphFilterPanel.jsx @@ -1,14 +1,16 @@ import PropTypes from 'prop-types'; import { isArray, uniq } from 'lodash'; -// Containers + import PlotlyPanel from '@eeacms/react-chart-editor/lib/components/containers/PlotlyPanel'; import PlotlyFold from '@eeacms/react-chart-editor/lib/components/containers/PlotlyFold'; -// Widgets import Dropdown from '@eeacms/react-chart-editor/lib/components/widgets/Dropdown'; import TextInput from '@eeacms/react-chart-editor/lib/components/widgets/TextInput'; -// Field import Field from '@eeacms/react-chart-editor/lib/components/fields/Field'; +// Containers +// Widgets +// Field + function getFilterOptions(rows) { if (!isArray(rows)) return []; return uniq(rows).map((value) => ({ diff --git a/src/PlotlyEditor/widgets/TemplateSelector.jsx b/src/PlotlyEditor/widgets/TemplateSelector.jsx index 24bd9d39..b4bdf965 100644 --- a/src/PlotlyEditor/widgets/TemplateSelector.jsx +++ b/src/PlotlyEditor/widgets/TemplateSelector.jsx @@ -1,9 +1,11 @@ import PropTypes from 'prop-types'; import { omit, sortBy } from 'lodash'; -import { renderTraceIcon } from '@eeacms/react-chart-editor'; +import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable'; +// import { renderTraceIcon } from '@eeacms/react-chart-editor'; function Template(props) { const { type, label, onSelect } = props; + const { renderTraceIcon } = props.reactChartEditorLib; const ComplexIcon = renderTraceIcon(type.icon || type.value, 'TraceType'); @@ -99,5 +101,8 @@ function TemplateSelector(props) { TemplateSelector.contextTypes = { ctx: PropTypes.object, }; +const InjectedTemplateSelector = injectLazyLibs(['react-chart-editor'])( + TemplateSelector, +); -export default TemplateSelector; +export default InjectedTemplateSelector; diff --git a/src/Widgets/TemplatesWidget.jsx b/src/Widgets/TemplatesWidget.jsx index 9615c787..c6e17b9d 100644 --- a/src/Widgets/TemplatesWidget.jsx +++ b/src/Widgets/TemplatesWidget.jsx @@ -1,3 +1,4 @@ +import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable'; import { useEffect, useMemo, useState } from 'react'; import PropTypes from 'prop-types'; import { sortBy, omit } from 'lodash'; @@ -8,16 +9,16 @@ import { PlusIcon } from 'plotly-icons'; import PlotlyEditor from '@eeacms/volto-plotlycharts/PlotlyEditor'; -const PlotlyButton = loadable(() => - import('@eeacms/react-chart-editor/lib/components/widgets/Button'), +const PlotlyButton = loadable( + () => import('@eeacms/react-chart-editor/lib/components/widgets/Button'), ); -const plotlyUtils = loadable.lib(() => - import('@eeacms/volto-plotlycharts/helpers/plotly'), +const plotlyUtils = loadable.lib( + () => import('@eeacms/volto-plotlycharts/helpers/plotly'), ); -const renderTraceIcon = __CLIENT__ - ? require('@eeacms/react-chart-editor').renderTraceIcon - : () => null; +// const renderTraceIcon = __CLIENT__ +// ? require('@eeacms/react-chart-editor').renderTraceIcon +// : () => null; const EditTemplate = (props) => { const [fadeInOut, setFadeInOut] = useState(true); @@ -55,11 +56,19 @@ const EditTemplate = (props) => { ); }; -const Template = ({ type, label, onEdit, onDelete, onClone }) => { +const Template = ({ + type, + label, + onEdit, + onDelete, + onClone, + reactChartEditor, +}) => { + const { renderTraceIcon } = reactChartEditor; const [open, setOpen] = useState(false); const ComplexIcon = useMemo( () => renderTraceIcon(type.icon || type.value, 'TraceType'), - [type], + [type, renderTraceIcon], ); return ( @@ -266,4 +275,4 @@ TemplatesWidget.contextTypes = { formData: PropTypes.object, }; -export default TemplatesWidget; +export default injectLazyLibs(['reactChartEditor'])(TemplatesWidget); From bdcc74a77e5099bc24a4698e48433233b7ce8a9a Mon Sep 17 00:00:00 2001 From: eea-jenkins Date: Thu, 14 Aug 2025 10:41:31 +0200 Subject: [PATCH 10/22] style: Automated code fix --- src/Widgets/TemplatesWidget.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Widgets/TemplatesWidget.jsx b/src/Widgets/TemplatesWidget.jsx index c6e17b9d..a2e768af 100644 --- a/src/Widgets/TemplatesWidget.jsx +++ b/src/Widgets/TemplatesWidget.jsx @@ -9,11 +9,11 @@ import { PlusIcon } from 'plotly-icons'; import PlotlyEditor from '@eeacms/volto-plotlycharts/PlotlyEditor'; -const PlotlyButton = loadable( - () => import('@eeacms/react-chart-editor/lib/components/widgets/Button'), +const PlotlyButton = loadable(() => + import('@eeacms/react-chart-editor/lib/components/widgets/Button'), ); -const plotlyUtils = loadable.lib( - () => import('@eeacms/volto-plotlycharts/helpers/plotly'), +const plotlyUtils = loadable.lib(() => + import('@eeacms/volto-plotlycharts/helpers/plotly'), ); // const renderTraceIcon = __CLIENT__ From 700fe341aec1cf0ebcdfd0b82b65f8867eb915c9 Mon Sep 17 00:00:00 2001 From: Tiberiu Ichim Date: Mon, 18 Aug 2025 10:31:19 +0300 Subject: [PATCH 11/22] Fix a var --- src/PlotlyEditor/DefaultEditor.jsx | 2 ++ src/PlotlyEditor/PlotlyEditor.jsx | 2 +- src/index.js | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/PlotlyEditor/DefaultEditor.jsx b/src/PlotlyEditor/DefaultEditor.jsx index c708f0ba..f6692210 100644 --- a/src/PlotlyEditor/DefaultEditor.jsx +++ b/src/PlotlyEditor/DefaultEditor.jsx @@ -70,6 +70,8 @@ class DefaultEditor extends PlotlyDefaultEditor { } render() { + console.log('DefaultEditor render'); + console.log(GraphThemePanel); const _ = this.context.localize; const { actions, diff --git a/src/PlotlyEditor/PlotlyEditor.jsx b/src/PlotlyEditor/PlotlyEditor.jsx index 27aeab78..4e2ae8e3 100644 --- a/src/PlotlyEditor/PlotlyEditor.jsx +++ b/src/PlotlyEditor/PlotlyEditor.jsx @@ -47,7 +47,7 @@ const withValue = (WrappedComponent) => { }; const UnconnectedPlotlyEditor = forwardRef((props, ref) => { - const { DefaultPlotlyEditor, constants } = props.reactChartEditor; + const { default: DefaultPlotlyEditor, constants } = props.reactChartEditor; const plotly = props.plotlyLib?.default || props.plotlyLib; const { TRACE_SRC_ATTRIBUTES, LAYOUT_SRC_ATTRIBUTES, EDITOR_ACTIONS } = constants; diff --git a/src/index.js b/src/index.js index 054c4095..7e4a38e2 100644 --- a/src/index.js +++ b/src/index.js @@ -67,10 +67,10 @@ const applyConfig = (config) => { config.settings.loadables = { ...config.settings.loadables, - reactChartEditorLib: loadable.lib(() => - import('@eeacms/react-chart-editor/lib'), - ), reactChartEditor: loadable.lib(() => import('@eeacms/react-chart-editor')), + reactChartEditorLib: loadable.lib( + () => import('@eeacms/react-chart-editor/lib'), + ), plotlyLib: loadable.lib(() => import('plotly.js/dist/plotly-with-meta')), Plotly: loadable.lib(() => import('plotly.js/dist/plotly.min')), }; From ebced8c76b0b5ff98a94c8acfb4dec3034281b99 Mon Sep 17 00:00:00 2001 From: eea-jenkins Date: Mon, 18 Aug 2025 09:34:41 +0200 Subject: [PATCH 12/22] style: Automated code fix --- src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 7e4a38e2..6cf70cdb 100644 --- a/src/index.js +++ b/src/index.js @@ -68,8 +68,8 @@ const applyConfig = (config) => { config.settings.loadables = { ...config.settings.loadables, reactChartEditor: loadable.lib(() => import('@eeacms/react-chart-editor')), - reactChartEditorLib: loadable.lib( - () => import('@eeacms/react-chart-editor/lib'), + reactChartEditorLib: loadable.lib(() => + import('@eeacms/react-chart-editor/lib'), ), plotlyLib: loadable.lib(() => import('plotly.js/dist/plotly-with-meta')), Plotly: loadable.lib(() => import('plotly.js/dist/plotly.min')), From f9d956886a91ecb52acfcafd6aa43b16916c2958 Mon Sep 17 00:00:00 2001 From: Tiberiu Ichim Date: Mon, 18 Aug 2025 17:05:41 +0300 Subject: [PATCH 13/22] Fix injection --- src/PlotlyEditor/DefaultEditor.jsx | 2 -- src/PlotlyEditor/PlotlyEditor.jsx | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/PlotlyEditor/DefaultEditor.jsx b/src/PlotlyEditor/DefaultEditor.jsx index f6692210..c708f0ba 100644 --- a/src/PlotlyEditor/DefaultEditor.jsx +++ b/src/PlotlyEditor/DefaultEditor.jsx @@ -70,8 +70,6 @@ class DefaultEditor extends PlotlyDefaultEditor { } render() { - console.log('DefaultEditor render'); - console.log(GraphThemePanel); const _ = this.context.localize; const { actions, diff --git a/src/PlotlyEditor/PlotlyEditor.jsx b/src/PlotlyEditor/PlotlyEditor.jsx index 4e2ae8e3..6bac400c 100644 --- a/src/PlotlyEditor/PlotlyEditor.jsx +++ b/src/PlotlyEditor/PlotlyEditor.jsx @@ -303,7 +303,7 @@ const UnconnectedPlotlyEditor = forwardRef((props, ref) => { }); const ConnectedPlotlyEditor = compose( - injectLazyLibs(['reactChartEditor']), + injectLazyLibs(['reactChartEditor', 'plotlyLib']), withValue, connectToProviderData((props) => ({ provider_url: props.value.provider_url, From 91ec3b41c6e7b6b2752b484e0aa9b7ccd4399d7b Mon Sep 17 00:00:00 2001 From: Tiberiu Ichim Date: Mon, 18 Aug 2025 17:35:57 +0300 Subject: [PATCH 14/22] Remove console.log --- src/Blocks/EmbedVisualization/View.jsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Blocks/EmbedVisualization/View.jsx b/src/Blocks/EmbedVisualization/View.jsx index be08e394..35fd04d5 100644 --- a/src/Blocks/EmbedVisualization/View.jsx +++ b/src/Blocks/EmbedVisualization/View.jsx @@ -3,10 +3,6 @@ import PlotlyComponent from '@eeacms/volto-plotlycharts/PlotlyComponent'; const View = (props) => { const { data = {} } = props; - console.log('View props:', props); - if (__SERVER__) { - console.log('searver'); - } return (
From 84581248ef0bdfb9a173349c56c05584a9e37aab Mon Sep 17 00:00:00 2001 From: Miu Razvan Date: Tue, 19 Aug 2025 12:22:18 +0300 Subject: [PATCH 15/22] add specific height feature when 'autosize: true' is used --- package.json | 2 +- src/PlotlyComponent/PlotlyComponent.jsx | 17 +++++------------ src/PlotlyEditor/panels/StyleLayoutPanel.jsx | 6 +++++- src/less/plotly.less | 3 ++- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 14178184..e92f0235 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@eeacms/volto-datablocks" ], "dependencies": { - "@eeacms/react-chart-editor": "0.47.4", + "@eeacms/react-chart-editor": "0.47.5", "@eeacms/volto-datablocks": "*", "@eeacms/volto-embed": "*", "@eeacms/volto-matomo": "*", diff --git a/src/PlotlyComponent/PlotlyComponent.jsx b/src/PlotlyComponent/PlotlyComponent.jsx index 8678b3ec..c114fc19 100644 --- a/src/PlotlyComponent/PlotlyComponent.jsx +++ b/src/PlotlyComponent/PlotlyComponent.jsx @@ -263,18 +263,11 @@ function UnconnectedPlotlyComponent(props) { {!loadingProviderData && (
( + diff --git a/src/less/plotly.less b/src/less/plotly.less index 9dfc1a13..7015db95 100644 --- a/src/less/plotly.less +++ b/src/less/plotly.less @@ -11,7 +11,8 @@ .plotly-component { margin-bottom: 1rem; - .svg-container { + .visualization, + .js-plotly-plot { height: var(--svg-container-height) !important; } From dbd3536c2460ea4ee7ceb97850f212c03510143d Mon Sep 17 00:00:00 2001 From: Dobricean Ioan Dorian <50819975+dobri1408@users.noreply.github.com> Date: Tue, 19 Aug 2025 18:38:34 +0300 Subject: [PATCH 16/22] fix metadata array --- src/Utils/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utils/utils.js b/src/Utils/utils.js index 5440e88b..82d11d34 100644 --- a/src/Utils/utils.js +++ b/src/Utils/utils.js @@ -191,7 +191,7 @@ export const generateCSVForDataset = ( } const metadataFlags = getMetadataFlags(core_metadata); - const metadataArrays = processMetadataArrays(metadataFlags); + const metadataArrays = processMetadataArrays(core_metadata, metadataFlags); return generateFinalCSV( array, From be744c922c7353fb95d507cfc5ef871b7754f0a1 Mon Sep 17 00:00:00 2001 From: Miu Razvan Date: Wed, 20 Aug 2025 10:32:25 +0300 Subject: [PATCH 17/22] further improve lazy loading plotly --- package.json | 3 +- src/Blocks/Treemap/Treemap.jsx | 9 +- src/PlotlyComponent/Placeholder.jsx | 9 +- src/PlotlyComponent/Plot.jsx | 4 +- src/PlotlyComponent/PlotlyComponent.jsx | 56 +++-- src/PlotlyEditor/PlotlyEditor.jsx | 2 - src/Utils/Download.jsx | 8 +- src/helpers/editor.js | 4 +- src/index.js | 1 - src/less/plotly.less | 18 ++ src/lib/react-plotly.js | 301 ++++++++++++++++++++++++ 11 files changed, 368 insertions(+), 47 deletions(-) create mode 100644 src/lib/react-plotly.js diff --git a/package.json b/package.json index e92f0235..c5b0d6c0 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@eeacms/volto-datablocks" ], "dependencies": { - "@eeacms/react-chart-editor": "0.47.5", + "@eeacms/react-chart-editor": "0.47.6", "@eeacms/volto-datablocks": "*", "@eeacms/volto-embed": "*", "@eeacms/volto-matomo": "*", @@ -34,7 +34,6 @@ "jsoneditor": "10.2.0", "jszip": "3.10.1", "plotly.js": "^2.35.3", - "react-plotly.js": "2.6.0", "remixicon": "4.6.0" }, "devDependencies": { diff --git a/src/Blocks/Treemap/Treemap.jsx b/src/Blocks/Treemap/Treemap.jsx index 66bbbb34..4f335fd4 100644 --- a/src/Blocks/Treemap/Treemap.jsx +++ b/src/Blocks/Treemap/Treemap.jsx @@ -9,11 +9,8 @@ import config from '@plone/volto/registry'; import { connectToProviderData } from '@eeacms/volto-datablocks/hocs'; import { VisibilitySensor } from '@eeacms/volto-datablocks/components'; -const LoadablePlotly = loadable(() => - import( - /* webpackChunkName: "bise-react-plotly" */ - 'react-plotly.js' - ), +const PlotlyComponent = loadable(() => + import('@eeacms/volto-plotlycharts/lib/react-plotly'), ); /* @@ -55,7 +52,7 @@ function Treemap(props) {
- +
import('react-plotly.js')); +const PlotlyComponent = loadable(() => + import('@eeacms/volto-plotlycharts/lib/react-plotly'), +); const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); diff --git a/src/PlotlyComponent/PlotlyComponent.jsx b/src/PlotlyComponent/PlotlyComponent.jsx index c530465a..4511d2a9 100644 --- a/src/PlotlyComponent/PlotlyComponent.jsx +++ b/src/PlotlyComponent/PlotlyComponent.jsx @@ -237,9 +237,6 @@ function UnconnectedPlotlyComponent(props) { mobile, })} > - {(loadingVisualization || loadingProviderData || !initialized) && ( - - )} {initialized && filters.length > 0 && (
{filters.map((filter, index) => { @@ -269,23 +266,32 @@ function UnconnectedPlotlyComponent(props) { })}
)} - {!loadingProviderData && ( -
- -
- )} +
+ {(loadingVisualization || loadingProviderData || !initialized) && ( + + )} + {!loadingProviderData && ( +
+ +
+ )} +
{initialized && ( + { + return ( +
+ +
+ ); + }} + >
); diff --git a/src/PlotlyEditor/PlotlyEditor.jsx b/src/PlotlyEditor/PlotlyEditor.jsx index 6bac400c..4e2ec3e3 100644 --- a/src/PlotlyEditor/PlotlyEditor.jsx +++ b/src/PlotlyEditor/PlotlyEditor.jsx @@ -9,8 +9,6 @@ import React, { import { compose } from 'redux'; import { useLocation } from 'react-router-dom'; import { cloneDeep, isEqual, isNil, sortBy, debounce } from 'lodash'; -// import DefaultPlotlyEditor, { constants } from '@eeacms/react-chart-editor'; -// import plotly from 'plotly.js/dist/plotly-with-meta'; import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable'; import { Api } from '@plone/volto/helpers'; diff --git a/src/Utils/Download.jsx b/src/Utils/Download.jsx index e3844f65..27f3ae1c 100644 --- a/src/Utils/Download.jsx +++ b/src/Utils/Download.jsx @@ -13,8 +13,6 @@ import { } from '@eeacms/volto-plotlycharts/helpers/csvString'; import { generateOriginalCSV, generateCSVForDataset } from './utils'; -const Plotly = loadable.lib(() => import('plotly.js/dist/plotly.min')); - function Download(props) { const location = useLocation(); const { chartData, filters, provider_metadata, reactChartEditorLib } = props; @@ -104,7 +102,7 @@ function Download(props) { }; const handleDownloadImage = async (type) => { - const plotly = (await Plotly.load()).default; + const plotly = props.plotlyLib?.default || props.plotlyLib; const container = document.createElement('div'); container.id = '__plotly_download_container__'; @@ -306,5 +304,7 @@ function Download(props) { ); } -const WithLibsDownload = injectLazyLibs(['reactChartEditorLib'])(Download); +const WithLibsDownload = injectLazyLibs(['reactChartEditorLib', 'plotlyLib'])( + Download, +); export default WithLibsDownload; diff --git a/src/helpers/editor.js b/src/helpers/editor.js index 8300041a..0e858d4b 100644 --- a/src/helpers/editor.js +++ b/src/helpers/editor.js @@ -5,7 +5,7 @@ import { Toast } from '@plone/volto/components'; import loadable from '@loadable/component'; const LoadableJsonEditor = loadable.lib(() => - import('jsoneditor/dist/jsoneditor'), + import('jsoneditor/dist/jsoneditor.min'), ); const jsoneditor = __CLIENT__ && LoadableJsonEditor; @@ -72,5 +72,5 @@ export function onPasteEditor(editor) { try { editor.current.repair(); editor.current.format(); - } catch {} + } catch { } } diff --git a/src/index.js b/src/index.js index 6cf70cdb..a94311b3 100644 --- a/src/index.js +++ b/src/index.js @@ -72,7 +72,6 @@ const applyConfig = (config) => { import('@eeacms/react-chart-editor/lib'), ), plotlyLib: loadable.lib(() => import('plotly.js/dist/plotly-with-meta')), - Plotly: loadable.lib(() => import('plotly.js/dist/plotly.min')), }; return [installBlocks].reduce((acc, apply) => apply(acc), config); diff --git a/src/less/plotly.less b/src/less/plotly.less index 7015db95..2bbcfea8 100644 --- a/src/less/plotly.less +++ b/src/less/plotly.less @@ -8,6 +8,24 @@ overflow-x: auto; } +.visualization-wrapper { + position: relative; + + &.loading { + height: 80px; + } + + .plotly-placeholder { + display: flex; + justify-content: center; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + padding: '1rem 0'; + } +} + .plotly-component { margin-bottom: 1rem; diff --git a/src/lib/react-plotly.js b/src/lib/react-plotly.js new file mode 100644 index 00000000..007d29d3 --- /dev/null +++ b/src/lib/react-plotly.js @@ -0,0 +1,301 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable'; + +// The naming convention is: +// - events are attached as `'plotly_' + eventName.toLowerCase()` +// - react props are `'on' + eventName` +const eventNames = [ + 'AfterExport', + 'AfterPlot', + 'Animated', + 'AnimatingFrame', + 'AnimationInterrupted', + 'AutoSize', + 'BeforeExport', + 'BeforeHover', + 'ButtonClicked', + 'Click', + 'ClickAnnotation', + 'Deselect', + 'DoubleClick', + 'Framework', + 'Hover', + 'LegendClick', + 'LegendDoubleClick', + 'Relayout', + 'Relayouting', + 'Restyle', + 'Redraw', + 'Selected', + 'Selecting', + 'SliderChange', + 'SliderEnd', + 'SliderStart', + 'SunburstClick', + 'Transitioning', + 'TransitionInterrupted', + 'Unhover', + 'WebGlContextLost', +]; + +const updateEvents = [ + 'plotly_restyle', + 'plotly_redraw', + 'plotly_relayout', + 'plotly_relayouting', + 'plotly_doubleclick', + 'plotly_animated', + 'plotly_sunburstclick', +]; + +// Check if a window is available since SSR (server-side rendering) +// breaks unnecessarily if you try to use it server-side. +const isBrowser = typeof window !== 'undefined'; + +class PlotlyComponent extends Component { + constructor(props) { + super(props); + + this.p = Promise.resolve(); + this.resizeHandler = null; + this.handlers = {}; + + this.syncWindowResize = this.syncWindowResize.bind(this); + this.syncEventHandlers = this.syncEventHandlers.bind(this); + this.attachUpdateEvents = this.attachUpdateEvents.bind(this); + this.getRef = this.getRef.bind(this); + this.handleUpdate = this.handleUpdate.bind(this); + this.figureCallback = this.figureCallback.bind(this); + this.updatePlotly = this.updatePlotly.bind(this); + this.plotly = props.plotlyLib?.default || props.plotlyLib; + } + + updatePlotly( + shouldInvokeResizeHandler, + figureCallbackFunction, + shouldAttachUpdateEvents, + ) { + this.p = this.p + .then(() => { + if (this.unmounting) { + return; + } + if (!this.el) { + throw new Error('Missing element reference'); + } + // eslint-disable-next-line consistent-return + return this.plotly.react(this.el, { + data: this.props.data, + layout: this.props.layout, + config: this.props.config, + frames: this.props.frames, + }); + }) + .then(() => { + if (this.unmounting) { + return; + } + this.syncWindowResize(shouldInvokeResizeHandler); + this.syncEventHandlers(); + this.figureCallback(figureCallbackFunction); + if (shouldAttachUpdateEvents) { + this.attachUpdateEvents(); + } + }) + .catch((err) => { + if (this.props.onError) { + this.props.onError(err); + } + }); + } + + componentDidMount() { + this.unmounting = false; + + this.updatePlotly(true, this.props.onInitialized, true); + } + + componentDidUpdate(prevProps) { + this.unmounting = false; + + // frames *always* changes identity so fall back to check length only :( + const numPrevFrames = + prevProps.frames && prevProps.frames.length ? prevProps.frames.length : 0; + const numNextFrames = + this.props.frames && this.props.frames.length + ? this.props.frames.length + : 0; + + const figureChanged = !( + prevProps.layout === this.props.layout && + prevProps.data === this.props.data && + prevProps.config === this.props.config && + numNextFrames === numPrevFrames + ); + const revisionDefined = prevProps.revision !== void 0; + const revisionChanged = prevProps.revision !== this.props.revision; + + if ( + !figureChanged && + (!revisionDefined || (revisionDefined && !revisionChanged)) + ) { + return; + } + + this.updatePlotly(false, this.props.onUpdate, false); + } + + componentWillUnmount() { + this.unmounting = true; + + this.figureCallback(this.props.onPurge); + + if (this.resizeHandler && isBrowser) { + window.removeEventListener('resize', this.resizeHandler); + this.resizeHandler = null; + } + + this.removeUpdateEvents(); + + this.plotly.purge(this.el); + } + + attachUpdateEvents() { + if (!this.el || !this.el.removeListener) { + return; + } + + updateEvents.forEach((updateEvent) => { + this.el.on(updateEvent, this.handleUpdate); + }); + } + + removeUpdateEvents() { + if (!this.el || !this.el.removeListener) { + return; + } + + updateEvents.forEach((updateEvent) => { + this.el.removeListener(updateEvent, this.handleUpdate); + }); + } + + handleUpdate() { + this.figureCallback(this.props.onUpdate); + } + + figureCallback(callback) { + if (typeof callback === 'function') { + const { data, layout } = this.el; + const frames = this.el._transitionData + ? this.el._transitionData._frames + : null; + const figure = { data, layout, frames }; + callback(figure, this.el); + } + } + + syncWindowResize(invoke) { + if (!isBrowser) { + return; + } + + if (this.props.useResizeHandler && !this.resizeHandler) { + this.resizeHandler = () => this.plotly.Plots.resize(this.el); + window.addEventListener('resize', this.resizeHandler); + if (invoke) { + this.resizeHandler(); + } + } else if (!this.props.useResizeHandler && this.resizeHandler) { + window.removeEventListener('resize', this.resizeHandler); + this.resizeHandler = null; + } + } + + getRef(el) { + this.el = el; + + if (this.props.debug && isBrowser) { + window.gd = this.el; + } + } + + // Attach and remove event handlers as they're added or removed from props: + syncEventHandlers() { + eventNames.forEach((eventName) => { + const prop = this.props['on' + eventName]; + const handler = this.handlers[eventName]; + const hasHandler = Boolean(handler); + + if (prop && !hasHandler) { + this.addEventHandler(eventName, prop); + } else if (!prop && hasHandler) { + // Needs to be removed: + this.removeEventHandler(eventName); + } else if (prop && hasHandler && prop !== handler) { + // replace the handler + this.removeEventHandler(eventName); + this.addEventHandler(eventName, prop); + } + }); + } + + addEventHandler(eventName, prop) { + this.handlers[eventName] = prop; + this.el.on(this.getPlotlyEventName(eventName), this.handlers[eventName]); + } + + removeEventHandler(eventName) { + this.el.removeListener( + this.getPlotlyEventName(eventName), + this.handlers[eventName], + ); + delete this.handlers[eventName]; + } + + getPlotlyEventName(eventName) { + return 'plotly_' + eventName.toLowerCase(); + } + + render() { + return ( +
+ ); + } +} + +PlotlyComponent.propTypes = { + data: PropTypes.arrayOf(PropTypes.object), + config: PropTypes.object, + layout: PropTypes.object, + frames: PropTypes.arrayOf(PropTypes.object), + revision: PropTypes.number, + onInitialized: PropTypes.func, + onPurge: PropTypes.func, + onError: PropTypes.func, + onUpdate: PropTypes.func, + debug: PropTypes.bool, + style: PropTypes.object, + className: PropTypes.string, + useResizeHandler: PropTypes.bool, + divId: PropTypes.string, +}; + +eventNames.forEach((eventName) => { + PlotlyComponent.propTypes['on' + eventName] = PropTypes.func; +}); + +PlotlyComponent.defaultProps = { + debug: false, + useResizeHandler: false, + data: [], + style: { position: 'relative', display: 'inline-block' }, +}; + +export default injectLazyLibs(['plotlyLib'])(PlotlyComponent); From b589483620c63d6db22d3220d6ee47c2769a4c8e Mon Sep 17 00:00:00 2001 From: eea-jenkins Date: Wed, 20 Aug 2025 09:36:23 +0200 Subject: [PATCH 18/22] style: Automated code fix --- src/helpers/editor.js | 2 +- src/less/plotly.less | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/helpers/editor.js b/src/helpers/editor.js index 0e858d4b..8c356ab7 100644 --- a/src/helpers/editor.js +++ b/src/helpers/editor.js @@ -72,5 +72,5 @@ export function onPasteEditor(editor) { try { editor.current.repair(); editor.current.format(); - } catch { } + } catch {} } diff --git a/src/less/plotly.less b/src/less/plotly.less index 2bbcfea8..732639c3 100644 --- a/src/less/plotly.less +++ b/src/less/plotly.less @@ -16,13 +16,13 @@ } .plotly-placeholder { - display: flex; - justify-content: center; position: absolute; top: 50%; left: 50%; - transform: translate(-50%, -50%); + display: flex; + justify-content: center; padding: '1rem 0'; + transform: translate(-50%, -50%); } } From 2c95cc86954c14ce5abcca2c8cffb53d32f7e11b Mon Sep 17 00:00:00 2001 From: Miu Razvan Date: Wed, 20 Aug 2025 10:38:18 +0300 Subject: [PATCH 19/22] fix table rendering of metadata flags --- src/PlotlyComponent/PlotlyComponent.jsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/PlotlyComponent/PlotlyComponent.jsx b/src/PlotlyComponent/PlotlyComponent.jsx index 4511d2a9..13d4ce3e 100644 --- a/src/PlotlyComponent/PlotlyComponent.jsx +++ b/src/PlotlyComponent/PlotlyComponent.jsx @@ -392,25 +392,25 @@ function EmbedData(props) { {metadataFlags.hasDataProvenance && ( <>

Data Provenance

-
+
)} {metadataFlags.hasOtherOrganisation && ( <>

Other Organisations

-
+
)} {metadataFlags.hasTemporalCoverage && ( <>

Temporal Coverage

-
+
)} {metadataFlags.hasGeoCoverage && ( <>

Geographical Coverage

-
+
)} {metadataFlags.hasPublisher && ( From dc67756a72ce3061d655dac4e6754c86968e9f5f Mon Sep 17 00:00:00 2001 From: Miu Razvan Date: Wed, 20 Aug 2025 10:43:06 +0300 Subject: [PATCH 20/22] fix eslint --- src/Utils/Download.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Utils/Download.jsx b/src/Utils/Download.jsx index 27f3ae1c..1ef8501d 100644 --- a/src/Utils/Download.jsx +++ b/src/Utils/Download.jsx @@ -2,7 +2,6 @@ import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable'; import React from 'react'; import cx from 'classnames'; import { cloneDeep } from 'lodash'; -import loadable from '@loadable/component'; import { useLocation } from 'react-router-dom'; import { Popup } from 'semantic-ui-react'; import { toPublicURL } from '@plone/volto/helpers'; From 49ff16b375923b94b3cb1f9b59e520f552607301 Mon Sep 17 00:00:00 2001 From: Miu Razvan Date: Wed, 20 Aug 2025 10:53:25 +0300 Subject: [PATCH 21/22] hide embed data table --- src/PlotlyComponent/PlotlyComponent.jsx | 2 +- src/lib/react-plotly.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PlotlyComponent/PlotlyComponent.jsx b/src/PlotlyComponent/PlotlyComponent.jsx index 13d4ce3e..c98073a0 100644 --- a/src/PlotlyComponent/PlotlyComponent.jsx +++ b/src/PlotlyComponent/PlotlyComponent.jsx @@ -385,7 +385,7 @@ function EmbedData(props) { const { array, readme, metadataArrays, metadataFlags } = embedData; return ( -
+

Embed Data

diff --git a/src/lib/react-plotly.js b/src/lib/react-plotly.js index 007d29d3..2add73c0 100644 --- a/src/lib/react-plotly.js +++ b/src/lib/react-plotly.js @@ -288,7 +288,7 @@ PlotlyComponent.propTypes = { }; eventNames.forEach((eventName) => { - PlotlyComponent.propTypes['on' + eventName] = PropTypes.func; + PlotlyComponent.propTypes['on' + eventName] = PropTypes.func; // eslint-disable-line }); PlotlyComponent.defaultProps = { From 00b1eab745a4af4645b573351cfa4e789cc9e7e4 Mon Sep 17 00:00:00 2001 From: EEA Jenkins <@users.noreply.github.com> Date: Wed, 20 Aug 2025 08:50:55 +0000 Subject: [PATCH 22/22] Automated release 13.0.4 --- CHANGELOG.md | 31 +++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b96416aa..0a71318a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,34 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +### [13.0.4](https://github.com/eea/volto-plotlycharts/compare/13.0.3...13.0.4) - 20 August 2025 + +#### :house: Internal changes + +- style: Automated code fix [eea-jenkins - [`b589483`](https://github.com/eea/volto-plotlycharts/commit/b589483620c63d6db22d3220d6ee47c2769a4c8e)] +- style: Automated code fix [eea-jenkins - [`ebced8c`](https://github.com/eea/volto-plotlycharts/commit/ebced8c76b0b5ff98a94c8acfb4dec3034281b99)] +- style: Automated code fix [eea-jenkins - [`bdcc74a`](https://github.com/eea/volto-plotlycharts/commit/bdcc74a77e5099bc24a4698e48433233b7ce8a9a)] +- style: Automated code fix [eea-jenkins - [`7f88384`](https://github.com/eea/volto-plotlycharts/commit/7f88384ddd9a4eab862298e9ce6d199d11e68c6d)] +- style: Automated code fix [eea-jenkins - [`55c075c`](https://github.com/eea/volto-plotlycharts/commit/55c075cad10cf2fe65421af49a2644aad62d1f6e)] + +#### :hammer_and_wrench: Others + +- hide embed data table [Miu Razvan - [`49ff16b`](https://github.com/eea/volto-plotlycharts/commit/49ff16b375923b94b3cb1f9b59e520f552607301)] +- fix eslint [Miu Razvan - [`dc67756`](https://github.com/eea/volto-plotlycharts/commit/dc67756a72ce3061d655dac4e6754c86968e9f5f)] +- fix table rendering of metadata flags [Miu Razvan - [`2c95cc8`](https://github.com/eea/volto-plotlycharts/commit/2c95cc86954c14ce5abcca2c8cffb53d32f7e11b)] +- further improve lazy loading plotly [Miu Razvan - [`be744c9`](https://github.com/eea/volto-plotlycharts/commit/be744c922c7353fb95d507cfc5ef871b7754f0a1)] +- fix metadata array [Dobricean Ioan Dorian - [`dbd3536`](https://github.com/eea/volto-plotlycharts/commit/dbd3536c2460ea4ee7ceb97850f212c03510143d)] +- add specific height feature when 'autosize: true' is used [Miu Razvan - [`8458124`](https://github.com/eea/volto-plotlycharts/commit/84581248ef0bdfb9a173349c56c05584a9e37aab)] +- Remove console.log [Tiberiu Ichim - [`91ec3b4`](https://github.com/eea/volto-plotlycharts/commit/91ec3b41c6e7b6b2752b484e0aa9b7ccd4399d7b)] +- Fix injection [Tiberiu Ichim - [`f9d9568`](https://github.com/eea/volto-plotlycharts/commit/f9d956886a91ecb52acfcafd6aa43b16916c2958)] +- Fix a var [Tiberiu Ichim - [`700fe34`](https://github.com/eea/volto-plotlycharts/commit/700fe341aec1cf0ebcdfd0b82b65f8867eb915c9)] +- Lazy loading plotly [Tiberiu Ichim - [`0587300`](https://github.com/eea/volto-plotlycharts/commit/058730005fffcec12e5f25579640ce9065b5bb91)] +- Lazy loading plotly [Tiberiu Ichim - [`ffed054`](https://github.com/eea/volto-plotlycharts/commit/ffed054854ac22af17738e0628296a05b6883dd9)] +- Remove console.log [Tiberiu Ichim - [`8073564`](https://github.com/eea/volto-plotlycharts/commit/8073564a4698c1a961cd47989a6e332157f19910)] +- WIP [Tiberiu Ichim - [`2a05efb`](https://github.com/eea/volto-plotlycharts/commit/2a05efb213c99d3d45e6648c777401ab450e9d2e)] +- WIP [Tiberiu Ichim - [`e2e36b9`](https://github.com/eea/volto-plotlycharts/commit/e2e36b9e22e6498ac69befaae0fe34ee11de138c)] +- WIP [Tiberiu Ichim - [`27ebe1d`](https://github.com/eea/volto-plotlycharts/commit/27ebe1d58a44f08a2f64ae3bc61c7580b4bdf4db)] +- WIP on embedding data [Tiberiu Ichim - [`1363df0`](https://github.com/eea/volto-plotlycharts/commit/1363df0e6a358bcd8a819932a0877bd47fe92c91)] ### [13.0.3](https://github.com/eea/volto-plotlycharts/compare/13.0.2...13.0.3) - 18 August 2025 #### :bug: Bug Fixes @@ -11,6 +39,9 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - fix(filters-styles): only apply to top_filters [nileshgulia1 - [`7bd3078`](https://github.com/eea/volto-plotlycharts/commit/7bd30780b028052aed2bd2ac60269b19c2a3403e)] - fix: width on visualization filters refs#288972 [nileshgulia1 - [`05e35be`](https://github.com/eea/volto-plotlycharts/commit/05e35be8d7ef7bafea5d7659d48c9971e7ef1191)] +#### :hammer_and_wrench: Others + +- Merge pull request #165 from eea/develop [Nilesh - [`5403f05`](https://github.com/eea/volto-plotlycharts/commit/5403f05d34ab58da29bcd0835dfeb8a58d022bfa)] ### [13.0.2](https://github.com/eea/volto-plotlycharts/compare/13.0.1...13.0.2) - 28 July 2025 #### :house: Internal changes diff --git a/package.json b/package.json index c5b0d6c0..76236ddc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@eeacms/volto-plotlycharts", - "version": "13.0.3", + "version": "13.0.4", "description": "Plotly Charts and Editor integration for Volto", "main": "src/index.js", "author": "European Environment Agency: IDM2 A-Team",