From 4a72463b71aab2d6a2faa4096469cfad7d793504 Mon Sep 17 00:00:00 2001 From: Manuel Trezza <5673677+mtrezza@users.noreply.github.com> Date: Sun, 18 Jan 2026 08:22:52 +0100 Subject: [PATCH] fix --- .../Data/Browser/GraphDialog.react.js | 8 +-- src/lib/GraphDataUtils.js | 54 +++++++++++-------- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/src/dashboard/Data/Browser/GraphDialog.react.js b/src/dashboard/Data/Browser/GraphDialog.react.js index 72f874aa4c..580485e624 100644 --- a/src/dashboard/Data/Browser/GraphDialog.react.js +++ b/src/dashboard/Data/Browser/GraphDialog.react.js @@ -84,19 +84,21 @@ export default class GraphDialog extends React.Component { } valid() { - const { chartType, xColumn, yColumn, valueColumn } = this.state; + const { chartType, xColumn, yColumn, valueColumn, calculatedValues } = this.state; const hasValueColumn = Array.isArray(valueColumn) && valueColumn.length > 0; + const hasCalculatedValues = Array.isArray(calculatedValues) && calculatedValues.length > 0; + const hasValuesToDisplay = hasValueColumn || hasCalculatedValues; switch (chartType) { case 'pie': case 'doughnut': - return hasValueColumn; + return hasValuesToDisplay; case 'scatter': return !!xColumn && !!yColumn; case 'bar': case 'line': case 'radar': - return !!xColumn && hasValueColumn; + return !!xColumn && hasValuesToDisplay; default: return false; } diff --git a/src/lib/GraphDataUtils.js b/src/lib/GraphDataUtils.js index def7e727ab..acacd022a3 100644 --- a/src/lib/GraphDataUtils.js +++ b/src/lib/GraphDataUtils.js @@ -363,14 +363,16 @@ export function processScatterData(data, xColumn, yColumn, maxPoints = 1000) { * @returns {Object} Chart.js compatible data */ export function processPieData(data, valueColumn, groupByColumn, aggregationType = 'count', calculatedValues = null) { - if (!valueColumn || !Array.isArray(data)) { + if (!Array.isArray(data)) { return null; } // Convert single valueColumn to array for uniform handling - const valueColumns = Array.isArray(valueColumn) ? valueColumn : [valueColumn]; + const valueColumns = Array.isArray(valueColumn) ? valueColumn : (valueColumn ? [valueColumn] : []); + const hasCalculatedValues = calculatedValues && Array.isArray(calculatedValues) && calculatedValues.length > 0; - if (valueColumns.length === 0) { + // Must have at least one value column or calculated value + if (valueColumns.length === 0 && !hasCalculatedValues) { return null; } @@ -512,14 +514,16 @@ export function processPieData(data, valueColumn, groupByColumn, aggregationType * @returns {Object} Chart.js compatible data */ export function processBarLineData(data, xColumn, valueColumn, groupByColumn, aggregationType = 'count', calculatedValues = null) { - if (!xColumn || !valueColumn || !Array.isArray(data)) { + if (!xColumn || !Array.isArray(data)) { return null; } // Convert single valueColumn to array for uniform handling - const valueColumns = Array.isArray(valueColumn) ? valueColumn : [valueColumn]; + const valueColumns = Array.isArray(valueColumn) ? valueColumn : (valueColumn ? [valueColumn] : []); + const hasCalculatedValues = calculatedValues && Array.isArray(calculatedValues) && calculatedValues.length > 0; - if (valueColumns.length === 0) { + // Must have at least one value column or calculated value + if (valueColumns.length === 0 && !hasCalculatedValues) { return null; } @@ -757,12 +761,16 @@ export function validateGraphConfig(config, columns) { return { isValid: false, error: 'No configuration provided' }; } - const { chartType, xColumn, yColumn, valueColumn } = config; + const { chartType, xColumn, yColumn, valueColumn, calculatedValues } = config; if (!chartType) { return { isValid: false, error: 'Chart type is required' }; } + const hasValueColumn = valueColumn && (!Array.isArray(valueColumn) || valueColumn.length > 0); + const hasCalculatedValues = calculatedValues && Array.isArray(calculatedValues) && calculatedValues.length > 0; + const hasValuesToDisplay = hasValueColumn || hasCalculatedValues; + // Check required columns based on chart type switch (chartType) { case 'scatter': @@ -776,14 +784,16 @@ export function validateGraphConfig(config, columns) { case 'pie': case 'doughnut': { - if (!valueColumn || (Array.isArray(valueColumn) && valueColumn.length === 0)) { - return { isValid: false, error: 'Pie charts require at least one value column' }; + if (!hasValuesToDisplay) { + return { isValid: false, error: 'Pie charts require at least one value column or calculated value' }; } - // Validate all value columns exist - const pieValueCols = Array.isArray(valueColumn) ? valueColumn : [valueColumn]; - for (const col of pieValueCols) { - if (!columns || !columns[col]) { - return { isValid: false, error: `Value column '${col}' does not exist` }; + // Validate all value columns exist (only if valueColumn is specified) + if (hasValueColumn) { + const pieValueCols = Array.isArray(valueColumn) ? valueColumn : [valueColumn]; + for (const col of pieValueCols) { + if (!columns || !columns[col]) { + return { isValid: false, error: `Value column '${col}' does not exist` }; + } } } break; @@ -792,17 +802,19 @@ export function validateGraphConfig(config, columns) { case 'bar': case 'line': case 'radar': { - if (!xColumn || !valueColumn || (Array.isArray(valueColumn) && valueColumn.length === 0)) { - return { isValid: false, error: 'Bar/line charts require both X axis and at least one value column' }; + if (!xColumn || !hasValuesToDisplay) { + return { isValid: false, error: 'Bar/line charts require both X axis and at least one value column or calculated value' }; } if (!columns || !columns[xColumn]) { return { isValid: false, error: 'X column does not exist' }; } - // Validate all value columns exist - const barValueCols = Array.isArray(valueColumn) ? valueColumn : [valueColumn]; - for (const col of barValueCols) { - if (!columns || !columns[col]) { - return { isValid: false, error: `Value column '${col}' does not exist` }; + // Validate all value columns exist (only if valueColumn is specified) + if (hasValueColumn) { + const barValueCols = Array.isArray(valueColumn) ? valueColumn : [valueColumn]; + for (const col of barValueCols) { + if (!columns || !columns[col]) { + return { isValid: false, error: `Value column '${col}' does not exist` }; + } } } break;