diff --git a/core/include/Variable/Variable.h b/core/include/Variable/Variable.h index 1941339..ea92956 100644 --- a/core/include/Variable/Variable.h +++ b/core/include/Variable/Variable.h @@ -80,6 +80,8 @@ public: signals: void updated(); + /// Signal emitted when when the data series of the variable is loaded for the first time + void dataInitialized(); private: class VariablePrivate; diff --git a/core/src/Variable/Variable.cpp b/core/src/Variable/Variable.cpp index b9869d0..d431fda 100644 --- a/core/src/Variable/Variable.cpp +++ b/core/src/Variable/Variable.cpp @@ -187,16 +187,23 @@ void Variable::mergeDataSeries(std::shared_ptr dataSeries) noexcept return; } + auto dataInit = false; + // Add or merge the data impl->lockWrite(); if (!impl->m_DataSeries) { impl->m_DataSeries = dataSeries->clone(); + dataInit = true; } else { impl->m_DataSeries->merge(dataSeries.get()); } impl->purgeDataSeries(); impl->unlock(); + + if (dataInit) { + emit dataInitialized(); + } } diff --git a/gui/src/Visualization/VisualizationGraphWidget.cpp b/gui/src/Visualization/VisualizationGraphWidget.cpp index f252c06..d46553d 100644 --- a/gui/src/Visualization/VisualizationGraphWidget.cpp +++ b/gui/src/Visualization/VisualizationGraphWidget.cpp @@ -294,28 +294,44 @@ void VisualizationGraphWidget::enableAcquisition(bool enable) void VisualizationGraphWidget::addVariable(std::shared_ptr variable, SqpRange range) { - // Uses delegate to create the qcpplot components according to the variable - auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget); + /// Lambda used to set graph's units and range according to the variable passed in parameter + auto loadRange = [this](std::shared_ptr variable, const SqpRange &range) { + impl->m_RenderingDelegate->setAxesUnits(*variable); - if (auto dataSeries = variable->dataSeries()) { - // Set axes properties according to the units of the data series - impl->m_RenderingDelegate->setAxesProperties(dataSeries); - - // Sets rendering properties for the new plottables - // Warning: this method must be called after setAxesProperties(), as it can access to some - // axes properties that have to be initialized - impl->m_RenderingDelegate->setPlottablesProperties(dataSeries, createdPlottables); - } + enableAcquisition(false); + setGraphRange(range); + enableAcquisition(true); - impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)}); + emit requestDataLoading({variable}, range, false); + }; connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated())); - this->enableAcquisition(false); - this->setGraphRange(range); - this->enableAcquisition(true); + // Calls update of graph's range and units when the data of the variable have been initialized. + // Note: we use QueuedConnection here as the update event must be called in the UI thread + connect(variable.get(), &Variable::dataInitialized, this, + [ varW = std::weak_ptr{variable}, range, loadRange ]() { + if (auto var = varW.lock()) { + // If the variable is the first added in the graph, we load its range + auto firstVariableInGraph = range == INVALID_RANGE; + auto loadedRange = firstVariableInGraph ? var->range() : range; + loadRange(var, loadedRange); + } + }, + Qt::QueuedConnection); + + // Uses delegate to create the qcpplot components according to the variable + auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget); + + // Sets graph properties + impl->m_RenderingDelegate->setGraphProperties(*variable, createdPlottables); - emit requestDataLoading(QVector >() << variable, range, false); + impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)}); + + // If the variable already has its data loaded, load its units and its range in the graph + if (variable->dataSeries() != nullptr) { + loadRange(variable, range); + } emit variableAdded(variable); }