##// END OF EJS Templates
Removed interaction handling in QCP since they are implemented in...
Removed interaction handling in QCP since they are implemented in SciQLop Before the wheel interaction was done multiple times on QCP side first then on SciQLop side. Signed-off-by: Alexis Jeandet <alexis.jeandet@member.fsf.org>

File last commit:

r1358:48660d9880a2
r1358:48660d9880a2
Show More
VisualizationGraphWidget.cpp
1045 lines | 37.2 KiB | text/x-c | CppLexer
/ gui / src / Visualization / VisualizationGraphWidget.cpp
mv visualization -> Visualization...
r95 #include "Visualization/VisualizationGraphWidget.h"
Alexandre Leroux
Updates visitor interface...
r207 #include "Visualization/IVisualizationWidgetVisitor.h"
Implements cursor mode
r960 #include "Visualization/VisualizationCursorItem.h"
Alexandre Leroux
Handles QCustomPlot plottables for vectors (2)...
r582 #include "Visualization/VisualizationDefs.h"
Correction for pull request
r243 #include "Visualization/VisualizationGraphHelper.h"
Alexandre Leroux
Creates a delegate offering methods for rendering a graph
r480 #include "Visualization/VisualizationGraphRenderingDelegate.h"
Selection of stacked zone via a dialog box
r1085 #include "Visualization/VisualizationMultiZoneSelectionDialog.h"
Display of selection zones on a graph
r1044 #include "Visualization/VisualizationSelectionZoneItem.h"
multi selection of zones
r1049 #include "Visualization/VisualizationSelectionZoneManager.h"
#include "Visualization/VisualizationWidget.h"
Integrates the drag&drop classes into the existing visualization classes.
r839 #include "Visualization/VisualizationZoneWidget.h"
Creation of VisualizationWidget, VizualizationTabWidget, VisualizationZoneWidget, VisualizationGraphWidget
r58 #include "ui_VisualizationGraphWidget.h"
Adds selection zone actions in the context menu
r1077 #include <Actions/ActionsGuiController.h>
LineEdit to filter the create catalogue menu
r1328 #include <Actions/FilteringAction.h>
Move Common MIME types constants in a Definition file in core module.
r848 #include <Common/MimeTypesDef.h>
The mock plugin can now create data with view operation
r235 #include <Data/ArrayData.h>
#include <Data/IDataSeries.h>
Alexandre Leroux
Prohibits the display of a spectrogram in an existing graph and the display of data on a graph already containing a spectrogram
r1022 #include <Data/SpectrogramSeries.h>
Rename "DragDropHelper" in "DragDropGuiController"
r1075 #include <DragAndDrop/DragDropGuiController.h>
Alexandre Leroux
Settings binding (5)...
r470 #include <Settings/SqpSettingsDefs.h>
The mock plugin can now create data with view operation
r235 #include <SqpApplication.h>
Drop of variable, graph and zones on the time widget
r878 #include <Time/TimeController.h>
Add the visualization gui classes
r118 #include <Variable/Variable.h>
(•̀ᴗ•́)و ̑̑ Some cleaning, remover previous implementation of VariableController...
r1349 #include <Variable/VariableController2.h>
The mock plugin can now create data with view operation
r235
Add the visualization gui classes
r118 #include <unordered_map>
Alexandre Leroux
Adds logs for null visitors
r219 Q_LOGGING_CATEGORY(LOG_VisualizationGraphWidget, "VisualizationGraphWidget")
Alexandre Leroux
Handles key modifiers for zoom...
r179 namespace {
drag of selection zones
r1047 /// Key pressed to enable drag&drop in all modes
const auto DRAG_DROP_MODIFIER = Qt::AltModifier;
Alexandre Leroux
Handles key modifiers for zoom...
r179 /// Key pressed to enable zoom on horizontal axis
Basic mouse wheel interactions + mode drag
r958 const auto HORIZONTAL_ZOOM_MODIFIER = Qt::ControlModifier;
Alexandre Leroux
Handles key modifiers for zoom...
r179
/// Key pressed to enable zoom on vertical axis
Basic mouse wheel interactions + mode drag
r958 const auto VERTICAL_ZOOM_MODIFIER = Qt::ShiftModifier;
/// Speed of a step of a wheel event for a pan, in percentage of the axis range
const auto PAN_SPEED = 5;
/// Key pressed to enable a calibration pan
const auto VERTICAL_PAN_MODIFIER = Qt::AltModifier;
Alexandre Leroux
Handles key modifiers for zoom...
r179
multi selection of zones
r1049 /// Key pressed to enable multi selection of selection zones
const auto MULTI_ZONE_SELECTION_MODIFIER = Qt::ControlModifier;
Implements zoom box interaction mode
r959 /// Minimum size for the zoom box, in percentage of the axis range
const auto ZOOM_BOX_MIN_SIZE = 0.8;
Implements cursor mode
r960 /// Format of the dates appearing in the label of a cursor
const auto CURSOR_LABELS_DATETIME_FORMAT = QStringLiteral("yyyy/MM/dd\nhh:mm:ss:zzz");
Alexandre Leroux
Handles key modifiers for zoom...
r179
} // namespace
Add the visualization gui classes
r118 struct VisualizationGraphWidget::VisualizationGraphWidgetPrivate {
Alexandre Leroux
Removes title and close button from graph widget...
r724 explicit VisualizationGraphWidgetPrivate(const QString &name)
: m_Name{name},
Alexandre Leroux
Corrects the problem of refreshing synchronized graphs from TimeWidget (1)...
r1271 m_Flags{GraphFlag::EnableAll},
Alexandre Leroux
Removes title and close button from graph widget...
r724 m_IsCalibration{false},
m_RenderingDelegate{nullptr}
Alexandre Leroux
Creates a delegate offering methods for rendering a graph
r480 {
}
Implementation of the calibration for the synchronization...
r445
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 void updateData(PlottablesMap &plottables, std::shared_ptr<Variable> variable,
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 const DateTimeRange &range)
Alexandre Leroux
Updates sqp color scale thresholds (2)...
r1020 {
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 VisualizationGraphHelper::updateData(plottables, variable, range);
Alexandre Leroux
Updates sqp color scale thresholds (2)...
r1020
// Prevents that data has changed to update rendering
m_RenderingDelegate->onPlotUpdated();
}
Alexandre Leroux
Removes title and close button from graph widget...
r724 QString m_Name;
Add the visualization gui classes
r118 // 1 variable -> n qcpplot
Alexandre Leroux
Handles QCustomPlot plottables for vectors (2)...
r582 std::map<std::shared_ptr<Variable>, PlottablesMap> m_VariableToPlotMultiMap;
Alexandre Leroux
Corrects the problem of refreshing synchronized graphs from TimeWidget (1)...
r1271 GraphFlags m_Flags;
Implementation of the calibration for the synchronization...
r445 bool m_IsCalibration;
Alexandre Leroux
Creates a delegate offering methods for rendering a graph
r480 /// Delegate used to attach rendering features to the plot
std::unique_ptr<VisualizationGraphRenderingDelegate> m_RenderingDelegate;
Implements zoom box interaction mode
r959
Display of selection zones on a graph
r1044 QCPItemRect *m_DrawingZoomRect = nullptr;
Undo zoom box action
r1046 QStack<QPair<QCPRange, QCPRange> > m_ZoomStack;
Display of selection zones on a graph
r1044
Implements cursor mode
r960 std::unique_ptr<VisualizationCursorItem> m_HorizontalCursor = nullptr;
std::unique_ptr<VisualizationCursorItem> m_VerticalCursor = nullptr;
Implements zoom box interaction mode
r959
Display of selection zones on a graph
r1044 VisualizationSelectionZoneItem *m_DrawingZone = nullptr;
VisualizationSelectionZoneItem *m_HoveredZone = nullptr;
QVector<VisualizationSelectionZoneItem *> m_SelectionZones;
Implements zoom box interaction mode
r959
Improves display of selected zones
r1051 bool m_HasMovedMouse = false; // Indicates if the mouse moved in a releaseMouse even
Resize and move of multiple zones together
r1050
refactoring + fix created graph range
r1292 bool m_VariableAutoRangeOnInit = true;
Implements zoom box interaction mode
r959 void startDrawingRect(const QPoint &pos, QCustomPlot &plot)
{
removeDrawingRect(plot);
auto axisPos = posToAxisPos(pos, plot);
Display of selection zones on a graph
r1044 m_DrawingZoomRect = new QCPItemRect{&plot};
QPen p;
p.setWidth(2);
m_DrawingZoomRect->setPen(p);
Implements zoom box interaction mode
r959
Display of selection zones on a graph
r1044 m_DrawingZoomRect->topLeft->setCoords(axisPos);
m_DrawingZoomRect->bottomRight->setCoords(axisPos);
Implements zoom box interaction mode
r959 }
void removeDrawingRect(QCustomPlot &plot)
{
Display of selection zones on a graph
r1044 if (m_DrawingZoomRect) {
plot.removeItem(m_DrawingZoomRect); // the item is deleted by QCustomPlot
m_DrawingZoomRect = nullptr;
Implements zoom box interaction mode
r959 plot.replot(QCustomPlot::rpQueuedReplot);
}
}
multi selection of zones
r1049 void startDrawingZone(const QPoint &pos, VisualizationGraphWidget *graph)
Display of selection zones on a graph
r1044 {
multi selection of zones
r1049 endDrawingZone(graph);
Display of selection zones on a graph
r1044
multi selection of zones
r1049 auto axisPos = posToAxisPos(pos, graph->plot());
Display of selection zones on a graph
r1044
multi selection of zones
r1049 m_DrawingZone = new VisualizationSelectionZoneItem{&graph->plot()};
Display of selection zones on a graph
r1044 m_DrawingZone->setRange(axisPos.x(), axisPos.x());
m_DrawingZone->setEditionEnabled(false);
}
multi selection of zones
r1049 void endDrawingZone(VisualizationGraphWidget *graph)
Display of selection zones on a graph
r1044 {
if (m_DrawingZone) {
auto drawingZoneRange = m_DrawingZone->range();
if (qAbs(drawingZoneRange.m_TEnd - drawingZoneRange.m_TStart) > 0) {
m_DrawingZone->setEditionEnabled(true);
multi selection of zones
r1049 addSelectionZone(m_DrawingZone);
Display of selection zones on a graph
r1044 }
else {
multi selection of zones
r1049 graph->plot().removeItem(m_DrawingZone); // the item is deleted by QCustomPlot
Display of selection zones on a graph
r1044 }
multi selection of zones
r1049 graph->plot().replot(QCustomPlot::rpQueuedReplot);
Display of selection zones on a graph
r1044 m_DrawingZone = nullptr;
}
}
void setSelectionZonesEditionEnabled(bool value)
{
for (auto s : m_SelectionZones) {
s->setEditionEnabled(value);
}
}
multi selection of zones
r1049 void addSelectionZone(VisualizationSelectionZoneItem *zone) { m_SelectionZones << zone; }
drag of selection zones
r1047 VisualizationSelectionZoneItem *selectionZoneAt(const QPoint &pos,
const QCustomPlot &plot) const
{
VisualizationSelectionZoneItem *selectionZoneItemUnderCursor = nullptr;
auto minDistanceToZone = -1;
for (auto zone : m_SelectionZones) {
auto distanceToZone = zone->selectTest(pos, false);
if ((minDistanceToZone < 0 || distanceToZone <= minDistanceToZone)
&& distanceToZone >= 0 && distanceToZone < plot.selectionTolerance()) {
selectionZoneItemUnderCursor = zone;
}
}
return selectionZoneItemUnderCursor;
}
Selection of stacked zone via a dialog box
r1085 QVector<VisualizationSelectionZoneItem *> selectionZonesAt(const QPoint &pos,
const QCustomPlot &plot) const
{
QVector<VisualizationSelectionZoneItem *> zones;
for (auto zone : m_SelectionZones) {
auto distanceToZone = zone->selectTest(pos, false);
if (distanceToZone >= 0 && distanceToZone < plot.selectionTolerance()) {
zones << zone;
}
}
return zones;
}
void moveSelectionZoneOnTop(VisualizationSelectionZoneItem *zone, QCustomPlot &plot)
{
if (!m_SelectionZones.isEmpty() && m_SelectionZones.last() != zone) {
zone->moveToTop();
m_SelectionZones.removeAll(zone);
m_SelectionZones.append(zone);
}
}
Implements zoom box interaction mode
r959 QPointF posToAxisPos(const QPoint &pos, QCustomPlot &plot) const
{
auto axisX = plot.axisRect()->axis(QCPAxis::atBottom);
auto axisY = plot.axisRect()->axis(QCPAxis::atLeft);
return QPointF{axisX->pixelToCoord(pos.x()), axisY->pixelToCoord(pos.y())};
}
Implements cursor mode
r960
bool pointIsInAxisRect(const QPointF &axisPoint, QCustomPlot &plot) const
{
auto axisX = plot.axisRect()->axis(QCPAxis::atBottom);
auto axisY = plot.axisRect()->axis(QCPAxis::atLeft);
return axisX->range().contains(axisPoint.x()) && axisY->range().contains(axisPoint.y());
}
Add the visualization gui classes
r118 };
Alexandre Leroux
Fixes reference
r205 VisualizationGraphWidget::VisualizationGraphWidget(const QString &name, QWidget *parent)
Integrates the drag&drop classes into the existing visualization classes.
r839 : VisualizationDragWidget{parent},
add {} missing
r120 ui{new Ui::VisualizationGraphWidget},
Alexandre Leroux
Removes title and close button from graph widget...
r724 impl{spimpl::make_unique_impl<VisualizationGraphWidgetPrivate>(name)}
Creation of VisualizationWidget, VizualizationTabWidget, VisualizationZoneWidget, VisualizationGraphWidget
r58 {
ui->setupUi(this);
Alexandre Leroux
Sets plot properties in a graph
r178
Alexandre Leroux
Adds a close button to a graph widget + calls close() method when clicked...
r266 // 'Close' options : widget is deleted when closed
setAttribute(Qt::WA_DeleteOnClose);
Alexandre Leroux
Adds name to a graph...
r196
Alexandre Leroux
Removes title and close button from graph widget...
r724 // The delegate must be initialized after the ui as it uses the plot
impl->m_RenderingDelegate = std::make_unique<VisualizationGraphRenderingDelegate>(*this);
Implements cursor mode
r960 // Init the cursors
impl->m_HorizontalCursor = std::make_unique<VisualizationCursorItem>(&plot());
impl->m_HorizontalCursor->setOrientation(Qt::Horizontal);
impl->m_VerticalCursor = std::make_unique<VisualizationCursorItem>(&plot());
impl->m_VerticalCursor->setOrientation(Qt::Vertical);
Implementation of the calibration for the synchronization...
r445 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
r481 connect(ui->widget, &QCustomPlot::mouseMove, this, &VisualizationGraphWidget::onMouseMove);
Alexandre Leroux
Handles key modifiers for zoom...
r179 connect(ui->widget, &QCustomPlot::mouseWheel, this, &VisualizationGraphWidget::onMouseWheel);
Alexandre Leroux
Handles double click on color scale...
r1002 connect(ui->widget, &QCustomPlot::mouseDoubleClick, this,
&VisualizationGraphWidget::onMouseDoubleClick);
Add Catalogue methods
r1159 connect(ui->widget->xAxis, static_cast<void (QCPAxis::*)(const QCPRange &, const QCPRange &)>(
&QCPAxis::rangeChanged),
LineEdit to filter the create catalogue menu
r1328 this, &VisualizationGraphWidget::onRangeChanged, Qt::DirectConnection);
Alexandre Leroux
Remove variable from graph (1)...
r269
// 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....
r298
All the codebase is modified to build with new Variable Controller...
r1348 //@TODO implement this :)
// connect(this, &VisualizationGraphWidget::requestDataLoading, &sqpApp->variableController(),
// &VariableController::onRequestDataLoading);
add Skeleton for displaying data which are already in cache
r571
All the codebase is modified to build with new Variable Controller...
r1348 // connect(&sqpApp->variableController(), &VariableController2::updateVarDisplaying, this,
// &VisualizationGraphWidget::onUpdateVarDisplaying);
Thibaud Rabillard
Makes QCustomPlot drawing faster on mac
r963
Add Qt::AA_EnableHighDpiScaling and QCP::phFastPolylines
r1320 // Necessary for all platform since Qt::AA_EnableHighDpiScaling is enable.
Thibaud Rabillard
Makes QCustomPlot drawing faster on mac
r963 plot().setPlottingHint(QCP::phFastPolylines, true);
Creation of VisualizationWidget, VizualizationTabWidget, VisualizationZoneWidget, VisualizationGraphWidget
r58 }
Alexandre Leroux
QCustomPlot notify the graph widget when the xRange changed
r227
Creation of VisualizationWidget, VizualizationTabWidget, VisualizationZoneWidget, VisualizationGraphWidget
r58 VisualizationGraphWidget::~VisualizationGraphWidget()
{
delete ui;
}
Add the visualization gui classes
r118
Integrates the drag&drop classes into the existing visualization classes.
r839 VisualizationZoneWidget *VisualizationGraphWidget::parentZoneWidget() const noexcept
{
auto parent = parentWidget();
Fixes for review
r846 while (parent != nullptr && !qobject_cast<VisualizationZoneWidget *>(parent)) {
Integrates the drag&drop classes into the existing visualization classes.
r839 parent = parent->parentWidget();
Fixes for review
r846 }
Integrates the drag&drop classes into the existing visualization classes.
r839
Format changes
r844 return qobject_cast<VisualizationZoneWidget *>(parent);
Integrates the drag&drop classes into the existing visualization classes.
r839 }
multi selection of zones
r1049 VisualizationWidget *VisualizationGraphWidget::parentVisualizationWidget() const
{
auto parent = parentWidget();
while (parent != nullptr && !qobject_cast<VisualizationWidget *>(parent)) {
parent = parent->parentWidget();
}
return qobject_cast<VisualizationWidget *>(parent);
}
Alexandre Leroux
Corrects the problem of refreshing synchronized graphs from TimeWidget (1)...
r1271 void VisualizationGraphWidget::setFlags(GraphFlags flags)
Add synchronization that keep delta
r444 {
Alexandre Leroux
Corrects the problem of refreshing synchronized graphs from TimeWidget (1)...
r1271 impl->m_Flags = std::move(flags);
Add synchronization that keep delta
r444 }
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 void VisualizationGraphWidget::addVariable(std::shared_ptr<Variable> variable, DateTimeRange range)
Add the visualization gui classes
r118 {
Alexandre Leroux
Calls the update of the graph's units and range data of a variable have been loaded...
r1284 // Uses delegate to create the qcpplot components according to the variable
auto createdPlottables = VisualizationGraphHelper::create(variable, *ui->widget);
// Sets graph properties
impl->m_RenderingDelegate->setGraphProperties(*variable, createdPlottables);
variable time is now set to range graphe displayed when it is displayed...
r314
Alexandre Leroux
Calls the update of the graph's units and range data of a variable have been loaded...
r1284 impl->m_VariableToPlotMultiMap.insert({variable, std::move(createdPlottables)});
// If the variable already has its data loaded, load its units and its range in the graph
if (variable->dataSeries() != nullptr) {
Removed old IDataProvider IF, some small steps toward new VC integration...
r1351 impl->m_RenderingDelegate->setAxesUnits(*variable);
this->setFlags(GraphFlag::DisableAll);
setGraphRange(range);
this->setFlags(GraphFlag::EnableAll);
Alexandre Leroux
Calls the update of the graph's units and range data of a variable have been loaded...
r1284 }
[WIP] new generic WS plugin and few other fixes...
r1352 //@TODO this is bad! when variable is moved to another graph it still fires
// even if this has been deleted
connect(variable.get(),&Variable::updated,this, &VisualizationGraphWidget::variableUpdated);
Removed old IDataProvider IF, some small steps toward new VC integration...
r1351 this->onUpdateVarDisplaying(variable,range);//My bullshit
Initialisation of the graph range at creation in a new graphe, or inside...
r548 emit variableAdded(variable);
variable time is now set to range graphe displayed when it is displayed...
r314 }
Alexandre Leroux
Remove variable from graph (2)...
r270 void VisualizationGraphWidget::removeVariable(std::shared_ptr<Variable> variable) noexcept
{
Alexandre Leroux
Remove variable from graph (3)...
r271 // Each component associated to the variable :
// - is removed from qcpplot (which deletes it)
// - is no longer referenced in the map
Alexandre Leroux
Handles QCustomPlot plottables for vectors (2)...
r582 auto variableIt = impl->m_VariableToPlotMultiMap.find(variable);
if (variableIt != impl->m_VariableToPlotMultiMap.cend()) {
Alexandre Leroux
Handles desynchronisation when removing variable from a graph (1)...
r737 emit variableAboutToBeRemoved(variable);
Alexandre Leroux
Handles QCustomPlot plottables for vectors (2)...
r582 auto &plottablesMap = variableIt->second;
for (auto plottableIt = plottablesMap.cbegin(), plottableEnd = plottablesMap.cend();
plottableIt != plottableEnd;) {
ui->widget->removePlottable(plottableIt->second);
plottableIt = plottablesMap.erase(plottableIt);
}
impl->m_VariableToPlotMultiMap.erase(variableIt);
Alexandre Leroux
Remove variable from graph (3)...
r271 }
// Updates graph
ui->widget->replot();
Alexandre Leroux
Remove variable from graph (2)...
r270 }
All the codebase is modified to build with new Variable Controller...
r1348 std::vector<std::shared_ptr<Variable> > VisualizationGraphWidget::variables() const
Integrates the drag&drop classes into the existing visualization classes.
r839 {
All the codebase is modified to build with new Variable Controller...
r1348 auto variables = std::vector<std::shared_ptr<Variable> >{};
Format changes
r844 for (auto it = std::cbegin(impl->m_VariableToPlotMultiMap);
it != std::cend(impl->m_VariableToPlotMultiMap); ++it) {
All the codebase is modified to build with new Variable Controller...
r1348 variables.push_back (it->first);
Integrates the drag&drop classes into the existing visualization classes.
r839 }
return variables;
}
Alexandre Leroux
Refactors VisualizationGraphWidget::setYRange()...
r900 void VisualizationGraphWidget::setYRange(std::shared_ptr<Variable> variable)
Initialisation of the graph range at creation in a new graphe, or inside...
r548 {
Alexandre Leroux
Refactors VisualizationGraphWidget::setYRange()...
r900 if (!variable) {
qCCritical(LOG_VisualizationGraphWidget()) << "Can't set y-axis range: variable is null";
return;
}
VisualizationGraphHelper::setYAxisRange(variable, *ui->widget);
Initialisation of the graph range at creation in a new graphe, or inside...
r548 }
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 DateTimeRange VisualizationGraphWidget::graphRange() const noexcept
Add synchronization that keep delta
r444 {
change grapheRange to graphRange
r545 auto graphRange = ui->widget->xAxis->range();
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 return DateTimeRange{graphRange.lower, graphRange.upper};
Add synchronization that keep delta
r444 }
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 void VisualizationGraphWidget::setGraphRange(const DateTimeRange &range, bool calibration)
Add synchronization that keep delta
r444 {
Remove old graph from selected zones
r1291 if (calibration) {
impl->m_IsCalibration = true;
}
Add synchronization that keep delta
r444 ui->widget->xAxis->setRange(range.m_TStart, range.m_TEnd);
ui->widget->replot();
Remove old graph from selected zones
r1291
if (calibration) {
impl->m_IsCalibration = false;
}
Add implementation for the range rescale. Variable is ignored here...
r438 }
refactoring + fix created graph range
r1292 void VisualizationGraphWidget::setAutoRangeOnVariableInitialization(bool value)
{
impl->m_VariableAutoRangeOnInit = value;
}
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 QVector<DateTimeRange> VisualizationGraphWidget::selectionZoneRanges() const
Keep the selection zones when a graph is dropped in another synchro zone
r1048 {
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 QVector<DateTimeRange> ranges;
Keep the selection zones when a graph is dropped in another synchro zone
r1048 for (auto zone : impl->m_SelectionZones) {
ranges << zone->range();
}
return ranges;
}
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 void VisualizationGraphWidget::addSelectionZones(const QVector<DateTimeRange> &ranges)
Keep the selection zones when a graph is dropped in another synchro zone
r1048 {
for (const auto &range : ranges) {
multi selection of zones
r1049 // note: ownership is transfered to QCustomPlot
Keep the selection zones when a graph is dropped in another synchro zone
r1048 auto zone = new VisualizationSelectionZoneItem(&plot());
zone->setRange(range.m_TStart, range.m_TEnd);
multi selection of zones
r1049 impl->addSelectionZone(zone);
Keep the selection zones when a graph is dropped in another synchro zone
r1048 }
plot().replot(QCustomPlot::rpQueuedReplot);
}
Link between selection zone item and event
r1293 VisualizationSelectionZoneItem *VisualizationGraphWidget::addSelectionZone(const QString &name,
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 const DateTimeRange &range)
Link between selection zone item and event
r1293 {
// note: ownership is transfered to QCustomPlot
auto zone = new VisualizationSelectionZoneItem(&plot());
zone->setName(name);
zone->setRange(range.m_TStart, range.m_TEnd);
impl->addSelectionZone(zone);
plot().replot(QCustomPlot::rpQueuedReplot);
return zone;
}
Action "Remove Selected Zones"
r1079 void VisualizationGraphWidget::removeSelectionZone(VisualizationSelectionZoneItem *selectionZone)
{
Add action to remove the selected zone with the "del" buttons
r1082 parentVisualizationWidget()->selectionZoneManager().setSelected(selectionZone, false);
if (impl->m_HoveredZone == selectionZone) {
impl->m_HoveredZone = nullptr;
setCursor(Qt::ArrowCursor);
}
Action "Remove Selected Zones"
r1079 impl->m_SelectionZones.removeAll(selectionZone);
plot().removeItem(selectionZone);
plot().replot(QCustomPlot::rpQueuedReplot);
}
Undo zoom box action
r1046 void VisualizationGraphWidget::undoZoom()
{
auto zoom = impl->m_ZoomStack.pop();
auto axisX = plot().axisRect()->axis(QCPAxis::atBottom);
auto axisY = plot().axisRect()->axis(QCPAxis::atLeft);
axisX->setRange(zoom.first);
axisY->setRange(zoom.second);
plot().replot(QCustomPlot::rpQueuedReplot);
}
Alexandre Leroux
Updates visitor interface...
r207 void VisualizationGraphWidget::accept(IVisualizationWidgetVisitor *visitor)
Add the visualization gui classes
r118 {
Alexandre Leroux
Implements accept() method of visualization widgets
r208 if (visitor) {
visitor->visit(this);
}
Alexandre Leroux
Adds logs for null visitors
r219 else {
qCCritical(LOG_VisualizationGraphWidget())
<< tr("Can't visit widget : the visitor is null");
}
Add the visualization gui classes
r118 }
Alexandre Leroux
Creates a interface that defines a variable container...
r209 bool VisualizationGraphWidget::canDrop(const Variable &variable) const
{
Alexandre Leroux
Prohibits the display of a spectrogram in an existing graph and the display of data on a graph already containing a spectrogram
r1022 auto isSpectrogram = [](const auto &variable) {
return std::dynamic_pointer_cast<SpectrogramSeries>(variable.dataSeries()) != nullptr;
};
// - A spectrogram series can't be dropped on graph with existing plottables
// - No data series can be dropped on graph with existing spectrogram series
return isSpectrogram(variable)
? impl->m_VariableToPlotMultiMap.empty()
: std::none_of(
impl->m_VariableToPlotMultiMap.cbegin(), impl->m_VariableToPlotMultiMap.cend(),
[isSpectrogram](const auto &entry) { return isSpectrogram(*entry.first); });
Alexandre Leroux
Creates a interface that defines a variable container...
r209 }
Alexandre Leroux
Unplot menu (5): adds contains() method to an IVariableContainer...
r327 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
r119 QString VisualizationGraphWidget::name() const
Add the visualization gui classes
r118 {
Alexandre Leroux
Removes title and close button from graph widget...
r724 return impl->m_Name;
Add the visualization gui classes
r118 }
drag of selection zones
r1047 QMimeData *VisualizationGraphWidget::mimeData(const QPoint &position) const
Integrates the drag&drop classes into the existing visualization classes.
r839 {
Fixes for review
r846 auto mimeData = new QMimeData;
Integrates the drag&drop classes into the existing visualization classes.
r839
drag of selection zones
r1047 auto selectionZoneItemUnderCursor = impl->selectionZoneAt(position, plot());
if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones
&& selectionZoneItemUnderCursor) {
mimeData->setData(MIME_TYPE_TIME_RANGE, TimeController::mimeDataForTimeRange(
selectionZoneItemUnderCursor->range()));
mimeData->setData(MIME_TYPE_SELECTION_ZONE, TimeController::mimeDataForTimeRange(
selectionZoneItemUnderCursor->range()));
}
else {
mimeData->setData(MIME_TYPE_GRAPH, QByteArray{});
auto timeRangeData = TimeController::mimeDataForTimeRange(graphRange());
mimeData->setData(MIME_TYPE_TIME_RANGE, timeRangeData);
}
Drop of variable, graph and zones on the time widget
r878
Format changes
r844 return mimeData;
Integrates the drag&drop classes into the existing visualization classes.
r839 }
drag of selection zones
r1047 QPixmap VisualizationGraphWidget::customDragPixmap(const QPoint &dragPosition)
{
auto selectionZoneItemUnderCursor = impl->selectionZoneAt(dragPosition, plot());
if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones
&& selectionZoneItemUnderCursor) {
auto zoneTopLeft = selectionZoneItemUnderCursor->topLeft->pixelPosition();
auto zoneBottomRight = selectionZoneItemUnderCursor->bottomRight->pixelPosition();
auto zoneSize = QSizeF{qAbs(zoneBottomRight.x() - zoneTopLeft.x()),
qAbs(zoneBottomRight.y() - zoneTopLeft.y())}
.toSize();
auto pixmap = QPixmap(zoneSize);
render(&pixmap, QPoint(), QRegion{QRect{zoneTopLeft.toPoint(), zoneSize}});
return pixmap;
}
return QPixmap();
}
Integrates the drag&drop classes into the existing visualization classes.
r839 bool VisualizationGraphWidget::isDragAllowed() const
{
return true;
}
Improves visual effect of dropping a variable in a graph
r873 void VisualizationGraphWidget::highlightForMerge(bool highlighted)
{
if (highlighted) {
plot().setBackground(QBrush(QColor("#BBD5EE")));
}
else {
plot().setBackground(QBrush(Qt::white));
}
plot().update();
}
Implements cursor mode
r960 void VisualizationGraphWidget::addVerticalCursor(double time)
{
impl->m_VerticalCursor->setPosition(time);
impl->m_VerticalCursor->setVisible(true);
auto text
= DateUtils::dateTime(time).toString(CURSOR_LABELS_DATETIME_FORMAT).replace(' ', '\n');
impl->m_VerticalCursor->setLabelText(text);
}
void VisualizationGraphWidget::addVerticalCursorAtViewportPosition(double position)
{
impl->m_VerticalCursor->setAbsolutePosition(position);
impl->m_VerticalCursor->setVisible(true);
auto axis = plot().axisRect()->axis(QCPAxis::atBottom);
auto text
= DateUtils::dateTime(axis->pixelToCoord(position)).toString(CURSOR_LABELS_DATETIME_FORMAT);
impl->m_VerticalCursor->setLabelText(text);
}
void VisualizationGraphWidget::removeVerticalCursor()
{
impl->m_VerticalCursor->setVisible(false);
plot().replot(QCustomPlot::rpQueuedReplot);
}
void VisualizationGraphWidget::addHorizontalCursor(double value)
{
impl->m_HorizontalCursor->setPosition(value);
impl->m_HorizontalCursor->setVisible(true);
impl->m_HorizontalCursor->setLabelText(QString::number(value));
}
void VisualizationGraphWidget::addHorizontalCursorAtViewportPosition(double position)
{
impl->m_HorizontalCursor->setAbsolutePosition(position);
impl->m_HorizontalCursor->setVisible(true);
auto axis = plot().axisRect()->axis(QCPAxis::atLeft);
impl->m_HorizontalCursor->setLabelText(QString::number(axis->pixelToCoord(position)));
}
void VisualizationGraphWidget::removeHorizontalCursor()
{
impl->m_HorizontalCursor->setVisible(false);
plot().replot(QCustomPlot::rpQueuedReplot);
}
Alexandre Leroux
Handles desynchronisation when removing variable from a graph (2)...
r738 void VisualizationGraphWidget::closeEvent(QCloseEvent *event)
{
Q_UNUSED(event);
Fix a bug with event edition from visu after a graph is closed
r1324 for (auto i : impl->m_SelectionZones) {
parentVisualizationWidget()->selectionZoneManager().setSelected(i, false);
}
Alexandre Leroux
Handles desynchronisation when removing variable from a graph (2)...
r738 // Prevents that all variables will be removed from graph when it will be closed
for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
emit variableAboutToBeRemoved(variableEntry.first);
}
}
Alexandre Leroux
Shows/hides plot overlay when entering/leaving graph
r728 void VisualizationGraphWidget::enterEvent(QEvent *event)
{
Q_UNUSED(event);
impl->m_RenderingDelegate->showGraphOverlay(true);
}
void VisualizationGraphWidget::leaveEvent(QEvent *event)
{
Q_UNUSED(event);
impl->m_RenderingDelegate->showGraphOverlay(false);
Implements cursor mode
r960
if (auto parentZone = parentZoneWidget()) {
parentZone->notifyMouseLeaveGraph(this);
}
else {
qCWarning(LOG_VisualizationGraphWidget()) << "leaveEvent: No parent zone widget";
}
Display of selection zones on a graph
r1044
if (impl->m_HoveredZone) {
impl->m_HoveredZone->setHovered(false);
impl->m_HoveredZone = nullptr;
}
Alexandre Leroux
Shows/hides plot overlay when entering/leaving graph
r728 }
drag of selection zones
r1047 QCustomPlot &VisualizationGraphWidget::plot() const noexcept
Alexandre Leroux
Passes directly GraphWidget in delegate...
r725 {
return *ui->widget;
}
Alexandre Leroux
Remove variable from graph (1)...
r269 void VisualizationGraphWidget::onGraphMenuRequested(const QPoint &pos) noexcept
Add the visualization gui classes
r118 {
Alexandre Leroux
Remove variable from graph (1)...
r269 QMenu graphMenu{};
Alexandre Leroux
Remove variable from graph (2)...
r270 // 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...
r196 }
Alexandre Leroux
Remove variable from graph (1)...
r269
Undo zoom box action
r1046 if (!impl->m_ZoomStack.isEmpty()) {
if (!graphMenu.isEmpty()) {
graphMenu.addSeparator();
}
graphMenu.addAction(tr("Undo Zoom"), [this]() { undoZoom(); });
}
Put the align actions in sub menus
r1083 // Selection Zone Actions
Adds selection zone actions in the context menu
r1077 auto selectionZoneItem = impl->selectionZoneAt(pos, plot());
if (selectionZoneItem) {
auto selectedItems = parentVisualizationWidget()->selectionZoneManager().selectedItems();
Alignment actions for zone selections
r1081 selectedItems.removeAll(selectionZoneItem);
selectedItems.prepend(selectionZoneItem); // Put the current selection zone first
Adds selection zone actions in the context menu
r1077 auto zoneActions = sqpApp->actionsGuiController().selectionZoneActions();
if (!zoneActions.isEmpty() && !graphMenu.isEmpty()) {
graphMenu.addSeparator();
}
Put the align actions in sub menus
r1083 QHash<QString, QMenu *> subMenus;
QHash<QString, bool> subMenusEnabled;
LineEdit to filter the create catalogue menu
r1328 QHash<QString, FilteringAction *> filteredMenu;
Put the align actions in sub menus
r1083
Adds selection zone actions in the context menu
r1077 for (auto zoneAction : zoneActions) {
Put the align actions in sub menus
r1083
auto isEnabled = zoneAction->isEnabled(selectedItems);
auto menu = &graphMenu;
LineEdit to filter the create catalogue menu
r1328 QString menuPath;
Put the align actions in sub menus
r1083 for (auto subMenuName : zoneAction->subMenuList()) {
LineEdit to filter the create catalogue menu
r1328 menuPath += '/';
menuPath += subMenuName;
if (!subMenus.contains(menuPath)) {
Put the align actions in sub menus
r1083 menu = menu->addMenu(subMenuName);
LineEdit to filter the create catalogue menu
r1328 subMenus[menuPath] = menu;
subMenusEnabled[menuPath] = isEnabled;
Put the align actions in sub menus
r1083 }
else {
LineEdit to filter the create catalogue menu
r1328 menu = subMenus.value(menuPath);
Put the align actions in sub menus
r1083 if (isEnabled) {
// The sub menu is enabled if at least one of its actions is enabled
LineEdit to filter the create catalogue menu
r1328 subMenusEnabled[menuPath] = true;
Put the align actions in sub menus
r1083 }
}
}
LineEdit to filter the create catalogue menu
r1328 FilteringAction *filterAction = nullptr;
if (sqpApp->actionsGuiController().isMenuFiltered(zoneAction->subMenuList())) {
filterAction = filteredMenu.value(menuPath);
if (!filterAction) {
filterAction = new FilteringAction{this};
filteredMenu[menuPath] = filterAction;
menu->addAction(filterAction);
}
}
Put the align actions in sub menus
r1083 auto action = menu->addAction(zoneAction->name());
action->setEnabled(isEnabled);
Add action to remove the selected zone with the "del" buttons
r1082 action->setShortcut(zoneAction->displayedShortcut());
Alignment actions for zone selections
r1081 QObject::connect(action, &QAction::triggered,
[zoneAction, selectedItems]() { zoneAction->execute(selectedItems); });
LineEdit to filter the create catalogue menu
r1328
if (filterAction && zoneAction->isFilteringAllowed()) {
filterAction->addActionToFilter(action);
}
Adds selection zone actions in the context menu
r1077 }
Put the align actions in sub menus
r1083
for (auto it = subMenus.cbegin(); it != subMenus.cend(); ++it) {
it.value()->setEnabled(subMenusEnabled[it.key()]);
}
Adds selection zone actions in the context menu
r1077 }
Alexandre Leroux
Remove variable from graph (1)...
r269 if (!graphMenu.isEmpty()) {
Alexandre Leroux
Fixed menus position
r655 graphMenu.exec(QCursor::pos());
Alexandre Leroux
Adds name to a graph...
r196 }
Add the visualization gui classes
r118 }
Alexandre Leroux
Handles key modifiers for zoom...
r179
Add synchronization that keep delta
r444 void VisualizationGraphWidget::onRangeChanged(const QCPRange &t1, const QCPRange &t2)
Alexandre Leroux
QCustomPlot notify the graph widget when the xRange changed
r227 {
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 auto graphRange = DateTimeRange{t1.lower, t1.upper};
auto oldGraphRange = DateTimeRange{t2.lower, t2.upper};
The mock plugin can now create data with view operation
r235
Alexandre Leroux
Corrects the problem of refreshing synchronized graphs from TimeWidget (1)...
r1271 if (impl->m_Flags.testFlag(GraphFlag::EnableAcquisition)) {
Implementation of V5 acquisition
r539 for (auto it = impl->m_VariableToPlotMultiMap.begin(),
end = impl->m_VariableToPlotMultiMap.end();
it != end; it = impl->m_VariableToPlotMultiMap.upper_bound(it->first)) {
Removed old IDataProvider IF, some small steps toward new VC integration...
r1351 sqpApp->variableController().asyncChangeRange(it->first, graphRange);
The mock plugin can now create data with view operation
r235 }
Alexandre Leroux
Corrects the problem of refreshing synchronized graphs from TimeWidget (2)...
r1272 }
Implementation of V5 acquisition
r539
Removed old IDataProvider IF, some small steps toward new VC integration...
r1351 if (impl->m_Flags.testFlag(GraphFlag::EnableSynchronization) && !impl->m_IsCalibration)
{
Alexandre Leroux
Corrects the problem of refreshing synchronized graphs from TimeWidget (2)...
r1272 emit synchronize(graphRange, oldGraphRange);
Alexandre Leroux
QCustomPlot notify the graph widget when the xRange changed
r227 }
Implements cursor mode
r960
auto pos = mapFromGlobal(QCursor::pos());
auto axisPos = impl->posToAxisPos(pos, plot());
if (auto parentZone = parentZoneWidget()) {
if (impl->pointIsInAxisRect(axisPos, plot())) {
parentZone->notifyMouseMoveInGraph(pos, axisPos, this);
}
else {
parentZone->notifyMouseLeaveGraph(this);
}
}
Alexandre Leroux
Corrects the problem of refreshing synchronized graphs from TimeWidget (2)...
r1272
// Quits calibration
impl->m_IsCalibration = false;
Alexandre Leroux
QCustomPlot notify the graph widget when the xRange changed
r227 }
Alexandre Leroux
Handles double click on color scale...
r1002 void VisualizationGraphWidget::onMouseDoubleClick(QMouseEvent *event) noexcept
{
impl->m_RenderingDelegate->onMouseDoubleClick(event);
}
Alexandre Leroux
Creates method that will display a tooltip and a tracer with data point information after a while
r481 void VisualizationGraphWidget::onMouseMove(QMouseEvent *event) noexcept
{
// Handles plot rendering when mouse is moving
impl->m_RenderingDelegate->onMouseMove(event);
Integrates the drag&drop classes into the existing visualization classes.
r839
Implements cursor mode
r960 auto axisPos = impl->posToAxisPos(event->pos(), plot());
Display of selection zones on a graph
r1044 // Zoom box and zone drawing
if (impl->m_DrawingZoomRect) {
impl->m_DrawingZoomRect->bottomRight->setCoords(axisPos);
}
else if (impl->m_DrawingZone) {
impl->m_DrawingZone->setEnd(axisPos.x());
Implements zoom box interaction mode
r959 }
Display of selection zones on a graph
r1044 // Cursor
Implements cursor mode
r960 if (auto parentZone = parentZoneWidget()) {
if (impl->pointIsInAxisRect(axisPos, plot())) {
parentZone->notifyMouseMoveInGraph(event->pos(), axisPos, this);
}
else {
parentZone->notifyMouseLeaveGraph(this);
}
}
Display of selection zones on a graph
r1044 // Search for the selection zone under the mouse
drag of selection zones
r1047 auto selectionZoneItemUnderCursor = impl->selectionZoneAt(event->pos(), plot());
Display of selection zones on a graph
r1044 if (selectionZoneItemUnderCursor && !impl->m_DrawingZone
&& sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones) {
// Sets the appropriate cursor shape
auto cursorShape = selectionZoneItemUnderCursor->curshorShapeForPosition(event->pos());
setCursor(cursorShape);
// Manages the hovered zone
if (selectionZoneItemUnderCursor != impl->m_HoveredZone) {
if (impl->m_HoveredZone) {
impl->m_HoveredZone->setHovered(false);
}
selectionZoneItemUnderCursor->setHovered(true);
impl->m_HoveredZone = selectionZoneItemUnderCursor;
plot().replot(QCustomPlot::rpQueuedReplot);
}
}
else {
// There is no zone under the mouse or the interaction mode is not "selection zones"
if (impl->m_HoveredZone) {
impl->m_HoveredZone->setHovered(false);
impl->m_HoveredZone = nullptr;
}
setCursor(Qt::ArrowCursor);
}
Resize and move of multiple zones together
r1050 impl->m_HasMovedMouse = true;
Integrates the drag&drop classes into the existing visualization classes.
r839 VisualizationDragWidget::mouseMoveEvent(event);
Alexandre Leroux
Creates method that will display a tooltip and a tracer with data point information after a while
r481 }
Alexandre Leroux
Handles key modifiers for zoom...
r179 void VisualizationGraphWidget::onMouseWheel(QWheelEvent *event) noexcept
{
Alexandre Leroux
Fix the problem of calling the zoom at wheel event on the color scale
r1330 // Processes event only if the wheel occurs on axis rect
if (!dynamic_cast<QCPAxisRect *>(ui->widget->layoutElementAt(event->posF()))) {
return;
}
Basic mouse wheel interactions + mode drag
r958 auto value = event->angleDelta().x() + event->angleDelta().y();
if (value != 0) {
auto direction = value > 0 ? 1.0 : -1.0;
auto isZoomX = event->modifiers().testFlag(HORIZONTAL_ZOOM_MODIFIER);
auto isZoomY = event->modifiers().testFlag(VERTICAL_ZOOM_MODIFIER);
impl->m_IsCalibration = event->modifiers().testFlag(VERTICAL_PAN_MODIFIER);
auto zoomOrientations = QFlags<Qt::Orientation>{};
zoomOrientations.setFlag(Qt::Horizontal, isZoomX);
zoomOrientations.setFlag(Qt::Vertical, isZoomY);
ui->widget->axisRect()->setRangeZoom(zoomOrientations);
Alexandre Leroux
Handles key modifiers for zoom...
r179
Basic mouse wheel interactions + mode drag
r958 if (!isZoomX && !isZoomY) {
auto axis = plot().axisRect()->axis(QCPAxis::atBottom);
auto diff = direction * (axis->range().size() * (PAN_SPEED / 100.0));
Alexandre Leroux
Handles key modifiers for zoom...
r179
Basic mouse wheel interactions + mode drag
r958 axis->setRange(axis->range() + diff);
if (plot().noAntialiasingOnDrag()) {
plot().setNotAntialiasedElements(QCP::aeAll);
}
Removed old IDataProvider IF, some small steps toward new VC integration...
r1351 //plot().replot(QCustomPlot::rpQueuedReplot);
Basic mouse wheel interactions + mode drag
r958 }
}
Alexandre Leroux
Handles key modifiers for zoom...
r179 }
The mock plugin can now create data with view operation
r235
Implementation of the calibration for the synchronization...
r445 void VisualizationGraphWidget::onMousePress(QMouseEvent *event) noexcept
{
Thibaud Rabillard
Fix interractions for mac
r1052 auto isDragDropClick = event->modifiers().testFlag(DRAG_DROP_MODIFIER);
multi selection of zones
r1049 auto isSelectionZoneMode
= sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones;
Thibaud Rabillard
Fix interractions for mac
r1052 auto isLeftClick = event->buttons().testFlag(Qt::LeftButton);
drag of selection zones
r1047
Thibaud Rabillard
Fix interractions for mac
r1052 if (!isDragDropClick && isLeftClick) {
drag of selection zones
r1047 if (sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::ZoomBox) {
// Starts a zoom box
impl->startDrawingRect(event->pos(), plot());
}
multi selection of zones
r1049 else if (isSelectionZoneMode && impl->m_DrawingZone == nullptr) {
drag of selection zones
r1047 // Starts a new selection zone
auto zoneAtPos = impl->selectionZoneAt(event->pos(), plot());
if (!zoneAtPos) {
multi selection of zones
r1049 impl->startDrawingZone(event->pos(), this);
drag of selection zones
r1047 }
Display of selection zones on a graph
r1044 }
}
// Allows mouse panning only in default mode
plot().setInteraction(QCP::iRangeDrag, sqpApp->plotsInteractionMode()
drag of selection zones
r1047 == SqpApplication::PlotsInteractionMode::None
&& !isDragDropClick);
Display of selection zones on a graph
r1044
multi selection of zones
r1049 // Allows zone edition only in selection zone mode without drag&drop
impl->setSelectionZonesEditionEnabled(isSelectionZoneMode && !isDragDropClick);
Improves display of selected zones
r1051 // Selection / Deselection
multi selection of zones
r1049 if (isSelectionZoneMode) {
auto isMultiSelectionClick = event->modifiers().testFlag(MULTI_ZONE_SELECTION_MODIFIER);
auto selectionZoneItemUnderCursor = impl->selectionZoneAt(event->pos(), plot());
Multi selection improvements
r1084
if (selectionZoneItemUnderCursor && !selectionZoneItemUnderCursor->selected()
&& !isMultiSelectionClick) {
parentVisualizationWidget()->selectionZoneManager().select(
{selectionZoneItemUnderCursor});
multi selection of zones
r1049 }
Multi selection improvements
r1084 else if (!selectionZoneItemUnderCursor && !isMultiSelectionClick && isLeftClick) {
multi selection of zones
r1049 parentVisualizationWidget()->selectionZoneManager().clearSelection();
}
else {
// No selection change
}
Multi selection improvements
r1084
if (selectionZoneItemUnderCursor && isLeftClick) {
selectionZoneItemUnderCursor->setAssociatedEditedZones(
parentVisualizationWidget()->selectionZoneManager().selectedItems());
}
multi selection of zones
r1049 }
Integrates the drag&drop classes into the existing visualization classes.
r839
Resize and move of multiple zones together
r1050
impl->m_HasMovedMouse = false;
Integrates the drag&drop classes into the existing visualization classes.
r839 VisualizationDragWidget::mousePressEvent(event);
Implementation of the calibration for the synchronization...
r445 }
void VisualizationGraphWidget::onMouseRelease(QMouseEvent *event) noexcept
{
Display of selection zones on a graph
r1044 if (impl->m_DrawingZoomRect) {
Implements zoom box interaction mode
r959
auto axisX = plot().axisRect()->axis(QCPAxis::atBottom);
auto axisY = plot().axisRect()->axis(QCPAxis::atLeft);
Display of selection zones on a graph
r1044 auto newAxisXRange = QCPRange{impl->m_DrawingZoomRect->topLeft->coords().x(),
impl->m_DrawingZoomRect->bottomRight->coords().x()};
Implements zoom box interaction mode
r959
Display of selection zones on a graph
r1044 auto newAxisYRange = QCPRange{impl->m_DrawingZoomRect->topLeft->coords().y(),
impl->m_DrawingZoomRect->bottomRight->coords().y()};
Implements zoom box interaction mode
r959
impl->removeDrawingRect(plot());
if (newAxisXRange.size() > axisX->range().size() * (ZOOM_BOX_MIN_SIZE / 100.0)
&& newAxisYRange.size() > axisY->range().size() * (ZOOM_BOX_MIN_SIZE / 100.0)) {
Undo zoom box action
r1046 impl->m_ZoomStack.push(qMakePair(axisX->range(), axisY->range()));
Implements zoom box interaction mode
r959 axisX->setRange(newAxisXRange);
axisY->setRange(newAxisYRange);
plot().replot(QCustomPlot::rpQueuedReplot);
}
}
multi selection of zones
r1049 impl->endDrawingZone(this);
Display of selection zones on a graph
r1044
Resize and move of multiple zones together
r1050 // Selection / Deselection
auto isSelectionZoneMode
= sqpApp->plotsInteractionMode() == SqpApplication::PlotsInteractionMode::SelectionZones;
if (isSelectionZoneMode) {
auto isMultiSelectionClick = event->modifiers().testFlag(MULTI_ZONE_SELECTION_MODIFIER);
auto selectionZoneItemUnderCursor = impl->selectionZoneAt(event->pos(), plot());
Selection of stacked zone via a dialog box
r1085 if (selectionZoneItemUnderCursor && event->button() == Qt::LeftButton
&& !impl->m_HasMovedMouse) {
auto zonesUnderCursor = impl->selectionZonesAt(event->pos(), plot());
if (zonesUnderCursor.count() > 1) {
// There are multiple zones under the mouse.
// Performs the selection with a selection dialog.
VisualizationMultiZoneSelectionDialog dialog{this};
dialog.setZones(zonesUnderCursor);
dialog.move(mapToGlobal(event->pos() - QPoint(dialog.width() / 2, 20)));
dialog.activateWindow();
dialog.raise();
if (dialog.exec() == QDialog::Accepted) {
auto selection = dialog.selectedZones();
if (!isMultiSelectionClick) {
parentVisualizationWidget()->selectionZoneManager().clearSelection();
}
for (auto it = selection.cbegin(); it != selection.cend(); ++it) {
auto zone = it.key();
auto isSelected = it.value();
parentVisualizationWidget()->selectionZoneManager().setSelected(zone,
isSelected);
if (isSelected) {
// Puts the zone on top of the stack so it can be moved or resized
impl->moveSelectionZoneOnTop(zone, plot());
}
}
}
Resize and move of multiple zones together
r1050 }
Selection of stacked zone via a dialog box
r1085 else {
if (!isMultiSelectionClick) {
parentVisualizationWidget()->selectionZoneManager().select(
{selectionZoneItemUnderCursor});
impl->moveSelectionZoneOnTop(selectionZoneItemUnderCursor, plot());
}
else {
parentVisualizationWidget()->selectionZoneManager().setSelected(
selectionZoneItemUnderCursor, !selectionZoneItemUnderCursor->selected()
|| event->button() == Qt::RightButton);
}
Resize and move of multiple zones together
r1050 }
}
else {
// No selection change
}
}
Implementation of the calibration for the synchronization...
r445 }
The mock plugin can now create data with view operation
r235 void VisualizationGraphWidget::onDataCacheVariableUpdated()
{
change grapheRange to graphRange
r545 auto graphRange = ui->widget->xAxis->range();
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 auto dateTime = DateTimeRange{graphRange.lower, graphRange.upper};
Implementation of the cache feature : download before display needs
r433
Alexandre Leroux
Handles QCustomPlot plottables for vectors (2)...
r582 for (auto &variableEntry : impl->m_VariableToPlotMultiMap) {
auto variable = variableEntry.first;
Downgrade dev log from info to debug
r441 qCDebug(LOG_VisualizationGraphWidget())
Implementation of V5 acquisition
r539 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated S" << variable->range();
Downgrade dev log from info to debug
r441 qCDebug(LOG_VisualizationGraphWidget())
Implementation of the cache feature : download before display needs
r433 << "TORM: VisualizationGraphWidget::onDataCacheVariableUpdated E" << dateTime;
Implementation of V5 acquisition
r539 if (dateTime.contains(variable->range()) || dateTime.intersect(variable->range())) {
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 impl->updateData(variableEntry.second, variable, variable->range());
Implementation of the cache feature : download before display needs
r433 }
The mock plugin can now create data with view operation
r235 }
}
add Skeleton for displaying data which are already in cache
r571
void VisualizationGraphWidget::onUpdateVarDisplaying(std::shared_ptr<Variable> variable,
Renamed SqpRange to DateTimeRange, introduced VariableController2 to...
r1346 const DateTimeRange &range)
add Skeleton for displaying data which are already in cache
r571 {
Alexandre Leroux
Handles QCustomPlot plottables for vectors (2)...
r582 auto it = impl->m_VariableToPlotMultiMap.find(variable);
if (it != impl->m_VariableToPlotMultiMap.end()) {
Alexandre Leroux
Updates VisualizationGraphHelper to use variable's type instead of dataseries
r1280 impl->updateData(it->second, variable, range);
add Skeleton for displaying data which are already in cache
r571 }
}
[WIP] new generic WS plugin and few other fixes...
r1352
void VisualizationGraphWidget::variableUpdated(QUuid id)
{
for(auto& [var,plotables]:impl->m_VariableToPlotMultiMap)
{
if(var->ID()==id)
{
impl->updateData(plotables,var,this->graphRange());
}
}
}