##// END OF EJS Templates
Remove variable from graph (1)...
Alexandre Leroux -
r269:848d92f3fb8a
parent child
Show More
@@ -1,55 +1,57
1 #ifndef SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
1 #ifndef SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
2 #define SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
2 #define SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
3
3
4 #include "Visualization/IVisualizationWidget.h"
4 #include "Visualization/IVisualizationWidget.h"
5
5
6 #include <QLoggingCategory>
6 #include <QLoggingCategory>
7 #include <QWidget>
7 #include <QWidget>
8
8
9 #include <memory>
9 #include <memory>
10
10
11 #include <Common/spimpl.h>
11 #include <Common/spimpl.h>
12
12
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphWidget)
13 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationGraphWidget)
14
14
15 class QCPRange;
15 class QCPRange;
16 class Variable;
16 class Variable;
17
17
18 namespace Ui {
18 namespace Ui {
19 class VisualizationGraphWidget;
19 class VisualizationGraphWidget;
20 } // namespace Ui
20 } // namespace Ui
21
21
22 class VisualizationGraphWidget : public QWidget, public IVisualizationWidget {
22 class VisualizationGraphWidget : public QWidget, public IVisualizationWidget {
23 Q_OBJECT
23 Q_OBJECT
24
24
25 public:
25 public:
26 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
26 explicit VisualizationGraphWidget(const QString &name = {}, QWidget *parent = 0);
27 virtual ~VisualizationGraphWidget();
27 virtual ~VisualizationGraphWidget();
28
28
29 void addVariable(std::shared_ptr<Variable> variable);
29 void addVariable(std::shared_ptr<Variable> variable);
30
30
31 // IVisualizationWidget interface
31 // IVisualizationWidget interface
32 void accept(IVisualizationWidgetVisitor *visitor) override;
32 void accept(IVisualizationWidgetVisitor *visitor) override;
33 bool canDrop(const Variable &variable) const override;
33 bool canDrop(const Variable &variable) const override;
34 QString name() const override;
34 QString name() const override;
35
35
36 void updateDisplay(std::shared_ptr<Variable> variable);
36 void updateDisplay(std::shared_ptr<Variable> variable);
37
37
38
38
39 private:
39 private:
40 Ui::VisualizationGraphWidget *ui;
40 Ui::VisualizationGraphWidget *ui;
41
41
42 class VisualizationGraphWidgetPrivate;
42 class VisualizationGraphWidgetPrivate;
43 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
43 spimpl::unique_impl_ptr<VisualizationGraphWidgetPrivate> impl;
44
44
45 private slots:
45 private slots:
46 /// Slot called when right clicking on the graph (displays a menu)
47 void onGraphMenuRequested(const QPoint &pos) noexcept;
46
48
47 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
49 void onRangeChanged(const QCPRange &t1, const QCPRange &t2);
48
50
49 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
51 /// Slot called when a mouse wheel was made, to perform some processing before the zoom is done
50 void onMouseWheel(QWheelEvent *event) noexcept;
52 void onMouseWheel(QWheelEvent *event) noexcept;
51
53
52 void onDataCacheVariableUpdated();
54 void onDataCacheVariableUpdated();
53 };
55 };
54
56
55 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
57 #endif // SCIQLOP_VISUALIZATIONGRAPHWIDGET_H
@@ -1,200 +1,215
1 #include "Visualization/VisualizationGraphWidget.h"
1 #include "Visualization/VisualizationGraphWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/VisualizationGraphHelper.h"
3 #include "Visualization/VisualizationGraphHelper.h"
4 #include "ui_VisualizationGraphWidget.h"
4 #include "ui_VisualizationGraphWidget.h"
5
5
6 #include <Data/ArrayData.h>
6 #include <Data/ArrayData.h>
7 #include <Data/IDataSeries.h>
7 #include <Data/IDataSeries.h>
8 #include <SqpApplication.h>
8 #include <SqpApplication.h>
9 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
10 #include <Variable/VariableController.h>
10 #include <Variable/VariableController.h>
11
11
12 #include <unordered_map>
12 #include <unordered_map>
13
13
14 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
14 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
15
15
16 namespace {
16 namespace {
17
17
18 /// Key pressed to enable zoom on horizontal axis
18 /// Key pressed to enable zoom on horizontal axis
19 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
19 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
20
20
21 /// Key pressed to enable zoom on vertical axis
21 /// Key pressed to enable zoom on vertical axis
22 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
22 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
23
23
24 } // namespace
24 } // namespace
25
25
26 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
26 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
27
27
28 // 1 variable -> n qcpplot
28 // 1 variable -> n qcpplot
29 std::unordered_multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *>
29 std::unordered_multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *>
30 m_VariableToPlotMultiMap;
30 m_VariableToPlotMultiMap;
31 };
31 };
32
32
33 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
33 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
34 : QWidget{parent},
34 : QWidget{parent},
35 ui{new Ui::VisualizationGraphWidget},
35 ui{new Ui::VisualizationGraphWidget},
36 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>()}
36 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>()}
37 {
37 {
38 ui->setupUi(this);
38 ui->setupUi(this);
39
39
40 ui->graphNameLabel->setText(name);
40 ui->graphNameLabel->setText(name);
41
41
42 // 'Close' options : widget is deleted when closed
42 // 'Close' options : widget is deleted when closed
43 setAttribute(Qt::WA_DeleteOnClose);
43 setAttribute(Qt::WA_DeleteOnClose);
44 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationGraphWidget::close);
44 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationGraphWidget::close);
45 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
45 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
46
46
47 // Set qcpplot properties :
47 // Set qcpplot properties :
48 // - Drag (on x-axis) and zoom are enabled
48 // - Drag (on x-axis) and zoom are enabled
49 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
49 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
50 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
50 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
51 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
51 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
52 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
52 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
53 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
53 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
54 &QCPAxis::rangeChanged),
54 &QCPAxis::rangeChanged),
55 this, &VisualizationGraphWidget::onRangeChanged);
55 this, &VisualizationGraphWidget::onRangeChanged);
56
57 // Activates menu when right clicking on the graph
58 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
59 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
60 &VisualizationGraphWidget::onGraphMenuRequested);
56 }
61 }
57
62
58
63
59 VisualizationGraphWidget::~VisualizationGraphWidget()
64 VisualizationGraphWidget::~VisualizationGraphWidget()
60 {
65 {
61 delete ui;
66 delete ui;
62 }
67 }
63
68
64 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable)
69 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable)
65 {
70 {
66 // Uses delegate to create the qcpplot components according to the variable
71 // Uses delegate to create the qcpplot components according to the variable
67 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
72 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
68
73
69 for (auto createdPlottable : qAsConst(createdPlottables)) {
74 for (auto createdPlottable : qAsConst(createdPlottables)) {
70 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
75 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
71 }
76 }
72
77
73 connect(variable.get(), SIGNAL(dataCacheUpdated()), this, SLOT(onDataCacheVariableUpdated()));
78 connect(variable.get(), SIGNAL(dataCacheUpdated()), this, SLOT(onDataCacheVariableUpdated()));
74 }
79 }
75
80
76 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
81 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
77 {
82 {
78 if (visitor) {
83 if (visitor) {
79 visitor->visit(this);
84 visitor->visit(this);
80 }
85 }
81 else {
86 else {
82 qCCritical(LOG_VisualizationGraphWidget())
87 qCCritical(LOG_VisualizationGraphWidget())
83 << tr("Can't visit widget : the visitor is null");
88 << tr("Can't visit widget : the visitor is null");
84 }
89 }
85 }
90 }
86
91
87 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
92 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
88 {
93 {
89 /// @todo : for the moment, a graph can always accomodate a variable
94 /// @todo : for the moment, a graph can always accomodate a variable
90 Q_UNUSED(variable);
95 Q_UNUSED(variable);
91 return true;
96 return true;
92 }
97 }
93
98
94 QString VisualizationGraphWidget::name() const
99 QString VisualizationGraphWidget::name() const
95 {
100 {
96 return ui->graphNameLabel->text();
101 return ui->graphNameLabel->text();
97 }
102 }
98
103
104 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
105 {
106 QMenu graphMenu{};
107
108
109 if (!graphMenu.isEmpty()) {
110 graphMenu.exec(mapToGlobal(pos));
111 }
112 }
113
99 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
114 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
100 {
115 {
101
116
102 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::onRangeChanged");
117 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::onRangeChanged");
103
118
104 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
119 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
105 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
120 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
106
121
107 auto variable = it->first;
122 auto variable = it->first;
108 qCInfo(LOG_VisualizationGraphWidget())
123 qCInfo(LOG_VisualizationGraphWidget())
109 << tr("TORM: VisualizationGraphWidget::onRangeChanged")
124 << tr("TORM: VisualizationGraphWidget::onRangeChanged")
110 << variable->dataSeries()->xAxisData()->size();
125 << variable->dataSeries()->xAxisData()->size();
111 auto dateTime = SqpDateTime{t2.lower, t2.upper};
126 auto dateTime = SqpDateTime{t2.lower, t2.upper};
112
127
113 if (!variable->contains(dateTime)) {
128 if (!variable->contains(dateTime)) {
114
129
115 auto variableDateTimeWithTolerance = dateTime;
130 auto variableDateTimeWithTolerance = dateTime;
116 if (variable->intersect(dateTime)) {
131 if (variable->intersect(dateTime)) {
117 auto variableDateTime = variable->dateTime();
132 auto variableDateTime = variable->dateTime();
118 if (variableDateTime.m_TStart < dateTime.m_TStart) {
133 if (variableDateTime.m_TStart < dateTime.m_TStart) {
119
134
120 auto diffEndToKeepDelta = dateTime.m_TEnd - variableDateTime.m_TEnd;
135 auto diffEndToKeepDelta = dateTime.m_TEnd - variableDateTime.m_TEnd;
121 dateTime.m_TStart = variableDateTime.m_TStart + diffEndToKeepDelta;
136 dateTime.m_TStart = variableDateTime.m_TStart + diffEndToKeepDelta;
122 // Tolerance have to be added to the right
137 // Tolerance have to be added to the right
123 // add 10% tolerance for right (end) side
138 // add 10% tolerance for right (end) side
124 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
139 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
125 variableDateTimeWithTolerance.m_TEnd += tolerance;
140 variableDateTimeWithTolerance.m_TEnd += tolerance;
126 }
141 }
127 if (variableDateTime.m_TEnd > dateTime.m_TEnd) {
142 if (variableDateTime.m_TEnd > dateTime.m_TEnd) {
128 auto diffStartToKeepDelta = dateTime.m_TStart - dateTime.m_TStart;
143 auto diffStartToKeepDelta = dateTime.m_TStart - dateTime.m_TStart;
129 dateTime.m_TEnd = variableDateTime.m_TEnd - diffStartToKeepDelta;
144 dateTime.m_TEnd = variableDateTime.m_TEnd - diffStartToKeepDelta;
130 // Tolerance have to be added to the left
145 // Tolerance have to be added to the left
131 // add 10% tolerance for left (start) side
146 // add 10% tolerance for left (start) side
132 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
147 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
133 variableDateTimeWithTolerance.m_TStart -= tolerance;
148 variableDateTimeWithTolerance.m_TStart -= tolerance;
134 }
149 }
135 }
150 }
136 else {
151 else {
137 // add 10% tolerance for each side
152 // add 10% tolerance for each side
138 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
153 auto tolerance = 0.1 * (dateTime.m_TEnd - dateTime.m_TStart);
139 variableDateTimeWithTolerance.m_TStart -= tolerance;
154 variableDateTimeWithTolerance.m_TStart -= tolerance;
140 variableDateTimeWithTolerance.m_TEnd += tolerance;
155 variableDateTimeWithTolerance.m_TEnd += tolerance;
141 }
156 }
142 variable->setDateTime(dateTime);
157 variable->setDateTime(dateTime);
143
158
144 // CHangement detected, we need to ask controller to request data loading
159 // CHangement detected, we need to ask controller to request data loading
145 sqpApp->variableController().requestDataLoading(variable,
160 sqpApp->variableController().requestDataLoading(variable,
146 variableDateTimeWithTolerance);
161 variableDateTimeWithTolerance);
147 }
162 }
148 }
163 }
149 }
164 }
150
165
151 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
166 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
152 {
167 {
153 auto zoomOrientations = QFlags<Qt::Orientation>{};
168 auto zoomOrientations = QFlags<Qt::Orientation>{};
154
169
155 // Lambda that enables a zoom orientation if the key modifier related to this orientation
170 // Lambda that enables a zoom orientation if the key modifier related to this orientation
156 // has
171 // has
157 // been pressed
172 // been pressed
158 auto enableOrientation
173 auto enableOrientation
159 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
174 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
160 auto orientationEnabled = event->modifiers().testFlag(modifier);
175 auto orientationEnabled = event->modifiers().testFlag(modifier);
161 zoomOrientations.setFlag(orientation, orientationEnabled);
176 zoomOrientations.setFlag(orientation, orientationEnabled);
162 };
177 };
163 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
178 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
164 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
179 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
165
180
166 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
181 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
167 }
182 }
168
183
169 void VisualizationGraphWidget::onDataCacheVariableUpdated()
184 void VisualizationGraphWidget::onDataCacheVariableUpdated()
170 {
185 {
171 // NOTE:
186 // NOTE:
172 // We don't want to call the method for each component of a variable unitarily, but for
187 // We don't want to call the method for each component of a variable unitarily, but for
173 // all
188 // all
174 // its components at once (eg its three components in the case of a vector).
189 // its components at once (eg its three components in the case of a vector).
175
190
176 // The unordered_multimap does not do this easily, so the question is whether to:
191 // The unordered_multimap does not do this easily, so the question is whether to:
177 // - use an ordered_multimap and the algos of std to group the values by key
192 // - use an ordered_multimap and the algos of std to group the values by key
178 // - use a map (unique keys) and store as values directly the list of components
193 // - use a map (unique keys) and store as values directly the list of components
179
194
180 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
195 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
181 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
196 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
182 auto variable = it->first;
197 auto variable = it->first;
183 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
198 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
184 variable->dataSeries(), variable->dateTime());
199 variable->dataSeries(), variable->dateTime());
185 }
200 }
186 }
201 }
187
202
188 void VisualizationGraphWidget::updateDisplay(std::shared_ptr<Variable> variable)
203 void VisualizationGraphWidget::updateDisplay(std::shared_ptr<Variable> variable)
189 {
204 {
190 auto abstractPlotableItPair = impl->m_VariableToPlotMultiMap.equal_range(variable);
205 auto abstractPlotableItPair = impl->m_VariableToPlotMultiMap.equal_range(variable);
191
206
192 auto abstractPlotableVect = QVector<QCPAbstractPlottable *>{};
207 auto abstractPlotableVect = QVector<QCPAbstractPlottable *>{};
193
208
194 for (auto it = abstractPlotableItPair.first; it != abstractPlotableItPair.second; ++it) {
209 for (auto it = abstractPlotableItPair.first; it != abstractPlotableItPair.second; ++it) {
195 abstractPlotableVect.push_back(it->second);
210 abstractPlotableVect.push_back(it->second);
196 }
211 }
197
212
198 VisualizationGraphHelper::updateData(abstractPlotableVect, variable->dataSeries(),
213 VisualizationGraphHelper::updateData(abstractPlotableVect, variable->dataSeries(),
199 variable->dateTime());
214 variable->dateTime());
200 }
215 }
General Comments 0
You need to be logged in to leave comments. Login now