##// END OF EJS Templates
Merge branch 'feature/VariableModel4' into develop
Alexandre Leroux -
r185:fa2e26651269 merge
parent child
Show More
@@ -0,0 +1,30
1 #ifndef SCIQLOP_GRAPHPLOTTABLESFACTORY_H
2 #define SCIQLOP_GRAPHPLOTTABLESFACTORY_H
3
4 #include <QLoggingCategory>
5 #include <QVector>
6
7 Q_DECLARE_LOGGING_CATEGORY(LOG_GraphPlottablesFactory)
8
9 class QCPAbstractPlottable;
10 class QCustomPlot;
11 class Variable;
12
13 /**
14 * @brief The GraphPlottablesFactory class aims to create the QCustomPlot components relative to a
15 * variable, depending on the data series of this variable
16 */
17 struct GraphPlottablesFactory {
18 /**
19 * Creates (if possible) the QCustomPlot components relative to the variable passed in
20 * parameter, and adds these to the plot passed in parameter.
21 * @param variable the variable for which to create the components
22 * @param plot the plot in which to add the created components. It takes ownership of these
23 * components.
24 * @return the list of the components created
25 */
26 static QVector<QCPAbstractPlottable *> create(const Variable *variable,
27 QCustomPlot &plot) noexcept;
28 };
29
30 #endif // SCIQLOP_GRAPHPLOTTABLESFACTORY_H
@@ -0,0 +1,91
1 #include "Visualization/GraphPlottablesFactory.h"
2 #include "Visualization/qcustomplot.h"
3
4 #include <Data/ScalarSeries.h>
5
6 #include <Variable/Variable.h>
7
8 Q_LOGGING_CATEGORY(LOG_GraphPlottablesFactory, "GraphPlottablesFactory")
9
10 namespace {
11
12 /// Format for datetimes on a axis
13 const auto DATETIME_TICKER_FORMAT = QStringLiteral("yyyy/MM/dd \nhh:mm:ss");
14
15 /// Generates the appropriate ticker for an axis, depending on whether the axis displays time or
16 /// non-time data
17 QSharedPointer<QCPAxisTicker> axisTicker(bool isTimeAxis)
18 {
19 if (isTimeAxis) {
20 auto dateTicker = QSharedPointer<QCPAxisTickerDateTime>::create();
21 dateTicker->setDateTimeFormat(DATETIME_TICKER_FORMAT);
22
23 return dateTicker;
24 }
25 else {
26 // default ticker
27 return QSharedPointer<QCPAxisTicker>::create();
28 }
29 }
30
31 QCPAbstractPlottable *createScalarSeriesComponent(ScalarSeries &scalarSeries, QCustomPlot &plot)
32 {
33 auto component = plot.addGraph();
34
35 if (component) {
36 // Graph data
37 component->setData(scalarSeries.xAxisData()->data(), scalarSeries.valuesData()->data(),
38 true);
39
40 // Axes properties
41 /// @todo : for the moment, no control is performed on the axes: the units and the tickers
42 /// are fixed for the default x-axis and y-axis of the plot, and according to the new graph
43
44 auto setAxisProperties = [](auto axis, const auto &unit) {
45 // label (unit name)
46 axis->setLabel(unit.m_Name);
47
48 // ticker (depending on the type of unit)
49 axis->setTicker(axisTicker(unit.m_TimeUnit));
50 };
51 setAxisProperties(plot.xAxis, scalarSeries.xAxisUnit());
52 setAxisProperties(plot.yAxis, scalarSeries.valuesUnit());
53
54 // Display all data
55 component->rescaleAxes();
56
57 plot.replot();
58 }
59 else {
60 qCDebug(LOG_GraphPlottablesFactory())
61 << QObject::tr("Can't create graph for the scalar series");
62 }
63
64 return component;
65 }
66
67 } // namespace
68
69 QVector<QCPAbstractPlottable *> GraphPlottablesFactory::create(const Variable *variable,
70 QCustomPlot &plot) noexcept
71 {
72 auto result = QVector<QCPAbstractPlottable *>{};
73
74 if (variable) {
75 // Gets the data series of the variable to call the creation of the right components
76 // according to its type
77 if (auto scalarSeries = dynamic_cast<ScalarSeries *>(variable->dataSeries())) {
78 result.append(createScalarSeriesComponent(*scalarSeries, plot));
79 }
80 else {
81 qCDebug(LOG_GraphPlottablesFactory())
82 << QObject::tr("Can't create graph plottables : unmanaged data series type");
83 }
84 }
85 else {
86 qCDebug(LOG_GraphPlottablesFactory())
87 << QObject::tr("Can't create graph plottables : the variable is null");
88 }
89
90 return result;
91 }
@@ -1,233 +1,239
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the SciQLop Software
3 3 -- Copyright (C) 2017, Plasma Physics Laboratory - CNRS
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 2 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------*/
19 19 /*-- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@member.fsf.org
21 21 ----------------------------------------------------------------------------*/
22 22 #include "MainWindow.h"
23 23 #include "ui_MainWindow.h"
24 24
25 25 #include <DataSource/DataSourceController.h>
26 26 #include <DataSource/DataSourceWidget.h>
27 27 #include <SidePane/SqpSidePane.h>
28 28 #include <SqpApplication.h>
29 29 #include <TimeWidget/TimeWidget.h>
30 #include <Variable/Variable.h>
31 #include <Visualization/VisualizationController.h>
30 32
31 33 #include <QAction>
32 34 #include <QDate>
33 35 #include <QDateTime>
34 36 #include <QDir>
35 37 #include <QFileDialog>
36 38 #include <QToolBar>
37 39 #include <QToolButton>
38 40 #include <memory.h>
39 41
40 42 //#include <omp.h>
41 43 //#include <network/filedownloader.h>
42 44 //#include <qlopdatabase.h>
43 45 //#include <qlopsettings.h>
44 46 //#include <qlopgui.h>
45 47 //#include <spacedata.h>
46 48 //#include "qlopcore.h"
47 49 //#include "qlopcodecmanager.h"
48 50 //#include "cdfcodec.h"
49 51 //#include "amdatxtcodec.h"
50 52 //#include <qlopplotmanager.h>
51 53
52 54 #include "iostream"
53 55
54 56 Q_LOGGING_CATEGORY(LOG_MainWindow, "MainWindow")
55 57
56 58 namespace {
57 59 const auto LEFTMAININSPECTORWIDGETSPLITTERINDEX = 0;
58 60 const auto LEFTINSPECTORSIDEPANESPLITTERINDEX = 1;
59 61 const auto VIEWPLITTERINDEX = 2;
60 62 const auto RIGHTINSPECTORSIDEPANESPLITTERINDEX = 3;
61 63 const auto RIGHTMAININSPECTORWIDGETSPLITTERINDEX = 4;
62 64 }
63 65
64 66 class MainWindow::MainWindowPrivate {
65 67 public:
66 68 QSize m_LastOpenLeftInspectorSize;
67 69 QSize m_LastOpenRightInspectorSize;
68 70 };
69 71
70 72 MainWindow::MainWindow(QWidget *parent)
71 73 : QMainWindow{parent},
72 74 m_Ui{new Ui::MainWindow},
73 75 impl{spimpl::make_unique_impl<MainWindowPrivate>()}
74 76 {
75 77 m_Ui->setupUi(this);
76 78
77 79 m_Ui->splitter->setCollapsible(LEFTINSPECTORSIDEPANESPLITTERINDEX, false);
78 80 m_Ui->splitter->setCollapsible(RIGHTINSPECTORSIDEPANESPLITTERINDEX, false);
79 81
80 82
81 83 auto leftSidePane = m_Ui->leftInspectorSidePane->sidePane();
82 84 auto openLeftInspectorAction = new QAction{QIcon{
83 85 ":/icones/previous.png",
84 86 },
85 87 tr("Show/hide the left inspector"), this};
86 88
87 89
88 90 auto spacerLeftTop = new QWidget{};
89 91 spacerLeftTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
90 92
91 93 auto spacerLeftBottom = new QWidget{};
92 94 spacerLeftBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
93 95
94 96 leftSidePane->addWidget(spacerLeftTop);
95 97 leftSidePane->addAction(openLeftInspectorAction);
96 98 leftSidePane->addWidget(spacerLeftBottom);
97 99
98 100
99 101 auto rightSidePane = m_Ui->rightInspectorSidePane->sidePane();
100 102 auto openRightInspectorAction = new QAction{QIcon{
101 103 ":/icones/next.png",
102 104 },
103 105 tr("Show/hide the right inspector"), this};
104 106
105 107 auto spacerRightTop = new QWidget{};
106 108 spacerRightTop->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
107 109
108 110 auto spacerRightBottom = new QWidget{};
109 111 spacerRightBottom->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
110 112
111 113 rightSidePane->addWidget(spacerRightTop);
112 114 rightSidePane->addAction(openRightInspectorAction);
113 115 rightSidePane->addWidget(spacerRightBottom);
114 116
115 117 openLeftInspectorAction->setCheckable(true);
116 118 openRightInspectorAction->setCheckable(true);
117 119
118 120 auto openInspector = [this](bool checked, bool right, auto action) {
119 121
120 122 action->setIcon(QIcon{(checked xor right) ? ":/icones/next.png" : ":/icones/previous.png"});
121 123
122 124 auto &lastInspectorSize
123 125 = right ? impl->m_LastOpenRightInspectorSize : impl->m_LastOpenLeftInspectorSize;
124 126
125 127 auto nextInspectorSize = right ? m_Ui->rightMainInspectorWidget->size()
126 128 : m_Ui->leftMainInspectorWidget->size();
127 129
128 130 // Update of the last opened geometry
129 131 if (checked) {
130 132 lastInspectorSize = nextInspectorSize;
131 133 }
132 134
133 135 auto startSize = lastInspectorSize;
134 136 auto endSize = startSize;
135 137 endSize.setWidth(0);
136 138
137 139 auto splitterInspectorIndex
138 140 = right ? RIGHTMAININSPECTORWIDGETSPLITTERINDEX : LEFTMAININSPECTORWIDGETSPLITTERINDEX;
139 141
140 142 auto currentSizes = m_Ui->splitter->sizes();
141 143 if (checked) {
142 144 // adjust sizes individually here, e.g.
143 145 currentSizes[splitterInspectorIndex] -= lastInspectorSize.width();
144 146 currentSizes[VIEWPLITTERINDEX] += lastInspectorSize.width();
145 147 m_Ui->splitter->setSizes(currentSizes);
146 148 }
147 149 else {
148 150 // adjust sizes individually here, e.g.
149 151 currentSizes[splitterInspectorIndex] += lastInspectorSize.width();
150 152 currentSizes[VIEWPLITTERINDEX] -= lastInspectorSize.width();
151 153 m_Ui->splitter->setSizes(currentSizes);
152 154 }
153 155
154 156 };
155 157
156 158
157 159 connect(openLeftInspectorAction, &QAction::triggered,
158 160 [openInspector, openLeftInspectorAction](bool checked) {
159 161 openInspector(checked, false, openLeftInspectorAction);
160 162 });
161 163 connect(openRightInspectorAction, &QAction::triggered,
162 164 [openInspector, openRightInspectorAction](bool checked) {
163 165 openInspector(checked, true, openRightInspectorAction);
164 166 });
165 167
166 168 this->menuBar()->addAction(tr("File"));
167 169 auto mainToolBar = this->addToolBar(QStringLiteral("MainToolBar"));
168 170
169 171 mainToolBar->addWidget(new TimeWidget{});
170 172
171 173 // Widgets / controllers connections
172 174 connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem *)),
173 175 m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem *)));
174 176
177 qRegisterMetaType<std::shared_ptr<Variable> >();
178 connect(&sqpApp->visualizationController(), SIGNAL(variableCreated(std::shared_ptr<Variable>)),
179 m_Ui->view, SLOT(displayVariable(std::shared_ptr<Variable>)));
180
175 181 /* QLopGUI::registerMenuBar(menuBar());
176 182 this->setWindowIcon(QIcon(":/sciqlopLOGO.svg"));
177 183 this->m_progressWidget = new QWidget();
178 184 this->m_progressLayout = new QVBoxLayout(this->m_progressWidget);
179 185 this->m_progressWidget->setLayout(this->m_progressLayout);
180 186 this->m_progressWidget->setWindowModality(Qt::WindowModal);
181 187 m_progressThreadIds = (int*) malloc(OMP_THREADS*sizeof(int));
182 188 for(int i=0;i<OMP_THREADS;i++)
183 189 {
184 190 this->m_progress.append(new QProgressBar(this->m_progressWidget));
185 191 this->m_progress.last()->setMinimum(0);
186 192 this->m_progress.last()->setMaximum(100);
187 193 this->m_progressLayout->addWidget(this->m_progress.last());
188 194 this->m_progressWidget->hide();
189 195 this->m_progressThreadIds[i] = -1;
190 196 }
191 197 this->m_progressWidget->setWindowTitle("Loading File");
192 198 const QList<QLopService*>ServicesToLoad=QList<QLopService*>()
193 199 << QLopCore::self()
194 200 << QLopPlotManager::self()
195 201 << QLopCodecManager::self()
196 202 << FileDownloader::self()
197 203 << QLopDataBase::self()
198 204 << SpaceData::self();
199 205
200 206 CDFCodec::registerToManager();
201 207 AMDATXTCodec::registerToManager();
202 208
203 209
204 210 for(int i=0;i<ServicesToLoad.count();i++)
205 211 {
206 212 qDebug()<<ServicesToLoad.at(i)->serviceName();
207 213 ServicesToLoad.at(i)->initialize(); //must be called before getGUI
208 214 QDockWidget* wdgt=ServicesToLoad.at(i)->getGUI();
209 215 if(wdgt)
210 216 {
211 217 wdgt->setAllowedAreas(Qt::AllDockWidgetAreas);
212 218 this->addDockWidget(Qt::TopDockWidgetArea,wdgt);
213 219 }
214 220 PythonQt::self()->getMainModule().addObject(ServicesToLoad.at(i)->serviceName(),(QObject*)ServicesToLoad.at(i));
215 221 }*/
216 222 }
217 223
218 224 MainWindow::~MainWindow()
219 225 {
220 226 }
221 227
222 228
223 229 void MainWindow::changeEvent(QEvent *e)
224 230 {
225 231 QMainWindow::changeEvent(e);
226 232 switch (e->type()) {
227 233 case QEvent::LanguageChange:
228 234 m_Ui->retranslateUi(this);
229 235 break;
230 236 default:
231 237 break;
232 238 }
233 239 }
@@ -1,50 +1,50
1 1 #ifndef SCIQLOP_DATASERIES_H
2 2 #define SCIQLOP_DATASERIES_H
3 3
4 4 #include <Data/ArrayData.h>
5 5 #include <Data/IDataSeries.h>
6 6
7 7 #include <memory>
8 8
9 9 /**
10 10 * @brief The DataSeries class is the base (abstract) implementation of IDataSeries.
11 11 *
12 12 * It proposes to set a dimension for the values ​​data
13 13 *
14 14 * @tparam Dim The dimension of the values data
15 15 *
16 16 */
17 17 template <int Dim>
18 18 class DataSeries : public IDataSeries {
19 19 public:
20 20 /// @sa IDataSeries::xAxisData()
21 21 std::shared_ptr<ArrayData<1> > xAxisData() override { return m_XAxisData; }
22 22
23 23 /// @sa IDataSeries::xAxisUnit()
24 QString xAxisUnit() const override { return m_XAxisUnit; }
24 Unit xAxisUnit() const override { return m_XAxisUnit; }
25 25
26 26 /// @return the values dataset
27 27 std::shared_ptr<ArrayData<Dim> > valuesData() const { return m_ValuesData; }
28 28
29 29 /// @sa IDataSeries::valuesUnit()
30 QString valuesUnit() const override { return m_ValuesUnit; }
30 Unit valuesUnit() const override { return m_ValuesUnit; }
31 31
32 32 protected:
33 33 /// Protected ctor (DataSeries is abstract)
34 explicit DataSeries(std::shared_ptr<ArrayData<1> > xAxisData, const QString &xAxisUnit,
35 std::shared_ptr<ArrayData<Dim> > valuesData, const QString &valuesUnit)
34 explicit DataSeries(std::shared_ptr<ArrayData<1> > xAxisData, Unit xAxisUnit,
35 std::shared_ptr<ArrayData<Dim> > valuesData, Unit valuesUnit)
36 36 : m_XAxisData{xAxisData},
37 m_XAxisUnit{xAxisUnit},
37 m_XAxisUnit{std::move(xAxisUnit)},
38 38 m_ValuesData{valuesData},
39 m_ValuesUnit{valuesUnit}
39 m_ValuesUnit{std::move(valuesUnit)}
40 40 {
41 41 }
42 42
43 43 private:
44 44 std::shared_ptr<ArrayData<1> > m_XAxisData;
45 QString m_XAxisUnit;
45 Unit m_XAxisUnit;
46 46 std::shared_ptr<ArrayData<Dim> > m_ValuesData;
47 QString m_ValuesUnit;
47 Unit m_ValuesUnit;
48 48 };
49 49
50 50 #endif // SCIQLOP_DATASERIES_H
@@ -1,37 +1,47
1 1 #ifndef SCIQLOP_IDATASERIES_H
2 2 #define SCIQLOP_IDATASERIES_H
3 3
4 4 #include <QString>
5 5
6 6 #include <memory>
7 7
8 8 template <int Dim>
9 9 class ArrayData;
10 10
11 struct Unit {
12 explicit Unit(const QString &name = {}, bool timeUnit = false)
13 : m_Name{name}, m_TimeUnit{timeUnit}
14 {
15 }
16
17 QString m_Name; ///< Unit name
18 bool m_TimeUnit; ///< The unit is a unit of time
19 };
20
11 21 /**
12 22 * @brief The IDataSeries aims to declare a data series.
13 23 *
14 24 * A data series is an entity that contains at least :
15 25 * - one dataset representing the x-axis
16 26 * - one dataset representing the values
17 27 *
18 28 * Each dataset is represented by an ArrayData, and is associated with a unit.
19 29 *
20 30 * An ArrayData can be unidimensional or two-dimensional, depending on the implementation of the
21 31 * IDataSeries. The x-axis dataset is always unidimensional.
22 32 *
23 33 * @sa ArrayData
24 34 */
25 35 class IDataSeries {
26 36 public:
27 37 virtual ~IDataSeries() noexcept = default;
28 38
29 39 /// Returns the x-axis dataset
30 40 virtual std::shared_ptr<ArrayData<1> > xAxisData() = 0;
31 41
32 virtual QString xAxisUnit() const = 0;
42 virtual Unit xAxisUnit() const = 0;
33 43
34 virtual QString valuesUnit() const = 0;
44 virtual Unit valuesUnit() const = 0;
35 45 };
36 46
37 47 #endif // SCIQLOP_IDATASERIES_H
@@ -1,28 +1,28
1 1 #ifndef SCIQLOP_SCALARSERIES_H
2 2 #define SCIQLOP_SCALARSERIES_H
3 3
4 4 #include <Data/DataSeries.h>
5 5
6 6 /**
7 7 * @brief The ScalarSeries class is the implementation for a data series representing a scalar.
8 8 */
9 9 class ScalarSeries : public DataSeries<1> {
10 10 public:
11 11 /**
12 12 * Ctor
13 13 * @param size the number of data the series will hold
14 14 * @param xAxisUnit x-axis unit
15 15 * @param valuesUnit values unit
16 16 */
17 explicit ScalarSeries(int size, const QString &xAxisUnit, const QString &valuesUnit);
17 explicit ScalarSeries(int size, Unit xAxisUnit, Unit valuesUnit);
18 18
19 19 /**
20 20 * Sets data for a specific index. The index has to be valid to be effective
21 21 * @param index the index to which the data will be set
22 22 * @param x the x-axis data
23 23 * @param value the value data
24 24 */
25 25 void setData(int index, double x, double value) noexcept;
26 26 };
27 27
28 28 #endif // SCIQLOP_SCALARSERIES_H
@@ -1,32 +1,35
1 1 #ifndef SCIQLOP_VARIABLE_H
2 2 #define SCIQLOP_VARIABLE_H
3 3
4 4 #include <Common/spimpl.h>
5 5
6 6 #include <QObject>
7 7
8 8 class IDataSeries;
9 9 class QString;
10 10
11 11 /**
12 12 * @brief The Variable class represents a variable in SciQlop.
13 13 */
14 14 class Variable {
15 15 public:
16 16 explicit Variable(const QString &name, const QString &unit, const QString &mission);
17 17
18 18 QString name() const noexcept;
19 19 QString mission() const noexcept;
20 20 QString unit() const noexcept;
21 21
22 22 void addDataSeries(std::unique_ptr<IDataSeries> dataSeries) noexcept;
23 23
24 /// @return the data of the variable, nullptr if there is no data
25 IDataSeries *dataSeries() const noexcept;
26
24 27 private:
25 28 class VariablePrivate;
26 29 spimpl::unique_impl_ptr<VariablePrivate> impl;
27 30 };
28 31
29 32 // Required for using shared_ptr in signals/slots
30 33 Q_DECLARE_METATYPE(std::shared_ptr<Variable>)
31 34
32 35 #endif // SCIQLOP_VARIABLE_H
@@ -1,43 +1,44
1 1 #ifndef SCIQLOP_VISUALIZATIONCONTROLLER_H
2 2 #define SCIQLOP_VISUALIZATIONCONTROLLER_H
3 3
4 4 #include <QLoggingCategory>
5 5 #include <QObject>
6 6 #include <QUuid>
7 7
8 8 #include <Common/spimpl.h>
9 9
10 10 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationController)
11 11
12 12 class DataSourceItem;
13 13 class Variable;
14 14
15 15 /**
16 16 * @brief The VisualizationController class aims to make the link between SciQlop and its plugins.
17 17 * This is the intermediate class that SciQlop has to use in the way to connect a data source.
18 18 * Please first use register method to initialize a plugin specified by its metadata name (JSON
19 19 * plugin source) then others specifics method will be able to access it. You can load a data source
20 20 * driver plugin then create a data source.
21 21 */
22 22 class VisualizationController : public QObject {
23 23 Q_OBJECT
24 24 public:
25 25 explicit VisualizationController(QObject *parent = 0);
26 26 virtual ~VisualizationController();
27 27
28 public slots:
29 /// Slot called when a variable has been created in SciQlop
30 void onVariableCreated(std::shared_ptr<Variable> variable) noexcept;
28 signals:
29 /// Signal emitted when a variable has been created in SciQlop
30 void variableCreated(std::shared_ptr<Variable> variable);
31 31
32 public slots:
32 33 /// Manage init/end of the controller
33 34 void initialize();
34 35 void finalize();
35 36
36 37 private:
37 38 void waitForFinish();
38 39
39 40 class VisualizationControllerPrivate;
40 41 spimpl::unique_impl_ptr<VisualizationControllerPrivate> impl;
41 42 };
42 43
43 44 #endif // SCIQLOP_VISUALIZATIONCONTROLLER_H
@@ -1,13 +1,13
1 1 #include <Data/ScalarSeries.h>
2 2
3 ScalarSeries::ScalarSeries(int size, const QString &xAxisUnit, const QString &valuesUnit)
4 : DataSeries{std::make_shared<ArrayData<1> >(size), xAxisUnit,
5 std::make_shared<ArrayData<1> >(size), valuesUnit}
3 ScalarSeries::ScalarSeries(int size, Unit xAxisUnit, Unit valuesUnit)
4 : DataSeries{std::make_shared<ArrayData<1> >(size), std::move(xAxisUnit),
5 std::make_shared<ArrayData<1> >(size), std::move(valuesUnit)}
6 6 {
7 7 }
8 8
9 9 void ScalarSeries::setData(int index, double x, double value) noexcept
10 10 {
11 11 xAxisData()->setData(index, x);
12 12 valuesData()->setData(index, value);
13 13 }
@@ -1,43 +1,48
1 1 #include "Variable/Variable.h"
2 2
3 3 #include <Data/IDataSeries.h>
4 4
5 5 struct Variable::VariablePrivate {
6 6 explicit VariablePrivate(const QString &name, const QString &unit, const QString &mission)
7 7 : m_Name{name}, m_Unit{unit}, m_Mission{mission}, m_DataSeries{nullptr}
8 8 {
9 9 }
10 10
11 11 QString m_Name;
12 12 QString m_Unit;
13 13 QString m_Mission;
14 14 std::unique_ptr<IDataSeries> m_DataSeries;
15 15 };
16 16
17 17 Variable::Variable(const QString &name, const QString &unit, const QString &mission)
18 18 : impl{spimpl::make_unique_impl<VariablePrivate>(name, unit, mission)}
19 19 {
20 20 }
21 21
22 22 QString Variable::name() const noexcept
23 23 {
24 24 return impl->m_Name;
25 25 }
26 26
27 27 QString Variable::mission() const noexcept
28 28 {
29 29 return impl->m_Mission;
30 30 }
31 31
32 32 QString Variable::unit() const noexcept
33 33 {
34 34 return impl->m_Unit;
35 35 }
36 36
37 37 void Variable::addDataSeries(std::unique_ptr<IDataSeries> dataSeries) noexcept
38 38 {
39 39 if (!impl->m_DataSeries) {
40 40 impl->m_DataSeries = std::move(dataSeries);
41 41 }
42 42 /// @todo : else, merge the two data series (if possible)
43 43 }
44
45 IDataSeries *Variable::dataSeries() const noexcept
46 {
47 return impl->m_DataSeries.get();
48 }
@@ -1,54 +1,48
1 1 #include <Visualization/VisualizationController.h>
2 2
3 3 #include <Variable/Variable.h>
4 4
5 5 #include <QMutex>
6 6 #include <QThread>
7 7
8 8 #include <QDir>
9 9 #include <QStandardPaths>
10 10
11 11 Q_LOGGING_CATEGORY(LOG_VisualizationController, "VisualizationController")
12 12
13 13 class VisualizationController::VisualizationControllerPrivate {
14 14 public:
15 15 QMutex m_WorkingMutex;
16 16 };
17 17
18 18 VisualizationController::VisualizationController(QObject *parent)
19 19 : impl{spimpl::make_unique_impl<VisualizationControllerPrivate>()}
20 20 {
21 21 qCDebug(LOG_VisualizationController()) << tr("VisualizationController construction")
22 22 << QThread::currentThread();
23 23 }
24 24
25 25 VisualizationController::~VisualizationController()
26 26 {
27 27 qCDebug(LOG_VisualizationController()) << tr("VisualizationController destruction")
28 28 << QThread::currentThread();
29 29 this->waitForFinish();
30 30 }
31 31
32 void VisualizationController::onVariableCreated(std::shared_ptr<Variable> variable) noexcept
33 {
34 /// @todo ALX : make new graph for the variable
35 qCDebug(LOG_VisualizationController()) << "new variable to display";
36 }
37
38 32 void VisualizationController::initialize()
39 33 {
40 34 qCDebug(LOG_VisualizationController()) << tr("VisualizationController init")
41 35 << QThread::currentThread();
42 36 impl->m_WorkingMutex.lock();
43 37 qCDebug(LOG_VisualizationController()) << tr("VisualizationController init END");
44 38 }
45 39
46 40 void VisualizationController::finalize()
47 41 {
48 42 impl->m_WorkingMutex.unlock();
49 43 }
50 44
51 45 void VisualizationController::waitForFinish()
52 46 {
53 47 QMutexLocker locker{&impl->m_WorkingMutex};
54 48 }
@@ -1,39 +1,43
1 1 #ifndef SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
2 2 #define SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
3 3
4 4 #include "Visualization/IVisualizationWidget.h"
5 5
6 6 #include <QWidget>
7 7
8 8 #include <memory>
9 9
10 10 #include <Common/spimpl.h>
11 11
12 12 class Variable;
13 13
14 14 namespace Ui {
15 15 class VisualizationGraphWidget;
16 16 } // namespace Ui
17 17
18 18 class VisualizationGraphWidget : public QWidget, public IVisualizationWidget {
19 19 Q_OBJECT
20 20
21 21 public:
22 22 explicit VisualizationGraphWidget(QWidget *parent = 0);
23 23 virtual ~VisualizationGraphWidget();
24 24
25 25 void addVariable(std::shared_ptr<Variable> variable);
26 26
27 27 // IVisualizationWidget interface
28 28 void accept(IVisualizationWidget *visitor) override;
29 29 void close() override;
30 30 QString name() const;
31 31
32 32 private:
33 33 Ui::VisualizationGraphWidget *ui;
34 34
35 35 class VisualizationGraphWidgetPrivate;
36 36 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
37
38 private slots:
39 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
40 void onMouseWheel(QWheelEvent *event) noexcept;
37 41 };
38 42
39 43 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
@@ -1,42 +1,52
1 1 #ifndef SCIQLOP_VISUALIZATIONWIDGET_H
2 2 #define SCIQLOP_VISUALIZATIONWIDGET_H
3 3
4 4 #include "Visualization/IVisualizationWidget.h"
5 5
6 6 #include <QLoggingCategory>
7 7 #include <QWidget>
8 8
9 class Variable;
9 10 class VisualizationTabWidget;
10 11
11 12 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget)
12 13
13 14 namespace Ui {
14 15 class VisualizationWidget;
15 16 } // namespace Ui
16 17
17 18 class VisualizationWidget : public QWidget, public IVisualizationWidget {
18 19 Q_OBJECT
19 20
20 21 public:
21 22 explicit VisualizationWidget(QWidget *parent = 0);
22 23 virtual ~VisualizationWidget();
23 24
24 25 /// Add a zone widget
25 26 virtual void addTab(VisualizationTabWidget *tabWidget);
26 27
27 28 /// Create a tab using a Variable
28 29 VisualizationTabWidget *createTab();
29 30
30 31 /// Remove a tab
31 32 void removeTab(VisualizationTabWidget *tab);
32 33
33 34 // IVisualizationWidget interface
34 35 void accept(IVisualizationWidget *visitor) override;
35 36 void close() override;
36 37 QString name() const;
37 38
39 public slots:
40 /**
41 * Displays a variable in a new graph of a new zone of the current tab
42 * @param variable the variable to display
43 * @todo this is a temporary method that will be replaced by own actions for each type of
44 * visualization widget
45 */
46 void displayVariable(std::shared_ptr<Variable> variable) noexcept;
47
38 48 private:
39 49 Ui::VisualizationWidget *ui;
40 50 };
41 51
42 52 #endif // VISUALIZATIONWIDGET_H
@@ -1,109 +1,109
1 1 #include "SqpApplication.h"
2 2
3 3 #include <Data/IDataProvider.h>
4 4 #include <DataSource/DataSourceController.h>
5 5 #include <QThread>
6 6 #include <Variable/Variable.h>
7 7 #include <Variable/VariableController.h>
8 8 #include <Visualization/VisualizationController.h>
9 9
10 10 Q_LOGGING_CATEGORY(LOG_SqpApplication, "SqpApplication")
11 11
12 12 class SqpApplication::SqpApplicationPrivate {
13 13 public:
14 14 SqpApplicationPrivate()
15 15 : m_DataSourceController{std::make_unique<DataSourceController>()},
16 16 m_VariableController{std::make_unique<VariableController>()},
17 17 m_VisualizationController{std::make_unique<VisualizationController>()}
18 18 {
19 19 // /////////////////////////////// //
20 20 // Connections between controllers //
21 21 // /////////////////////////////// //
22 22
23 23 // VariableController <-> DataSourceController
24 24 qRegisterMetaType<std::shared_ptr<IDataProvider> >();
25 25 connect(m_DataSourceController.get(),
26 26 SIGNAL(variableCreationRequested(const QString &, std::shared_ptr<IDataProvider>)),
27 27 m_VariableController.get(),
28 28 SLOT(createVariable(const QString &, std::shared_ptr<IDataProvider>)));
29 29
30 30 // VariableController <-> VisualizationController
31 31 qRegisterMetaType<std::shared_ptr<Variable> >();
32 32 connect(m_VariableController.get(), SIGNAL(variableCreated(std::shared_ptr<Variable>)),
33 33 m_VisualizationController.get(),
34 SLOT(onVariableCreated(std::shared_ptr<Variable>)));
34 SIGNAL(variableCreated(std::shared_ptr<Variable>)));
35 35
36 36 m_DataSourceController->moveToThread(&m_DataSourceControllerThread);
37 37 m_VariableController->moveToThread(&m_VariableControllerThread);
38 38 m_VisualizationController->moveToThread(&m_VisualizationControllerThread);
39 39 }
40 40
41 41 virtual ~SqpApplicationPrivate()
42 42 {
43 43 qCInfo(LOG_SqpApplication()) << tr("SqpApplicationPrivate destruction");
44 44 m_DataSourceControllerThread.quit();
45 45 m_DataSourceControllerThread.wait();
46 46
47 47 m_VariableControllerThread.quit();
48 48 m_VariableControllerThread.wait();
49 49
50 50 m_VisualizationControllerThread.quit();
51 51 m_VisualizationControllerThread.wait();
52 52 }
53 53
54 54 std::unique_ptr<DataSourceController> m_DataSourceController;
55 55 std::unique_ptr<VariableController> m_VariableController;
56 56 std::unique_ptr<VisualizationController> m_VisualizationController;
57 57 QThread m_DataSourceControllerThread;
58 58 QThread m_VariableControllerThread;
59 59 QThread m_VisualizationControllerThread;
60 60 };
61 61
62 62
63 63 SqpApplication::SqpApplication(int &argc, char **argv)
64 64 : QApplication{argc, argv}, impl{spimpl::make_unique_impl<SqpApplicationPrivate>()}
65 65 {
66 66 qCInfo(LOG_SqpApplication()) << tr("SqpApplication construction");
67 67
68 68 connect(&impl->m_DataSourceControllerThread, &QThread::started,
69 69 impl->m_DataSourceController.get(), &DataSourceController::initialize);
70 70 connect(&impl->m_DataSourceControllerThread, &QThread::finished,
71 71 impl->m_DataSourceController.get(), &DataSourceController::finalize);
72 72
73 73 connect(&impl->m_VariableControllerThread, &QThread::started, impl->m_VariableController.get(),
74 74 &VariableController::initialize);
75 75 connect(&impl->m_VariableControllerThread, &QThread::finished, impl->m_VariableController.get(),
76 76 &VariableController::finalize);
77 77
78 78 connect(&impl->m_VisualizationControllerThread, &QThread::started,
79 79 impl->m_VisualizationController.get(), &VisualizationController::initialize);
80 80 connect(&impl->m_VisualizationControllerThread, &QThread::finished,
81 81 impl->m_VisualizationController.get(), &VisualizationController::finalize);
82 82
83 83 impl->m_DataSourceControllerThread.start();
84 84 impl->m_VariableControllerThread.start();
85 85 impl->m_VisualizationControllerThread.start();
86 86 }
87 87
88 88 SqpApplication::~SqpApplication()
89 89 {
90 90 }
91 91
92 92 void SqpApplication::initialize()
93 93 {
94 94 }
95 95
96 96 DataSourceController &SqpApplication::dataSourceController() noexcept
97 97 {
98 98 return *impl->m_DataSourceController;
99 99 }
100 100
101 101 VariableController &SqpApplication::variableController() noexcept
102 102 {
103 103 return *impl->m_VariableController;
104 104 }
105 105
106 106 VisualizationController &SqpApplication::visualizationController() noexcept
107 107 {
108 108 return *impl->m_VisualizationController;
109 109 }
@@ -1,47 +1,86
1 1 #include "Visualization/VisualizationGraphWidget.h"
2 #include "Visualization/GraphPlottablesFactory.h"
2 3 #include "ui_VisualizationGraphWidget.h"
3 4
4 5 #include <Variable/Variable.h>
5 6
6 7 #include <unordered_map>
7 8
9 namespace {
10
11 /// Key pressed to enable zoom on horizontal axis
12 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
13
14 /// Key pressed to enable zoom on vertical axis
15 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
16
17 } // namespace
18
8 19 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
9 20
10 21 // 1 variable -> n qcpplot
11 std::unordered_map<std::shared_ptr<Variable>, std::unique_ptr<QCPAbstractPlottable> >
12 m_VariableToPlotMap;
22 std::unordered_map<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMap;
13 23 };
14 24
15 25 VisualizationGraphWidget::VisualizationGraphWidget(QWidget *parent)
16 26 : QWidget{parent},
17 27 ui{new Ui::VisualizationGraphWidget},
18 28 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>()}
19 29 {
20 30 ui->setupUi(this);
31
32 // Set qcpplot properties :
33 // - Drag (on x-axis) and zoom are enabled
34 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
35 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
36 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
37 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
21 38 }
22 39
23 40 VisualizationGraphWidget::~VisualizationGraphWidget()
24 41 {
25 42 delete ui;
26 43 }
27 44
28 45 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable)
29 46 {
30 // todo: first check is variable contains data then check how many plot have to be created
47 // Uses delegate to create the qcpplot components according to the variable
48 auto createdPlottables = GraphPlottablesFactory::create(variable.get(), *ui->widget);
49
50 for (auto createdPlottable : qAsConst(createdPlottables)) {
51 impl->m_VariableToPlotMap.insert({variable, createdPlottable});
52 }
31 53 }
32 54
33 55 void VisualizationGraphWidget::accept(IVisualizationWidget *visitor)
34 56 {
35 57 // TODO: manage the visitor
36 58 }
37 59
38 60 void VisualizationGraphWidget::close()
39 61 {
40 62 // The main view cannot be directly closed.
41 63 return;
42 64 }
43 65
44 66 QString VisualizationGraphWidget::name() const
45 67 {
46 68 return QStringLiteral("MainView");
47 69 }
70
71 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
72 {
73 auto zoomOrientations = QFlags<Qt::Orientation>{};
74
75 // Lambda that enables a zoom orientation if the key modifier related to this orientation has
76 // been pressed
77 auto enableOrientation
78 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
79 auto orientationEnabled = event->modifiers().testFlag(modifier);
80 zoomOrientations.setFlag(orientation, orientationEnabled);
81 };
82 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
83 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
84
85 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
86 }
@@ -1,80 +1,105
1 1 #include "Visualization/VisualizationWidget.h"
2 #include "Visualization/VisualizationGraphWidget.h"
2 3 #include "Visualization/VisualizationTabWidget.h"
4 #include "Visualization/VisualizationZoneWidget.h"
3 5 #include "Visualization/qcustomplot.h"
4 6
5 7 #include "ui_VisualizationWidget.h"
6 8
7 9 #include <QToolButton>
8 10
9 11 Q_LOGGING_CATEGORY(LOG_VisualizationWidget, "VisualizationWidget")
10 12
11 13 VisualizationWidget::VisualizationWidget(QWidget *parent)
12 14 : QWidget{parent}, ui{new Ui::VisualizationWidget}
13 15 {
14 16 ui->setupUi(this);
15 17
16 18 auto addTabViewButton = new QToolButton{ui->tabWidget};
17 19 addTabViewButton->setText(tr("Add View"));
18 20 addTabViewButton->setCursor(Qt::ArrowCursor);
19 21 addTabViewButton->setAutoRaise(true);
20 22 ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner);
21 23 auto width = ui->tabWidget->cornerWidget()->width();
22 24 auto height = ui->tabWidget->cornerWidget()->height();
23 25 addTabViewButton->setMinimumHeight(height);
24 26 addTabViewButton->setMinimumWidth(width);
25 27 ui->tabWidget->setMinimumHeight(height);
26 28 ui->tabWidget->setMinimumWidth(width);
27 29
28 30 auto addTabView = [&]() {
29 31 auto index = ui->tabWidget->addTab(new VisualizationTabWidget(ui->tabWidget),
30 32 QString("View %1").arg(ui->tabWidget->count() + 1));
31 33 qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index);
32 34 };
33 35
34 36 auto removeTabView = [&](int index) {
35 37 ui->tabWidget->removeTab(index);
36 38 qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index);
37 39 };
38 40
39 41 ui->tabWidget->setTabsClosable(true);
40 42
41 43 connect(addTabViewButton, &QToolButton::clicked, addTabView);
42 44 connect(ui->tabWidget, &QTabWidget::tabCloseRequested, removeTabView);
43 45 }
44 46
45 47 VisualizationWidget::~VisualizationWidget()
46 48 {
47 49 delete ui;
48 50 }
49 51
50 52 void VisualizationWidget::addTab(VisualizationTabWidget *tabWidget)
51 53 {
52 54 // NOTE: check is this method has to be deleted because of its dupplicated version visible as
53 55 // lambda function (in the constructor)
54 56 }
55 57
56 58 VisualizationTabWidget *VisualizationWidget::createTab()
57 59 {
58 60 }
59 61
60 62 void VisualizationWidget::removeTab(VisualizationTabWidget *tab)
61 63 {
62 64 // NOTE: check is this method has to be deleted because of its dupplicated version visible as
63 65 // lambda function (in the constructor)
64 66 }
65 67
66 68 void VisualizationWidget::accept(IVisualizationWidget *visitor)
67 69 {
68 70 // TODO: manage the visitor
69 71 }
70 72
71 73 void VisualizationWidget::close()
72 74 {
73 75 // The main view cannot be directly closed.
74 76 return;
75 77 }
76 78
77 79 QString VisualizationWidget::name() const
78 80 {
79 81 return QStringLiteral("MainView");
80 82 }
83
84 void VisualizationWidget::displayVariable(std::shared_ptr<Variable> variable) noexcept
85 {
86 if (auto currentTab = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->currentWidget())) {
87 if (auto newZone = currentTab->createZone()) {
88 if (auto newGraph = newZone->createGraph()) {
89 newGraph->addVariable(variable);
90 }
91 else {
92 qCDebug(LOG_VisualizationWidget())
93 << tr("Can't display the variable : can't create the graph");
94 }
95 }
96 else {
97 qCDebug(LOG_VisualizationWidget())
98 << tr("Can't display the variable : can't create a new zone in the current tab");
99 }
100 }
101 else {
102 qCDebug(LOG_VisualizationWidget())
103 << tr("Can't display the variable : there is no current tab");
104 }
105 }
@@ -1,30 +1,30
1 1 #include "CosinusProvider.h"
2 2
3 3 #include <Data/DataProviderParameters.h>
4 4 #include <Data/ScalarSeries.h>
5 5
6 6 #include <cmath>
7 7
8 8 std::unique_ptr<IDataSeries>
9 9 CosinusProvider::retrieveData(const DataProviderParameters &parameters) const
10 10 {
11 11 // Gets the timerange from the parameters
12 12 auto start = parameters.m_TStart;
13 13 auto end = parameters.m_TEnd;
14 14
15 15 // We assure that timerange is valid
16 16 if (end < start) {
17 17 std::swap(start, end);
18 18 }
19 19
20 20 // Generates scalar series containing cosinus values (one value per second)
21 21 auto scalarSeries
22 = std::make_unique<ScalarSeries>(end - start, QStringLiteral("t"), QStringLiteral(""));
22 = std::make_unique<ScalarSeries>(end - start, Unit{QStringLiteral("t"), true}, Unit{});
23 23
24 24 auto dataIndex = 0;
25 25 for (auto time = start; time < end; ++time, ++dataIndex) {
26 26 scalarSeries->setData(dataIndex, time, std::cos(time));
27 27 }
28 28
29 29 return scalarSeries;
30 30 }
General Comments 0
You need to be logged in to leave comments. Login now