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