@@ -70,6 +70,7 public: | |||
|
70 | 70 | void setYRange(std::shared_ptr<Variable> variable); |
|
71 | 71 | SqpRange graphRange() const noexcept; |
|
72 | 72 | void setGraphRange(const SqpRange &range, bool calibration = false); |
|
73 | void setAutoRangeOnVariableInitialization(bool value); | |
|
73 | 74 | |
|
74 | 75 | // Zones |
|
75 | 76 | /// Returns the ranges of all the selection zones on the graph |
@@ -27,6 +27,9 Q_LOGGING_CATEGORY(LOG_CatalogueEventsWidget, "CatalogueEventsWidget") | |||
|
27 | 27 | /// Fixed size of the validation column |
|
28 | 28 | const auto VALIDATION_COLUMN_SIZE = 35; |
|
29 | 29 | |
|
30 | /// Percentage added to the range of a event when it is displayed | |
|
31 | const auto EVENT_RANGE_MARGE = 30; // in % | |
|
32 | ||
|
30 | 33 | struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate { |
|
31 | 34 | |
|
32 | 35 | CatalogueEventsModel *m_Model = nullptr; |
@@ -185,99 +188,130 struct CatalogueEventsWidget::CatalogueEventsWidgetPrivate { | |||
|
185 | 188 | } |
|
186 | 189 | } |
|
187 | 190 | |
|
191 | QVector<SqpRange> getGraphRanges(const std::shared_ptr<DBEvent> &event) | |
|
192 | { | |
|
193 | // Retrieves the range of each product and the maximum size | |
|
194 | QVector<SqpRange> graphRanges; | |
|
195 | double maxDt = 0; | |
|
196 | for (auto eventProduct : event->getEventProducts()) { | |
|
197 | SqpRange eventRange; | |
|
198 | eventRange.m_TStart = eventProduct.getTStart(); | |
|
199 | eventRange.m_TEnd = eventProduct.getTEnd(); | |
|
200 | graphRanges << eventRange; | |
|
201 | ||
|
202 | auto dt = eventRange.m_TEnd - eventRange.m_TStart; | |
|
203 | if (dt > maxDt) { | |
|
204 | maxDt = dt; | |
|
205 | } | |
|
206 | } | |
|
207 | ||
|
208 | // Adds the marge | |
|
209 | maxDt *= (100.0 + EVENT_RANGE_MARGE) / 100.0; | |
|
210 | ||
|
211 | // Corrects the graph ranges so that they all have the same size | |
|
212 | QVector<SqpRange> correctedGraphRanges; | |
|
213 | for (auto range : graphRanges) { | |
|
214 | auto dt = range.m_TEnd - range.m_TStart; | |
|
215 | auto diff = qAbs((maxDt - dt) / 2.0); | |
|
216 | ||
|
217 | SqpRange correctedRange; | |
|
218 | correctedRange.m_TStart = range.m_TStart - diff; | |
|
219 | correctedRange.m_TEnd = range.m_TEnd + diff; | |
|
220 | ||
|
221 | correctedGraphRanges << correctedRange; | |
|
222 | } | |
|
223 | ||
|
224 | return correctedGraphRanges; | |
|
225 | } | |
|
226 | ||
|
188 | 227 | void updateForGraphMode(QTreeView *treeView) |
|
189 | 228 | { |
|
190 | 229 | auto selectedRows = treeView->selectionModel()->selectedRows(); |
|
230 | if (selectedRows.count() != 1) { | |
|
231 | qCWarning(LOG_CatalogueEventsWidget()) | |
|
232 | << "updateGraphMode: not compatible with multiple events selected"; | |
|
233 | return; | |
|
234 | } | |
|
191 | 235 | |
|
192 | if (selectedRows.count() == 1) { | |
|
193 | auto event = m_Model->getEvent(selectedRows.first()); | |
|
194 | if (m_VisualizationWidget && event) { | |
|
195 | if (auto tab = m_VisualizationWidget->currentTabWidget()) { | |
|
196 | if (auto zone = tab->getZoneWithName(m_ZoneForGraphMode)) { | |
|
197 | ||
|
198 | for (auto graph : m_CustomGraphs) { | |
|
199 | graph->close(); | |
|
200 | auto variables = graph->variables().toVector(); | |
|
201 | ||
|
202 | QMetaObject::invokeMethod( | |
|
203 | &sqpApp->variableController(), "deleteVariables", | |
|
204 | Qt::QueuedConnection, | |
|
205 | Q_ARG(QVector<std::shared_ptr<Variable> >, variables)); | |
|
206 | } | |
|
207 | m_CustomGraphs.clear(); | |
|
208 | ||
|
209 | QVector<SqpRange> graphRanges; | |
|
210 | double maxDt = 0; | |
|
211 | for (auto eventProduct : event->getEventProducts()) { | |
|
212 | SqpRange eventRange; | |
|
213 | eventRange.m_TStart = eventProduct.getTStart(); | |
|
214 | eventRange.m_TEnd = eventProduct.getTEnd(); | |
|
215 | graphRanges << eventRange; | |
|
216 | ||
|
217 | auto dt = eventRange.m_TEnd - eventRange.m_TStart; | |
|
218 | if (dt > maxDt) { | |
|
219 | maxDt = dt; | |
|
220 | } | |
|
221 | } | |
|
236 | if (!m_VisualizationWidget) { | |
|
237 | qCWarning(LOG_CatalogueEventsWidget()) | |
|
238 | << "updateGraphMode: visualization widget not found"; | |
|
239 | return; | |
|
240 | } | |
|
241 | ||
|
242 | auto event = m_Model->getEvent(selectedRows.first()); | |
|
243 | if (!event) { | |
|
244 | // A event product is probably selected | |
|
245 | qCInfo(LOG_CatalogueEventsWidget()) << "updateGraphMode: no events are selected"; | |
|
246 | return; | |
|
247 | } | |
|
248 | ||
|
249 | auto tab = m_VisualizationWidget->currentTabWidget(); | |
|
250 | if (!tab) { | |
|
251 | qCWarning(LOG_CatalogueEventsWidget()) | |
|
252 | << "updateGraphMode: no tab found in the visualization"; | |
|
253 | return; | |
|
254 | } | |
|
222 | 255 | |
|
223 | QVector<SqpRange> correctedGraphRanges; | |
|
224 | for (auto range : graphRanges) { | |
|
225 | auto dt = range.m_TEnd - range.m_TStart; | |
|
226 | auto diff = qAbs((maxDt - dt) / 2.0); | |
|
256 | auto zone = tab->getZoneWithName(m_ZoneForGraphMode); | |
|
257 | if (!zone) { | |
|
258 | qCWarning(LOG_CatalogueEventsWidget()) << "updateGraphMode: zone not found"; | |
|
259 | return; | |
|
260 | } | |
|
227 | 261 | |
|
228 | SqpRange correctedRange; | |
|
229 | correctedRange.m_TStart = range.m_TStart - diff; | |
|
230 | correctedRange.m_TEnd = range.m_TEnd + diff; | |
|
262 | // Close the previous graph and delete the asociated variables | |
|
263 | for (auto graph : m_CustomGraphs) { | |
|
264 | graph->close(); | |
|
265 | auto variables = graph->variables().toVector(); | |
|
231 | 266 | |
|
232 | correctedGraphRanges << correctedRange; | |
|
233 | } | |
|
267 | QMetaObject::invokeMethod(&sqpApp->variableController(), "deleteVariables", | |
|
268 | Qt::QueuedConnection, | |
|
269 | Q_ARG(QVector<std::shared_ptr<Variable> >, variables)); | |
|
270 | } | |
|
271 | m_CustomGraphs.clear(); | |
|
234 | 272 | |
|
235 | auto itRange = correctedGraphRanges.cbegin(); | |
|
236 | for (auto eventProduct : event->getEventProducts()) { | |
|
237 | auto productId = eventProduct.getProductId(); | |
|
273 | // Calculates the range of each graph which will be created | |
|
274 | auto graphRange = getGraphRanges(event); | |
|
238 | 275 | |
|
239 | auto range = *itRange; | |
|
240 | ++itRange; | |
|
276 | // Loops through the event products and create the graph | |
|
277 | auto itRange = graphRange.cbegin(); | |
|
278 | for (auto eventProduct : event->getEventProducts()) { | |
|
279 | auto productId = eventProduct.getProductId(); | |
|
241 | 280 | |
|
242 | auto context = new QObject{treeView}; | |
|
243 | QObject::connect( | |
|
244 | &sqpApp->variableController(), &VariableController::variableAdded, | |
|
245 | context, | |
|
246 | [this, zone, context, range, productId](auto variable) { | |
|
281 | auto range = *itRange; | |
|
282 | ++itRange; | |
|
247 | 283 | |
|
248 | if (variable->metadata() | |
|
249 | .value(DataSourceItem::ID_DATA_KEY, "UnknownID") | |
|
250 | .toString() | |
|
251 | == productId) { | |
|
252 | auto graph = zone->createGraph(variable); | |
|
253 | m_CustomGraphs << graph; | |
|
284 | SqpRange productRange; | |
|
285 | productRange.m_TStart = eventProduct.getTStart(); | |
|
286 | productRange.m_TEnd = eventProduct.getTEnd(); | |
|
254 | 287 | |
|
255 | graph->setGraphRange(range, true); | |
|
288 | auto context = new QObject{treeView}; | |
|
289 | QObject::connect( | |
|
290 | &sqpApp->variableController(), &VariableController::variableAdded, context, | |
|
291 | [this, zone, context, range, productRange, productId](auto variable) { | |
|
256 | 292 | |
|
257 | delete context; // removes the connection | |
|
258 |
|
|
|
259 | }, | |
|
260 | Qt::QueuedConnection); | |
|
293 | if (variable->metadata().value(DataSourceItem::ID_DATA_KEY).toString() | |
|
294 | == productId) { | |
|
295 | auto graph = zone->createGraph(variable); | |
|
296 | graph->setAutoRangeOnVariableInitialization(false); | |
|
261 | 297 | |
|
262 | QMetaObject::invokeMethod( | |
|
263 | &sqpApp->dataSourceController(), "requestVariableFromProductIdKey", | |
|
264 | Qt::QueuedConnection, Q_ARG(QString, productId)); | |
|
265 | } | |
|
298 | graph->addSelectionZones({productRange}); | |
|
299 | m_CustomGraphs << graph; | |
|
300 | ||
|
301 | graph->setGraphRange(range, true); | |
|
302 | ||
|
303 | // Removes the graph from the graph list if it is closed manually | |
|
304 | QObject::connect(graph, &VisualizationGraphWidget::destroyed, | |
|
305 | [this, graph]() { m_CustomGraphs.removeAll(graph); }); | |
|
306 | ||
|
307 | delete context; // removes the connection | |
|
266 | 308 | } |
|
267 | } | |
|
268 |
|
|
|
269 | qCWarning(LOG_CatalogueEventsWidget()) | |
|
270 | << "updateGraphMode: no tab found in the visualization"; | |
|
271 | } | |
|
272 | } | |
|
273 | else { | |
|
274 | qCWarning(LOG_CatalogueEventsWidget()) | |
|
275 | << "updateGraphMode: visualization widget not found"; | |
|
276 | } | |
|
277 | } | |
|
278 | else { | |
|
279 | qCWarning(LOG_CatalogueEventsWidget()) | |
|
280 | << "updateGraphMode: not compatible with multiple events selected"; | |
|
309 | }, | |
|
310 | Qt::QueuedConnection); | |
|
311 | ||
|
312 | QMetaObject::invokeMethod(&sqpApp->dataSourceController(), | |
|
313 | "requestVariableFromProductIdKey", Qt::QueuedConnection, | |
|
314 | Q_ARG(QString, productId)); | |
|
281 | 315 | } |
|
282 | 316 | } |
|
283 | 317 |
@@ -94,6 +94,8 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate { | |||
|
94 | 94 | |
|
95 | 95 | bool m_HasMovedMouse = false; // Indicates if the mouse moved in a releaseMouse even |
|
96 | 96 | |
|
97 | bool m_VariableAutoRangeOnInit = true; | |
|
98 | ||
|
97 | 99 | void startDrawingRect(const QPoint &pos, QCustomPlot &plot) |
|
98 | 100 | { |
|
99 | 101 | removeDrawingRect(plot); |
@@ -314,7 +316,10 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, S | |||
|
314 | 316 | if (auto var = varW.lock()) { |
|
315 | 317 | // If the variable is the first added in the graph, we load its range |
|
316 | 318 | auto firstVariableInGraph = range == INVALID_RANGE; |
|
317 |
auto loadedRange = |
|
|
319 | auto loadedRange = graphRange(); | |
|
320 | if (impl->m_VariableAutoRangeOnInit) { | |
|
321 | loadedRange = firstVariableInGraph ? var->range() : range; | |
|
322 | } | |
|
318 | 323 | loadRange(var, loadedRange); |
|
319 | 324 | setYRange(var); |
|
320 | 325 | } |
@@ -406,6 +411,11 void VisualizationGraphWidget::setGraphRange(const SqpRange &range, bool calibra | |||
|
406 | 411 | qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END"); |
|
407 | 412 | } |
|
408 | 413 | |
|
414 | void VisualizationGraphWidget::setAutoRangeOnVariableInitialization(bool value) | |
|
415 | { | |
|
416 | impl->m_VariableAutoRangeOnInit = value; | |
|
417 | } | |
|
418 | ||
|
409 | 419 | QVector<SqpRange> VisualizationGraphWidget::selectionZoneRanges() const |
|
410 | 420 | { |
|
411 | 421 | QVector<SqpRange> ranges; |
General Comments 0
You need to be logged in to leave comments.
Login now