##// END OF EJS Templates
Merge branch 'feature/CatalogueGuiPart5' into develop
trabillard -
r1349:aa6b3e9d2907 merge
parent child
Show More
@@ -0,0 +1,26
1 #ifndef SCIQLOP_DATASERIESTYPE_H
2 #define SCIQLOP_DATASERIESTYPE_H
3
4 #include <QString>
5
6 enum class DataSeriesType { SCALAR, SPECTROGRAM, VECTOR, UNKNOWN };
7
8 struct DataSeriesTypeUtils {
9 static DataSeriesType fromString(const QString &type)
10 {
11 if (type == QStringLiteral("scalar")) {
12 return DataSeriesType::SCALAR;
13 }
14 else if (type == QStringLiteral("spectrogram")) {
15 return DataSeriesType::SPECTROGRAM;
16 }
17 else if (type == QStringLiteral("vector")) {
18 return DataSeriesType::VECTOR;
19 }
20 else {
21 return DataSeriesType::UNKNOWN;
22 }
23 }
24 };
25
26 #endif // SCIQLOP_DATASERIESTYPE_H
@@ -386,8 +386,8 bool MainWindow::MainWindowPrivate::checkDataToSave(QWidget *parentWidget)
386 if (hasChanges) {
386 if (hasChanges) {
387 // There are some unsaved changes
387 // There are some unsaved changes
388 switch (QMessageBox::question(
388 switch (QMessageBox::question(
389 parentWidget, "Save changes",
389 parentWidget, tr("Save changes"),
390 tr("The catalogue controller unsaved changes.\nDo you want to save them ?"),
390 tr("The catalogue controller has unsaved changes.\nDo you want to save them ?"),
391 QMessageBox::SaveAll | QMessageBox::Discard | QMessageBox::Cancel,
391 QMessageBox::SaveAll | QMessageBox::Discard | QMessageBox::Cancel,
392 QMessageBox::SaveAll)) {
392 QMessageBox::SaveAll)) {
393 case QMessageBox::SaveAll:
393 case QMessageBox::SaveAll:
@@ -75,6 +75,10 public slots:
75 void initialize();
75 void initialize();
76 void finalize();
76 void finalize();
77
77
78 /// Request the creation of a variable from the ID_DATA_KEY of a product
79 void requestVariableFromProductIdKey(const QString &datasourceIdKey);
80
81 /// Request the creation of a variable from metadata of a product
78 void requestVariable(const QVariantHash &productData);
82 void requestVariable(const QVariantHash &productData);
79
83
80 signals:
84 signals:
@@ -145,6 +145,14 public:
145 */
145 */
146 DataSourceItem *findItem(const QVariantHash &data, bool recursive);
146 DataSourceItem *findItem(const QVariantHash &data, bool recursive);
147
147
148 /**
149 * @brief Searches the first child matching the specified \p ID_DATA_KEY in its metadata.
150 * @param id The id to search.
151 * @param recursive So the search recursively.
152 * @return the item matching the data or nullptr if it was not found.
153 */
154 DataSourceItem *findItem(const QString &datasourceIdKey, bool recursive);
155
148 bool operator==(const DataSourceItem &other);
156 bool operator==(const DataSourceItem &other);
149 bool operator!=(const DataSourceItem &other);
157 bool operator!=(const DataSourceItem &other);
150
158
@@ -4,6 +4,7
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/DataSeriesIterator.h>
6 #include <Data/DataSeriesIterator.h>
7 #include <Data/DataSeriesType.h>
7 #include <Data/SqpRange.h>
8 #include <Data/SqpRange.h>
8
9
9 #include <QLoggingCategory>
10 #include <QLoggingCategory>
@@ -54,6 +55,9 public:
54 /// @return the data of the variable, nullptr if there is no data
55 /// @return the data of the variable, nullptr if there is no data
55 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
56 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
56
57
58 /// @return the type of data that the variable holds
59 DataSeriesType type() const noexcept;
60
57 QVariantHash metadata() const noexcept;
61 QVariantHash metadata() const noexcept;
58
62
59 bool contains(const SqpRange &range) const noexcept;
63 bool contains(const SqpRange &range) const noexcept;
@@ -76,6 +80,8 public:
76
80
77 signals:
81 signals:
78 void updated();
82 void updated();
83 /// Signal emitted when when the data series of the variable is loaded for the first time
84 void dataInitialized();
79
85
80 private:
86 private:
81 class VariablePrivate;
87 class VariablePrivate;
@@ -48,26 +48,6 public:
48 */
48 */
49 std::shared_ptr<Variable> cloneVariable(std::shared_ptr<Variable> variable) noexcept;
49 std::shared_ptr<Variable> cloneVariable(std::shared_ptr<Variable> variable) noexcept;
50
50
51 /**
52 * Deletes from the controller the variable passed in parameter.
53 *
54 * Delete a variable includes:
55 * - the deletion of the various references to the variable in SciQlop
56 * - the deletion of the model variable
57 * - the deletion of the provider associated with the variable
58 * - removing the cache associated with the variable
59 *
60 * @param variable the variable to delete from the controller.
61 */
62 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
63
64 /**
65 * Deletes from the controller the variables passed in parameter.
66 * @param variables the variables to delete from the controller.
67 * @sa deleteVariable()
68 */
69 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
70
71 /// Returns the MIME data associated to a list of variables
51 /// Returns the MIME data associated to a list of variables
72 QByteArray mimeDataForVariables(const QList<std::shared_ptr<Variable> > &variables) const;
52 QByteArray mimeDataForVariables(const QList<std::shared_ptr<Variable> > &variables) const;
73
53
@@ -89,7 +69,29 signals:
89 /// validated, canceled, or failed)
69 /// validated, canceled, or failed)
90 void acquisitionFinished();
70 void acquisitionFinished();
91
71
72 void variableAdded(const std::shared_ptr<Variable> &variable);
73
92 public slots:
74 public slots:
75 /**
76 * Deletes from the controller the variable passed in parameter.
77 *
78 * Delete a variable includes:
79 * - the deletion of the various references to the variable in SciQlop
80 * - the deletion of the model variable
81 * - the deletion of the provider associated with the variable
82 * - removing the cache associated with the variable
83 *
84 * @param variable the variable to delete from the controller.
85 */
86 void deleteVariable(std::shared_ptr<Variable> variable) noexcept;
87
88 /**
89 * Deletes from the controller the variables passed in parameter.
90 * @param variables the variables to delete from the controller.
91 * @sa deleteVariable()
92 */
93 void deleteVariables(const QVector<std::shared_ptr<Variable> > &variables) noexcept;
94
93 /// Request the data loading of the variable whithin range
95 /// Request the data loading of the variable whithin range
94 void onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables, const SqpRange &range,
96 void onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables, const SqpRange &range,
95 bool synchronise);
97 bool synchronise);
@@ -37,6 +37,20 public:
37
37
38 return sourceItem;
38 return sourceItem;
39 }
39 }
40
41 // Search for the first datasource item matching the specified ID_DATA_KEY
42 DataSourceItem *findDataSourceItem(const QString &datasourceIdKey)
43 {
44 DataSourceItem *sourceItem = nullptr;
45 for (const auto &item : m_DataSourceItems) {
46 sourceItem = item.second->findItem(datasourceIdKey, true);
47 if (sourceItem) {
48 break;
49 }
50 }
51
52 return sourceItem;
53 }
40 };
54 };
41
55
42 DataSourceController::DataSourceController(QObject *parent)
56 DataSourceController::DataSourceController(QObject *parent)
@@ -149,6 +163,20 void DataSourceController::finalize()
149 impl->m_WorkingMutex.unlock();
163 impl->m_WorkingMutex.unlock();
150 }
164 }
151
165
166 void DataSourceController::requestVariableFromProductIdKey(const QString &datasourceIdKey)
167 {
168 auto sourceItem = impl->findDataSourceItem(datasourceIdKey);
169
170 if (sourceItem) {
171 auto sourceName = sourceItem->rootItem().name();
172 auto sourceId = impl->m_DataSources.key(sourceName);
173 loadProductItem(sourceId, *sourceItem);
174 }
175 else {
176 qCWarning(LOG_DataSourceController()) << tr("requestVariable, product data not found");
177 }
178 }
179
152 void DataSourceController::requestVariable(const QVariantHash &productData)
180 void DataSourceController::requestVariable(const QVariantHash &productData)
153 {
181 {
154 auto sourceItem = impl->findDataSourceItem(productData);
182 auto sourceItem = impl->findDataSourceItem(productData);
@@ -165,6 +165,24 DataSourceItem *DataSourceItem::findItem(const QVariantHash &data, bool recursiv
165 return nullptr;
165 return nullptr;
166 }
166 }
167
167
168 DataSourceItem *DataSourceItem::findItem(const QString &datasourceIdKey, bool recursive)
169 {
170 for (const auto &child : impl->m_Children) {
171 auto childId = child->impl->m_Data.value(ID_DATA_KEY);
172 if (childId == datasourceIdKey) {
173 return child.get();
174 }
175
176 if (recursive) {
177 if (auto foundItem = child->findItem(datasourceIdKey, true)) {
178 return foundItem;
179 }
180 }
181 }
182
183 return nullptr;
184 }
185
168 bool DataSourceItem::operator==(const DataSourceItem &other)
186 bool DataSourceItem::operator==(const DataSourceItem &other)
169 {
187 {
170 // Compares items' attributes
188 // Compares items' attributes
@@ -9,6 +9,29
9
9
10 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
10 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
11
11
12 namespace {
13
14 /**
15 * Searches in metadata for a value that can be converted to DataSeriesType
16 * @param metadata the metadata where to search
17 * @return the value converted to a DataSeriesType if it was found, UNKNOWN type otherwise
18 * @sa DataSeriesType
19 */
20 DataSeriesType findDataSeriesType(const QVariantHash &metadata)
21 {
22 auto dataSeriesType = DataSeriesType::UNKNOWN;
23
24 // Go through the metadata and stop at the first value that could be converted to DataSeriesType
25 for (auto it = metadata.cbegin(), end = metadata.cend();
26 it != end && dataSeriesType == DataSeriesType::UNKNOWN; ++it) {
27 dataSeriesType = DataSeriesTypeUtils::fromString(it.value().toString());
28 }
29
30 return dataSeriesType;
31 }
32
33 } // namespace
34
12 struct Variable::VariablePrivate {
35 struct Variable::VariablePrivate {
13 explicit VariablePrivate(const QString &name, const QVariantHash &metadata)
36 explicit VariablePrivate(const QString &name, const QVariantHash &metadata)
14 : m_Name{name},
37 : m_Name{name},
@@ -17,7 +40,8 struct Variable::VariablePrivate {
17 m_Metadata{metadata},
40 m_Metadata{metadata},
18 m_DataSeries{nullptr},
41 m_DataSeries{nullptr},
19 m_RealRange{INVALID_RANGE},
42 m_RealRange{INVALID_RANGE},
20 m_NbPoints{0}
43 m_NbPoints{0},
44 m_Type{findDataSeriesType(m_Metadata)}
21 {
45 {
22 }
46 }
23
47
@@ -28,7 +52,8 struct Variable::VariablePrivate {
28 m_Metadata{other.m_Metadata},
52 m_Metadata{other.m_Metadata},
29 m_DataSeries{other.m_DataSeries != nullptr ? other.m_DataSeries->clone() : nullptr},
53 m_DataSeries{other.m_DataSeries != nullptr ? other.m_DataSeries->clone() : nullptr},
30 m_RealRange{other.m_RealRange},
54 m_RealRange{other.m_RealRange},
31 m_NbPoints{other.m_NbPoints}
55 m_NbPoints{other.m_NbPoints},
56 m_Type{findDataSeriesType(m_Metadata)}
32 {
57 {
33 }
58 }
34
59
@@ -75,6 +100,7 struct Variable::VariablePrivate {
75 std::shared_ptr<IDataSeries> m_DataSeries;
100 std::shared_ptr<IDataSeries> m_DataSeries;
76 SqpRange m_RealRange;
101 SqpRange m_RealRange;
77 int m_NbPoints;
102 int m_NbPoints;
103 DataSeriesType m_Type;
78
104
79 QReadWriteLock m_Lock;
105 QReadWriteLock m_Lock;
80 };
106 };
@@ -161,16 +187,23 void Variable::mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
161 return;
187 return;
162 }
188 }
163
189
190 auto dataInit = false;
191
164 // Add or merge the data
192 // Add or merge the data
165 impl->lockWrite();
193 impl->lockWrite();
166 if (!impl->m_DataSeries) {
194 if (!impl->m_DataSeries) {
167 impl->m_DataSeries = dataSeries->clone();
195 impl->m_DataSeries = dataSeries->clone();
196 dataInit = true;
168 }
197 }
169 else {
198 else {
170 impl->m_DataSeries->merge(dataSeries.get());
199 impl->m_DataSeries->merge(dataSeries.get());
171 }
200 }
172 impl->purgeDataSeries();
201 impl->purgeDataSeries();
173 impl->unlock();
202 impl->unlock();
203
204 if (dataInit) {
205 emit dataInitialized();
206 }
174 }
207 }
175
208
176
209
@@ -183,6 +216,15 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
183 return dataSeries;
216 return dataSeries;
184 }
217 }
185
218
219 DataSeriesType Variable::type() const noexcept
220 {
221 impl->lockRead();
222 auto type = impl->m_Type;
223 impl->unlock();
224
225 return type;
226 }
227
186 QVariantHash Variable::metadata() const noexcept
228 QVariantHash Variable::metadata() const noexcept
187 {
229 {
188 impl->lockRead();
230 impl->lockRead();
@@ -373,6 +373,8 VariableController::createVariable(const QString &name, const QVariantHash &meta
373 // impl->processRequest(newVariable, range, varRequestId);
373 // impl->processRequest(newVariable, range, varRequestId);
374 // impl->updateVariableRequest(varRequestId);
374 // impl->updateVariableRequest(varRequestId);
375
375
376 emit variableAdded(newVariable);
377
376 return newVariable;
378 return newVariable;
377 }
379 }
378
380
@@ -9,6 +9,7 class DBCatalogue;
9 class DBEvent;
9 class DBEvent;
10 class DBEventProduct;
10 class DBEventProduct;
11 class VisualizationWidget;
11 class VisualizationWidget;
12 class VisualizationSelectionZoneItem;
12
13
13 namespace Ui {
14 namespace Ui {
14 class CatalogueEventsWidget;
15 class CatalogueEventsWidget;
@@ -21,10 +22,13 class CatalogueEventsWidget : public QWidget {
21
22
22 signals:
23 signals:
23 void eventsSelected(const QVector<std::shared_ptr<DBEvent> > &event);
24 void eventsSelected(const QVector<std::shared_ptr<DBEvent> > &event);
25 void eventsRemoved(const QVector<std::shared_ptr<DBEvent> > &event);
24 void eventProductsSelected(
26 void eventProductsSelected(
25 const QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > >
27 const QVector<QPair<std::shared_ptr<DBEvent>, std::shared_ptr<DBEventProduct> > >
26 &eventproducts);
28 &eventproducts);
27 void selectionCleared();
29 void selectionCleared();
30 void selectionZoneAdded(const std::shared_ptr<DBEvent> &event, const QString &productId,
31 VisualizationSelectionZoneItem *selectionZone);
28
32
29 public:
33 public:
30 explicit CatalogueEventsWidget(QWidget *parent = 0);
34 explicit CatalogueEventsWidget(QWidget *parent = 0);
@@ -39,6 +43,8 public:
39 bool isAllEventsDisplayed() const;
43 bool isAllEventsDisplayed() const;
40 bool isEventDisplayed(const std::shared_ptr<DBEvent> &event) const;
44 bool isEventDisplayed(const std::shared_ptr<DBEvent> &event) const;
41
45
46 void refreshEvent(const std::shared_ptr<DBEvent> &event);
47
42 public slots:
48 public slots:
43 void populateWithCatalogues(const QVector<std::shared_ptr<DBCatalogue> > &catalogues);
49 void populateWithCatalogues(const QVector<std::shared_ptr<DBCatalogue> > &catalogues);
44 void populateWithAllEvents();
50 void populateWithAllEvents();
@@ -12,6 +12,10 class CatalogueEventsWidget;
12 class CatalogueSideBarWidget;
12 class CatalogueSideBarWidget;
13
13
14 class VisualizationWidget;
14 class VisualizationWidget;
15 class VisualizationSelectionZoneItem;
16
17 class DBEvent;
18
15
19
16 class CatalogueExplorer : public QDialog {
20 class CatalogueExplorer : public QDialog {
17 Q_OBJECT
21 Q_OBJECT
@@ -25,6 +29,10 public:
25 CatalogueEventsWidget &eventsWidget() const;
29 CatalogueEventsWidget &eventsWidget() const;
26 CatalogueSideBarWidget &sideBarWidget() const;
30 CatalogueSideBarWidget &sideBarWidget() const;
27
31
32 void clearSelectionZones();
33 void addSelectionZoneItem(const std::shared_ptr<DBEvent> &event, const QString &productId,
34 VisualizationSelectionZoneItem *selectionZone);
35
28 private:
36 private:
29 Ui::CatalogueExplorer *ui;
37 Ui::CatalogueExplorer *ui;
30
38
@@ -36,6 +36,8 public:
36 const std::shared_ptr<DBEventProduct> &eventProduct);
36 const std::shared_ptr<DBEventProduct> &eventProduct);
37 void setCatalogue(const std::shared_ptr<DBCatalogue> &catalogue);
37 void setCatalogue(const std::shared_ptr<DBCatalogue> &catalogue);
38
38
39 void refresh();
40
39 public slots:
41 public slots:
40 void showPage(Page page);
42 void showPage(Page page);
41
43
@@ -12,6 +12,7 class IDataSeries;
12 class QCPAxis;
12 class QCPAxis;
13 class QCustomPlot;
13 class QCustomPlot;
14 class SqpColorScale;
14 class SqpColorScale;
15 class Variable;
15
16
16 /// Formats a data value according to the axis on which it is present
17 /// Formats a data value according to the axis on which it is present
17 QString formatValue(double value, const QCPAxis &axis);
18 QString formatValue(double value, const QCPAxis &axis);
@@ -27,11 +28,17 struct IAxisHelper {
27 /// @param plot the plot for which to set axe properties
28 /// @param plot the plot for which to set axe properties
28 /// @param colorScale the color scale for which to set properties
29 /// @param colorScale the color scale for which to set properties
29 virtual void setProperties(QCustomPlot &plot, SqpColorScale &colorScale) = 0;
30 virtual void setProperties(QCustomPlot &plot, SqpColorScale &colorScale) = 0;
31
32 /// Set the units of the plot's axes and the color scale associated to plot passed as
33 /// parameters
34 /// @param plot the plot for which to set axe units
35 /// @param colorScale the color scale for which to set unit
36 virtual void setUnits(QCustomPlot &plot, SqpColorScale &colorScale) = 0;
30 };
37 };
31
38
32 struct IAxisHelperFactory {
39 struct IAxisHelperFactory {
33 /// Creates IAxisHelper according to a data series
40 /// Creates IPlottablesHelper according to the type of data series a variable holds
34 static std::unique_ptr<IAxisHelper> create(std::shared_ptr<IDataSeries> dataSeries) noexcept;
41 static std::unique_ptr<IAxisHelper> create(const Variable &variable) noexcept;
35 };
42 };
36
43
37 #endif // SCIQLOP_AXISRENDERINGUTILS_H
44 #endif // SCIQLOP_AXISRENDERINGUTILS_H
@@ -1,6 +1,8
1 #ifndef SCIQLOP_PLOTTABLESRENDERINGUTILS_H
1 #ifndef SCIQLOP_PLOTTABLESRENDERINGUTILS_H
2 #define SCIQLOP_PLOTTABLESRENDERINGUTILS_H
2 #define SCIQLOP_PLOTTABLESRENDERINGUTILS_H
3
3
4 #include <Data/DataSeriesType.h>
5
4 #include <Visualization/VisualizationDefs.h>
6 #include <Visualization/VisualizationDefs.h>
5
7
6 #include <memory>
8 #include <memory>
@@ -9,9 +11,9
9
11
10 Q_DECLARE_LOGGING_CATEGORY(LOG_PlottablesRenderingUtils)
12 Q_DECLARE_LOGGING_CATEGORY(LOG_PlottablesRenderingUtils)
11
13
12 class IDataSeries;
13 class QCPColorScale;
14 class QCPColorScale;
14 class QCustomPlot;
15 class QCustomPlot;
16 class Variable;
15
17
16 /**
18 /**
17 * Helper used to handle plottables rendering
19 * Helper used to handle plottables rendering
@@ -25,9 +27,8 struct IPlottablesHelper {
25 };
27 };
26
28
27 struct IPlottablesHelperFactory {
29 struct IPlottablesHelperFactory {
28 /// Creates IPlottablesHelper according to a data series
30 /// Creates IPlottablesHelper according to the type of data series a variable holds
29 static std::unique_ptr<IPlottablesHelper>
31 static std::unique_ptr<IPlottablesHelper> create(const Variable &variable) noexcept;
30 create(std::shared_ptr<IDataSeries> dataSeries) noexcept;
31 };
32 };
32
33
33 #endif // SCIQLOP_PLOTTABLESRENDERINGUTILS_H
34 #endif // SCIQLOP_PLOTTABLESRENDERINGUTILS_H
@@ -32,7 +32,7 struct VisualizationGraphHelper {
32 */
32 */
33 static PlottablesMap create(std::shared_ptr<Variable> variable, QCustomPlot &plot) noexcept;
33 static PlottablesMap create(std::shared_ptr<Variable> variable, QCustomPlot &plot) noexcept;
34
34
35 static void updateData(PlottablesMap &plottables, std::shared_ptr<IDataSeries> dataSeries,
35 static void updateData(PlottablesMap &plottables, std::shared_ptr<Variable> variable,
36 const SqpRange &dateTime);
36 const SqpRange &dateTime);
37
37
38 static void setYAxisRange(std::shared_ptr<Variable> variable, QCustomPlot &plot) noexcept;
38 static void setYAxisRange(std::shared_ptr<Variable> variable, QCustomPlot &plot) noexcept;
@@ -9,6 +9,7 class IDataSeries;
9 class QCustomPlot;
9 class QCustomPlot;
10 class QMouseEvent;
10 class QMouseEvent;
11 class Unit;
11 class Unit;
12 class Variable;
12 class VisualizationGraphWidget;
13 class VisualizationGraphWidget;
13
14
14 class VisualizationGraphRenderingDelegate {
15 class VisualizationGraphRenderingDelegate {
@@ -23,13 +24,14 public:
23 /// Updates rendering when data of plot changed
24 /// Updates rendering when data of plot changed
24 void onPlotUpdated() noexcept;
25 void onPlotUpdated() noexcept;
25
26
26 /// Sets properties of the plot's axes from the data series passed as parameter
27 /// Sets units of the plot's axes according to the properties of the variable passed as
27 void setAxesProperties(std::shared_ptr<IDataSeries> dataSeries) noexcept;
28 /// parameter
29 void setAxesUnits(const Variable &variable) noexcept;
28
30
29 /// Sets rendering properties of the plottables passed as parameter, from the data series that
31 /// Sets graph properties of the plottables passed as parameter, from the variable that
30 /// generated these
32 /// generated these
31 void setPlottablesProperties(std::shared_ptr<IDataSeries> dataSeries,
33 void setGraphProperties(const Variable &variable, PlottablesMap &plottables) noexcept;
32 PlottablesMap &plottables) noexcept;
34
33
35
34 /// Shows or hides graph overlay (name, close button, etc.)
36 /// Shows or hides graph overlay (name, close button, etc.)
35 void showGraphOverlay(bool show) noexcept;
37 void showGraphOverlay(bool show) noexcept;
@@ -69,13 +69,16 public:
69 /// Sets the y-axis range based on the data of a variable
69 /// Sets the y-axis range based on the data of a variable
70 void setYRange(std::shared_ptr<Variable> variable);
70 void setYRange(std::shared_ptr<Variable> variable);
71 SqpRange graphRange() const noexcept;
71 SqpRange graphRange() const noexcept;
72 void setGraphRange(const SqpRange &range);
72 void setGraphRange(const SqpRange &range, bool calibration = false);
73 void setAutoRangeOnVariableInitialization(bool value);
73
74
74 // Zones
75 // Zones
75 /// Returns the ranges of all the selection zones on the graph
76 /// Returns the ranges of all the selection zones on the graph
76 QVector<SqpRange> selectionZoneRanges() const;
77 QVector<SqpRange> selectionZoneRanges() const;
77 /// Adds new selection zones in the graph
78 /// Adds new selection zones in the graph
78 void addSelectionZones(const QVector<SqpRange> &ranges);
79 void addSelectionZones(const QVector<SqpRange> &ranges);
80 /// Adds a new selection zone in the graph
81 VisualizationSelectionZoneItem *addSelectionZone(const QString &name, const SqpRange &range);
79 /// Removes the specified selection zone
82 /// Removes the specified selection zone
80 void removeSelectionZone(VisualizationSelectionZoneItem *selectionZone);
83 void removeSelectionZone(VisualizationSelectionZoneItem *selectionZone);
81
84
@@ -8,6 +8,11
8 class VisualizationGraphWidget;
8 class VisualizationGraphWidget;
9
9
10 class VisualizationSelectionZoneItem : public QCPItemRect {
10 class VisualizationSelectionZoneItem : public QCPItemRect {
11 Q_OBJECT
12
13 signals:
14 /// Signal emitted when the zone range is edited manually
15 void rangeEdited(const SqpRange &range);
11
16
12 public:
17 public:
13 VisualizationSelectionZoneItem(QCustomPlot *plot);
18 VisualizationSelectionZoneItem(QCustomPlot *plot);
@@ -20,6 +20,7 gui_moc_headers = [
20 'include/Visualization/VisualizationDragDropContainer.h',
20 'include/Visualization/VisualizationDragDropContainer.h',
21 'include/Visualization/VisualizationDragWidget.h',
21 'include/Visualization/VisualizationDragWidget.h',
22 'include/Visualization/ColorScaleEditor.h',
22 'include/Visualization/ColorScaleEditor.h',
23 'include/Visualization/VisualizationSelectionZoneItem.h',
23 'include/Actions/SelectionZoneAction.h',
24 'include/Actions/SelectionZoneAction.h',
24 'include/Visualization/VisualizationMultiZoneSelectionDialog.h',
25 'include/Visualization/VisualizationMultiZoneSelectionDialog.h',
25 'include/Catalogue/CatalogueExplorer.h',
26 'include/Catalogue/CatalogueExplorer.h',
@@ -48,14 +48,18 struct CatalogueActionManager::CatalogueActionManagerPrivate {
48 auto eventProduct = std::make_shared<DBEventProduct>();
48 auto eventProduct = std::make_shared<DBEventProduct>();
49 eventProduct->setEvent(*event);
49 eventProduct->setEvent(*event);
50
50
51 auto productId
52 = var->metadata().value(DataSourceItem::ID_DATA_KEY, "UnknownID").toString();
53
51 auto zoneRange = zone->range();
54 auto zoneRange = zone->range();
52 eventProduct->setTStart(zoneRange.m_TStart);
55 eventProduct->setTStart(zoneRange.m_TStart);
53 eventProduct->setTEnd(zoneRange.m_TEnd);
56 eventProduct->setTEnd(zoneRange.m_TEnd);
54
57
55 eventProduct->setProductId(
58 eventProduct->setProductId(productId);
56 var->metadata().value(DataSourceItem::ID_DATA_KEY, "UnknownID").toString());
57
59
58 productList.push_back(*eventProduct);
60 productList.push_back(*eventProduct);
61
62 m_CatalogueExplorer->addSelectionZoneItem(event, productId, zone);
59 }
63 }
60 }
64 }
61
65
@@ -6,7 +6,13
6 #include <Catalogue/CatalogueExplorerHelper.h>
6 #include <Catalogue/CatalogueExplorerHelper.h>
7 #include <CatalogueDao.h>
7 #include <CatalogueDao.h>
8 #include <DBCatalogue.h>
8 #include <DBCatalogue.h>
9 #include <DBEventProduct.h>
10 #include <DataSource/DataSourceController.h>
11 #include <DataSource/DataSourceItem.h>
9 #include <SqpApplication.h>
12 #include <SqpApplication.h>
13 #include <Variable/Variable.h>
14 #include <Variable/VariableController.h>
15 #include <Visualization/VisualizationGraphWidget.h>
10 #include <Visualization/VisualizationTabWidget.h>
16 #include <Visualization/VisualizationTabWidget.h>
11 #include <Visualization/VisualizationWidget.h>
17 #include <Visualization/VisualizationWidget.h>
12 #include <Visualization/VisualizationZoneWidget.h>
18 #include <Visualization/VisualizationZoneWidget.h>
@@ -21,6 +27,9 Q_LOGGING_CATEGORY(LOG_CatalogueEventsWidget, "CatalogueEventsWidget")
21 /// Fixed size of the validation column
27 /// Fixed size of the validation column
22 const auto VALIDATION_COLUMN_SIZE = 35;
28 const auto VALIDATION_COLUMN_SIZE = 35;
23
29
30 /// Percentage added to the range of a event when it is displayed
31 const auto EVENT_RANGE_MARGE = 30; // in %
32
24 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
33 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
25
34
26 CatalogueEventsModel *m_Model = nullptr;
35 CatalogueEventsModel *m_Model = nullptr;
@@ -28,6 +37,7 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
28 QString m_ZoneForGraphMode;
37 QString m_ZoneForGraphMode;
29 QVector<std::shared_ptr<DBCatalogue> > m_DisplayedCatalogues;
38 QVector<std::shared_ptr<DBCatalogue> > m_DisplayedCatalogues;
30 bool m_AllEventDisplayed = false;
39 bool m_AllEventDisplayed = false;
40 QVector<VisualizationGraphWidget *> m_CustomGraphs;
31
41
32 VisualizationWidget *m_VisualizationWidget = nullptr;
42 VisualizationWidget *m_VisualizationWidget = nullptr;
33
43
@@ -178,31 +188,134 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate {
178 }
188 }
179 }
189 }
180
190
181 void updateForGraphMode(QTreeView *treeView)
191 QVector<SqpRange> getGraphRanges(const std::shared_ptr<DBEvent> &event)
182 {
192 {
183 auto selectedRows = treeView->selectionModel()->selectedRows();
193 // Retrieves the range of each product and the maximum size
184
194 QVector<SqpRange> graphRanges;
185 if (selectedRows.count() == 1) {
195 double maxDt = 0;
186 auto event = m_Model->getEvent(selectedRows.first());
196 for (auto eventProduct : event->getEventProducts()) {
187 if (m_VisualizationWidget) {
197 SqpRange eventRange;
188 if (auto tab = m_VisualizationWidget->currentTabWidget()) {
198 eventRange.m_TStart = eventProduct.getTStart();
189 if (auto zone = tab->getZoneWithName(m_ZoneForGraphMode)) {
199 eventRange.m_TEnd = eventProduct.getTEnd();
190 // TODO
200 graphRanges << eventRange;
191 }
201
192 }
202 auto dt = eventRange.m_TEnd - eventRange.m_TStart;
193 else {
203 if (dt > maxDt) {
194 qCWarning(LOG_CatalogueEventsWidget())
204 maxDt = dt;
195 << "updateGraphMode: no tab found in the visualization";
196 }
197 }
198 else {
199 qCWarning(LOG_CatalogueEventsWidget())
200 << "updateGraphMode: visualization widget not found";
201 }
205 }
202 }
206 }
203 else {
207
208 // Adds the marge
209 maxDt *= (100.0 + EVENT_RANGE_MARGE) / 100.0;
210
211 // Corrects the graph ranges so that they all have the same size
212 QVector<SqpRange> correctedGraphRanges;
213 for (auto range : graphRanges) {
214 auto dt = range.m_TEnd - range.m_TStart;
215 auto diff = qAbs((maxDt - dt) / 2.0);
216
217 SqpRange correctedRange;
218 correctedRange.m_TStart = range.m_TStart - diff;
219 correctedRange.m_TEnd = range.m_TEnd + diff;
220
221 correctedGraphRanges << correctedRange;
222 }
223
224 return correctedGraphRanges;
225 }
226
227 void updateForGraphMode(CatalogueEventsWidget *catalogueEventWidget)
228 {
229 auto selectedRows = catalogueEventWidget->ui->treeView->selectionModel()->selectedRows();
230 if (selectedRows.count() != 1) {
204 qCWarning(LOG_CatalogueEventsWidget())
231 qCWarning(LOG_CatalogueEventsWidget())
205 << "updateGraphMode: not compatible with multiple events selected";
232 << "updateGraphMode: not compatible with multiple events selected";
233 return;
234 }
235
236 if (!m_VisualizationWidget) {
237 qCWarning(LOG_CatalogueEventsWidget())
238 << "updateGraphMode: visualization widget not found";
239 return;
240 }
241
242 auto event = m_Model->getEvent(selectedRows.first());
243 if (!event) {
244 // A event product is probably selected
245 qCInfo(LOG_CatalogueEventsWidget()) << "updateGraphMode: no events are selected";
246 return;
247 }
248
249 auto tab = m_VisualizationWidget->currentTabWidget();
250 if (!tab) {
251 qCWarning(LOG_CatalogueEventsWidget())
252 << "updateGraphMode: no tab found in the visualization";
253 return;
254 }
255
256 auto zone = tab->getZoneWithName(m_ZoneForGraphMode);
257 if (!zone) {
258 qCWarning(LOG_CatalogueEventsWidget()) << "updateGraphMode: zone not found";
259 return;
260 }
261
262 // Close the previous graph and delete the asociated variables
263 for (auto graph : m_CustomGraphs) {
264 graph->close();
265 auto variables = graph->variables().toVector();
266
267 QMetaObject::invokeMethod(&sqpApp->variableController(), "deleteVariables",
268 Qt::QueuedConnection,
269 Q_ARG(QVector<std::shared_ptr<Variable> >, variables));
270 }
271 m_CustomGraphs.clear();
272
273 // Calculates the range of each graph which will be created
274 auto graphRange = getGraphRanges(event);
275
276 // Loops through the event products and create the graph
277 auto itRange = graphRange.cbegin();
278 for (auto eventProduct : event->getEventProducts()) {
279 auto productId = eventProduct.getProductId();
280
281 auto range = *itRange;
282 ++itRange;
283
284 SqpRange productRange;
285 productRange.m_TStart = eventProduct.getTStart();
286 productRange.m_TEnd = eventProduct.getTEnd();
287
288 auto context = new QObject{catalogueEventWidget};
289 QObject::connect(
290 &sqpApp->variableController(), &VariableController::variableAdded, context,
291 [this, catalogueEventWidget, zone, context, event, range, productRange,
292 productId](auto variable) {
293
294 if (variable->metadata().value(DataSourceItem::ID_DATA_KEY).toString()
295 == productId) {
296 auto graph = zone->createGraph(variable);
297 graph->setAutoRangeOnVariableInitialization(false);
298
299 auto selectionZone
300 = graph->addSelectionZone(event->getName(), productRange);
301 emit catalogueEventWidget->selectionZoneAdded(event, productId,
302 selectionZone);
303 m_CustomGraphs << graph;
304
305 graph->setGraphRange(range, true);
306
307 // Removes the graph from the graph list if it is closed manually
308 QObject::connect(graph, &VisualizationGraphWidget::destroyed,
309 [this, graph]() { m_CustomGraphs.removeAll(graph); });
310
311 delete context; // removes the connection
312 }
313 },
314 Qt::QueuedConnection);
315
316 QMetaObject::invokeMethod(&sqpApp->dataSourceController(),
317 "requestVariableFromProductIdKey", Qt::QueuedConnection,
318 Q_ARG(QString, productId));
206 }
319 }
207 }
320 }
208
321
@@ -256,7 +369,7 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
256 this->mapToGlobal(ui->btnChart->frameGeometry().center()))
369 this->mapToGlobal(ui->btnChart->frameGeometry().center()))
257 .value(0);
370 .value(0);
258
371
259 impl->updateForGraphMode(ui->treeView);
372 impl->updateForGraphMode(this);
260 }
373 }
261 });
374 });
262
375
@@ -268,7 +381,7 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
268 if (!events.isEmpty() && eventProducts.isEmpty()) {
381 if (!events.isEmpty() && eventProducts.isEmpty()) {
269
382
270 if (QMessageBox::warning(this, tr("Remove Event(s)"),
383 if (QMessageBox::warning(this, tr("Remove Event(s)"),
271 tr("The selected event(s) will be completly removed "
384 tr("The selected event(s) will be permanently removed "
272 "from the repository!\nAre you sure you want to continue?"),
385 "from the repository!\nAre you sure you want to continue?"),
273 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
386 QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
274 == QMessageBox::Yes) {
387 == QMessageBox::Yes) {
@@ -277,6 +390,8 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
277 sqpApp->catalogueController().removeEvent(event);
390 sqpApp->catalogueController().removeEvent(event);
278 impl->removeEvent(event, ui->treeView);
391 impl->removeEvent(event, ui->treeView);
279 }
392 }
393
394 emit this->eventsRemoved(events);
280 }
395 }
281 }
396 }
282 });
397 });
@@ -295,7 +410,7 CatalogueEventsWidget::CatalogueEventsWidget(QWidget *parent)
295 impl->updateForTimeMode(ui->treeView);
410 impl->updateForTimeMode(ui->treeView);
296 }
411 }
297 else if (isNotMultiSelection && ui->btnChart->isChecked()) {
412 else if (isNotMultiSelection && ui->btnChart->isChecked()) {
298 impl->updateForGraphMode(ui->treeView);
413 impl->updateForGraphMode(this);
299 }
414 }
300
415
301 QVector<std::shared_ptr<DBEvent> > events;
416 QVector<std::shared_ptr<DBEvent> > events;
@@ -398,6 +513,11 bool CatalogueEventsWidget::isEventDisplayed(const std::shared_ptr<DBEvent> &eve
398 return impl->m_Model->indexOf(event).isValid();
513 return impl->m_Model->indexOf(event).isValid();
399 }
514 }
400
515
516 void CatalogueEventsWidget::refreshEvent(const std::shared_ptr<DBEvent> &event)
517 {
518 impl->m_Model->refreshEvent(event, true);
519 }
520
401 void CatalogueEventsWidget::populateWithCatalogues(
521 void CatalogueEventsWidget::populateWithCatalogues(
402 const QVector<std::shared_ptr<DBCatalogue> > &catalogues)
522 const QVector<std::shared_ptr<DBCatalogue> > &catalogues)
403 {
523 {
@@ -4,13 +4,22
4 #include <Catalogue/CatalogueActionManager.h>
4 #include <Catalogue/CatalogueActionManager.h>
5 #include <Catalogue/CatalogueController.h>
5 #include <Catalogue/CatalogueController.h>
6 #include <SqpApplication.h>
6 #include <SqpApplication.h>
7 #include <Visualization/VisualizationGraphWidget.h>
8 #include <Visualization/VisualizationSelectionZoneItem.h>
7 #include <Visualization/VisualizationWidget.h>
9 #include <Visualization/VisualizationWidget.h>
8
10
9 #include <DBCatalogue.h>
11 #include <DBCatalogue.h>
10 #include <DBEvent.h>
12 #include <DBEvent.h>
13 #include <DBEventProduct.h>
14
15 #include <unordered_map>
11
16
12 struct CatalogueExplorer::CatalogueExplorerPrivate {
17 struct CatalogueExplorer::CatalogueExplorerPrivate {
13 CatalogueActionManager m_ActionManager;
18 CatalogueActionManager m_ActionManager;
19 std::unordered_map<std::shared_ptr<DBEvent>, QVector<VisualizationSelectionZoneItem *> >
20 m_SelectionZonesPerEvents;
21
22 QMetaObject::Connection m_Conn;
14
23
15 CatalogueExplorerPrivate(CatalogueExplorer *catalogueExplorer)
24 CatalogueExplorerPrivate(CatalogueExplorer *catalogueExplorer)
16 : m_ActionManager(catalogueExplorer)
25 : m_ActionManager(catalogueExplorer)
@@ -27,6 +36,7 CatalogueExplorer::CatalogueExplorer(QWidget *parent)
27
36
28 impl->m_ActionManager.installSelectionZoneActions();
37 impl->m_ActionManager.installSelectionZoneActions();
29
38
39 // Updates events and inspector when something is selected in the catalogue widget
30 connect(ui->catalogues, &CatalogueSideBarWidget::catalogueSelected, [this](auto catalogues) {
40 connect(ui->catalogues, &CatalogueSideBarWidget::catalogueSelected, [this](auto catalogues) {
31 if (catalogues.count() == 1) {
41 if (catalogues.count() == 1) {
32 ui->inspector->setCatalogue(catalogues.first());
42 ui->inspector->setCatalogue(catalogues.first());
@@ -66,6 +76,7 CatalogueExplorer::CatalogueExplorer(QWidget *parent)
66 ui->events->clear();
76 ui->events->clear();
67 });
77 });
68
78
79 // Updates the inspectot when something is selected in the events
69 connect(ui->events, &CatalogueEventsWidget::eventsSelected, [this](auto events) {
80 connect(ui->events, &CatalogueEventsWidget::eventsSelected, [this](auto events) {
70 if (events.count() == 1) {
81 if (events.count() == 1) {
71 ui->inspector->setEvent(events.first());
82 ui->inspector->setEvent(events.first());
@@ -88,6 +99,27 CatalogueExplorer::CatalogueExplorer(QWidget *parent)
88 connect(ui->events, &CatalogueEventsWidget::selectionCleared,
99 connect(ui->events, &CatalogueEventsWidget::selectionCleared,
89 [this]() { ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty); });
100 [this]() { ui->inspector->showPage(CatalogueInspectorWidget::Page::Empty); });
90
101
102 // Manage Selection Zones associated to events
103 connect(ui->events, &CatalogueEventsWidget::selectionZoneAdded,
104 [this](auto event, auto productId, auto zone) {
105 this->addSelectionZoneItem(event, productId, zone);
106 });
107
108 connect(ui->events, &CatalogueEventsWidget::eventsRemoved, [this](auto events) {
109 for (auto event : events) {
110 auto associatedSelectionZonesIt = impl->m_SelectionZonesPerEvents.find(event);
111 if (associatedSelectionZonesIt != impl->m_SelectionZonesPerEvents.cend()) {
112 for (auto selectionZone : associatedSelectionZonesIt->second) {
113 auto parentGraph = selectionZone->parentGraphWidget();
114 parentGraph->removeSelectionZone(selectionZone);
115 }
116
117 impl->m_SelectionZonesPerEvents.erase(event);
118 }
119 }
120 });
121
122 // Updates changes from the inspector
91 connect(ui->inspector, &CatalogueInspectorWidget::catalogueUpdated, [this](auto catalogue) {
123 connect(ui->inspector, &CatalogueInspectorWidget::catalogueUpdated, [this](auto catalogue) {
92 sqpApp->catalogueController().updateCatalogue(catalogue);
124 sqpApp->catalogueController().updateCatalogue(catalogue);
93 ui->catalogues->setCatalogueChanges(catalogue, true);
125 ui->catalogues->setCatalogueChanges(catalogue, true);
@@ -107,6 +139,7 CatalogueExplorer::CatalogueExplorer(QWidget *parent)
107
139
108 CatalogueExplorer::~CatalogueExplorer()
140 CatalogueExplorer::~CatalogueExplorer()
109 {
141 {
142 disconnect(impl->m_Conn);
110 delete ui;
143 delete ui;
111 }
144 }
112
145
@@ -124,3 +157,37 CatalogueSideBarWidget &CatalogueExplorer::sideBarWidget() const
124 {
157 {
125 return *ui->catalogues;
158 return *ui->catalogues;
126 }
159 }
160
161 void CatalogueExplorer::clearSelectionZones()
162 {
163 impl->m_SelectionZonesPerEvents.clear();
164 }
165
166 void CatalogueExplorer::addSelectionZoneItem(const std::shared_ptr<DBEvent> &event,
167 const QString &productId,
168 VisualizationSelectionZoneItem *selectionZone)
169 {
170 impl->m_SelectionZonesPerEvents[event] << selectionZone;
171 connect(selectionZone, &VisualizationSelectionZoneItem::rangeEdited,
172 [event, productId, this](auto range) {
173 auto productList = event->getEventProducts();
174 for (auto &product : productList) {
175 if (product.getProductId() == productId) {
176 product.setTStart(range.m_TStart);
177 product.setTEnd(range.m_TEnd);
178 }
179 }
180 event->setEventProducts(productList);
181 sqpApp->catalogueController().updateEvent(event);
182 ui->events->refreshEvent(event);
183 ui->events->setEventChanges(event, true);
184 ui->inspector->refresh();
185 });
186
187 impl->m_Conn = connect(selectionZone, &VisualizationSelectionZoneItem::destroyed,
188 [event, selectionZone, this]() {
189 if (!impl->m_SelectionZonesPerEvents.empty()) {
190 impl->m_SelectionZonesPerEvents[event].removeAll(selectionZone);
191 }
192 });
193 }
@@ -209,3 +209,19 void CatalogueInspectorWidget::setCatalogue(const std::shared_ptr<DBCatalogue> &
209
209
210 blockSignals(false);
210 blockSignals(false);
211 }
211 }
212
213 void CatalogueInspectorWidget::refresh()
214 {
215 switch (static_cast<Page>(ui->stackedWidget->currentIndex())) {
216 case Page::CatalogueProperties:
217 setCatalogue(impl->m_DisplayedCatalogue);
218 break;
219 case Page::EventProperties: {
220 auto isEventShowed = ui->leEventName->isEnabled();
221 setEvent(impl->m_DisplayedEvent);
222 if (!isEventShowed && impl->m_DisplayedEvent) {
223 setEventProduct(impl->m_DisplayedEvent, impl->m_DisplayedEventProduct);
224 }
225 }
226 }
227 }
@@ -7,6 +7,7
7 #include "Visualization/VisualizationWidget.h"
7 #include "Visualization/VisualizationWidget.h"
8 #include "Visualization/operations/FindVariableOperation.h"
8 #include "Visualization/operations/FindVariableOperation.h"
9
9
10 #include "DataSource/DataSourceController.h"
10 #include "Variable/Variable.h"
11 #include "Variable/Variable.h"
11 #include "Variable/VariableController.h"
12 #include "Variable/VariableController.h"
12
13
@@ -286,11 +287,22 bool DragDropGuiController::checkMimeDataForVisualization(
286 // result = false: cannot drop multiple variables in the visualisation
287 // result = false: cannot drop multiple variables in the visualisation
287 }
288 }
288 }
289 }
290 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
291 auto productDataList = sqpApp->dataSourceController().productsDataForMimeData(
292 mimeData->data(MIME_TYPE_PRODUCT_LIST));
293 if (productDataList.count() == 1) {
294 result = true;
295 }
296 else {
297 // result = false: cannot drop multiple products in the visualisation
298 }
299 }
289 else {
300 else {
290 // Other MIME data
301 // Other MIME data
291 // no special rules, accepted by default
302 // no special rules, accepted by default
292 result = true;
303 result = true;
293 }
304 }
294
305
306
295 return result;
307 return result;
296 }
308 }
@@ -4,6 +4,8
4 #include <Data/SpectrogramSeries.h>
4 #include <Data/SpectrogramSeries.h>
5 #include <Data/VectorSeries.h>
5 #include <Data/VectorSeries.h>
6
6
7 #include <Variable/Variable.h>
8
7 #include <Visualization/SqpColorScale.h>
9 #include <Visualization/SqpColorScale.h>
8 #include <Visualization/qcustomplot.h>
10 #include <Visualization/qcustomplot.h>
9
11
@@ -68,11 +70,17 void setAxisProperties(QCPAxis &axis, const Unit &unit,
68 */
70 */
69 template <typename T, typename Enabled = void>
71 template <typename T, typename Enabled = void>
70 struct AxisSetter {
72 struct AxisSetter {
71 static void setProperties(T &, QCustomPlot &, SqpColorScale &)
73 static void setProperties(QCustomPlot &, SqpColorScale &)
72 {
74 {
73 // Default implementation does nothing
75 // Default implementation does nothing
74 qCCritical(LOG_AxisRenderingUtils()) << "Can't set axis properties: unmanaged type of data";
76 qCCritical(LOG_AxisRenderingUtils()) << "Can't set axis properties: unmanaged type of data";
75 }
77 }
78
79 static void setUnits(T &, QCustomPlot &, SqpColorScale &)
80 {
81 // Default implementation does nothing
82 qCCritical(LOG_AxisRenderingUtils()) << "Can't set axis units: unmanaged type of data";
83 }
76 };
84 };
77
85
78 /**
86 /**
@@ -83,7 +91,12 struct AxisSetter {
83 template <typename T>
91 template <typename T>
84 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
92 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
85 or std::is_base_of<VectorSeries, T>::value> > {
93 or std::is_base_of<VectorSeries, T>::value> > {
86 static void setProperties(T &dataSeries, QCustomPlot &plot, SqpColorScale &)
94 static void setProperties(QCustomPlot &, SqpColorScale &)
95 {
96 // Nothing to do
97 }
98
99 static void setUnits(T &dataSeries, QCustomPlot &plot, SqpColorScale &)
87 {
100 {
88 dataSeries.lockRead();
101 dataSeries.lockRead();
89 auto xAxisUnit = dataSeries.xAxisUnit();
102 auto xAxisUnit = dataSeries.xAxisUnit();
@@ -101,17 +114,8 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>:
101 */
114 */
102 template <typename T>
115 template <typename T>
103 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
116 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
104 static void setProperties(T &dataSeries, QCustomPlot &plot, SqpColorScale &colorScale)
117 static void setProperties(QCustomPlot &plot, SqpColorScale &colorScale)
105 {
118 {
106 dataSeries.lockRead();
107 auto xAxisUnit = dataSeries.xAxisUnit();
108 auto yAxisUnit = dataSeries.yAxisUnit();
109 auto valuesUnit = dataSeries.valuesUnit();
110 dataSeries.unlock();
111
112 setAxisProperties(*plot.xAxis, xAxisUnit);
113 setAxisProperties(*plot.yAxis, yAxisUnit, QCPAxis::stLogarithmic);
114
115 // Displays color scale in plot
119 // Displays color scale in plot
116 plot.plotLayout()->insertRow(0);
120 plot.plotLayout()->insertRow(0);
117 plot.plotLayout()->addElement(0, 0, colorScale.m_Scale);
121 plot.plotLayout()->addElement(0, 0, colorScale.m_Scale);
@@ -125,9 +129,21 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<SpectrogramSeries
125 }
129 }
126
130
127 // Set color scale properties
131 // Set color scale properties
128 setAxisProperties(*colorScale.m_Scale->axis(), valuesUnit, QCPAxis::stLogarithmic);
129 colorScale.m_AutomaticThreshold = true;
132 colorScale.m_AutomaticThreshold = true;
130 }
133 }
134
135 static void setUnits(T &dataSeries, QCustomPlot &plot, SqpColorScale &colorScale)
136 {
137 dataSeries.lockRead();
138 auto xAxisUnit = dataSeries.xAxisUnit();
139 auto yAxisUnit = dataSeries.yAxisUnit();
140 auto valuesUnit = dataSeries.valuesUnit();
141 dataSeries.unlock();
142
143 setAxisProperties(*plot.xAxis, xAxisUnit);
144 setAxisProperties(*plot.yAxis, yAxisUnit, QCPAxis::stLogarithmic);
145 setAxisProperties(*colorScale.m_Scale->axis(), valuesUnit, QCPAxis::stLogarithmic);
146 }
131 };
147 };
132
148
133 /**
149 /**
@@ -136,14 +152,25 struct AxisSetter<T, typename std::enable_if_t<std::is_base_of<SpectrogramSeries
136 */
152 */
137 template <typename T>
153 template <typename T>
138 struct AxisHelper : public IAxisHelper {
154 struct AxisHelper : public IAxisHelper {
139 explicit AxisHelper(T &dataSeries) : m_DataSeries{dataSeries} {}
155 explicit AxisHelper(std::shared_ptr<T> dataSeries) : m_DataSeries{dataSeries} {}
140
156
141 void setProperties(QCustomPlot &plot, SqpColorScale &colorScale) override
157 void setProperties(QCustomPlot &plot, SqpColorScale &colorScale) override
142 {
158 {
143 AxisSetter<T>::setProperties(m_DataSeries, plot, colorScale);
159 AxisSetter<T>::setProperties(plot, colorScale);
144 }
160 }
145
161
146 T &m_DataSeries;
162 void setUnits(QCustomPlot &plot, SqpColorScale &colorScale) override
163 {
164 if (m_DataSeries) {
165 AxisSetter<T>::setUnits(*m_DataSeries, plot, colorScale);
166 }
167 else {
168 qCCritical(LOG_AxisRenderingUtils()) << "Can't set units: inconsistency between the "
169 "type of data series and the type supposed";
170 }
171 }
172
173 std::shared_ptr<T> m_DataSeries;
147 };
174 };
148
175
149 } // namespace
176 } // namespace
@@ -159,19 +186,22 QString formatValue(double value, const QCPAxis &axis)
159 }
186 }
160 }
187 }
161
188
162 std::unique_ptr<IAxisHelper>
189 std::unique_ptr<IAxisHelper> IAxisHelperFactory::create(const Variable &variable) noexcept
163 IAxisHelperFactory::create(std::shared_ptr<IDataSeries> dataSeries) noexcept
164 {
190 {
165 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
191 switch (variable.type()) {
166 return std::make_unique<AxisHelper<ScalarSeries> >(*scalarSeries);
192 case DataSeriesType::SCALAR:
167 }
193 return std::make_unique<AxisHelper<ScalarSeries> >(
168 else if (auto spectrogramSeries = std::dynamic_pointer_cast<SpectrogramSeries>(dataSeries)) {
194 std::dynamic_pointer_cast<ScalarSeries>(variable.dataSeries()));
169 return std::make_unique<AxisHelper<SpectrogramSeries> >(*spectrogramSeries);
195 case DataSeriesType::SPECTROGRAM:
170 }
196 return std::make_unique<AxisHelper<SpectrogramSeries> >(
171 else if (auto vectorSeries = std::dynamic_pointer_cast<VectorSeries>(dataSeries)) {
197 std::dynamic_pointer_cast<SpectrogramSeries>(variable.dataSeries()));
172 return std::make_unique<AxisHelper<VectorSeries> >(*vectorSeries);
198 case DataSeriesType::VECTOR:
173 }
199 return std::make_unique<AxisHelper<VectorSeries> >(
174 else {
200 std::dynamic_pointer_cast<VectorSeries>(variable.dataSeries()));
175 return std::make_unique<AxisHelper<IDataSeries> >(*dataSeries);
201 default:
202 // Creates default helper
203 break;
176 }
204 }
205
206 return std::make_unique<AxisHelper<IDataSeries> >(nullptr);
177 }
207 }
@@ -6,6 +6,8
6 #include <Data/SpectrogramSeries.h>
6 #include <Data/SpectrogramSeries.h>
7 #include <Data/VectorSeries.h>
7 #include <Data/VectorSeries.h>
8
8
9 #include <Variable/Variable.h>
10
9 #include <Visualization/qcustomplot.h>
11 #include <Visualization/qcustomplot.h>
10
12
11 Q_LOGGING_CATEGORY(LOG_PlottablesRenderingUtils, "PlottablesRenderingUtils")
13 Q_LOGGING_CATEGORY(LOG_PlottablesRenderingUtils, "PlottablesRenderingUtils")
@@ -17,7 +19,7 namespace {
17 */
19 */
18 template <typename T, typename Enabled = void>
20 template <typename T, typename Enabled = void>
19 struct PlottablesSetter {
21 struct PlottablesSetter {
20 static void setProperties(T &, PlottablesMap &)
22 static void setProperties(PlottablesMap &)
21 {
23 {
22 // Default implementation does nothing
24 // Default implementation does nothing
23 qCCritical(LOG_PlottablesRenderingUtils())
25 qCCritical(LOG_PlottablesRenderingUtils())
@@ -33,20 +35,25 struct PlottablesSetter {
33 template <typename T>
35 template <typename T>
34 struct PlottablesSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
36 struct PlottablesSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
35 or std::is_base_of<VectorSeries, T>::value> > {
37 or std::is_base_of<VectorSeries, T>::value> > {
36 static void setProperties(T &dataSeries, PlottablesMap &plottables)
38 static void setProperties(PlottablesMap &plottables)
37 {
39 {
38 // Gets the number of components of the data series
40 // Finds the plottable with the highest index to determine the number of colors to generate
39 dataSeries.lockRead();
41 auto end = plottables.cend();
40 auto componentCount = dataSeries.valuesData()->componentCount();
42 auto maxPlottableIndexIt
41 dataSeries.unlock();
43 = std::max_element(plottables.cbegin(), end, [](const auto &it1, const auto &it2) {
44 return it1.first < it2.first;
45 });
46 auto componentCount = maxPlottableIndexIt != end ? maxPlottableIndexIt->first + 1 : 0;
42
47
43 // Generates colors for each component
48 // Generates colors for each component
44 auto colors = ColorUtils::colors(Qt::blue, Qt::red, componentCount);
49 auto colors = ColorUtils::colors(Qt::blue, Qt::red, componentCount);
45
50
46 // For each component of the data series, creates a QCPGraph to add to the plot
51 // For each component of the data series, creates a QCPGraph to add to the plot
47 for (auto i = 0; i < componentCount; ++i) {
52 for (auto i = 0; i < componentCount; ++i) {
48 auto graph = plottables.at(i);
53 auto graphIt = plottables.find(i);
49 graph->setPen(QPen{colors.at(i)});
54 if (graphIt != end) {
55 graphIt->second->setPen(QPen{colors.at(i)});
56 }
50 }
57 }
51 }
58 }
52 };
59 };
@@ -58,7 +65,7 struct PlottablesSetter<T, typename std::enable_if_t<std::is_base_of<ScalarSerie
58 template <typename T>
65 template <typename T>
59 struct PlottablesSetter<T,
66 struct PlottablesSetter<T,
60 typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
67 typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
61 static void setProperties(T &, PlottablesMap &plottables)
68 static void setProperties(PlottablesMap &plottables)
62 {
69 {
63 // Checks that for a spectrogram there is only one plottable, that is a colormap
70 // Checks that for a spectrogram there is only one plottable, that is a colormap
64 if (plottables.size() != 1) {
71 if (plottables.size() != 1) {
@@ -92,31 +99,28 struct PlottablesSetter<T,
92 */
99 */
93 template <typename T>
100 template <typename T>
94 struct PlottablesHelper : public IPlottablesHelper {
101 struct PlottablesHelper : public IPlottablesHelper {
95 explicit PlottablesHelper(T &dataSeries) : m_DataSeries{dataSeries} {}
96
97 void setProperties(PlottablesMap &plottables) override
102 void setProperties(PlottablesMap &plottables) override
98 {
103 {
99 PlottablesSetter<T>::setProperties(m_DataSeries, plottables);
104 PlottablesSetter<T>::setProperties(plottables);
100 }
105 }
101
102 T &m_DataSeries;
103 };
106 };
104
107
105 } // namespace
108 } // namespace
106
109
107 std::unique_ptr<IPlottablesHelper>
110 std::unique_ptr<IPlottablesHelper>
108 IPlottablesHelperFactory::create(std::shared_ptr<IDataSeries> dataSeries) noexcept
111 IPlottablesHelperFactory::create(const Variable &variable) noexcept
109 {
112 {
110 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
113 switch (variable.type()) {
111 return std::make_unique<PlottablesHelper<ScalarSeries> >(*scalarSeries);
114 case DataSeriesType::SCALAR:
112 }
115 return std::make_unique<PlottablesHelper<ScalarSeries> >();
113 else if (auto spectrogramSeries = std::dynamic_pointer_cast<SpectrogramSeries>(dataSeries)) {
116 case DataSeriesType::SPECTROGRAM:
114 return std::make_unique<PlottablesHelper<SpectrogramSeries> >(*spectrogramSeries);
117 return std::make_unique<PlottablesHelper<SpectrogramSeries> >();
115 }
118 case DataSeriesType::VECTOR:
116 else if (auto vectorSeries = std::dynamic_pointer_cast<VectorSeries>(dataSeries)) {
119 return std::make_unique<PlottablesHelper<VectorSeries> >();
117 return std::make_unique<PlottablesHelper<VectorSeries> >(*vectorSeries);
120 default:
118 }
121 // Returns default helper
119 else {
122 break;
120 return std::make_unique<PlottablesHelper<IDataSeries> >(*dataSeries);
121 }
123 }
124
125 return std::make_unique<PlottablesHelper<IDataSeries> >();
122 }
126 }
@@ -25,7 +25,7 public:
25 */
25 */
26 template <typename T, typename Enabled = void>
26 template <typename T, typename Enabled = void>
27 struct PlottablesCreator {
27 struct PlottablesCreator {
28 static PlottablesMap createPlottables(T &, QCustomPlot &)
28 static PlottablesMap createPlottables(QCustomPlot &)
29 {
29 {
30 qCCritical(LOG_DataSeries())
30 qCCritical(LOG_DataSeries())
31 << QObject::tr("Can't create plottables: unmanaged data series type");
31 << QObject::tr("Can't create plottables: unmanaged data series type");
@@ -33,34 +33,37 struct PlottablesCreator {
33 }
33 }
34 };
34 };
35
35
36 PlottablesMap createGraphs(QCustomPlot &plot, int nbGraphs)
37 {
38 PlottablesMap result{};
39
40 // Creates {nbGraphs} QCPGraph to add to the plot
41 for (auto i = 0; i < nbGraphs; ++i) {
42 auto graph = plot.addGraph();
43 result.insert({i, graph});
44 }
45
46 plot.replot();
47
48 return result;
49 }
50
36 /**
51 /**
37 * Specialization of PlottablesCreator for scalars and vectors
52 * Specialization of PlottablesCreator for scalars
38 * @sa ScalarSeries
53 * @sa ScalarSeries
39 * @sa VectorSeries
40 */
54 */
41 template <typename T>
55 template <typename T>
42 struct PlottablesCreator<T,
56 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value> > {
43 typename std::enable_if_t<std::is_base_of<ScalarSeries, T>::value
57 static PlottablesMap createPlottables(QCustomPlot &plot) { return createGraphs(plot, 1); }
44 or std::is_base_of<VectorSeries, T>::value> > {
58 };
45 static PlottablesMap createPlottables(T &dataSeries, QCustomPlot &plot)
46 {
47 PlottablesMap result{};
48
49 // Gets the number of components of the data series
50 dataSeries.lockRead();
51 auto componentCount = dataSeries.valuesData()->componentCount();
52 dataSeries.unlock();
53
54 // For each component of the data series, creates a QCPGraph to add to the plot
55 for (auto i = 0; i < componentCount; ++i) {
56 auto graph = plot.addGraph();
57 result.insert({i, graph});
58 }
59
60 plot.replot();
61
59
62 return result;
60 /**
63 }
61 * Specialization of PlottablesCreator for vectors
62 * @sa VectorSeries
63 */
64 template <typename T>
65 struct PlottablesCreator<T, typename std::enable_if_t<std::is_base_of<VectorSeries, T>::value> > {
66 static PlottablesMap createPlottables(QCustomPlot &plot) { return createGraphs(plot, 3); }
64 };
67 };
65
68
66 /**
69 /**
@@ -70,7 +73,7 struct PlottablesCreator<T,
70 template <typename T>
73 template <typename T>
71 struct PlottablesCreator<T,
74 struct PlottablesCreator<T,
72 typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
75 typename std::enable_if_t<std::is_base_of<SpectrogramSeries, T>::value> > {
73 static PlottablesMap createPlottables(T &dataSeries, QCustomPlot &plot)
76 static PlottablesMap createPlottables(QCustomPlot &plot)
74 {
77 {
75 PlottablesMap result{};
78 PlottablesMap result{};
76 result.insert({0, new QCPColorMap{plot.xAxis, plot.yAxis}});
79 result.insert({0, new QCPColorMap{plot.xAxis, plot.yAxis}});
@@ -264,41 +267,59 struct IPlottablesHelper {
264 */
267 */
265 template <typename T>
268 template <typename T>
266 struct PlottablesHelper : public IPlottablesHelper {
269 struct PlottablesHelper : public IPlottablesHelper {
267 explicit PlottablesHelper(T &dataSeries) : m_DataSeries{dataSeries} {}
270 explicit PlottablesHelper(std::shared_ptr<T> dataSeries) : m_DataSeries{dataSeries} {}
268
271
269 PlottablesMap create(QCustomPlot &plot) const override
272 PlottablesMap create(QCustomPlot &plot) const override
270 {
273 {
271 return PlottablesCreator<T>::createPlottables(m_DataSeries, plot);
274 return PlottablesCreator<T>::createPlottables(plot);
272 }
275 }
273
276
274 void update(PlottablesMap &plottables, const SqpRange &range, bool rescaleAxes) const override
277 void update(PlottablesMap &plottables, const SqpRange &range, bool rescaleAxes) const override
275 {
278 {
276 PlottablesUpdater<T>::updatePlottables(m_DataSeries, plottables, range, rescaleAxes);
279 if (m_DataSeries) {
280 PlottablesUpdater<T>::updatePlottables(*m_DataSeries, plottables, range, rescaleAxes);
281 }
282 else {
283 qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
284 "between the type of data series and the "
285 "type supposed";
286 }
277 }
287 }
278
288
279 void setYAxisRange(const SqpRange &xAxisRange, QCustomPlot &plot) const override
289 void setYAxisRange(const SqpRange &xAxisRange, QCustomPlot &plot) const override
280 {
290 {
281 return PlottablesUpdater<T>::setPlotYAxisRange(m_DataSeries, xAxisRange, plot);
291 if (m_DataSeries) {
292 PlottablesUpdater<T>::setPlotYAxisRange(*m_DataSeries, xAxisRange, plot);
293 }
294 else {
295 qCCritical(LOG_VisualizationGraphHelper()) << "Can't update plottables: inconsistency "
296 "between the type of data series and the "
297 "type supposed";
298 }
282 }
299 }
283
300
284 T &m_DataSeries;
301 std::shared_ptr<T> m_DataSeries;
285 };
302 };
286
303
287 /// Creates IPlottablesHelper according to a data series
304 /// Creates IPlottablesHelper according to the type of data series a variable holds
288 std::unique_ptr<IPlottablesHelper> createHelper(std::shared_ptr<IDataSeries> dataSeries) noexcept
305 std::unique_ptr<IPlottablesHelper> createHelper(std::shared_ptr<Variable> variable) noexcept
289 {
306 {
290 if (auto scalarSeries = std::dynamic_pointer_cast<ScalarSeries>(dataSeries)) {
307 switch (variable->type()) {
291 return std::make_unique<PlottablesHelper<ScalarSeries> >(*scalarSeries);
308 case DataSeriesType::SCALAR:
292 }
309 return std::make_unique<PlottablesHelper<ScalarSeries> >(
293 else if (auto spectrogramSeries = std::dynamic_pointer_cast<SpectrogramSeries>(dataSeries)) {
310 std::dynamic_pointer_cast<ScalarSeries>(variable->dataSeries()));
294 return std::make_unique<PlottablesHelper<SpectrogramSeries> >(*spectrogramSeries);
311 case DataSeriesType::SPECTROGRAM:
295 }
312 return std::make_unique<PlottablesHelper<SpectrogramSeries> >(
296 else if (auto vectorSeries = std::dynamic_pointer_cast<VectorSeries>(dataSeries)) {
313 std::dynamic_pointer_cast<SpectrogramSeries>(variable->dataSeries()));
297 return std::make_unique<PlottablesHelper<VectorSeries> >(*vectorSeries);
314 case DataSeriesType::VECTOR:
298 }
315 return std::make_unique<PlottablesHelper<VectorSeries> >(
299 else {
316 std::dynamic_pointer_cast<VectorSeries>(variable->dataSeries()));
300 return std::make_unique<PlottablesHelper<IDataSeries> >(*dataSeries);
317 default:
318 // Creates default helper
319 break;
301 }
320 }
321
322 return std::make_unique<PlottablesHelper<IDataSeries> >(nullptr);
302 }
323 }
303
324
304 } // namespace
325 } // namespace
@@ -307,7 +328,7 PlottablesMap VisualizationGraphHelper::create(std::shared_ptr<Variable> variabl
307 QCustomPlot &plot) noexcept
328 QCustomPlot &plot) noexcept
308 {
329 {
309 if (variable) {
330 if (variable) {
310 auto helper = createHelper(variable->dataSeries());
331 auto helper = createHelper(variable);
311 auto plottables = helper->create(plot);
332 auto plottables = helper->create(plot);
312 return plottables;
333 return plottables;
313 }
334 }
@@ -322,7 +343,7 void VisualizationGraphHelper::setYAxisRange(std::shared_ptr<Variable> variable,
322 QCustomPlot &plot) noexcept
343 QCustomPlot &plot) noexcept
323 {
344 {
324 if (variable) {
345 if (variable) {
325 auto helper = createHelper(variable->dataSeries());
346 auto helper = createHelper(variable);
326 helper->setYAxisRange(variable->range(), plot);
347 helper->setYAxisRange(variable->range(), plot);
327 }
348 }
328 else {
349 else {
@@ -332,9 +353,9 void VisualizationGraphHelper::setYAxisRange(std::shared_ptr<Variable> variable,
332 }
353 }
333
354
334 void VisualizationGraphHelper::updateData(PlottablesMap &plottables,
355 void VisualizationGraphHelper::updateData(PlottablesMap &plottables,
335 std::shared_ptr<IDataSeries> dataSeries,
356 std::shared_ptr<Variable> variable,
336 const SqpRange &dateTime)
357 const SqpRange &dateTime)
337 {
358 {
338 auto helper = createHelper(dataSeries);
359 auto helper = createHelper(variable);
339 helper->update(plottables, dateTime);
360 helper->update(plottables, dateTime);
340 }
361 }
@@ -9,6 +9,7
9 #include <Common/DateUtils.h>
9 #include <Common/DateUtils.h>
10
10
11 #include <Data/IDataSeries.h>
11 #include <Data/IDataSeries.h>
12 #include <Variable/Variable.h>
12
13
13 #include <SqpApplication.h>
14 #include <SqpApplication.h>
14
15
@@ -302,14 +303,14 void VisualizationGraphRenderingDelegate::onPlotUpdated() noexcept
302 impl->m_Plot.replot();
303 impl->m_Plot.replot();
303 }
304 }
304
305
305 void VisualizationGraphRenderingDelegate::setAxesProperties(
306 void VisualizationGraphRenderingDelegate::setAxesUnits(const Variable &variable) noexcept
306 std::shared_ptr<IDataSeries> dataSeries) noexcept
307 {
307 {
308 // Stores x-axis label to be able to retrieve it when x-axis pixmap is unselected
309 impl->m_XAxisLabel = dataSeries->xAxisUnit().m_Name;
310
308
311 auto axisHelper = IAxisHelperFactory::create(dataSeries);
309 auto axisHelper = IAxisHelperFactory::create(variable);
312 axisHelper->setProperties(impl->m_Plot, impl->m_ColorScale);
310 axisHelper->setUnits(impl->m_Plot, impl->m_ColorScale);
311
312 // Stores x-axis label to be able to retrieve it when x-axis pixmap is unselected
313 impl->m_XAxisLabel = impl->m_Plot.xAxis->label();
313
314
314 // Updates x-axis state
315 // Updates x-axis state
315 impl->updateXAxisState();
316 impl->updateXAxisState();
@@ -317,10 +318,15 void VisualizationGraphRenderingDelegate::setAxesProperties(
317 impl->m_Plot.layer(AXES_LAYER)->replot();
318 impl->m_Plot.layer(AXES_LAYER)->replot();
318 }
319 }
319
320
320 void VisualizationGraphRenderingDelegate::setPlottablesProperties(
321 void VisualizationGraphRenderingDelegate::setGraphProperties(const Variable &variable,
321 std::shared_ptr<IDataSeries> dataSeries, PlottablesMap &plottables) noexcept
322 PlottablesMap &plottables) noexcept
322 {
323 {
323 auto plottablesHelper = IPlottablesHelperFactory::create(dataSeries);
324 // Axes' properties
325 auto axisHelper = IAxisHelperFactory::create(variable);
326 axisHelper->setProperties(impl->m_Plot, impl->m_ColorScale);
327
328 // Plottables' properties
329 auto plottablesHelper = IPlottablesHelperFactory::create(variable);
324 plottablesHelper->setProperties(plottables);
330 plottablesHelper->setProperties(plottables);
325 }
331 }
326
332
@@ -65,10 +65,10 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
65 {
65 {
66 }
66 }
67
67
68 void updateData(PlottablesMap &plottables, std::shared_ptr<IDataSeries> dataSeries,
68 void updateData(PlottablesMap &plottables, std::shared_ptr<Variable> variable,
69 const SqpRange &range)
69 const SqpRange &range)
70 {
70 {
71 VisualizationGraphHelper::updateData(plottables, dataSeries, range);
71 VisualizationGraphHelper::updateData(plottables, variable, range);
72
72
73 // Prevents that data has changed to update rendering
73 // Prevents that data has changed to update rendering
74 m_RenderingDelegate->onPlotUpdated();
74 m_RenderingDelegate->onPlotUpdated();
@@ -94,6 +94,8 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
94
94
95 bool m_HasMovedMouse = false; // Indicates if the mouse moved in a releaseMouse even
95 bool m_HasMovedMouse = false; // Indicates if the mouse moved in a releaseMouse even
96
96
97 bool m_VariableAutoRangeOnInit = true;
98
97 void startDrawingRect(const QPoint &pos, QCustomPlot &plot)
99 void startDrawingRect(const QPoint &pos, QCustomPlot &plot)
98 {
100 {
99 removeDrawingRect(plot);
101 removeDrawingRect(plot);
@@ -294,28 +296,48 void VisualizationGraphWidget::setFlags(GraphFlags flags)
294
296
295 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, SqpRange range)
297 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, SqpRange range)
296 {
298 {
297 // Uses delegate to create the qcpplot components according to the variable
299 /// Lambda used to set graph's units and range according to the variable passed in parameter
298 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
300 auto loadRange = [this](std::shared_ptr<Variable> variable, const SqpRange &range) {
299
301 impl->m_RenderingDelegate->setAxesUnits(*variable);
300 if (auto dataSeries = variable->dataSeries()) {
301 // Set axes properties according to the units of the data series
302 impl->m_RenderingDelegate->setAxesProperties(dataSeries);
303
302
304 // Sets rendering properties for the new plottables
303 this->setFlags(GraphFlag::DisableAll);
305 // Warning: this method must be called after setAxesProperties(), as it can access to some
304 setGraphRange(range);
306 // axes properties that have to be initialized
305 this->setFlags(GraphFlag::EnableAll);
307 impl->m_RenderingDelegate->setPlottablesProperties(dataSeries, createdPlottables);
308 }
309
306
310 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
307 emit requestDataLoading({variable}, range, false);
308 };
311
309
312 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
310 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
313
311
314 this->setFlags(GraphFlag::DisableAll);
312 // Calls update of graph's range and units when the data of the variable have been initialized.
315 this->setGraphRange(range);
313 // Note: we use QueuedConnection here as the update event must be called in the UI thread
316 this->setFlags(GraphFlag::EnableAll);
314 connect(variable.get(), &Variable::dataInitialized, this,
315 [ varW = std::weak_ptr<Variable>{variable}, range, loadRange, this ]() {
316 if (auto var = varW.lock()) {
317 // If the variable is the first added in the graph, we load its range
318 auto firstVariableInGraph = range == INVALID_RANGE;
319 auto loadedRange = graphRange();
320 if (impl->m_VariableAutoRangeOnInit) {
321 loadedRange = firstVariableInGraph ? var->range() : range;
322 }
323 loadRange(var, loadedRange);
324 setYRange(var);
325 }
326 },
327 Qt::QueuedConnection);
328
329 // Uses delegate to create the qcpplot components according to the variable
330 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
331
332 // Sets graph properties
333 impl->m_RenderingDelegate->setGraphProperties(*variable, createdPlottables);
334
335 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
317
336
318 emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable, range, false);
337 // If the variable already has its data loaded, load its units and its range in the graph
338 if (variable->dataSeries() != nullptr) {
339 loadRange(variable, range);
340 }
319
341
320 emit variableAdded(variable);
342 emit variableAdded(variable);
321 }
343 }
@@ -371,14 +393,29 SqpRange VisualizationGraphWidget::graphRange() const noexcept
371 return SqpRange{graphRange.lower, graphRange.upper};
393 return SqpRange{graphRange.lower, graphRange.upper};
372 }
394 }
373
395
374 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
396 void VisualizationGraphWidget::setGraphRange(const SqpRange &range, bool calibration)
375 {
397 {
376 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
398 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
399
400 if (calibration) {
401 impl->m_IsCalibration = true;
402 }
403
377 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
404 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
378 ui->widget->replot();
405 ui->widget->replot();
406
407 if (calibration) {
408 impl->m_IsCalibration = false;
409 }
410
379 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
411 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
380 }
412 }
381
413
414 void VisualizationGraphWidget::setAutoRangeOnVariableInitialization(bool value)
415 {
416 impl->m_VariableAutoRangeOnInit = value;
417 }
418
382 QVector<SqpRange> VisualizationGraphWidget::selectionZoneRanges() const
419 QVector<SqpRange> VisualizationGraphWidget::selectionZoneRanges() const
383 {
420 {
384 QVector<SqpRange> ranges;
421 QVector<SqpRange> ranges;
@@ -401,6 +438,20 void VisualizationGraphWidget::addSelectionZones(const QVector<SqpRange> &ranges
401 plot().replot(QCustomPlot::rpQueuedReplot);
438 plot().replot(QCustomPlot::rpQueuedReplot);
402 }
439 }
403
440
441 VisualizationSelectionZoneItem *VisualizationGraphWidget::addSelectionZone(const QString &name,
442 const SqpRange &range)
443 {
444 // note: ownership is transfered to QCustomPlot
445 auto zone = new VisualizationSelectionZoneItem(&plot());
446 zone->setName(name);
447 zone->setRange(range.m_TStart, range.m_TEnd);
448 impl->addSelectionZone(zone);
449
450 plot().replot(QCustomPlot::rpQueuedReplot);
451
452 return zone;
453 }
454
404 void VisualizationGraphWidget::removeSelectionZone(VisualizationSelectionZoneItem *selectionZone)
455 void VisualizationGraphWidget::removeSelectionZone(VisualizationSelectionZoneItem *selectionZone)
405 {
456 {
406 parentVisualizationWidget()->selectionZoneManager().setSelected(selectionZone, false);
457 parentVisualizationWidget()->selectionZoneManager().setSelected(selectionZone, false);
@@ -989,7 +1040,7 void VisualizationGraphWidget::onDataCacheVariableUpdated()
989 qCDebug(LOG_VisualizationGraphWidget())
1040 qCDebug(LOG_VisualizationGraphWidget())
990 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
1041 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
991 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
1042 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
992 impl->updateData(variableEntry.second, variable->dataSeries(), variable->range());
1043 impl->updateData(variableEntry.second, variable, variable->range());
993 }
1044 }
994 }
1045 }
995 }
1046 }
@@ -999,6 +1050,6 void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> v
999 {
1050 {
1000 auto it = impl->m_VariableToPlotMultiMap.find(variable);
1051 auto it = impl->m_VariableToPlotMultiMap.find(variable);
1001 if (it != impl->m_VariableToPlotMultiMap.end()) {
1052 if (it != impl->m_VariableToPlotMultiMap.end()) {
1002 impl->updateData(it->second, variable->dataSeries(), range);
1053 impl->updateData(it->second, variable, range);
1003 }
1054 }
1004 }
1055 }
@@ -388,8 +388,11 void VisualizationSelectionZoneItem::mouseMoveEvent(QMouseEvent *event, const QP
388 break;
388 break;
389 }
389 }
390
390
391 emit rangeEdited(range());
392
391 for (auto associatedZone : impl->m_AssociatedEditedZones) {
393 for (auto associatedZone : impl->m_AssociatedEditedZones) {
392 associatedZone->parentPlot()->replot();
394 associatedZone->parentPlot()->replot();
395 emit associatedZone->rangeEdited(associatedZone->range());
393 }
396 }
394 }
397 }
395 else {
398 else {
@@ -7,6 +7,7
7
7
8 #include "Visualization/MacScrollBarStyle.h"
8 #include "Visualization/MacScrollBarStyle.h"
9
9
10 #include "DataSource/DataSourceController.h"
10 #include "Variable/VariableController.h"
11 #include "Variable/VariableController.h"
11
12
12 #include "Common/MimeTypesDef.h"
13 #include "Common/MimeTypesDef.h"
@@ -69,6 +70,8 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
69 void dropZone(int index, VisualizationTabWidget *tabWidget);
70 void dropZone(int index, VisualizationTabWidget *tabWidget);
70 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
71 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
71 VisualizationTabWidget *tabWidget);
72 VisualizationTabWidget *tabWidget);
73 void dropProducts(const QVariantList &productsMetaData, int index,
74 VisualizationTabWidget *tabWidget);
72 };
75 };
73
76
74 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
77 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
@@ -91,6 +94,8 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *par
91 VisualizationDragDropContainer::DropBehavior::Inserted);
94 VisualizationDragDropContainer::DropBehavior::Inserted);
92 ui->dragDropContainer->setMimeType(MIME_TYPE_VARIABLE_LIST,
95 ui->dragDropContainer->setMimeType(MIME_TYPE_VARIABLE_LIST,
93 VisualizationDragDropContainer::DropBehavior::Inserted);
96 VisualizationDragDropContainer::DropBehavior::Inserted);
97 ui->dragDropContainer->setMimeType(MIME_TYPE_PRODUCT_LIST,
98 VisualizationDragDropContainer::DropBehavior::Inserted);
94
99
95 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
100 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
96 return sqpApp->dragDropGuiController().checkMimeDataForVisualization(mimeData,
101 return sqpApp->dragDropGuiController().checkMimeDataForVisualization(mimeData,
@@ -229,6 +234,11 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData)
229 mimeData->data(MIME_TYPE_VARIABLE_LIST));
234 mimeData->data(MIME_TYPE_VARIABLE_LIST));
230 impl->dropVariables(variables, index, this);
235 impl->dropVariables(variables, index, this);
231 }
236 }
237 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
238 auto productsData = sqpApp->dataSourceController().productsDataForMimeData(
239 mimeData->data(MIME_TYPE_PRODUCT_LIST));
240 impl->dropProducts(productsData, index, this);
241 }
232 else {
242 else {
233 qCWarning(LOG_VisualizationZoneWidget())
243 qCWarning(LOG_VisualizationZoneWidget())
234 << tr("VisualizationTabWidget::dropMimeData, unknown MIME data received.");
244 << tr("VisualizationTabWidget::dropMimeData, unknown MIME data received.");
@@ -352,3 +362,28 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropVariables(
352
362
353 tabWidget->createZone(variables, index);
363 tabWidget->createZone(variables, index);
354 }
364 }
365
366 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropProducts(
367 const QVariantList &productsMetaData, int index, VisualizationTabWidget *tabWidget)
368 {
369 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
370 // compatible variable here
371 if (productsMetaData.count() != 1) {
372 qCWarning(LOG_VisualizationZoneWidget())
373 << tr("VisualizationTabWidget::dropProducts, dropping multiple products, operation "
374 "aborted.");
375 return;
376 }
377
378 auto context = new QObject{tabWidget};
379 connect(&sqpApp->variableController(), &VariableController::variableAdded, context,
380 [this, index, tabWidget, context](auto variable) {
381 tabWidget->createZone({variable}, index);
382 delete context; // removes the connection
383 },
384 Qt::QueuedConnection);
385
386 auto productData = productsMetaData.first().toHash();
387 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
388 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
389 }
@@ -10,6 +10,7
10 #include "Common/VisualizationDef.h"
10 #include "Common/VisualizationDef.h"
11
11
12 #include <Data/SqpRange.h>
12 #include <Data/SqpRange.h>
13 #include <DataSource/DataSourceController.h>
13 #include <Time/TimeController.h>
14 #include <Time/TimeController.h>
14 #include <Variable/Variable.h>
15 #include <Variable/Variable.h>
15 #include <Variable/VariableController.h>
16 #include <Variable/VariableController.h>
@@ -78,6 +79,8 struct VisualizationZoneWidget::VisualizationZoneWidgetPrivate {
78 void dropGraph(int index, VisualizationZoneWidget *zoneWidget);
79 void dropGraph(int index, VisualizationZoneWidget *zoneWidget);
79 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
80 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
80 VisualizationZoneWidget *zoneWidget);
81 VisualizationZoneWidget *zoneWidget);
82 void dropProducts(const QVariantList &productsData, int index,
83 VisualizationZoneWidget *zoneWidget);
81 };
84 };
82
85
83 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
86 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *parent)
@@ -94,6 +97,8 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *p
94 VisualizationDragDropContainer::DropBehavior::Inserted);
97 VisualizationDragDropContainer::DropBehavior::Inserted);
95 ui->dragDropContainer->setMimeType(
98 ui->dragDropContainer->setMimeType(
96 MIME_TYPE_VARIABLE_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
99 MIME_TYPE_VARIABLE_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
100 ui->dragDropContainer->setMimeType(
101 MIME_TYPE_PRODUCT_LIST, VisualizationDragDropContainer::DropBehavior::InsertedAndMerged);
97 ui->dragDropContainer->setMimeType(MIME_TYPE_TIME_RANGE,
102 ui->dragDropContainer->setMimeType(MIME_TYPE_TIME_RANGE,
98 VisualizationDragDropContainer::DropBehavior::Merged);
103 VisualizationDragDropContainer::DropBehavior::Merged);
99 ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE,
104 ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE,
@@ -477,6 +482,11 void VisualizationZoneWidget::dropMimeData(int index, const QMimeData *mimeData)
477 mimeData->data(MIME_TYPE_VARIABLE_LIST));
482 mimeData->data(MIME_TYPE_VARIABLE_LIST));
478 impl->dropVariables(variables, index, this);
483 impl->dropVariables(variables, index, this);
479 }
484 }
485 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
486 auto products = sqpApp->dataSourceController().productsDataForMimeData(
487 mimeData->data(MIME_TYPE_PRODUCT_LIST));
488 impl->dropProducts(products, index, this);
489 }
480 else {
490 else {
481 qCWarning(LOG_VisualizationZoneWidget())
491 qCWarning(LOG_VisualizationZoneWidget())
482 << tr("VisualizationZoneWidget::dropMimeData, unknown MIME data received.");
492 << tr("VisualizationZoneWidget::dropMimeData, unknown MIME data received.");
@@ -502,6 +512,22 void VisualizationZoneWidget::dropMimeDataOnGraph(VisualizationDragWidget *dragW
502 graphWidget->addVariable(var, graphWidget->graphRange());
512 graphWidget->addVariable(var, graphWidget->graphRange());
503 }
513 }
504 }
514 }
515 else if (mimeData->hasFormat(MIME_TYPE_PRODUCT_LIST)) {
516 auto products = sqpApp->dataSourceController().productsDataForMimeData(
517 mimeData->data(MIME_TYPE_PRODUCT_LIST));
518
519 auto context = new QObject{this};
520 connect(&sqpApp->variableController(), &VariableController::variableAdded, context,
521 [this, graphWidget, context](auto variable) {
522 graphWidget->addVariable(variable, graphWidget->graphRange());
523 delete context; // removes the connection
524 },
525 Qt::QueuedConnection);
526
527 auto productData = products.first().toHash();
528 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
529 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
530 }
505 else if (mimeData->hasFormat(MIME_TYPE_TIME_RANGE)) {
531 else if (mimeData->hasFormat(MIME_TYPE_TIME_RANGE)) {
506 auto range = TimeController::timeRangeForMimeData(mimeData->data(MIME_TYPE_TIME_RANGE));
532 auto range = TimeController::timeRangeForMimeData(mimeData->data(MIME_TYPE_TIME_RANGE));
507 graphWidget->setGraphRange(range);
533 graphWidget->setGraphRange(range);
@@ -599,3 +625,28 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropVariables(
599
625
600 zoneWidget->createGraph(variables, index);
626 zoneWidget->createGraph(variables, index);
601 }
627 }
628
629 void VisualizationZoneWidget::VisualizationZoneWidgetPrivate::dropProducts(
630 const QVariantList &productsData, int index, VisualizationZoneWidget *zoneWidget)
631 {
632 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
633 // compatible variable here
634 if (productsData.count() != 1) {
635 qCWarning(LOG_VisualizationZoneWidget())
636 << tr("VisualizationTabWidget::dropProducts, dropping multiple products, operation "
637 "aborted.");
638 return;
639 }
640
641 auto context = new QObject{zoneWidget};
642 connect(&sqpApp->variableController(), &VariableController::variableAdded, context,
643 [this, index, zoneWidget, context](auto variable) {
644 zoneWidget->createGraph(variable, index);
645 delete context; // removes the connection
646 },
647 Qt::QueuedConnection);
648
649 auto productData = productsData.first().toHash();
650 QMetaObject::invokeMethod(&sqpApp->dataSourceController(), "requestVariable",
651 Qt::QueuedConnection, Q_ARG(QVariantHash, productData));
652 }
@@ -85,9 +85,6
85 </item>
85 </item>
86 <item>
86 <item>
87 <widget class="QToolButton" name="btnChart">
87 <widget class="QToolButton" name="btnChart">
88 <property name="enabled">
89 <bool>false</bool>
90 </property>
91 <property name="text">
88 <property name="text">
92 <string>G</string>
89 <string>G</string>
93 </property>
90 </property>
@@ -3,6 +3,8
3
3
4 #include "AmdaGlobal.h"
4 #include "AmdaGlobal.h"
5
5
6 #include <Data/DataSeriesType.h>
7
6 #include <QLoggingCategory>
8 #include <QLoggingCategory>
7
9
8 #include <memory>
10 #include <memory>
@@ -12,10 +14,8 class IDataSeries;
12 Q_DECLARE_LOGGING_CATEGORY(LOG_AmdaResultParser)
14 Q_DECLARE_LOGGING_CATEGORY(LOG_AmdaResultParser)
13
15
14 struct SCIQLOP_AMDA_EXPORT AmdaResultParser {
16 struct SCIQLOP_AMDA_EXPORT AmdaResultParser {
15 enum class ValueType { SCALAR, SPECTROGRAM, VECTOR, UNKNOWN };
16
17 static std::shared_ptr<IDataSeries> readTxt(const QString &filePath,
17 static std::shared_ptr<IDataSeries> readTxt(const QString &filePath,
18 ValueType valueType) noexcept;
18 DataSeriesType valueType) noexcept;
19 };
19 };
20
20
21 #endif // SCIQLOP_AMDARESULTPARSER_H
21 #endif // SCIQLOP_AMDARESULTPARSER_H
@@ -39,21 +39,6 QString dateFormat(double sqpRange) noexcept
39 return dateTime.toString(AMDA_TIME_FORMAT);
39 return dateTime.toString(AMDA_TIME_FORMAT);
40 }
40 }
41
41
42 AmdaResultParser::ValueType valueType(const QString &valueType)
43 {
44 if (valueType == QStringLiteral("scalar")) {
45 return AmdaResultParser::ValueType::SCALAR;
46 }
47 else if (valueType == QStringLiteral("spectrogram")) {
48 return AmdaResultParser::ValueType::SPECTROGRAM;
49 }
50 else if (valueType == QStringLiteral("vector")) {
51 return AmdaResultParser::ValueType::VECTOR;
52 }
53 else {
54 return AmdaResultParser::ValueType::UNKNOWN;
55 }
56 }
57
42
58 } // namespace
43 } // namespace
59
44
@@ -171,7 +156,8 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVa
171
156
172 // Retrieves the data type that determines whether the expected format for the result file is
157 // Retrieves the data type that determines whether the expected format for the result file is
173 // scalar, vector...
158 // scalar, vector...
174 auto productValueType = valueType(data.value(AMDA_DATA_TYPE_KEY).toString());
159 auto productValueType
160 = DataSeriesTypeUtils::fromString(data.value(AMDA_DATA_TYPE_KEY).toString());
175
161
176 // /////////// //
162 // /////////// //
177 // Creates URL //
163 // Creates URL //
@@ -24,16 +24,16 bool isCommentLine(const QString &line)
24 * @param valueType the type of values expected in the AMDA file (scalars, vectors, spectrograms...)
24 * @param valueType the type of values expected in the AMDA file (scalars, vectors, spectrograms...)
25 * @return the helper created
25 * @return the helper created
26 */
26 */
27 std::unique_ptr<IAmdaResultParserHelper> createHelper(AmdaResultParser::ValueType valueType)
27 std::unique_ptr<IAmdaResultParserHelper> createHelper(DataSeriesType valueType)
28 {
28 {
29 switch (valueType) {
29 switch (valueType) {
30 case AmdaResultParser::ValueType::SCALAR:
30 case DataSeriesType::SCALAR:
31 return std::make_unique<ScalarParserHelper>();
31 return std::make_unique<ScalarParserHelper>();
32 case AmdaResultParser::ValueType::SPECTROGRAM:
32 case DataSeriesType::SPECTROGRAM:
33 return std::make_unique<SpectrogramParserHelper>();
33 return std::make_unique<SpectrogramParserHelper>();
34 case AmdaResultParser::ValueType::VECTOR:
34 case DataSeriesType::VECTOR:
35 return std::make_unique<VectorParserHelper>();
35 return std::make_unique<VectorParserHelper>();
36 case AmdaResultParser::ValueType::UNKNOWN:
36 case DataSeriesType::UNKNOWN:
37 // Invalid case
37 // Invalid case
38 break;
38 break;
39 }
39 }
@@ -82,9 +82,9 void readResults(IAmdaResultParserHelper &helper, QTextStream &stream)
82 } // namespace
82 } // namespace
83
83
84 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(const QString &filePath,
84 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(const QString &filePath,
85 ValueType valueType) noexcept
85 DataSeriesType type) noexcept
86 {
86 {
87 if (valueType == ValueType::UNKNOWN) {
87 if (type == DataSeriesType::UNKNOWN) {
88 qCCritical(LOG_AmdaResultParser())
88 qCCritical(LOG_AmdaResultParser())
89 << QObject::tr("Can't retrieve AMDA data: the type of values to be read is unknown");
89 << QObject::tr("Can't retrieve AMDA data: the type of values to be read is unknown");
90 return nullptr;
90 return nullptr;
@@ -110,7 +110,7 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(const QString &filePath,
110 return nullptr;
110 return nullptr;
111 }
111 }
112
112
113 auto helper = createHelper(valueType);
113 auto helper = createHelper(type);
114 Q_ASSERT(helper != nullptr);
114 Q_ASSERT(helper != nullptr);
115
115
116 // Reads header file to retrieve properties
116 // Reads header file to retrieve properties
@@ -115,7 +115,7 void TestAmdaAcquisition::testAcquisition()
115 // Retrieves data file
115 // Retrieves data file
116 QFETCH(QString, dataFilename);
116 QFETCH(QString, dataFilename);
117 auto filePath = QFileInfo{TESTS_RESOURCES_PATH, dataFilename}.absoluteFilePath();
117 auto filePath = QFileInfo{TESTS_RESOURCES_PATH, dataFilename}.absoluteFilePath();
118 auto results = AmdaResultParser::readTxt(filePath, AmdaResultParser::ValueType::SCALAR);
118 auto results = AmdaResultParser::readTxt(filePath, DataSeriesType::SCALAR);
119
119
120 /// Lambda used to validate a variable at each step
120 /// Lambda used to validate a variable at each step
121 auto validateVariable = [results](std::shared_ptr<Variable> variable, const SqpRange &range) {
121 auto validateVariable = [results](std::shared_ptr<Variable> variable, const SqpRange &range) {
@@ -187,7 +187,7 private:
187 }
187 }
188
188
189 template <typename T>
189 template <typename T>
190 void testRead(AmdaResultParser::ValueType valueType)
190 void testRead(DataSeriesType valueType)
191 {
191 {
192 QFETCH(QString, inputFileName);
192 QFETCH(QString, inputFileName);
193 QFETCH(ExpectedResults<T>, expectedResults);
193 QFETCH(ExpectedResults<T>, expectedResults);
@@ -319,7 +319,7 void TestAmdaResultParser::testReadScalarTxt_data()
319
319
320 void TestAmdaResultParser::testReadScalarTxt()
320 void TestAmdaResultParser::testReadScalarTxt()
321 {
321 {
322 testRead<ScalarSeries>(AmdaResultParser::ValueType::SCALAR);
322 testRead<ScalarSeries>(DataSeriesType::SCALAR);
323 }
323 }
324
324
325 void TestAmdaResultParser::testReadSpectrogramTxt_data()
325 void TestAmdaResultParser::testReadSpectrogramTxt_data()
@@ -533,7 +533,7 void TestAmdaResultParser::testReadSpectrogramTxt_data()
533
533
534 void TestAmdaResultParser::testReadSpectrogramTxt()
534 void TestAmdaResultParser::testReadSpectrogramTxt()
535 {
535 {
536 testRead<SpectrogramSeries>(AmdaResultParser::ValueType::SPECTROGRAM);
536 testRead<SpectrogramSeries>(DataSeriesType::SPECTROGRAM);
537 }
537 }
538
538
539 void TestAmdaResultParser::testReadVectorTxt_data()
539 void TestAmdaResultParser::testReadVectorTxt_data()
@@ -572,7 +572,7 void TestAmdaResultParser::testReadVectorTxt_data()
572
572
573 void TestAmdaResultParser::testReadVectorTxt()
573 void TestAmdaResultParser::testReadVectorTxt()
574 {
574 {
575 testRead<VectorSeries>(AmdaResultParser::ValueType::VECTOR);
575 testRead<VectorSeries>(DataSeriesType::VECTOR);
576 }
576 }
577
577
578 QTEST_MAIN(TestAmdaResultParser)
578 QTEST_MAIN(TestAmdaResultParser)
General Comments 0
You need to be logged in to leave comments. Login now