diff --git a/core/include/Data/SqpDateTime.h b/core/include/Data/SqpDateTime.h index 0a936e2..3ea0484 100644 --- a/core/include/Data/SqpDateTime.h +++ b/core/include/Data/SqpDateTime.h @@ -17,12 +17,12 @@ struct SqpDateTime { /// End time double m_TEnd; - bool contains(const SqpDateTime &dateTime) + bool contains(const SqpDateTime &dateTime) const noexcept { return (m_TStart <= dateTime.m_TStart && m_TEnd >= dateTime.m_TEnd); } - bool intersect(const SqpDateTime &dateTime) + bool intersect(const SqpDateTime &dateTime) const noexcept { return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd); } diff --git a/core/include/Variable/Variable.h b/core/include/Variable/Variable.h index 1bd730c..0232cb1 100644 --- a/core/include/Variable/Variable.h +++ b/core/include/Variable/Variable.h @@ -34,8 +34,9 @@ public: /// @return the data of the variable, nullptr if there is no data IDataSeries *dataSeries() const noexcept; - bool contains(const SqpDateTime &dateTime); - bool intersect(const SqpDateTime &dateTime); + bool contains(const SqpDateTime &dateTime) const noexcept; + bool intersect(const SqpDateTime &dateTime) const noexcept; + bool isInside(const SqpDateTime &dateTime) const noexcept; public slots: void setDataSeries(std::shared_ptr dataSeries) noexcept; diff --git a/core/include/Variable/VariableModel.h b/core/include/Variable/VariableModel.h index 02b204b..7fa865a 100644 --- a/core/include/Variable/VariableModel.h +++ b/core/include/Variable/VariableModel.h @@ -25,12 +25,10 @@ public: * Creates a new variable in the model * @param name the name of the new variable * @param dateTime the dateTime of the new variable - * @param defaultDataSeries the default data of the new variable * @return the pointer to the new variable */ - std::shared_ptr - createVariable(const QString &name, const SqpDateTime &dateTime, - std::shared_ptr defaultDataSeries) noexcept; + std::shared_ptr createVariable(const QString &name, + const SqpDateTime &dateTime) noexcept; std::shared_ptr variable(int index) const; diff --git a/core/src/Variable/Variable.cpp b/core/src/Variable/Variable.cpp index 7f98687..17795a3 100644 --- a/core/src/Variable/Variable.cpp +++ b/core/src/Variable/Variable.cpp @@ -78,12 +78,17 @@ IDataSeries *Variable::dataSeries() const noexcept return impl->m_DataSeries.get(); } -bool Variable::contains(const SqpDateTime &dateTime) +bool Variable::contains(const SqpDateTime &dateTime) const noexcept { return impl->m_DateTime.contains(dateTime); } -bool Variable::intersect(const SqpDateTime &dateTime) +bool Variable::intersect(const SqpDateTime &dateTime) const noexcept { return impl->m_DateTime.intersect(dateTime); } + +bool Variable::isInside(const SqpDateTime &dateTime) const noexcept +{ + return dateTime.contains(SqpDateTime{impl->m_DateTime.m_TStart, impl->m_DateTime.m_TEnd}); +} diff --git a/core/src/Variable/VariableCacheController.cpp b/core/src/Variable/VariableCacheController.cpp index b5cbd3b..a648b4d 100644 --- a/core/src/Variable/VariableCacheController.cpp +++ b/core/src/Variable/VariableCacheController.cpp @@ -55,7 +55,7 @@ void VariableCacheController::addDateTime(std::shared_ptr variable, impl->m_VariableToSqpDateTimeListMap.at(variable), 0); } catch (const std::out_of_range &e) { - qCWarning(LOG_VariableCacheController()) << e.what(); + qCWarning(LOG_VariableCacheController()) << "addDateTime" << e.what(); } } } @@ -71,13 +71,12 @@ VariableCacheController::provideNotInCacheDateTimeList(std::shared_ptr // list of date time request associated to the variable // We assume that the list is ordered in a way that l(0) < l(1). We assume also a < b // (with a & b of type SqpDateTime) means ts(b) > te(a) - - try { - impl->addInCacheDataByStart(dateTime, impl->m_VariableToSqpDateTimeListMap.at(variable), - notInCache, 0, dateTime.m_TStart); + auto it = impl->m_VariableToSqpDateTimeListMap.find(variable); + if (it != impl->m_VariableToSqpDateTimeListMap.end()) { + impl->addInCacheDataByStart(dateTime, it->second, notInCache, 0, dateTime.m_TStart); } - catch (const std::out_of_range &e) { - qCWarning(LOG_VariableCacheController()) << e.what(); + else { + notInCache << dateTime; } return notInCache; diff --git a/core/src/Variable/VariableController.cpp b/core/src/Variable/VariableController.cpp index 41021cb..0ac0a8b 100644 --- a/core/src/Variable/VariableController.cpp +++ b/core/src/Variable/VariableController.cpp @@ -99,17 +99,21 @@ void VariableController::createVariable(const QString &name, /// - default data are generated for the variable, without taking into account the timerange set /// in sciqlop auto dateTime = impl->m_TimeController->dateTime(); - if (auto newVariable = impl->m_VariableModel->createVariable( - name, dateTime, generateDefaultDataSeries(*provider, dateTime))) { + if (auto newVariable = impl->m_VariableModel->createVariable(name, dateTime)) { // store the provider impl->m_VariableToProviderMap[newVariable] = provider; - connect(provider.get(), &IDataProvider::dataProvided, newVariable.get(), - &Variable::setDataSeries); + auto addDateTimeAcquired + = [this, newVariable](auto dataSeriesAcquired, auto dateTimeToPutInCache) { - // store in cache - impl->m_VariableCacheController->addDateTime(newVariable, dateTime); + impl->m_VariableCacheController->addDateTime(newVariable, dateTimeToPutInCache); + newVariable->setDataSeries(dataSeriesAcquired); + + }; + + connect(provider.get(), &IDataProvider::dataProvided, addDateTimeAcquired); + this->onRequestDataLoading(newVariable, dateTime); // notify the creation emit variableCreated(newVariable); @@ -144,8 +148,6 @@ void VariableController::onRequestDataLoading(std::shared_ptr variable // Ask the provider for each data on the dateTimeListNotInCache impl->m_VariableToProviderMap.at(variable)->requestDataLoading( std::move(dateTimeListNotInCache)); - // store in cache - impl->m_VariableCacheController->addDateTime(variable, dateTime); } else { emit variable->updated(); diff --git a/core/src/Variable/VariableModel.cpp b/core/src/Variable/VariableModel.cpp index f03350b..9d6c6f1 100644 --- a/core/src/Variable/VariableModel.cpp +++ b/core/src/Variable/VariableModel.cpp @@ -52,9 +52,8 @@ VariableModel::VariableModel(QObject *parent) { } -std::shared_ptr -VariableModel::createVariable(const QString &name, const SqpDateTime &dateTime, - std::shared_ptr defaultDataSeries) noexcept +std::shared_ptr VariableModel::createVariable(const QString &name, + const SqpDateTime &dateTime) noexcept { auto insertIndex = rowCount(); beginInsertRows({}, insertIndex, insertIndex); @@ -62,7 +61,6 @@ VariableModel::createVariable(const QString &name, const SqpDateTime &dateTime, /// @todo For the moment, the other data of the variable is initialized with default values auto variable = std::make_shared(name, QStringLiteral("unit"), QStringLiteral("mission"), dateTime); - variable->setDataSeries(std::move(defaultDataSeries)); impl->m_Variables.push_back(variable); diff --git a/gui/include/Visualization/VisualizationGraphWidget.h b/gui/include/Visualization/VisualizationGraphWidget.h index 5e0d037..28673a8 100644 --- a/gui/include/Visualization/VisualizationGraphWidget.h +++ b/gui/include/Visualization/VisualizationGraphWidget.h @@ -28,6 +28,7 @@ public: virtual ~VisualizationGraphWidget(); void addVariable(std::shared_ptr variable); + void addVariableUsingGraph(std::shared_ptr variable); /// Removes a variable from the graph void removeVariable(std::shared_ptr variable) noexcept; @@ -52,7 +53,7 @@ private slots: /// Slot called when right clicking on the graph (displays a menu) void onGraphMenuRequested(const QPoint &pos) noexcept; - void onRangeChanged(const QCPRange &t1, const QCPRange &t2); + void onRangeChanged(const QCPRange &t1); /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done void onMouseWheel(QWheelEvent *event) noexcept; diff --git a/gui/src/Visualization/VisualizationGraphHelper.cpp b/gui/src/Visualization/VisualizationGraphHelper.cpp index da5e732..b80cb8f 100644 --- a/gui/src/Visualization/VisualizationGraphHelper.cpp +++ b/gui/src/Visualization/VisualizationGraphHelper.cpp @@ -42,7 +42,6 @@ void updateScalarData(QCPAbstractPlottable *component, ScalarSeries &scalarSerie const auto &valuesData = scalarSeries.valuesData()->data(); const auto count = xData.count(); qCInfo(LOG_VisualizationGraphHelper()) << "TORM: Current points in cache" << xData.count(); - auto xValue = QVector(count); auto vValue = QVector(count); @@ -63,6 +62,10 @@ void updateScalarData(QCPAbstractPlottable *component, ScalarSeries &scalarSerie << xValue.count(); qcpGraph->setData(xValue, vValue); + + // Display all data + component->rescaleAxes(); + component->parentPlot()->replot(); } else { /// @todo DEBUG @@ -97,7 +100,6 @@ QCPAbstractPlottable *createScalarSeriesComponent(ScalarSeries &scalarSeries, QC // Display all data component->rescaleAxes(); - plot.replot(); } else { diff --git a/gui/src/Visualization/VisualizationGraphWidget.cpp b/gui/src/Visualization/VisualizationGraphWidget.cpp index 059beb8..2c37585 100644 --- a/gui/src/Visualization/VisualizationGraphWidget.cpp +++ b/gui/src/Visualization/VisualizationGraphWidget.cpp @@ -49,9 +49,9 @@ VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); ui->widget->axisRect()->setRangeDrag(Qt::Horizontal); connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel); - connect(ui->widget->xAxis, static_cast( - &QCPAxis::rangeChanged), - this, &VisualizationGraphWidget::onRangeChanged); + connect(ui->widget->xAxis, + static_cast(&QCPAxis::rangeChanged), this, + &VisualizationGraphWidget::onRangeChanged); // Activates menu when right clicking on the graph ui->widget->setContextMenuPolicy(Qt::CustomContextMenu); @@ -80,6 +80,34 @@ void VisualizationGraphWidget::addVariable(std::shared_ptr variable) connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated())); } +void VisualizationGraphWidget::addVariableUsingGraph(std::shared_ptr variable) +{ + + // when adding a variable, we need to set its time range to the current graph range + auto grapheRange = ui->widget->xAxis->range(); + auto dateTime = SqpDateTime{grapheRange.lower, grapheRange.upper}; + variable->setDateTime(dateTime); + + auto variableDateTimeWithTolerance = dateTime; + + // add 10% tolerance for each side + auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart); + variableDateTimeWithTolerance.m_TStart -= tolerance; + variableDateTimeWithTolerance.m_TEnd += tolerance; + + // Uses delegate to create the qcpplot components according to the variable + auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget); + + for (auto createdPlottable : qAsConst(createdPlottables)) { + impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable}); + } + + connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated())); + + // CHangement detected, we need to ask controller to request data loading + emit requestDataLoading(variable, variableDateTimeWithTolerance); +} + void VisualizationGraphWidget::removeVariable(std::shared_ptr variable) noexcept { // Each component associated to the variable : @@ -136,23 +164,23 @@ void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept } } -void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2) +void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1) { - qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::onRangeChanged"); for (auto it = impl->m_VariableToPlotMultiMap.cbegin(); it != impl->m_VariableToPlotMultiMap.cend(); ++it) { auto variable = it->first; - auto dateTime = SqpDateTime{t2.lower, t2.upper}; + auto dateTime = SqpDateTime{t1.lower, t1.upper}; if (!variable->contains(dateTime)) { auto variableDateTimeWithTolerance = dateTime; - if (variable->intersect(dateTime)) { + if (!variable->isInside(dateTime)) { auto variableDateTime = variable->dateTime(); if (variableDateTime.m_TStart < dateTime.m_TStart) { + qCDebug(LOG_VisualizationGraphWidget()) << tr("TDetection pan to right:"); auto diffEndToKeepDelta = dateTime.m_TEnd - variableDateTime.m_TEnd; dateTime.m_TStart = variableDateTime.m_TStart + diffEndToKeepDelta; @@ -161,7 +189,8 @@ void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart); variableDateTimeWithTolerance.m_TEnd += tolerance; } - if (variableDateTime.m_TEnd > dateTime.m_TEnd) { + else if (variableDateTime.m_TEnd > dateTime.m_TEnd) { + qCDebug(LOG_VisualizationGraphWidget()) << tr("Detection pan to left: "); auto diffStartToKeepDelta = variableDateTime.m_TStart - dateTime.m_TStart; dateTime.m_TEnd = variableDateTime.m_TEnd - diffStartToKeepDelta; // Tolerance have to be added to the left @@ -169,8 +198,13 @@ void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart); variableDateTimeWithTolerance.m_TStart -= tolerance; } + else { + qCWarning(LOG_VisualizationGraphWidget()) + << tr("Detection anormal zoom detection: "); + } } else { + qCDebug(LOG_VisualizationGraphWidget()) << tr("Detection zoom out: "); // add 10% tolerance for each side auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart); variableDateTimeWithTolerance.m_TStart -= tolerance; @@ -181,6 +215,9 @@ void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange // CHangement detected, we need to ask controller to request data loading emit requestDataLoading(variable, variableDateTimeWithTolerance); } + else { + qCDebug(LOG_VisualizationGraphWidget()) << tr("Detection zoom in: "); + } } } diff --git a/gui/src/Visualization/operations/GenerateVariableMenuOperation.cpp b/gui/src/Visualization/operations/GenerateVariableMenuOperation.cpp index 37f1955..dec20d8 100644 --- a/gui/src/Visualization/operations/GenerateVariableMenuOperation.cpp +++ b/gui/src/Visualization/operations/GenerateVariableMenuOperation.cpp @@ -137,7 +137,7 @@ void GenerateVariableMenuOperation::visit(VisualizationGraphWidget *graphWidget) if (graphWidget) { impl->visitLeaf( *graphWidget, QObject::tr("Open in %1").arg(graphWidget->name()), - [ var = impl->m_Variable, graphWidget ]() { graphWidget->addVariable(var); }); + [ var = impl->m_Variable, graphWidget ]() { graphWidget->addVariableUsingGraph(var); }); } else { qCCritical(LOG_GenerateVariableMenuOperation(),