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