##// END OF EJS Templates
Settings binding (5)...
Alexandre Leroux -
r470:5e3a35bfa2fe
parent child
Show More
@@ -1,401 +1,412
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 <Settings/SqpSettingsDefs.h>
8 #include <SqpApplication.h>
9 #include <SqpApplication.h>
9 #include <Variable/Variable.h>
10 #include <Variable/Variable.h>
10 #include <Variable/VariableController.h>
11 #include <Variable/VariableController.h>
11
12
12 #include <unordered_map>
13 #include <unordered_map>
13
14
14 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
15 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
15
16
16 namespace {
17 namespace {
17
18
18 /// Key pressed to enable zoom on horizontal axis
19 /// Key pressed to enable zoom on horizontal axis
19 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
20 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
20
21
21 /// Key pressed to enable zoom on vertical axis
22 /// Key pressed to enable zoom on vertical axis
22 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
23 const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
23
24
25 /// Gets a tolerance value from application settings. If the setting can't be found, the default
26 /// value passed in parameter is returned
27 double toleranceValue(const QString &key, double defaultValue) noexcept
28 {
29 return QSettings{}.value(key, defaultValue).toDouble();
30 }
31
24 } // namespace
32 } // namespace
25
33
26 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
34 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
27
35
28 explicit VisualizationGraphWidgetPrivate() : m_DoSynchronize{true}, m_IsCalibration{false} {}
36 explicit VisualizationGraphWidgetPrivate() : m_DoSynchronize{true}, m_IsCalibration{false} {}
29
37
30
38
31 // Return the operation when range changed
39 // Return the operation when range changed
32 VisualizationGraphWidgetZoomType getZoomType(const QCPRange &t1, const QCPRange &t2);
40 VisualizationGraphWidgetZoomType getZoomType(const QCPRange &t1, const QCPRange &t2);
33
41
34 // 1 variable -> n qcpplot
42 // 1 variable -> n qcpplot
35 std::multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMultiMap;
43 std::multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMultiMap;
36
44
37 bool m_DoSynchronize;
45 bool m_DoSynchronize;
38 bool m_IsCalibration;
46 bool m_IsCalibration;
39 };
47 };
40
48
41 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
49 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
42 : QWidget{parent},
50 : QWidget{parent},
43 ui{new Ui::VisualizationGraphWidget},
51 ui{new Ui::VisualizationGraphWidget},
44 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>()}
52 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>()}
45 {
53 {
46 ui->setupUi(this);
54 ui->setupUi(this);
47
55
48 ui->graphNameLabel->setText(name);
56 ui->graphNameLabel->setText(name);
49
57
50 // 'Close' options : widget is deleted when closed
58 // 'Close' options : widget is deleted when closed
51 setAttribute(Qt::WA_DeleteOnClose);
59 setAttribute(Qt::WA_DeleteOnClose);
52 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationGraphWidget::close);
60 connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationGraphWidget::close);
53 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
61 ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
54
62
55 // Set qcpplot properties :
63 // Set qcpplot properties :
56 // - Drag (on x-axis) and zoom are enabled
64 // - Drag (on x-axis) and zoom are enabled
57 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
65 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
58 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
66 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
59 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
67 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
60 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
68 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
61 connect(ui->widget, &QCustomPlot::mouseRelease, this,
69 connect(ui->widget, &QCustomPlot::mouseRelease, this,
62 &VisualizationGraphWidget::onMouseRelease);
70 &VisualizationGraphWidget::onMouseRelease);
63 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
71 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
64 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
72 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
65 &QCPAxis::rangeChanged),
73 &QCPAxis::rangeChanged),
66 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
74 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
67
75
68 // Activates menu when right clicking on the graph
76 // Activates menu when right clicking on the graph
69 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
77 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
70 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
78 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
71 &VisualizationGraphWidget::onGraphMenuRequested);
79 &VisualizationGraphWidget::onGraphMenuRequested);
72
80
73 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
81 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
74 &VariableController::onRequestDataLoading);
82 &VariableController::onRequestDataLoading);
75 }
83 }
76
84
77
85
78 VisualizationGraphWidget::~VisualizationGraphWidget()
86 VisualizationGraphWidget::~VisualizationGraphWidget()
79 {
87 {
80 delete ui;
88 delete ui;
81 }
89 }
82
90
83 void VisualizationGraphWidget::enableSynchronize(bool enable)
91 void VisualizationGraphWidget::enableSynchronize(bool enable)
84 {
92 {
85 impl->m_DoSynchronize = enable;
93 impl->m_DoSynchronize = enable;
86 }
94 }
87
95
88 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable)
96 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable)
89 {
97 {
90 // Uses delegate to create the qcpplot components according to the variable
98 // Uses delegate to create the qcpplot components according to the variable
91 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
99 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
92
100
93 for (auto createdPlottable : qAsConst(createdPlottables)) {
101 for (auto createdPlottable : qAsConst(createdPlottables)) {
94 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
102 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
95 }
103 }
96
104
97 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
105 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
98 }
106 }
99 void VisualizationGraphWidget::addVariableUsingGraph(std::shared_ptr<Variable> variable)
107 void VisualizationGraphWidget::addVariableUsingGraph(std::shared_ptr<Variable> variable)
100 {
108 {
101
109
102 // when adding a variable, we need to set its time range to the current graph range
110 // when adding a variable, we need to set its time range to the current graph range
103 auto grapheRange = ui->widget->xAxis->range();
111 auto grapheRange = ui->widget->xAxis->range();
104 auto dateTime = SqpDateTime{grapheRange.lower, grapheRange.upper};
112 auto dateTime = SqpDateTime{grapheRange.lower, grapheRange.upper};
105 variable->setDateTime(dateTime);
113 variable->setDateTime(dateTime);
106
114
107 auto variableDateTimeWithTolerance = dateTime;
115 auto variableDateTimeWithTolerance = dateTime;
108
116
109 // add 20% tolerance for each side
117 // add tolerance for each side
110 auto tolerance = 0.2 * (dateTime.m_TEnd - dateTime.m_TStart);
118 auto toleranceFactor
119 = toleranceValue(GENERAL_TOLERANCE_AT_INIT_KEY, GENERAL_TOLERANCE_AT_INIT_DEFAULT_VALUE);
120 auto tolerance = toleranceFactor * (dateTime.m_TEnd - dateTime.m_TStart);
111 variableDateTimeWithTolerance.m_TStart -= tolerance;
121 variableDateTimeWithTolerance.m_TStart -= tolerance;
112 variableDateTimeWithTolerance.m_TEnd += tolerance;
122 variableDateTimeWithTolerance.m_TEnd += tolerance;
113
123
114 // Uses delegate to create the qcpplot components according to the variable
124 // Uses delegate to create the qcpplot components according to the variable
115 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
125 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
116
126
117 for (auto createdPlottable : qAsConst(createdPlottables)) {
127 for (auto createdPlottable : qAsConst(createdPlottables)) {
118 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
128 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
119 }
129 }
120
130
121 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
131 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
122
132
123 // CHangement detected, we need to ask controller to request data loading
133 // CHangement detected, we need to ask controller to request data loading
124 emit requestDataLoading(variable, variableDateTimeWithTolerance);
134 emit requestDataLoading(variable, variableDateTimeWithTolerance);
125 }
135 }
126
136
127 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
137 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
128 {
138 {
129 // Each component associated to the variable :
139 // Each component associated to the variable :
130 // - is removed from qcpplot (which deletes it)
140 // - is removed from qcpplot (which deletes it)
131 // - is no longer referenced in the map
141 // - is no longer referenced in the map
132 auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
142 auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
133 for (auto it = componentsIt.first; it != componentsIt.second;) {
143 for (auto it = componentsIt.first; it != componentsIt.second;) {
134 ui->widget->removePlottable(it->second);
144 ui->widget->removePlottable(it->second);
135 it = impl->m_VariableToPlotMultiMap.erase(it);
145 it = impl->m_VariableToPlotMultiMap.erase(it);
136 }
146 }
137
147
138 // Updates graph
148 // Updates graph
139 ui->widget->replot();
149 ui->widget->replot();
140 }
150 }
141
151
142 void VisualizationGraphWidget::setRange(std::shared_ptr<Variable> variable,
152 void VisualizationGraphWidget::setRange(std::shared_ptr<Variable> variable,
143 const SqpDateTime &range)
153 const SqpDateTime &range)
144 {
154 {
145 // Note: in case of different axes that depends on variable, we could start with a code like
155 // Note: in case of different axes that depends on variable, we could start with a code like
146 // that:
156 // that:
147 // auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
157 // auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
148 // for (auto it = componentsIt.first; it != componentsIt.second;) {
158 // for (auto it = componentsIt.first; it != componentsIt.second;) {
149 // }
159 // }
150 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
160 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
151 ui->widget->replot();
161 ui->widget->replot();
152 }
162 }
153
163
154 SqpDateTime VisualizationGraphWidget::graphRange() const noexcept
164 SqpDateTime VisualizationGraphWidget::graphRange() const noexcept
155 {
165 {
156 auto grapheRange = ui->widget->xAxis->range();
166 auto grapheRange = ui->widget->xAxis->range();
157 return SqpDateTime{grapheRange.lower, grapheRange.upper};
167 return SqpDateTime{grapheRange.lower, grapheRange.upper};
158 }
168 }
159
169
160 void VisualizationGraphWidget::setGraphRange(const SqpDateTime &range)
170 void VisualizationGraphWidget::setGraphRange(const SqpDateTime &range)
161 {
171 {
162 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
172 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
163 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
173 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
164 ui->widget->replot();
174 ui->widget->replot();
165 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
175 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
166 }
176 }
167
177
168 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
178 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
169 {
179 {
170 if (visitor) {
180 if (visitor) {
171 visitor->visit(this);
181 visitor->visit(this);
172 }
182 }
173 else {
183 else {
174 qCCritical(LOG_VisualizationGraphWidget())
184 qCCritical(LOG_VisualizationGraphWidget())
175 << tr("Can't visit widget : the visitor is null");
185 << tr("Can't visit widget : the visitor is null");
176 }
186 }
177 }
187 }
178
188
179 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
189 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
180 {
190 {
181 /// @todo : for the moment, a graph can always accomodate a variable
191 /// @todo : for the moment, a graph can always accomodate a variable
182 Q_UNUSED(variable);
192 Q_UNUSED(variable);
183 return true;
193 return true;
184 }
194 }
185
195
186 bool VisualizationGraphWidget::contains(const Variable &variable) const
196 bool VisualizationGraphWidget::contains(const Variable &variable) const
187 {
197 {
188 // Finds the variable among the keys of the map
198 // Finds the variable among the keys of the map
189 auto variablePtr = &variable;
199 auto variablePtr = &variable;
190 auto findVariable
200 auto findVariable
191 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
201 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
192
202
193 auto end = impl->m_VariableToPlotMultiMap.cend();
203 auto end = impl->m_VariableToPlotMultiMap.cend();
194 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
204 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
195 return it != end;
205 return it != end;
196 }
206 }
197
207
198 QString VisualizationGraphWidget::name() const
208 QString VisualizationGraphWidget::name() const
199 {
209 {
200 return ui->graphNameLabel->text();
210 return ui->graphNameLabel->text();
201 }
211 }
202
212
203 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
213 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
204 {
214 {
205 QMenu graphMenu{};
215 QMenu graphMenu{};
206
216
207 // Iterates on variables (unique keys)
217 // Iterates on variables (unique keys)
208 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
218 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
209 end = impl->m_VariableToPlotMultiMap.cend();
219 end = impl->m_VariableToPlotMultiMap.cend();
210 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
220 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
211 // 'Remove variable' action
221 // 'Remove variable' action
212 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
222 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
213 [ this, var = it->first ]() { removeVariable(var); });
223 [ this, var = it->first ]() { removeVariable(var); });
214 }
224 }
215
225
216 if (!graphMenu.isEmpty()) {
226 if (!graphMenu.isEmpty()) {
217 graphMenu.exec(mapToGlobal(pos));
227 graphMenu.exec(mapToGlobal(pos));
218 }
228 }
219 }
229 }
220
230
221 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
231 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
222 {
232 {
223 qCInfo(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::onRangeChanged")
233 qCInfo(LOG_VisualizationGraphWidget())
224 << QThread::currentThread()->objectName();
234 << tr("VisualizationGraphWidget::onRangeChanged") << QThread::currentThread()->objectName();
225
235
226 auto dateTimeRange = SqpDateTime{t1.lower, t1.upper};
236 auto dateTimeRange = SqpDateTime{t1.lower, t1.upper};
227
237
228 auto zoomType = impl->getZoomType(t1, t2);
238 auto zoomType = impl->getZoomType(t1, t2);
229 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
239 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
230 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
240 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
231
241
232 auto variable = it->first;
242 auto variable = it->first;
233 auto currentDateTime = dateTimeRange;
243 auto currentDateTime = dateTimeRange;
234
244
235 auto toleranceFactor = 0.2;
245 auto toleranceFactor = toleranceValue(GENERAL_TOLERANCE_AT_UPDATE_KEY,
246 GENERAL_TOLERANCE_AT_UPDATE_DEFAULT_VALUE);
236 auto tolerance = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
247 auto tolerance = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
237 auto variableDateTimeWithTolerance = currentDateTime;
248 auto variableDateTimeWithTolerance = currentDateTime;
238 variableDateTimeWithTolerance.m_TStart -= tolerance;
249 variableDateTimeWithTolerance.m_TStart -= tolerance;
239 variableDateTimeWithTolerance.m_TEnd += tolerance;
250 variableDateTimeWithTolerance.m_TEnd += tolerance;
240
251
241 qCDebug(LOG_VisualizationGraphWidget()) << "r" << currentDateTime;
252 qCDebug(LOG_VisualizationGraphWidget()) << "r" << currentDateTime;
242 qCDebug(LOG_VisualizationGraphWidget()) << "t" << variableDateTimeWithTolerance;
253 qCDebug(LOG_VisualizationGraphWidget()) << "t" << variableDateTimeWithTolerance;
243 qCDebug(LOG_VisualizationGraphWidget()) << "v" << variable->dateTime();
254 qCDebug(LOG_VisualizationGraphWidget()) << "v" << variable->dateTime();
244 // If new range with tol is upper than variable datetime parameters. we need to request new
255 // If new range with tol is upper than variable datetime parameters. we need to request new
245 // data
256 // data
246 if (!variable->contains(variableDateTimeWithTolerance)) {
257 if (!variable->contains(variableDateTimeWithTolerance)) {
247
258
248 auto variableDateTimeWithTolerance = currentDateTime;
259 auto variableDateTimeWithTolerance = currentDateTime;
249 if (!variable->isInside(currentDateTime)) {
260 if (!variable->isInside(currentDateTime)) {
250 auto variableDateTime = variable->dateTime();
261 auto variableDateTime = variable->dateTime();
251 if (variable->contains(variableDateTimeWithTolerance)) {
262 if (variable->contains(variableDateTimeWithTolerance)) {
252 qCDebug(LOG_VisualizationGraphWidget())
263 qCDebug(LOG_VisualizationGraphWidget())
253 << tr("TORM: Detection zoom in that need request:");
264 << tr("TORM: Detection zoom in that need request:");
254 // add tolerance for each side
265 // add tolerance for each side
255 tolerance
266 tolerance
256 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
267 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
257 variableDateTimeWithTolerance.m_TStart -= tolerance;
268 variableDateTimeWithTolerance.m_TStart -= tolerance;
258 variableDateTimeWithTolerance.m_TEnd += tolerance;
269 variableDateTimeWithTolerance.m_TEnd += tolerance;
259 }
270 }
260 else if (variableDateTime.m_TStart < currentDateTime.m_TStart) {
271 else if (variableDateTime.m_TStart < currentDateTime.m_TStart) {
261 qCInfo(LOG_VisualizationGraphWidget()) << tr("TORM: Detection pan to right:");
272 qCInfo(LOG_VisualizationGraphWidget()) << tr("TORM: Detection pan to right:");
262
273
263 auto diffEndToKeepDelta = currentDateTime.m_TEnd - variableDateTime.m_TEnd;
274 auto diffEndToKeepDelta = currentDateTime.m_TEnd - variableDateTime.m_TEnd;
264 currentDateTime.m_TStart = variableDateTime.m_TStart + diffEndToKeepDelta;
275 currentDateTime.m_TStart = variableDateTime.m_TStart + diffEndToKeepDelta;
265 // Tolerance have to be added to the right
276 // Tolerance have to be added to the right
266 // add tolerance for right (end) side
277 // add tolerance for right (end) side
267 tolerance
278 tolerance
268 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
279 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
269 variableDateTimeWithTolerance.m_TEnd += tolerance;
280 variableDateTimeWithTolerance.m_TEnd += tolerance;
270 }
281 }
271 else if (variableDateTime.m_TEnd > currentDateTime.m_TEnd) {
282 else if (variableDateTime.m_TEnd > currentDateTime.m_TEnd) {
272 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Detection pan to left: ");
283 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Detection pan to left: ");
273 auto diffStartToKeepDelta
284 auto diffStartToKeepDelta
274 = variableDateTime.m_TStart - currentDateTime.m_TStart;
285 = variableDateTime.m_TStart - currentDateTime.m_TStart;
275 currentDateTime.m_TEnd = variableDateTime.m_TEnd - diffStartToKeepDelta;
286 currentDateTime.m_TEnd = variableDateTime.m_TEnd - diffStartToKeepDelta;
276 // Tolerance have to be added to the left
287 // Tolerance have to be added to the left
277 // add tolerance for left (start) side
288 // add tolerance for left (start) side
278 tolerance
289 tolerance
279 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
290 = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
280 variableDateTimeWithTolerance.m_TStart -= tolerance;
291 variableDateTimeWithTolerance.m_TStart -= tolerance;
281 }
292 }
282 else {
293 else {
283 qCCritical(LOG_VisualizationGraphWidget())
294 qCCritical(LOG_VisualizationGraphWidget())
284 << tr("Detection anormal zoom detection: ");
295 << tr("Detection anormal zoom detection: ");
285 }
296 }
286 }
297 }
287 else {
298 else {
288 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Detection zoom out: ");
299 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Detection zoom out: ");
289 // add tolerance for each side
300 // add tolerance for each side
290 tolerance = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
301 tolerance = toleranceFactor * (currentDateTime.m_TEnd - currentDateTime.m_TStart);
291 variableDateTimeWithTolerance.m_TStart -= tolerance;
302 variableDateTimeWithTolerance.m_TStart -= tolerance;
292 variableDateTimeWithTolerance.m_TEnd += tolerance;
303 variableDateTimeWithTolerance.m_TEnd += tolerance;
293 zoomType = VisualizationGraphWidgetZoomType::ZoomOut;
304 zoomType = VisualizationGraphWidgetZoomType::ZoomOut;
294 }
305 }
295 if (!variable->contains(dateTimeRange)) {
306 if (!variable->contains(dateTimeRange)) {
296 qCDebug(LOG_VisualizationGraphWidget())
307 qCDebug(LOG_VisualizationGraphWidget())
297 << "TORM: Modif on variable datetime detected" << currentDateTime;
308 << "TORM: Modif on variable datetime detected" << currentDateTime;
298 variable->setDateTime(currentDateTime);
309 variable->setDateTime(currentDateTime);
299 }
310 }
300
311
301 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Request data detection: ");
312 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: Request data detection: ");
302 // CHangement detected, we need to ask controller to request data loading
313 // CHangement detected, we need to ask controller to request data loading
303 emit requestDataLoading(variable, variableDateTimeWithTolerance);
314 emit requestDataLoading(variable, variableDateTimeWithTolerance);
304 }
315 }
305 else {
316 else {
306 qCInfo(LOG_VisualizationGraphWidget())
317 qCInfo(LOG_VisualizationGraphWidget())
307 << tr("TORM: Detection zoom in that doesn't need request: ");
318 << tr("TORM: Detection zoom in that doesn't need request: ");
308 zoomType = VisualizationGraphWidgetZoomType::ZoomIn;
319 zoomType = VisualizationGraphWidgetZoomType::ZoomIn;
309 }
320 }
310 }
321 }
311
322
312 if (impl->m_DoSynchronize && !impl->m_IsCalibration) {
323 if (impl->m_DoSynchronize && !impl->m_IsCalibration) {
313 auto oldDateTime = SqpDateTime{t2.lower, t2.upper};
324 auto oldDateTime = SqpDateTime{t2.lower, t2.upper};
314 qCDebug(LOG_VisualizationGraphWidget())
325 qCDebug(LOG_VisualizationGraphWidget())
315 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
326 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
316 << QThread::currentThread()->objectName();
327 << QThread::currentThread()->objectName();
317 emit synchronize(dateTimeRange, oldDateTime, zoomType);
328 emit synchronize(dateTimeRange, oldDateTime, zoomType);
318 }
329 }
319 }
330 }
320
331
321 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
332 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
322 {
333 {
323 auto zoomOrientations = QFlags<Qt::Orientation>{};
334 auto zoomOrientations = QFlags<Qt::Orientation>{};
324
335
325 // Lambda that enables a zoom orientation if the key modifier related to this orientation
336 // Lambda that enables a zoom orientation if the key modifier related to this orientation
326 // has
337 // has
327 // been pressed
338 // been pressed
328 auto enableOrientation
339 auto enableOrientation
329 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
340 = [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
330 auto orientationEnabled = event->modifiers().testFlag(modifier);
341 auto orientationEnabled = event->modifiers().testFlag(modifier);
331 zoomOrientations.setFlag(orientation, orientationEnabled);
342 zoomOrientations.setFlag(orientation, orientationEnabled);
332 };
343 };
333 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
344 enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
334 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
345 enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
335
346
336 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
347 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
337 }
348 }
338
349
339 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
350 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
340 {
351 {
341 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
352 impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
342 }
353 }
343
354
344 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
355 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
345 {
356 {
346 impl->m_IsCalibration = false;
357 impl->m_IsCalibration = false;
347 }
358 }
348
359
349 void VisualizationGraphWidget::onDataCacheVariableUpdated()
360 void VisualizationGraphWidget::onDataCacheVariableUpdated()
350 {
361 {
351 // NOTE:
362 // NOTE:
352 // We don't want to call the method for each component of a variable unitarily, but for
363 // We don't want to call the method for each component of a variable unitarily, but for
353 // all
364 // all
354 // its components at once (eg its three components in the case of a vector).
365 // its components at once (eg its three components in the case of a vector).
355
366
356 // The unordered_multimap does not do this easily, so the question is whether to:
367 // The unordered_multimap does not do this easily, so the question is whether to:
357 // - use an ordered_multimap and the algos of std to group the values by key
368 // - use an ordered_multimap and the algos of std to group the values by key
358 // - use a map (unique keys) and store as values directly the list of components
369 // - use a map (unique keys) and store as values directly the list of components
359
370
360 auto grapheRange = ui->widget->xAxis->range();
371 auto grapheRange = ui->widget->xAxis->range();
361 auto dateTime = SqpDateTime{grapheRange.lower, grapheRange.upper};
372 auto dateTime = SqpDateTime{grapheRange.lower, grapheRange.upper};
362
373
363 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
374 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
364 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
375 it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
365 auto variable = it->first;
376 auto variable = it->first;
366 qCDebug(LOG_VisualizationGraphWidget())
377 qCDebug(LOG_VisualizationGraphWidget())
367 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S"
378 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S"
368 << variable->dateTime();
379 << variable->dateTime();
369 qCDebug(LOG_VisualizationGraphWidget())
380 qCDebug(LOG_VisualizationGraphWidget())
370 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
381 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
371 if (dateTime.contains(variable->dateTime()) || dateTime.intersect(variable->dateTime())) {
382 if (dateTime.contains(variable->dateTime()) || dateTime.intersect(variable->dateTime())) {
372
383
373 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
384 VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
374 variable->dataSeries(), variable->dateTime());
385 variable->dataSeries(), variable->dateTime());
375 }
386 }
376 }
387 }
377 }
388 }
378
389
379 VisualizationGraphWidgetZoomType
390 VisualizationGraphWidgetZoomType
380 VisualizationGraphWidget::VisualizationGraphWidgetPrivate::getZoomType(const QCPRange &t1,
391 VisualizationGraphWidget::VisualizationGraphWidgetPrivate::getZoomType(const QCPRange &t1,
381 const QCPRange &t2)
392 const QCPRange &t2)
382 {
393 {
383 // t1.lower <= t2.lower && t2.upper <= t1.upper
394 // t1.lower <= t2.lower && t2.upper <= t1.upper
384 auto zoomType = VisualizationGraphWidgetZoomType::Unknown;
395 auto zoomType = VisualizationGraphWidgetZoomType::Unknown;
385 if (t1.lower <= t2.lower && t2.upper <= t1.upper) {
396 if (t1.lower <= t2.lower && t2.upper <= t1.upper) {
386 zoomType = VisualizationGraphWidgetZoomType::ZoomOut;
397 zoomType = VisualizationGraphWidgetZoomType::ZoomOut;
387 }
398 }
388 else if (t1.lower > t2.lower && t1.upper > t2.upper) {
399 else if (t1.lower > t2.lower && t1.upper > t2.upper) {
389 zoomType = VisualizationGraphWidgetZoomType::PanRight;
400 zoomType = VisualizationGraphWidgetZoomType::PanRight;
390 }
401 }
391 else if (t1.lower < t2.lower && t1.upper < t2.upper) {
402 else if (t1.lower < t2.lower && t1.upper < t2.upper) {
392 zoomType = VisualizationGraphWidgetZoomType::PanLeft;
403 zoomType = VisualizationGraphWidgetZoomType::PanLeft;
393 }
404 }
394 else if (t1.lower > t2.lower && t2.upper > t1.upper) {
405 else if (t1.lower > t2.lower && t2.upper > t1.upper) {
395 zoomType = VisualizationGraphWidgetZoomType::ZoomIn;
406 zoomType = VisualizationGraphWidgetZoomType::ZoomIn;
396 }
407 }
397 else {
408 else {
398 qCCritical(LOG_VisualizationGraphWidget()) << "getZoomType: Unknown type detected";
409 qCCritical(LOG_VisualizationGraphWidget()) << "getZoomType: Unknown type detected";
399 }
410 }
400 return zoomType;
411 return zoomType;
401 }
412 }
General Comments 0
You need to be logged in to leave comments. Login now