##// END OF EJS Templates
Implements zoom box interaction mode
trabillard -
r959:6b01e312fcf2
parent child
Show More
@@ -1,416 +1,490
1 #include "Visualization/VisualizationGraphWidget.h"
1 #include "Visualization/VisualizationGraphWidget.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 #include "Visualization/VisualizationDefs.h"
3 #include "Visualization/VisualizationDefs.h"
4 #include "Visualization/VisualizationGraphHelper.h"
4 #include "Visualization/VisualizationGraphHelper.h"
5 #include "Visualization/VisualizationGraphRenderingDelegate.h"
5 #include "Visualization/VisualizationGraphRenderingDelegate.h"
6 #include "Visualization/VisualizationZoneWidget.h"
6 #include "Visualization/VisualizationZoneWidget.h"
7 #include "ui_VisualizationGraphWidget.h"
7 #include "ui_VisualizationGraphWidget.h"
8
8
9 #include <Common/MimeTypesDef.h>
9 #include <Common/MimeTypesDef.h>
10 #include <Data/ArrayData.h>
10 #include <Data/ArrayData.h>
11 #include <Data/IDataSeries.h>
11 #include <Data/IDataSeries.h>
12 #include <DragAndDrop/DragDropHelper.h>
12 #include <DragAndDrop/DragDropHelper.h>
13 #include <Settings/SqpSettingsDefs.h>
13 #include <Settings/SqpSettingsDefs.h>
14 #include <SqpApplication.h>
14 #include <SqpApplication.h>
15 #include <Time/TimeController.h>
15 #include <Time/TimeController.h>
16 #include <Variable/Variable.h>
16 #include <Variable/Variable.h>
17 #include <Variable/VariableController.h>
17 #include <Variable/VariableController.h>
18
18
19 #include <unordered_map>
19 #include <unordered_map>
20
20
21 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
21 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
22
22
23 namespace {
23 namespace {
24
24
25 /// Key pressed to enable zoom on horizontal axis
25 /// Key pressed to enable zoom on horizontal axis
26 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::ControlModifier;
26 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::ControlModifier;
27
27
28 /// Key pressed to enable zoom on vertical axis
28 /// Key pressed to enable zoom on vertical axis
29 const auto VERTICAL_ZOOM_MODIFIER = Qt::ShiftModifier;
29 const auto VERTICAL_ZOOM_MODIFIER = Qt::ShiftModifier;
30
30
31 /// Speed of a step of a wheel event for a pan, in percentage of the axis range
31 /// Speed of a step of a wheel event for a pan, in percentage of the axis range
32 const auto PAN_SPEED = 5;
32 const auto PAN_SPEED = 5;
33
33
34 /// Key pressed to enable a calibration pan
34 /// Key pressed to enable a calibration pan
35 const auto VERTICAL_PAN_MODIFIER = Qt::AltModifier;
35 const auto VERTICAL_PAN_MODIFIER = Qt::AltModifier;
36
36
37 /// Minimum size for the zoom box, in percentage of the axis range
38 const auto ZOOM_BOX_MIN_SIZE = 0.8;
39
37 } // namespace
40 } // namespace
38
41
39 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
42 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
40
43
41 explicit VisualizationGraphWidgetPrivate(const QString &name)
44 explicit VisualizationGraphWidgetPrivate(const QString &name)
42 : m_Name{name},
45 : m_Name{name},
43 m_DoAcquisition{true},
46 m_DoAcquisition{true},
44 m_IsCalibration{false},
47 m_IsCalibration{false},
45 m_RenderingDelegate{nullptr}
48 m_RenderingDelegate{nullptr}
46 {
49 {
47 }
50 }
48
51
49 QString m_Name;
52 QString m_Name;
50 // 1 variable -> n qcpplot
53 // 1 variable -> n qcpplot
51 std::map<std::shared_ptr<Variable>, PlottablesMap> m_VariableToPlotMultiMap;
54 std::map<std::shared_ptr<Variable>, PlottablesMap> m_VariableToPlotMultiMap;
52 bool m_DoAcquisition;
55 bool m_DoAcquisition;
53 bool m_IsCalibration;
56 bool m_IsCalibration;
54 /// Delegate used to attach rendering features to the plot
57 /// Delegate used to attach rendering features to the plot
55 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
58 std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
59
60 QCPItemRect *m_DrawingRect = nullptr;
61
62 void configureDrawingRect()
63 {
64 if (m_DrawingRect) {
65 QPen p;
66 p.setWidth(2);
67 m_DrawingRect->setPen(p);
68 }
69 }
70
71 void startDrawingRect(const QPoint &pos, QCustomPlot &plot)
72 {
73 removeDrawingRect(plot);
74
75 auto axisPos = posToAxisPos(pos, plot);
76
77 m_DrawingRect = new QCPItemRect{&plot};
78 configureDrawingRect();
79
80 m_DrawingRect->topLeft->setCoords(axisPos);
81 m_DrawingRect->bottomRight->setCoords(axisPos);
82 }
83
84 void removeDrawingRect(QCustomPlot &plot)
85 {
86 if (m_DrawingRect) {
87 plot.removeItem(m_DrawingRect); // the item is deleted by QCustomPlot
88 m_DrawingRect = nullptr;
89 plot.replot(QCustomPlot::rpQueuedReplot);
90 }
91 }
92
93 QPointF posToAxisPos(const QPoint &pos, QCustomPlot &plot) const
94 {
95 auto axisX = plot.axisRect()->axis(QCPAxis::atBottom);
96 auto axisY = plot.axisRect()->axis(QCPAxis::atLeft);
97 return QPointF{axisX->pixelToCoord(pos.x()), axisY->pixelToCoord(pos.y())};
98 }
56 };
99 };
57
100
58 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
101 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
59 : VisualizationDragWidget{parent},
102 : VisualizationDragWidget{parent},
60 ui{new Ui::VisualizationGraphWidget},
103 ui{new Ui::VisualizationGraphWidget},
61 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>(name)}
104 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>(name)}
62 {
105 {
63 ui->setupUi(this);
106 ui->setupUi(this);
64
107
65 // 'Close' options : widget is deleted when closed
108 // 'Close' options : widget is deleted when closed
66 setAttribute(Qt::WA_DeleteOnClose);
109 setAttribute(Qt::WA_DeleteOnClose);
67
110
68 // Set qcpplot properties :
111 // Set qcpplot properties :
69 // - Drag (on x-axis) and zoom are enabled
112 // - Drag (on x-axis) and zoom are enabled
70 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
113 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
71 ui->widget->setInteractions(QCP::iRangeZoom | QCP::iSelectItems);
114 ui->widget->setInteractions(QCP::iRangeZoom | QCP::iSelectItems);
72
115
73 // The delegate must be initialized after the ui as it uses the plot
116 // The delegate must be initialized after the ui as it uses the plot
74 impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*this);
117 impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*this);
75
118
76 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
119 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
77 connect(ui->widget, &QCustomPlot::mouseRelease, this,
120 connect(ui->widget, &QCustomPlot::mouseRelease, this,
78 &VisualizationGraphWidget::onMouseRelease);
121 &VisualizationGraphWidget::onMouseRelease);
79 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
122 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
80 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
123 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
81 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
124 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
82 &QCPAxis::rangeChanged),
125 &QCPAxis::rangeChanged),
83 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
126 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
84
127
85 // Activates menu when right clicking on the graph
128 // Activates menu when right clicking on the graph
86 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
129 ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
87 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
130 connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
88 &VisualizationGraphWidget::onGraphMenuRequested);
131 &VisualizationGraphWidget::onGraphMenuRequested);
89
132
90 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
133 connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
91 &VariableController::onRequestDataLoading);
134 &VariableController::onRequestDataLoading);
92
135
93 connect(&sqpApp->variableController(), &VariableController::updateVarDisplaying, this,
136 connect(&sqpApp->variableController(), &VariableController::updateVarDisplaying, this,
94 &VisualizationGraphWidget::onUpdateVarDisplaying);
137 &VisualizationGraphWidget::onUpdateVarDisplaying);
95 }
138 }
96
139
97
140
98 VisualizationGraphWidget::~VisualizationGraphWidget()
141 VisualizationGraphWidget::~VisualizationGraphWidget()
99 {
142 {
100 delete ui;
143 delete ui;
101 }
144 }
102
145
103 VisualizationZoneWidget *VisualizationGraphWidget::parentZoneWidget() const noexcept
146 VisualizationZoneWidget *VisualizationGraphWidget::parentZoneWidget() const noexcept
104 {
147 {
105 auto parent = parentWidget();
148 auto parent = parentWidget();
106 while (parent != nullptr && !qobject_cast<VisualizationZoneWidget *>(parent)) {
149 while (parent != nullptr && !qobject_cast<VisualizationZoneWidget *>(parent)) {
107 parent = parent->parentWidget();
150 parent = parent->parentWidget();
108 }
151 }
109
152
110 return qobject_cast<VisualizationZoneWidget *>(parent);
153 return qobject_cast<VisualizationZoneWidget *>(parent);
111 }
154 }
112
155
113 void VisualizationGraphWidget::enableAcquisition(bool enable)
156 void VisualizationGraphWidget::enableAcquisition(bool enable)
114 {
157 {
115 impl->m_DoAcquisition = enable;
158 impl->m_DoAcquisition = enable;
116 }
159 }
117
160
118 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, SqpRange range)
161 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, SqpRange range)
119 {
162 {
120 // Uses delegate to create the qcpplot components according to the variable
163 // Uses delegate to create the qcpplot components according to the variable
121 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
164 auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
122
165
123 if (auto dataSeries = variable->dataSeries()) {
166 if (auto dataSeries = variable->dataSeries()) {
124 // Set axes properties according to the units of the data series
167 // Set axes properties according to the units of the data series
125 impl->m_RenderingDelegate->setAxesProperties(dataSeries);
168 impl->m_RenderingDelegate->setAxesProperties(dataSeries);
126
169
127 // Sets rendering properties for the new plottables
170 // Sets rendering properties for the new plottables
128 // Warning: this method must be called after setAxesProperties(), as it can access to some
171 // Warning: this method must be called after setAxesProperties(), as it can access to some
129 // axes properties that have to be initialized
172 // axes properties that have to be initialized
130 impl->m_RenderingDelegate->setPlottablesProperties(dataSeries, createdPlottables);
173 impl->m_RenderingDelegate->setPlottablesProperties(dataSeries, createdPlottables);
131 }
174 }
132
175
133 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
176 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
134
177
135 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
178 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
136
179
137 this->enableAcquisition(false);
180 this->enableAcquisition(false);
138 this->setGraphRange(range);
181 this->setGraphRange(range);
139 this->enableAcquisition(true);
182 this->enableAcquisition(true);
140
183
141 emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable, range, false);
184 emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable, range, false);
142
185
143 emit variableAdded(variable);
186 emit variableAdded(variable);
144 }
187 }
145
188
146 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
189 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
147 {
190 {
148 // Each component associated to the variable :
191 // Each component associated to the variable :
149 // - is removed from qcpplot (which deletes it)
192 // - is removed from qcpplot (which deletes it)
150 // - is no longer referenced in the map
193 // - is no longer referenced in the map
151 auto variableIt = impl->m_VariableToPlotMultiMap.find(variable);
194 auto variableIt = impl->m_VariableToPlotMultiMap.find(variable);
152 if (variableIt != impl->m_VariableToPlotMultiMap.cend()) {
195 if (variableIt != impl->m_VariableToPlotMultiMap.cend()) {
153 emit variableAboutToBeRemoved(variable);
196 emit variableAboutToBeRemoved(variable);
154
197
155 auto &plottablesMap = variableIt->second;
198 auto &plottablesMap = variableIt->second;
156
199
157 for (auto plottableIt = plottablesMap.cbegin(), plottableEnd = plottablesMap.cend();
200 for (auto plottableIt = plottablesMap.cbegin(), plottableEnd = plottablesMap.cend();
158 plottableIt != plottableEnd;) {
201 plottableIt != plottableEnd;) {
159 ui->widget->removePlottable(plottableIt->second);
202 ui->widget->removePlottable(plottableIt->second);
160 plottableIt = plottablesMap.erase(plottableIt);
203 plottableIt = plottablesMap.erase(plottableIt);
161 }
204 }
162
205
163 impl->m_VariableToPlotMultiMap.erase(variableIt);
206 impl->m_VariableToPlotMultiMap.erase(variableIt);
164 }
207 }
165
208
166 // Updates graph
209 // Updates graph
167 ui->widget->replot();
210 ui->widget->replot();
168 }
211 }
169
212
170 QList<std::shared_ptr<Variable> > VisualizationGraphWidget::variables() const
213 QList<std::shared_ptr<Variable> > VisualizationGraphWidget::variables() const
171 {
214 {
172 auto variables = QList<std::shared_ptr<Variable> >{};
215 auto variables = QList<std::shared_ptr<Variable> >{};
173 for (auto it = std::cbegin(impl->m_VariableToPlotMultiMap);
216 for (auto it = std::cbegin(impl->m_VariableToPlotMultiMap);
174 it != std::cend(impl->m_VariableToPlotMultiMap); ++it) {
217 it != std::cend(impl->m_VariableToPlotMultiMap); ++it) {
175 variables << it->first;
218 variables << it->first;
176 }
219 }
177
220
178 return variables;
221 return variables;
179 }
222 }
180
223
181 void VisualizationGraphWidget::setYRange(std::shared_ptr<Variable> variable)
224 void VisualizationGraphWidget::setYRange(std::shared_ptr<Variable> variable)
182 {
225 {
183 if (!variable) {
226 if (!variable) {
184 qCCritical(LOG_VisualizationGraphWidget()) << "Can't set y-axis range: variable is null";
227 qCCritical(LOG_VisualizationGraphWidget()) << "Can't set y-axis range: variable is null";
185 return;
228 return;
186 }
229 }
187
230
188 VisualizationGraphHelper::setYAxisRange(variable, *ui->widget);
231 VisualizationGraphHelper::setYAxisRange(variable, *ui->widget);
189 }
232 }
190
233
191 SqpRange VisualizationGraphWidget::graphRange() const noexcept
234 SqpRange VisualizationGraphWidget::graphRange() const noexcept
192 {
235 {
193 auto graphRange = ui->widget->xAxis->range();
236 auto graphRange = ui->widget->xAxis->range();
194 return SqpRange{graphRange.lower, graphRange.upper};
237 return SqpRange{graphRange.lower, graphRange.upper};
195 }
238 }
196
239
197 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
240 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
198 {
241 {
199 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
242 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
200 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
243 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
201 ui->widget->replot();
244 ui->widget->replot();
202 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
245 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
203 }
246 }
204
247
205 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
248 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
206 {
249 {
207 if (visitor) {
250 if (visitor) {
208 visitor->visit(this);
251 visitor->visit(this);
209 }
252 }
210 else {
253 else {
211 qCCritical(LOG_VisualizationGraphWidget())
254 qCCritical(LOG_VisualizationGraphWidget())
212 << tr("Can't visit widget : the visitor is null");
255 << tr("Can't visit widget : the visitor is null");
213 }
256 }
214 }
257 }
215
258
216 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
259 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
217 {
260 {
218 /// @todo : for the moment, a graph can always accomodate a variable
261 /// @todo : for the moment, a graph can always accomodate a variable
219 Q_UNUSED(variable);
262 Q_UNUSED(variable);
220 return true;
263 return true;
221 }
264 }
222
265
223 bool VisualizationGraphWidget::contains(const Variable &variable) const
266 bool VisualizationGraphWidget::contains(const Variable &variable) const
224 {
267 {
225 // Finds the variable among the keys of the map
268 // Finds the variable among the keys of the map
226 auto variablePtr = &variable;
269 auto variablePtr = &variable;
227 auto findVariable
270 auto findVariable
228 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
271 = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
229
272
230 auto end = impl->m_VariableToPlotMultiMap.cend();
273 auto end = impl->m_VariableToPlotMultiMap.cend();
231 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
274 auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
232 return it != end;
275 return it != end;
233 }
276 }
234
277
235 QString VisualizationGraphWidget::name() const
278 QString VisualizationGraphWidget::name() const
236 {
279 {
237 return impl->m_Name;
280 return impl->m_Name;
238 }
281 }
239
282
240 QMimeData *VisualizationGraphWidget::mimeData() const
283 QMimeData *VisualizationGraphWidget::mimeData() const
241 {
284 {
242 auto mimeData = new QMimeData;
285 auto mimeData = new QMimeData;
243 mimeData->setData(MIME_TYPE_GRAPH, QByteArray{});
286 mimeData->setData(MIME_TYPE_GRAPH, QByteArray{});
244
287
245 auto timeRangeData = TimeController::mimeDataForTimeRange(graphRange());
288 auto timeRangeData = TimeController::mimeDataForTimeRange(graphRange());
246 mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData);
289 mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData);
247
290
248 return mimeData;
291 return mimeData;
249 }
292 }
250
293
251 bool VisualizationGraphWidget::isDragAllowed() const
294 bool VisualizationGraphWidget::isDragAllowed() const
252 {
295 {
253 return true;
296 return true;
254 }
297 }
255
298
256 void VisualizationGraphWidget::highlightForMerge(bool highlighted)
299 void VisualizationGraphWidget::highlightForMerge(bool highlighted)
257 {
300 {
258 if (highlighted) {
301 if (highlighted) {
259 plot().setBackground(QBrush(QColor("#BBD5EE")));
302 plot().setBackground(QBrush(QColor("#BBD5EE")));
260 }
303 }
261 else {
304 else {
262 plot().setBackground(QBrush(Qt::white));
305 plot().setBackground(QBrush(Qt::white));
263 }
306 }
264
307
265 plot().update();
308 plot().update();
266 }
309 }
267
310
268 void VisualizationGraphWidget::closeEvent(QCloseEvent *event)
311 void VisualizationGraphWidget::closeEvent(QCloseEvent *event)
269 {
312 {
270 Q_UNUSED(event);
313 Q_UNUSED(event);
271
314
272 // Prevents that all variables will be removed from graph when it will be closed
315 // Prevents that all variables will be removed from graph when it will be closed
273 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
316 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
274 emit variableAboutToBeRemoved(variableEntry.first);
317 emit variableAboutToBeRemoved(variableEntry.first);
275 }
318 }
276 }
319 }
277
320
278 void VisualizationGraphWidget::enterEvent(QEvent *event)
321 void VisualizationGraphWidget::enterEvent(QEvent *event)
279 {
322 {
280 Q_UNUSED(event);
323 Q_UNUSED(event);
281 impl->m_RenderingDelegate->showGraphOverlay(true);
324 impl->m_RenderingDelegate->showGraphOverlay(true);
282 }
325 }
283
326
284 void VisualizationGraphWidget::leaveEvent(QEvent *event)
327 void VisualizationGraphWidget::leaveEvent(QEvent *event)
285 {
328 {
286 Q_UNUSED(event);
329 Q_UNUSED(event);
287 impl->m_RenderingDelegate->showGraphOverlay(false);
330 impl->m_RenderingDelegate->showGraphOverlay(false);
288 }
331 }
289
332
290 QCustomPlot &VisualizationGraphWidget::plot() noexcept
333 QCustomPlot &VisualizationGraphWidget::plot() noexcept
291 {
334 {
292 return *ui->widget;
335 return *ui->widget;
293 }
336 }
294
337
295 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
338 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
296 {
339 {
297 QMenu graphMenu{};
340 QMenu graphMenu{};
298
341
299 // Iterates on variables (unique keys)
342 // Iterates on variables (unique keys)
300 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
343 for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
301 end = impl->m_VariableToPlotMultiMap.cend();
344 end = impl->m_VariableToPlotMultiMap.cend();
302 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
345 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
303 // 'Remove variable' action
346 // 'Remove variable' action
304 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
347 graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
305 [ this, var = it->first ]() { removeVariable(var); });
348 [ this, var = it->first ]() { removeVariable(var); });
306 }
349 }
307
350
308 if (!graphMenu.isEmpty()) {
351 if (!graphMenu.isEmpty()) {
309 graphMenu.exec(QCursor::pos());
352 graphMenu.exec(QCursor::pos());
310 }
353 }
311 }
354 }
312
355
313 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
356 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
314 {
357 {
315 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
358 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
316 << QThread::currentThread()->objectName() << "DoAcqui"
359 << QThread::currentThread()->objectName() << "DoAcqui"
317 << impl->m_DoAcquisition;
360 << impl->m_DoAcquisition;
318
361
319 auto graphRange = SqpRange{t1.lower, t1.upper};
362 auto graphRange = SqpRange{t1.lower, t1.upper};
320 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
363 auto oldGraphRange = SqpRange{t2.lower, t2.upper};
321
364
322 if (impl->m_DoAcquisition) {
365 if (impl->m_DoAcquisition) {
323 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
366 QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
324
367
325 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
368 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
326 end = impl->m_VariableToPlotMultiMap.end();
369 end = impl->m_VariableToPlotMultiMap.end();
327 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
370 it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
328 variableUnderGraphVector.push_back(it->first);
371 variableUnderGraphVector.push_back(it->first);
329 }
372 }
330 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange,
373 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange,
331 !impl->m_IsCalibration);
374 !impl->m_IsCalibration);
332
375
333 if (!impl->m_IsCalibration) {
376 if (!impl->m_IsCalibration) {
334 qCDebug(LOG_VisualizationGraphWidget())
377 qCDebug(LOG_VisualizationGraphWidget())
335 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
378 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
336 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
379 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
337 emit synchronize(graphRange, oldGraphRange);
380 emit synchronize(graphRange, oldGraphRange);
338 }
381 }
339 }
382 }
340 }
383 }
341
384
342 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
385 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
343 {
386 {
344 // Handles plot rendering when mouse is moving
387 // Handles plot rendering when mouse is moving
345 impl->m_RenderingDelegate->onMouseMove(event);
388 impl->m_RenderingDelegate->onMouseMove(event);
346
389
390 if (impl->m_DrawingRect) {
391 auto axisPos = impl->posToAxisPos(event->pos(), plot());
392 impl->m_DrawingRect->bottomRight->setCoords(axisPos);
393 }
394
347 VisualizationDragWidget::mouseMoveEvent(event);
395 VisualizationDragWidget::mouseMoveEvent(event);
348 }
396 }
349
397
350 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
398 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
351 {
399 {
352 auto value = event->angleDelta().x() + event->angleDelta().y();
400 auto value = event->angleDelta().x() + event->angleDelta().y();
353 if (value != 0) {
401 if (value != 0) {
354
402
355 auto direction = value > 0 ? 1.0 : -1.0;
403 auto direction = value > 0 ? 1.0 : -1.0;
356 auto isZoomX = event->modifiers().testFlag(HORIZONTAL_ZOOM_MODIFIER);
404 auto isZoomX = event->modifiers().testFlag(HORIZONTAL_ZOOM_MODIFIER);
357 auto isZoomY = event->modifiers().testFlag(VERTICAL_ZOOM_MODIFIER);
405 auto isZoomY = event->modifiers().testFlag(VERTICAL_ZOOM_MODIFIER);
358 impl->m_IsCalibration = event->modifiers().testFlag(VERTICAL_PAN_MODIFIER);
406 impl->m_IsCalibration = event->modifiers().testFlag(VERTICAL_PAN_MODIFIER);
359
407
360 auto zoomOrientations = QFlags<Qt::Orientation>{};
408 auto zoomOrientations = QFlags<Qt::Orientation>{};
361 zoomOrientations.setFlag(Qt::Horizontal, isZoomX);
409 zoomOrientations.setFlag(Qt::Horizontal, isZoomX);
362 zoomOrientations.setFlag(Qt::Vertical, isZoomY);
410 zoomOrientations.setFlag(Qt::Vertical, isZoomY);
363
411
364 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
412 ui->widget->axisRect()->setRangeZoom(zoomOrientations);
365
413
366 if (!isZoomX && !isZoomY) {
414 if (!isZoomX && !isZoomY) {
367 auto axis = plot().axisRect()->axis(QCPAxis::atBottom);
415 auto axis = plot().axisRect()->axis(QCPAxis::atBottom);
368 auto diff = direction * (axis->range().size() * (PAN_SPEED / 100.0));
416 auto diff = direction * (axis->range().size() * (PAN_SPEED / 100.0));
369
417
370 axis->setRange(axis->range() + diff);
418 axis->setRange(axis->range() + diff);
371
419
372 if (plot().noAntialiasingOnDrag()) {
420 if (plot().noAntialiasingOnDrag()) {
373 plot().setNotAntialiasedElements(QCP::aeAll);
421 plot().setNotAntialiasedElements(QCP::aeAll);
374 }
422 }
375
423
376 plot().replot(QCustomPlot::rpQueuedReplot);
424 plot().replot(QCustomPlot::rpQueuedReplot);
377 }
425 }
378 }
426 }
379 }
427 }
380
428
381 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
429 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
382 {
430 {
431 if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::ZoomBox) {
432 impl->startDrawingRect(event->pos(), plot());
433 }
434
383 VisualizationDragWidget::mousePressEvent(event);
435 VisualizationDragWidget::mousePressEvent(event);
384 }
436 }
385
437
386 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
438 void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
387 {
439 {
440 if (impl->m_DrawingRect) {
441
442 auto axisX = plot().axisRect()->axis(QCPAxis::atBottom);
443 auto axisY = plot().axisRect()->axis(QCPAxis::atLeft);
444
445 auto newAxisXRange = QCPRange{impl->m_DrawingRect->topLeft->coords().x(),
446 impl->m_DrawingRect->bottomRight->coords().x()};
447
448 auto newAxisYRange = QCPRange{impl->m_DrawingRect->topLeft->coords().y(),
449 impl->m_DrawingRect->bottomRight->coords().y()};
450
451 impl->removeDrawingRect(plot());
452
453 if (newAxisXRange.size() > axisX->range().size() * (ZOOM_BOX_MIN_SIZE / 100.0)
454 && newAxisYRange.size() > axisY->range().size() * (ZOOM_BOX_MIN_SIZE / 100.0)) {
455 axisX->setRange(newAxisXRange);
456 axisY->setRange(newAxisYRange);
457
458 plot().replot(QCustomPlot::rpQueuedReplot);
459 }
460 }
461
388 impl->m_IsCalibration = false;
462 impl->m_IsCalibration = false;
389 }
463 }
390
464
391 void VisualizationGraphWidget::onDataCacheVariableUpdated()
465 void VisualizationGraphWidget::onDataCacheVariableUpdated()
392 {
466 {
393 auto graphRange = ui->widget->xAxis->range();
467 auto graphRange = ui->widget->xAxis->range();
394 auto dateTime = SqpRange{graphRange.lower, graphRange.upper};
468 auto dateTime = SqpRange{graphRange.lower, graphRange.upper};
395
469
396 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
470 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
397 auto variable = variableEntry.first;
471 auto variable = variableEntry.first;
398 qCDebug(LOG_VisualizationGraphWidget())
472 qCDebug(LOG_VisualizationGraphWidget())
399 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
473 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
400 qCDebug(LOG_VisualizationGraphWidget())
474 qCDebug(LOG_VisualizationGraphWidget())
401 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
475 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
402 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
476 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
403 VisualizationGraphHelper::updateData(variableEntry.second, variable->dataSeries(),
477 VisualizationGraphHelper::updateData(variableEntry.second, variable->dataSeries(),
404 variable->range());
478 variable->range());
405 }
479 }
406 }
480 }
407 }
481 }
408
482
409 void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> variable,
483 void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> variable,
410 const SqpRange &range)
484 const SqpRange &range)
411 {
485 {
412 auto it = impl->m_VariableToPlotMultiMap.find(variable);
486 auto it = impl->m_VariableToPlotMultiMap.find(variable);
413 if (it != impl->m_VariableToPlotMultiMap.end()) {
487 if (it != impl->m_VariableToPlotMultiMap.end()) {
414 VisualizationGraphHelper::updateData(it->second, variable->dataSeries(), range);
488 VisualizationGraphHelper::updateData(it->second, variable->dataSeries(), range);
415 }
489 }
416 }
490 }
General Comments 0
You need to be logged in to leave comments. Login now