##// END OF EJS Templates
Add impletation for displaying data that are already in cache when...
Add impletation for displaying data that are already in cache when acquisition is requested

File last commit:

r538:ba71c0cdaccd
r539:575eda7156d0
Show More
VisualizationGraphWidget.cpp
320 lines | 12.1 KiB | text/x-c | CppLexer
/ gui / src / Visualization / VisualizationGraphWidget.cpp
mv visualization -> Visualization...
r93 #include "Visualization/VisualizationGraphWidget.h"
Alexandre Leroux
Updates visitor interface...
r192 #include "Visualization/IVisualizationWidgetVisitor.h"
Correction for pull request
r227 #include "Visualization/VisualizationGraphHelper.h"
Alexandre Leroux
Creates a delegate offering methods for rendering a graph
r442 #include "Visualization/VisualizationGraphRenderingDelegate.h"
Creation of VisualizationWidget, VizualizationTabWidget, VisualizationZoneWidget, VisualizationGraphWidget
r58 #include "ui_VisualizationGraphWidget.h"
The mock plugin can now create data with view operation
r219 #include <Data/ArrayData.h>
#include <Data/IDataSeries.h>
Alexandre Leroux
Settings binding (5)...
r434 #include <Settings/SqpSettingsDefs.h>
The mock plugin can now create data with view operation
r219 #include <SqpApplication.h>
Add the visualization gui classes
r111 #include <Variable/Variable.h>
The mock plugin can now create data with view operation
r219 #include <Variable/VariableController.h>
Add the visualization gui classes
r111 #include <unordered_map>
Alexandre Leroux
Adds logs for null visitors
r204 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
Alexandre Leroux
Handles key modifiers for zoom...
r166 namespace {
/// Key pressed to enable zoom on horizontal axis
const auto HORIZONTAL_ZOOM_MODIFIER = Qt::NoModifier;
/// Key pressed to enable zoom on vertical axis
const auto VERTICAL_ZOOM_MODIFIER = Qt::ControlModifier;
} // namespace
Add the visualization gui classes
r111 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
Alexandre Leroux
Creates a delegate offering methods for rendering a graph
r442 explicit VisualizationGraphWidgetPrivate()
Implementation of V5 acquisition
r510 : m_DoAcquisition{true}, m_IsCalibration{false}, m_RenderingDelegate{nullptr}
Alexandre Leroux
Creates a delegate offering methods for rendering a graph
r442 {
}
Implementation of the calibration for the synchronization...
r411
Add the visualization gui classes
r111 // 1 variable -> n qcpplot
Alexandre Leroux
Remove variable from graph (2)...
r250 std::multimap<std::shared_ptr<Variable>, QCPAbstractPlottable *> m_VariableToPlotMultiMap;
Implementation of V5 acquisition
r510 bool m_DoAcquisition;
Implementation of the calibration for the synchronization...
r411 bool m_IsCalibration;
Alexandre Leroux
Creates a delegate offering methods for rendering a graph
r442 QCPItemTracer *m_TextTracer;
/// Delegate used to attach rendering features to the plot
std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
Add the visualization gui classes
r111 };
Alexandre Leroux
Fixes reference
r191 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
add {} missing
r113 : QWidget{parent},
ui{new Ui::VisualizationGraphWidget},
Add the visualization gui classes
r111 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>()}
Creation of VisualizationWidget, VizualizationTabWidget, VisualizationZoneWidget, VisualizationGraphWidget
r58 {
ui->setupUi(this);
Alexandre Leroux
Sets plot properties in a graph
r165
Alexandre Leroux
Creates a delegate offering methods for rendering a graph
r442 // The delegate must be initialized after the ui as it uses the plot
impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*ui->widget);
Alexandre Leroux
Adds a close button to a graph widget + calls close() method when clicked...
r246 ui->graphNameLabel->setText(name);
// 'Close' options : widget is deleted when closed
setAttribute(Qt::WA_DeleteOnClose);
connect(ui->closeButton, &QToolButton::clicked, this, &VisualizationGraphWidget::close);
ui->closeButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
Alexandre Leroux
Adds name to a graph...
r182
Alexandre Leroux
Sets plot properties in a graph
r165 // Set qcpplot properties :
Alexandre Leroux
Enables drag only for x-axis
r167 // - Drag (on x-axis) and zoom are enabled
Alexandre Leroux
Handles key modifiers for zoom...
r166 // - Mouse wheel on qcpplot is intercepted to determine the zoom orientation
Alexandre Leroux
Sets plot properties in a graph
r165 ui->widget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
Alexandre Leroux
Enables drag only for x-axis
r167 ui->widget->axisRect()->setRangeDrag(Qt::Horizontal);
Alexandre Leroux
Creates method that will display a tooltip and a tracer with data point information after a while
r443
Implementation of the calibration for the synchronization...
r411 connect(ui->widget, &QCustomPlot::mousePress, this, &VisualizationGraphWidget::onMousePress);
connect(ui->widget, &QCustomPlot::mouseRelease, this,
&VisualizationGraphWidget::onMouseRelease);
Alexandre Leroux
Creates method that will display a tooltip and a tracer with data point information after a while
r443 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
Alexandre Leroux
Handles key modifiers for zoom...
r166 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
Add synchronization that keep delta
r410 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
&QCPAxis::rangeChanged),
Implementation of the calibration for the synchronization...
r411 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
Alexandre Leroux
Remove variable from graph (1)...
r249
// Activates menu when right clicking on the graph
ui->widget->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->widget, &QCustomPlot::customContextMenuRequested, this,
&VisualizationGraphWidget::onGraphMenuRequested);
Fix the cosinus bug....
r276
connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
&VariableController::onRequestDataLoading);
add Skeleton for displaying data which are already in cache
r538
connect(&sqpApp->variableController(), &VariableController::updateVarDisplaying, this,
&VisualizationGraphWidget::onUpdateVarDisplaying);
Creation of VisualizationWidget, VizualizationTabWidget, VisualizationZoneWidget, VisualizationGraphWidget
r58 }
Alexandre Leroux
QCustomPlot notify the graph widget when the xRange changed
r211
Creation of VisualizationWidget, VizualizationTabWidget, VisualizationZoneWidget, VisualizationGraphWidget
r58 VisualizationGraphWidget::~VisualizationGraphWidget()
{
delete ui;
}
Add the visualization gui classes
r111
Implementation of V5 acquisition
r510 void VisualizationGraphWidget::enableAcquisition(bool enable)
Add synchronization that keep delta
r410 {
Implementation of V5 acquisition
r510 impl->m_DoAcquisition = enable;
Add synchronization that keep delta
r410 }
Initialisation of the graph range at creation in a new graphe, or inside...
r518 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, SqpRange range)
Add the visualization gui classes
r111 {
Alexandre Leroux
Uses factory in the VariableGraphWidget
r171 // Uses delegate to create the qcpplot components according to the variable
Initialisation of the graph range at creation in a new graphe, or inside...
r518 auto createdPlottables = VisualizationGraphHelper::createV2(variable, *ui->widget);
Alexandre Leroux
Uses factory in the VariableGraphWidget
r171
for (auto createdPlottable : qAsConst(createdPlottables)) {
The mock plugin can now create data with view operation
r219 impl->m_VariableToPlotMultiMap.insert({variable, createdPlottable});
Alexandre Leroux
Uses factory in the VariableGraphWidget
r171 }
The mock plugin can now create data with view operation
r219
Fix the cosinus bug....
r276 connect(variable.get(), SIGNAL(updated()), this, SLOT(onDataCacheVariableUpdated()));
Add synchronization part of v5 acquisition
r511
Initialisation of the graph range at creation in a new graphe, or inside...
r518 auto varRange = variable->range();
variable time is now set to range graphe displayed when it is displayed...
r289
Initialisation of the graph range at creation in a new graphe, or inside...
r518 this->enableAcquisition(false);
this->setGraphRange(range);
this->enableAcquisition(true);
variable time is now set to range graphe displayed when it is displayed...
r289
Initialisation of the graph range at creation in a new graphe, or inside...
r518 emit requestDataLoading(QVector<std::shared_ptr<Variable> >() << variable, range, varRange,
false);
emit variableAdded(variable);
variable time is now set to range graphe displayed when it is displayed...
r289 }
Alexandre Leroux
Remove variable from graph (2)...
r250 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
{
Alexandre Leroux
Remove variable from graph (3)...
r251 // Each component associated to the variable :
// - is removed from qcpplot (which deletes it)
// - is no longer referenced in the map
auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
for (auto it = componentsIt.first; it != componentsIt.second;) {
ui->widget->removePlottable(it->second);
it = impl->m_VariableToPlotMultiMap.erase(it);
}
// Updates graph
ui->widget->replot();
Alexandre Leroux
Remove variable from graph (2)...
r250 }
Change SqpRange for SqpDateTime
r471 void VisualizationGraphWidget::setRange(std::shared_ptr<Variable> variable, const SqpRange &range)
Add implementation for the range rescale. Variable is ignored here...
r404 {
Correction for MR
r413 // Note: in case of different axes that depends on variable, we could start with a code like
// that:
Add implementation for the range rescale. Variable is ignored here...
r404 // auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
// for (auto it = componentsIt.first; it != componentsIt.second;) {
// }
ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
Add synchronization that keep delta
r410 ui->widget->replot();
}
Initialisation of the graph range at creation in a new graphe, or inside...
r518 void VisualizationGraphWidget::setYRange(const SqpRange &range)
{
ui->widget->yAxis->setRange(range.m_TStart, range.m_TEnd);
}
Change SqpRange for SqpDateTime
r471 SqpRange VisualizationGraphWidget::graphRange() const noexcept
Add synchronization that keep delta
r410 {
change grapheRange to graphRange
r516 auto graphRange = ui->widget->xAxis->range();
return SqpRange{graphRange.lower, graphRange.upper};
Add synchronization that keep delta
r410 }
Change SqpRange for SqpDateTime
r471 void VisualizationGraphWidget::setGraphRange(const SqpRange &range)
Add synchronization that keep delta
r410 {
Implementation of the calibration for the synchronization...
r411 qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange START");
Add synchronization that keep delta
r410 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
ui->widget->replot();
qCDebug(LOG_VisualizationGraphWidget()) << tr("VisualizationGraphWidget::setGraphRange END");
Add implementation for the range rescale. Variable is ignored here...
r404 }
Alexandre Leroux
Updates visitor interface...
r192 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
Add the visualization gui classes
r111 {
Alexandre Leroux
Implements accept() method of visualization widgets
r193 if (visitor) {
visitor->visit(this);
}
Alexandre Leroux
Adds logs for null visitors
r204 else {
qCCritical(LOG_VisualizationGraphWidget())
<< tr("Can't visit widget : the visitor is null");
}
Add the visualization gui classes
r111 }
Alexandre Leroux
Creates a interface that defines a variable container...
r194 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
{
/// @todo : for the moment, a graph can always accomodate a variable
Q_UNUSED(variable);
return true;
}
Alexandre Leroux
Unplot menu (5): adds contains() method to an IVariableContainer...
r301 bool VisualizationGraphWidget::contains(const Variable &variable) const
{
// Finds the variable among the keys of the map
auto variablePtr = &variable;
auto findVariable
= [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); };
auto end = impl->m_VariableToPlotMultiMap.cend();
auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable);
return it != end;
}
Add const and override
r112 QString VisualizationGraphWidget::name() const
Add the visualization gui classes
r111 {
Alexandre Leroux
Adds a close button to a graph widget + calls close() method when clicked...
r246 return ui->graphNameLabel->text();
Add the visualization gui classes
r111 }
Alexandre Leroux
Remove variable from graph (1)...
r249 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
Add the visualization gui classes
r111 {
Alexandre Leroux
Remove variable from graph (1)...
r249 QMenu graphMenu{};
Alexandre Leroux
Remove variable from graph (2)...
r250 // Iterates on variables (unique keys)
for (auto it = impl->m_VariableToPlotMultiMap.cbegin(),
end = impl->m_VariableToPlotMultiMap.cend();
it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
// 'Remove variable' action
graphMenu.addAction(tr("Remove variable %1").arg(it->first->name()),
[ this, var = it->first ]() { removeVariable(var); });
Alexandre Leroux
Adds name to a graph...
r182 }
Alexandre Leroux
Remove variable from graph (1)...
r249
if (!graphMenu.isEmpty()) {
graphMenu.exec(mapToGlobal(pos));
Alexandre Leroux
Adds name to a graph...
r182 }
Add the visualization gui classes
r111 }
Alexandre Leroux
Handles key modifiers for zoom...
r166
Add synchronization that keep delta
r410 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
Alexandre Leroux
QCustomPlot notify the graph widget when the xRange changed
r211 {
Implementation of V5 acquisition
r510 qCDebug(LOG_VisualizationGraphWidget()) << tr("TORM: VisualizationGraphWidget::onRangeChanged")
<< QThread::currentThread()->objectName() << "DoAcqui"
<< impl->m_DoAcquisition;
Add synchronization that keep delta
r410
Implementation of V5 acquisition
r510 auto graphRange = SqpRange{t1.lower, t1.upper};
auto oldGraphRange = SqpRange{t2.lower, t2.upper};
The mock plugin can now create data with view operation
r219
Implementation of V5 acquisition
r510 if (impl->m_DoAcquisition) {
QVector<std::shared_ptr<Variable> > variableUnderGraphVector;
Add intersect méthode on variable and sqpDateTime...
r240
Implementation of V5 acquisition
r510 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
end = impl->m_VariableToPlotMultiMap.end();
it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
variableUnderGraphVector.push_back(it->first);
The mock plugin can now create data with view operation
r219 }
Implementation of V5 acquisition
r510 emit requestDataLoading(std::move(variableUnderGraphVector), graphRange, oldGraphRange,
!impl->m_IsCalibration);
if (!impl->m_IsCalibration) {
The dataSeries of a variable is now shared istead of uniq to avoid...
r513 qCDebug(LOG_VisualizationGraphWidget())
Implementation of V5 acquisition
r510 << tr("TORM: VisualizationGraphWidget::Synchronize notify !!")
Add synchronization part of v5 acquisition
r511 << QThread::currentThread()->objectName() << graphRange << oldGraphRange;
Implementation of V5 acquisition
r510 emit synchronize(graphRange, oldGraphRange);
The cache is now updated only if date requested has been successfully...
r293 }
Alexandre Leroux
QCustomPlot notify the graph widget when the xRange changed
r211 }
}
Alexandre Leroux
Creates method that will display a tooltip and a tracer with data point information after a while
r443 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
{
// Handles plot rendering when mouse is moving
impl->m_RenderingDelegate->onMouseMove(event);
}
Alexandre Leroux
Handles key modifiers for zoom...
r166 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
{
auto zoomOrientations = QFlags<Qt::Orientation>{};
Implementation of the new Dela T computation strategy
r241 // Lambda that enables a zoom orientation if the key modifier related to this orientation
// has
Alexandre Leroux
Handles key modifiers for zoom...
r166 // been pressed
auto enableOrientation
= [&zoomOrientations, event](const auto &orientation, const auto &modifier) {
auto orientationEnabled = event->modifiers().testFlag(modifier);
zoomOrientations.setFlag(orientation, orientationEnabled);
};
enableOrientation(Qt::Vertical, VERTICAL_ZOOM_MODIFIER);
enableOrientation(Qt::Horizontal, HORIZONTAL_ZOOM_MODIFIER);
ui->widget->axisRect()->setRangeZoom(zoomOrientations);
}
The mock plugin can now create data with view operation
r219
Implementation of the calibration for the synchronization...
r411 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
{
impl->m_IsCalibration = event->modifiers().testFlag(Qt::ControlModifier);
}
void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
{
impl->m_IsCalibration = false;
}
The mock plugin can now create data with view operation
r219 void VisualizationGraphWidget::onDataCacheVariableUpdated()
{
Correction for pull request
r227 // NOTE:
Implementation of the new Dela T computation strategy
r241 // We don't want to call the method for each component of a variable unitarily, but for
// all
Correction for pull request
r227 // its components at once (eg its three components in the case of a vector).
// The unordered_multimap does not do this easily, so the question is whether to:
// - use an ordered_multimap and the algos of std to group the values by key
// - use a map (unique keys) and store as values directly the list of components
change grapheRange to graphRange
r516 auto graphRange = ui->widget->xAxis->range();
auto dateTime = SqpRange{graphRange.lower, graphRange.upper};
Implementation of the cache feature : download before display needs
r399
The mock plugin can now create data with view operation
r219 for (auto it = impl->m_VariableToPlotMultiMap.cbegin();
it != impl->m_VariableToPlotMultiMap.cend(); ++it) {
auto variable = it->first;
Downgrade dev log from info to debug
r407 qCDebug(LOG_VisualizationGraphWidget())
Implementation of V5 acquisition
r510 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
Downgrade dev log from info to debug
r407 qCDebug(LOG_VisualizationGraphWidget())
Implementation of the cache feature : download before display needs
r399 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
Implementation of V5 acquisition
r510 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
Implementation of the cache feature : download before display needs
r399
VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
Implementation of V5 acquisition
r510 variable->dataSeries(), variable->range());
Implementation of the cache feature : download before display needs
r399 }
The mock plugin can now create data with view operation
r219 }
}
add Skeleton for displaying data which are already in cache
r538
void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> variable,
const SqpRange &range)
{
auto componentsIt = impl->m_VariableToPlotMultiMap.equal_range(variable);
for (auto it = componentsIt.first; it != componentsIt.second;) {
VisualizationGraphHelper::updateData(QVector<QCPAbstractPlottable *>{} << it->second,
variable->dataSeries(), range);
}
}