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