@@ -0,0 +1,32 | |||||
|
1 | #ifndef SCIQLOP_GRAPHPLOTTABLESFACTORY_H | |||
|
2 | #define SCIQLOP_GRAPHPLOTTABLESFACTORY_H | |||
|
3 | ||||
|
4 | #include <QLoggingCategory> | |||
|
5 | #include <QVector> | |||
|
6 | ||||
|
7 | #include <memory> | |||
|
8 | ||||
|
9 | Q_DECLARE_LOGGING_CATEGORY(LOG_GraphPlottablesFactory) | |||
|
10 | ||||
|
11 | class QCPAbstractPlottable; | |||
|
12 | class QCustomPlot; | |||
|
13 | class Variable; | |||
|
14 | ||||
|
15 | /** | |||
|
16 | * @brief The GraphPlottablesFactory class aims to create the QCustomPlot components relative to a | |||
|
17 | * variable, depending on the data series of this variable | |||
|
18 | */ | |||
|
19 | struct GraphPlottablesFactory { | |||
|
20 | /** | |||
|
21 | * Creates (if possible) the QCustomPlot components relative to the variable passed in | |||
|
22 | * parameter, and adds these to the plot passed in parameter. | |||
|
23 | * @param variable the variable for which to create the components | |||
|
24 | * @param plot the plot in which to add the created components. It takes ownership of these | |||
|
25 | * components. | |||
|
26 | * @return the list of the components created | |||
|
27 | */ | |||
|
28 | static QVector<QCPAbstractPlottable *> create(std::shared_ptr<Variable> variable, | |||
|
29 | QCustomPlot &plot) noexcept; | |||
|
30 | }; | |||
|
31 | ||||
|
32 | #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(std::shared_ptr<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 | } |
@@ -27,6 +27,8 | |||||
27 | #include <SidePane/SqpSidePane.h> |
|
27 | #include <SidePane/SqpSidePane.h> | |
28 | #include <SqpApplication.h> |
|
28 | #include <SqpApplication.h> | |
29 | #include <TimeWidget/TimeWidget.h> |
|
29 | #include <TimeWidget/TimeWidget.h> | |
|
30 | #include <Variable/Variable.h> | |||
|
31 | #include <Visualization/VisualizationController.h> | |||
30 |
|
32 | |||
31 | #include <QAction> |
|
33 | #include <QAction> | |
32 | #include <QDate> |
|
34 | #include <QDate> | |
@@ -172,6 +174,10 MainWindow::MainWindow(QWidget *parent) | |||||
172 | connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem *)), |
|
174 | connect(&sqpApp->dataSourceController(), SIGNAL(dataSourceItemSet(DataSourceItem *)), | |
173 | m_Ui->dataSourceWidget, SLOT(addDataSource(DataSourceItem *))); |
|
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 | /* QLopGUI::registerMenuBar(menuBar()); |
|
181 | /* QLopGUI::registerMenuBar(menuBar()); | |
176 | this->setWindowIcon(QIcon(":/sciqlopLOGO.svg")); |
|
182 | this->setWindowIcon(QIcon(":/sciqlopLOGO.svg")); | |
177 | this->m_progressWidget = new QWidget(); |
|
183 | this->m_progressWidget = new QWidget(); |
@@ -21,18 +21,18 public: | |||||
21 | std::shared_ptr<ArrayData<1> > xAxisData() override { return m_XAxisData; } |
|
21 | std::shared_ptr<ArrayData<1> > xAxisData() override { return m_XAxisData; } | |
22 |
|
22 | |||
23 | /// @sa IDataSeries::xAxisUnit() |
|
23 | /// @sa IDataSeries::xAxisUnit() | |
24 |
|
|
24 | Unit xAxisUnit() const override { return m_XAxisUnit; } | |
25 |
|
25 | |||
26 | /// @return the values dataset |
|
26 | /// @return the values dataset | |
27 | std::shared_ptr<ArrayData<Dim> > valuesData() const { return m_ValuesData; } |
|
27 | std::shared_ptr<ArrayData<Dim> > valuesData() const { return m_ValuesData; } | |
28 |
|
28 | |||
29 | /// @sa IDataSeries::valuesUnit() |
|
29 | /// @sa IDataSeries::valuesUnit() | |
30 |
|
|
30 | Unit valuesUnit() const override { return m_ValuesUnit; } | |
31 |
|
31 | |||
32 | protected: |
|
32 | protected: | |
33 | /// Protected ctor (DataSeries is abstract) |
|
33 | /// Protected ctor (DataSeries is abstract) | |
34 |
explicit DataSeries(std::shared_ptr<ArrayData<1> > xAxisData, const |
|
34 | explicit DataSeries(std::shared_ptr<ArrayData<1> > xAxisData, const Unit &xAxisUnit, | |
35 |
std::shared_ptr<ArrayData<Dim> > valuesData, const |
|
35 | std::shared_ptr<ArrayData<Dim> > valuesData, const Unit &valuesUnit) | |
36 | : m_XAxisData{xAxisData}, |
|
36 | : m_XAxisData{xAxisData}, | |
37 | m_XAxisUnit{xAxisUnit}, |
|
37 | m_XAxisUnit{xAxisUnit}, | |
38 | m_ValuesData{valuesData}, |
|
38 | m_ValuesData{valuesData}, | |
@@ -42,9 +42,9 protected: | |||||
42 |
|
42 | |||
43 | private: |
|
43 | private: | |
44 | std::shared_ptr<ArrayData<1> > m_XAxisData; |
|
44 | std::shared_ptr<ArrayData<1> > m_XAxisData; | |
45 |
|
|
45 | Unit m_XAxisUnit; | |
46 | std::shared_ptr<ArrayData<Dim> > m_ValuesData; |
|
46 | std::shared_ptr<ArrayData<Dim> > m_ValuesData; | |
47 |
|
|
47 | Unit m_ValuesUnit; | |
48 | }; |
|
48 | }; | |
49 |
|
49 | |||
50 | #endif // SCIQLOP_DATASERIES_H |
|
50 | #endif // SCIQLOP_DATASERIES_H |
@@ -8,6 +8,16 | |||||
8 | template <int Dim> |
|
8 | template <int Dim> | |
9 | class ArrayData; |
|
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 | * @brief The IDataSeries aims to declare a data series. |
|
22 | * @brief The IDataSeries aims to declare a data series. | |
13 | * |
|
23 | * | |
@@ -29,9 +39,9 public: | |||||
29 | /// Returns the x-axis dataset |
|
39 | /// Returns the x-axis dataset | |
30 | virtual std::shared_ptr<ArrayData<1> > xAxisData() = 0; |
|
40 | virtual std::shared_ptr<ArrayData<1> > xAxisData() = 0; | |
31 |
|
41 | |||
32 |
virtual |
|
42 | virtual Unit xAxisUnit() const = 0; | |
33 |
|
43 | |||
34 |
virtual |
|
44 | virtual Unit valuesUnit() const = 0; | |
35 | }; |
|
45 | }; | |
36 |
|
46 | |||
37 | #endif // SCIQLOP_IDATASERIES_H |
|
47 | #endif // SCIQLOP_IDATASERIES_H |
@@ -14,7 +14,7 public: | |||||
14 | * @param xAxisUnit x-axis unit |
|
14 | * @param xAxisUnit x-axis unit | |
15 | * @param valuesUnit values unit |
|
15 | * @param valuesUnit values unit | |
16 | */ |
|
16 | */ | |
17 |
explicit ScalarSeries(int size, const |
|
17 | explicit ScalarSeries(int size, const Unit &xAxisUnit, const Unit &valuesUnit); | |
18 |
|
18 | |||
19 | /** |
|
19 | /** | |
20 | * Sets data for a specific index. The index has to be valid to be effective |
|
20 | * Sets data for a specific index. The index has to be valid to be effective |
@@ -21,6 +21,9 public: | |||||
21 |
|
21 | |||
22 | void addDataSeries(std::unique_ptr<IDataSeries> dataSeries) noexcept; |
|
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 | private: |
|
27 | private: | |
25 | class VariablePrivate; |
|
28 | class VariablePrivate; | |
26 | spimpl::unique_impl_ptr<VariablePrivate> impl; |
|
29 | spimpl::unique_impl_ptr<VariablePrivate> impl; |
@@ -25,10 +25,11 public: | |||||
25 | explicit VisualizationController(QObject *parent = 0); |
|
25 | explicit VisualizationController(QObject *parent = 0); | |
26 | virtual ~VisualizationController(); |
|
26 | virtual ~VisualizationController(); | |
27 |
|
27 | |||
28 | public slots: |
|
28 | signals: | |
29 |
/// S |
|
29 | /// Signal emitted when a variable has been created in SciQlop | |
30 |
void |
|
30 | void variableCreated(std::shared_ptr<Variable> variable); | |
31 |
|
31 | |||
|
32 | public slots: | |||
32 | /// Manage init/end of the controller |
|
33 | /// Manage init/end of the controller | |
33 | void initialize(); |
|
34 | void initialize(); | |
34 | void finalize(); |
|
35 | void finalize(); |
@@ -1,6 +1,6 | |||||
1 | #include <Data/ScalarSeries.h> |
|
1 | #include <Data/ScalarSeries.h> | |
2 |
|
2 | |||
3 |
ScalarSeries::ScalarSeries(int size, const |
|
3 | ScalarSeries::ScalarSeries(int size, const Unit &xAxisUnit, const Unit &valuesUnit) | |
4 | : DataSeries{std::make_shared<ArrayData<1> >(size), xAxisUnit, |
|
4 | : DataSeries{std::make_shared<ArrayData<1> >(size), xAxisUnit, | |
5 | std::make_shared<ArrayData<1> >(size), valuesUnit} |
|
5 | std::make_shared<ArrayData<1> >(size), valuesUnit} | |
6 | { |
|
6 | { |
@@ -41,3 +41,8 void Variable::addDataSeries(std::unique_ptr<IDataSeries> dataSeries) noexcept | |||||
41 | } |
|
41 | } | |
42 | /// @todo : else, merge the two data series (if possible) |
|
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 | } |
@@ -29,12 +29,6 VisualizationController::~VisualizationController() | |||||
29 | this->waitForFinish(); |
|
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 | void VisualizationController::initialize() |
|
32 | void VisualizationController::initialize() | |
39 | { |
|
33 | { | |
40 | qCDebug(LOG_VisualizationController()) << tr("VisualizationController init") |
|
34 | qCDebug(LOG_VisualizationController()) << tr("VisualizationController init") |
@@ -34,6 +34,10 private: | |||||
34 |
|
34 | |||
35 | class VisualizationGraphWidgetPrivate; |
|
35 | class VisualizationGraphWidgetPrivate; | |
36 | spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl; |
|
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 | #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H |
|
43 | #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H |
@@ -6,6 +6,7 | |||||
6 | #include <QLoggingCategory> |
|
6 | #include <QLoggingCategory> | |
7 | #include <QWidget> |
|
7 | #include <QWidget> | |
8 |
|
8 | |||
|
9 | class Variable; | |||
9 | class VisualizationTabWidget; |
|
10 | class VisualizationTabWidget; | |
10 |
|
11 | |||
11 | Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget) |
|
12 | Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationWidget) | |
@@ -35,6 +36,15 public: | |||||
35 | void close() override; |
|
36 | void close() override; | |
36 | QString name() const; |
|
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 | private: |
|
48 | private: | |
39 | Ui::VisualizationWidget *ui; |
|
49 | Ui::VisualizationWidget *ui; | |
40 | }; |
|
50 | }; |
@@ -31,7 +31,7 public: | |||||
31 | qRegisterMetaType<std::shared_ptr<Variable> >(); |
|
31 | qRegisterMetaType<std::shared_ptr<Variable> >(); | |
32 | connect(m_VariableController.get(), SIGNAL(variableCreated(std::shared_ptr<Variable>)), |
|
32 | connect(m_VariableController.get(), SIGNAL(variableCreated(std::shared_ptr<Variable>)), | |
33 | m_VisualizationController.get(), |
|
33 | m_VisualizationController.get(), | |
34 |
SL |
|
34 | SIGNAL(variableCreated(std::shared_ptr<Variable>))); | |
35 |
|
35 | |||
36 | m_DataSourceController->moveToThread(&m_DataSourceControllerThread); |
|
36 | m_DataSourceController->moveToThread(&m_DataSourceControllerThread); | |
37 | m_VariableController->moveToThread(&m_VariableControllerThread); |
|
37 | m_VariableController->moveToThread(&m_VariableControllerThread); |
@@ -1,15 +1,25 | |||||
1 | #include "Visualization/VisualizationGraphWidget.h" |
|
1 | #include "Visualization/VisualizationGraphWidget.h" | |
|
2 | #include "Visualization/GraphPlottablesFactory.h" | |||
2 | #include "ui_VisualizationGraphWidget.h" |
|
3 | #include "ui_VisualizationGraphWidget.h" | |
3 |
|
4 | |||
4 | #include <Variable/Variable.h> |
|
5 | #include <Variable/Variable.h> | |
5 |
|
6 | |||
6 | #include <unordered_map> |
|
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 | struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate { |
|
19 | struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate { | |
9 |
|
20 | |||
10 | // 1 variable -> n qcpplot |
|
21 | // 1 variable -> n qcpplot | |
11 |
std::unordered_map<std::shared_ptr<Variable>, |
|
22 | std::unordered_map<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMap; | |
12 | m_VariableToPlotMap; |
|
|||
13 | }; |
|
23 | }; | |
14 |
|
24 | |||
15 | VisualizationGraphWidget::VisualizationGraphWidget(QWidget *parent) |
|
25 | VisualizationGraphWidget::VisualizationGraphWidget(QWidget *parent) | |
@@ -18,6 +28,13 VisualizationGraphWidget::VisualizationGraphWidget(QWidget *parent) | |||||
18 | impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>()} |
|
28 | impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>()} | |
19 | { |
|
29 | { | |
20 | ui->setupUi(this); |
|
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 | VisualizationGraphWidget::~VisualizationGraphWidget() |
|
40 | VisualizationGraphWidget::~VisualizationGraphWidget() | |
@@ -27,7 +44,12 VisualizationGraphWidget::~VisualizationGraphWidget() | |||||
27 |
|
44 | |||
28 | void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable) |
|
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, *ui->widget); | |||
|
49 | ||||
|
50 | for (auto createdPlottable : qAsConst(createdPlottables)) { | |||
|
51 | impl->m_VariableToPlotMap.insert({variable, createdPlottable}); | |||
|
52 | } | |||
31 | } |
|
53 | } | |
32 |
|
54 | |||
33 | void VisualizationGraphWidget::accept(IVisualizationWidget *visitor) |
|
55 | void VisualizationGraphWidget::accept(IVisualizationWidget *visitor) | |
@@ -45,3 +67,20 QString VisualizationGraphWidget::name() const | |||||
45 | { |
|
67 | { | |
46 | return QStringLiteral("MainView"); |
|
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,5 +1,7 | |||||
1 | #include "Visualization/VisualizationWidget.h" |
|
1 | #include "Visualization/VisualizationWidget.h" | |
|
2 | #include "Visualization/VisualizationGraphWidget.h" | |||
2 | #include "Visualization/VisualizationTabWidget.h" |
|
3 | #include "Visualization/VisualizationTabWidget.h" | |
|
4 | #include "Visualization/VisualizationZoneWidget.h" | |||
3 | #include "Visualization/qcustomplot.h" |
|
5 | #include "Visualization/qcustomplot.h" | |
4 |
|
6 | |||
5 | #include "ui_VisualizationWidget.h" |
|
7 | #include "ui_VisualizationWidget.h" | |
@@ -16,24 +18,36 VisualizationWidget::VisualizationWidget(QWidget *parent) | |||||
16 | auto addTabViewButton = new QToolButton{ui->tabWidget}; |
|
18 | auto addTabViewButton = new QToolButton{ui->tabWidget}; | |
17 | addTabViewButton->setText(tr("Add View")); |
|
19 | addTabViewButton->setText(tr("Add View")); | |
18 | addTabViewButton->setCursor(Qt::ArrowCursor); |
|
20 | addTabViewButton->setCursor(Qt::ArrowCursor); | |
19 | addTabViewButton->setAutoRaise(true); |
|
|||
20 | ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner); |
|
21 | ui->tabWidget->setCornerWidget(addTabViewButton, Qt::TopRightCorner); | |
21 | auto width = ui->tabWidget->cornerWidget()->width(); |
|
22 | ||
22 | auto height = ui->tabWidget->cornerWidget()->height(); |
|
23 | auto enableMinimumCornerWidgetSize = [this](bool enable) { | |
23 | addTabViewButton->setMinimumHeight(height); |
|
24 | ||
24 | addTabViewButton->setMinimumWidth(width); |
|
25 | auto tabViewCornerWidget = ui->tabWidget->cornerWidget(); | |
25 | ui->tabWidget->setMinimumHeight(height); |
|
26 | auto width = enable ? tabViewCornerWidget->width() : 0; | |
26 | ui->tabWidget->setMinimumWidth(width); |
|
27 | auto height = enable ? tabViewCornerWidget->height() : 0; | |
27 |
|
28 | tabViewCornerWidget->setMinimumHeight(height); | ||
28 | auto addTabView = [&]() { |
|
29 | tabViewCornerWidget->setMinimumWidth(width); | |
|
30 | ui->tabWidget->setMinimumHeight(height); | |||
|
31 | ui->tabWidget->setMinimumWidth(width); | |||
|
32 | }; | |||
|
33 | ||||
|
34 | auto addTabView = [this, enableMinimumCornerWidgetSize]() { | |||
29 | auto index = ui->tabWidget->addTab(new VisualizationTabWidget(ui->tabWidget), |
|
35 | auto index = ui->tabWidget->addTab(new VisualizationTabWidget(ui->tabWidget), | |
30 | QString("View %1").arg(ui->tabWidget->count() + 1)); |
|
36 | QString("View %1").arg(ui->tabWidget->count() + 1)); | |
|
37 | if (ui->tabWidget->count() > 0) { | |||
|
38 | enableMinimumCornerWidgetSize(false); | |||
|
39 | } | |||
31 | qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index); |
|
40 | qCInfo(LOG_VisualizationWidget()) << tr("add the tab of index %1").arg(index); | |
32 | }; |
|
41 | }; | |
33 |
|
42 | |||
34 |
auto removeTabView = [ |
|
43 | auto removeTabView = [this, enableMinimumCornerWidgetSize](int index) { | |
|
44 | if (ui->tabWidget->count() == 1) { | |||
|
45 | enableMinimumCornerWidgetSize(true); | |||
|
46 | } | |||
|
47 | ||||
35 | ui->tabWidget->removeTab(index); |
|
48 | ui->tabWidget->removeTab(index); | |
36 | qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index); |
|
49 | qCInfo(LOG_VisualizationWidget()) << tr("remove the tab of index %1").arg(index); | |
|
50 | ||||
37 | }; |
|
51 | }; | |
38 |
|
52 | |||
39 | ui->tabWidget->setTabsClosable(true); |
|
53 | ui->tabWidget->setTabsClosable(true); | |
@@ -78,3 +92,26 QString VisualizationWidget::name() const | |||||
78 | { |
|
92 | { | |
79 | return QStringLiteral("MainView"); |
|
93 | return QStringLiteral("MainView"); | |
80 | } |
|
94 | } | |
|
95 | ||||
|
96 | void VisualizationWidget::displayVariable(std::shared_ptr<Variable> variable) noexcept | |||
|
97 | { | |||
|
98 | if (auto currentTab = dynamic_cast<VisualizationTabWidget *>(ui->tabWidget->currentWidget())) { | |||
|
99 | if (auto newZone = currentTab->createZone()) { | |||
|
100 | if (auto newGraph = newZone->createGraph()) { | |||
|
101 | newGraph->addVariable(variable); | |||
|
102 | } | |||
|
103 | else { | |||
|
104 | qCCritical(LOG_VisualizationWidget()) | |||
|
105 | << tr("Can't display the variable : can't create the graph"); | |||
|
106 | } | |||
|
107 | } | |||
|
108 | else { | |||
|
109 | qCCritical(LOG_VisualizationWidget()) | |||
|
110 | << tr("Can't display the variable : can't create a new zone in the current tab"); | |||
|
111 | } | |||
|
112 | } | |||
|
113 | else { | |||
|
114 | qCCritical(LOG_VisualizationWidget()) | |||
|
115 | << tr("Can't display the variable : there is no current tab"); | |||
|
116 | } | |||
|
117 | } |
@@ -14,14 +14,32 | |||||
14 | <string>Form</string> |
|
14 | <string>Form</string> | |
15 | </property> |
|
15 | </property> | |
16 | <layout class="QVBoxLayout" name="verticalLayout_2"> |
|
16 | <layout class="QVBoxLayout" name="verticalLayout_2"> | |
|
17 | <property name="spacing"> | |||
|
18 | <number>3</number> | |||
|
19 | </property> | |||
|
20 | <property name="leftMargin"> | |||
|
21 | <number>0</number> | |||
|
22 | </property> | |||
|
23 | <property name="topMargin"> | |||
|
24 | <number>0</number> | |||
|
25 | </property> | |||
|
26 | <property name="rightMargin"> | |||
|
27 | <number>0</number> | |||
|
28 | </property> | |||
|
29 | <property name="bottomMargin"> | |||
|
30 | <number>0</number> | |||
|
31 | </property> | |||
17 | <item> |
|
32 | <item> | |
18 | <widget class="QFrame" name="visualizationZoneFrame"> |
|
33 | <widget class="QFrame" name="visualizationZoneFrame"> | |
19 | <property name="frameShape"> |
|
34 | <property name="frameShape"> | |
20 |
<enum>QFrame:: |
|
35 | <enum>QFrame::Box</enum> | |
21 | </property> |
|
36 | </property> | |
22 | <property name="frameShadow"> |
|
37 | <property name="frameShadow"> | |
23 | <enum>QFrame::Raised</enum> |
|
38 | <enum>QFrame::Raised</enum> | |
24 | </property> |
|
39 | </property> | |
|
40 | <property name="lineWidth"> | |||
|
41 | <number>1</number> | |||
|
42 | </property> | |||
25 | <layout class="QVBoxLayout" name="verticalLayout"/> |
|
43 | <layout class="QVBoxLayout" name="verticalLayout"/> | |
26 | </widget> |
|
44 | </widget> | |
27 | </item> |
|
45 | </item> |
@@ -19,7 +19,7 CosinusProvider::retrieveData(const DataProviderParameters ¶meters) const | |||||
19 |
|
19 | |||
20 | // Generates scalar series containing cosinus values (one value per second) |
|
20 | // Generates scalar series containing cosinus values (one value per second) | |
21 | auto scalarSeries |
|
21 | auto scalarSeries | |
22 |
= std::make_unique<ScalarSeries>(end - start, QStringLiteral("t"), |
|
22 | = std::make_unique<ScalarSeries>(end - start, Unit{QStringLiteral("t"), true}, Unit{}); | |
23 |
|
23 | |||
24 | auto dataIndex = 0; |
|
24 | auto dataIndex = 0; | |
25 | for (auto time = start; time < end; ++time, ++dataIndex) { |
|
25 | for (auto time = start; time < end; ++time, ++dataIndex) { |
General Comments 0
You need to be logged in to leave comments.
Login now