libpappsomspp
Library for mass spectrometry
pappso::BaseTracePlotWidget Class Reference

#include <basetraceplotwidget.h>

Inheritance diagram for pappso::BaseTracePlotWidget:
pappso::BasePlotWidget pappso::DriftSpecTracePlotWidget pappso::MassSpecTracePlotWidget pappso::TicXicChromTracePlotWidget

Public Member Functions

 BaseTracePlotWidget (QWidget *parent=0)
 
 BaseTracePlotWidget (QWidget *parent, const QString &x_axis_label, const QString &y_axis_label)
 
virtual ~BaseTracePlotWidget ()
 Destruct this BaseTracePlotWidget instance. More...
 
virtual void setGraphData (int graph_index, const std::vector< double > &keys, const std::vector< double > &values)
 
virtual void setGraphData (QCPGraph *graph_p, const std::vector< double > &keys, const std::vector< double > &values)
 
virtual void clearGraphData (int graph_index)
 
virtual void axisDoubleClickHandler (QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) override
 
virtual void axisRescale () override
 RANGE-related functions. More...
 
virtual void axisReframe () override
 
virtual void axisZoom () override
 
virtual void axisPan () override
 
virtual QCPGraph * addTrace (const pappso::Trace &trace, const QColor &color)
 
virtual bool findIntegrationLowerRangeForKey (int index, double key, QCPRange &range)
 Find a minimal integration range starting at an existing data point. More...
 
std::vector< double > getValuesX (int index) const
 
std::vector< double > getValuesY (int index) const
 
QCPRange getValueRangeOnKeyRange (QCPAbstractPlottable *plottable_p, bool &ok)
 
QCPRange getValueRangeOnKeyRange (int index, bool &ok)
 
double getYatX (double x, QCPGraph *graph_p)
 
double getYatX (double x, int index=0)
 
pappso::Trace toTrace (int index) const
 
pappso::Trace toTrace (const QCPGraph *graph_p) const
 
pappso::Trace toTrace (const QCPRange &x_axis_range, int index) const
 
pappso::Trace toTrace (const QCPRange &x_axis_range, const QCPGraph *graph_p) const
 
- Public Member Functions inherited from pappso::BasePlotWidget
 BasePlotWidget (QWidget *parent)
 
 BasePlotWidget (QWidget *parent, const QString &x_axis_label, const QString &y_axis_label)
 
virtual ~BasePlotWidget ()
 Destruct this BasePlotWidget instance. More...
 
virtual bool setupWidget ()
 
virtual void setPen (const QPen &pen)
 
virtual const QPen & getPen () const
 
virtual void setPlottingColor (QCPAbstractPlottable *plottable_p, const QColor &new_color)
 
virtual void setPlottingColor (int index, const QColor &new_color)
 
virtual QColor getPlottingColor (QCPAbstractPlottable *plottable_p) const
 
virtual QColor getPlottingColor (int index=0) const
 
virtual void setAxisLabelX (const QString &label)
 
virtual void setAxisLabelY (const QString &label)
 
virtual void resetAxesRangeHistory ()
 
virtual void updateAxesRangeHistory ()
 Create new axis range history items and append them to the history. More...
 
virtual void restorePreviousAxesRangeHistory ()
 Go up one history element in the axis history. More...
 
virtual void restoreAxesRangeHistory (std::size_t index)
 Get the axis histories at index index and update the plot ranges. More...
 
virtual void keyPressEvent (QKeyEvent *event)
 KEYBOARD-related EVENTS. More...
 
virtual void keyReleaseEvent (QKeyEvent *event)
 Handle specific key codes and trigger respective actions. More...
 
virtual void spaceKeyReleaseEvent (QKeyEvent *event)
 
virtual void directionKeyPressEvent (QKeyEvent *event)
 
virtual void directionKeyReleaseEvent (QKeyEvent *event)
 
virtual void mousePseudoButtonKeyPressEvent (QKeyEvent *event)
 
virtual void mousePseudoButtonKeyReleaseEvent (QKeyEvent *event)
 
virtual void mousePressHandler (QMouseEvent *event)
 KEYBOARD-related EVENTS. More...
 
virtual void mouseReleaseHandler (QMouseEvent *event)
 
virtual void mouseReleaseHandlerLeftButton ()
 
virtual void mouseReleaseHandlerRightButton ()
 
virtual void mouseWheelHandler (QWheelEvent *event)
 
virtual void mouseMoveHandler (QMouseEvent *event)
 KEYBOARD-related EVENTS. More...
 
virtual void mouseMoveHandlerNotDraggingCursor ()
 
virtual void mouseMoveHandlerDraggingCursor ()
 
virtual void mouseMoveHandlerLeftButtonDraggingCursor ()
 
virtual void mouseMoveHandlerRightButtonDraggingCursor ()
 
bool isClickOntoXAxis (const QPointF &mousePoint)
 
bool isClickOntoYAxis (const QPointF &mousePoint)
 
int dragDirection ()
 MOUSE-related EVENTS. More...
 
virtual void moveMouseCursorGraphCoordToGlobal (QPointF plot_coordinates)
 
virtual void moveMouseCursorPixelCoordToGlobal (QPointF local_coordinates)
 
virtual void horizontalMoveMouseCursorCountPixels (int pixel_count)
 
virtual QPointF horizontalGetGraphCoordNewPointCountPixels (int pixel_count)
 
virtual void verticalMoveMouseCursorCountPixels (int pixel_count)
 
virtual QPointF verticalGetGraphCoordNewPointCountPixels (int pixel_count)
 
virtual QCPRange getRangeX (bool &found_range, int index) const
 MOUSE MOVEMENTS mouse/keyboard-triggered. More...
 
virtual QCPRange getRangeY (bool &found_range, int index) const
 
QCPRange getRange (Axis axis, RangeType range_type, bool &found_range) const
 
virtual QCPRange getInnermostRangeX (bool &found_range) const
 
virtual QCPRange getOutermostRangeX (bool &found_range) const
 
virtual QCPRange getInnermostRangeY (bool &found_range) const
 
virtual QCPRange getOutermostRangeY (bool &found_range) const
 
void yMinMaxOnXAxisCurrentRange (double &min, double &max, QCPAbstractPlottable *plottable_p=nullptr)
 
void yMinMaxOnXAxisCurrentRange (double &min, double &max, int index)
 
virtual void replotWithAxesRanges (QCPRange xAxisRange, QCPRange yAxisRange, Axis axis)
 
virtual void replotWithAxisRangeX (double lower, double upper)
 
virtual void replotWithAxisRangeY (double lower, double upper)
 
virtual void hideAllPlotItems ()
 PLOTTING / REPLOTTING functions. More...
 
virtual void showTracers ()
 Show the traces (vertical and horizontal). More...
 
virtual void hideTracers ()
 Hide the traces (vertical and horizontal). More...
 
virtual void drawXDeltaFeatures ()
 
virtual void drawYDeltaFeatures ()
 
virtual void calculateDragDeltas ()
 
virtual bool isVerticalDisplacementAboveThreshold ()
 
virtual void drawSelectionRectangleAndPrepareZoom (bool as_line_segment=false, bool for_integration=false)
 
virtual void updateSelectionRectangle (bool as_line_segment=false, bool for_integration=false)
 
virtual void resetSelectionRectangle ()
 
virtual void hideSelectionRectangle (bool reset_values=false)
 
virtual bool isSelectionRectangleVisible ()
 
virtual PolygonType whatIsVisibleOfTheSelectionRectangle ()
 
virtual void setFocus ()
 PLOT ITEMS : TRACER TEXT ITEMS... More...
 
virtual void redrawPlotBackground (QWidget *focusedPlotWidget)
 Redraw the background of the focusedPlotWidget plot widget. More...
 
virtual void updateContextXandYAxisRanges ()
 
virtual const BasePlotContextgetContext () const
 

Additional Inherited Members

- Signals inherited from pappso::BasePlotWidget
void setFocusSignal ()
 
void lastCursorHoveredPointSignal (const QPointF &pointf)
 
void plotRangesChangedSignal (const BasePlotContext &context)
 
void xAxisMeasurementSignal (const BasePlotContext &context, bool with_delta)
 
void keyPressEventSignal (const BasePlotContext &context)
 
void keyReleaseEventSignal (const BasePlotContext &context)
 
void mouseReleaseEventSignal (const BasePlotContext &context)
 
void mouseWheelEventSignal (const BasePlotContext &context)
 
void plottableSelectionChangedSignal (QCPAbstractPlottable *plottable_p, bool selected)
 
void integrationRequestedSignal (const BasePlotContext &context)
 
void plottableDestructionRequestedSignal (BasePlotWidget *base_plot_widget_p, QCPAbstractPlottable *plottable_p, const BasePlotContext &context)
 
- Protected Member Functions inherited from pappso::BasePlotWidget
virtual void createAllAncillaryItems ()
 
virtual void update1DSelectionRectangle (bool for_integration=false)
 
virtual void update2DSelectionRectangleSquare (bool for_integration=false)
 
virtual void update2DSelectionRectangleSkewed (bool for_integration=false)
 
virtual QString allLayerNamesToString () const
 
virtual QString layerableLayerName (QCPLayerable *layerable_p) const
 
virtual int layerableLayerIndex (QCPLayerable *layerable_p) const
 
- Protected Attributes inherited from pappso::BasePlotWidget
QString m_name = "NOT_SET"
 Name of the plot widget. More...
 
QString m_desc = "NOT_SET"
 Description of the plot widget. More...
 
QString m_fileName
 The name of the data file from which the mass data were read. More...
 
QString m_axisLabelX
 
QString m_axisLabelY
 
BasePlotContext m_context
 
int m_leftMousePseudoButtonKey = Qt::Key_Less
 
int m_rightMousePseudoButtonKey = Qt::Key_Greater
 
QCPItemLine * mp_selectionRectangeLine1 = nullptr
 Rectangle defining the borders of zoomed-in/out data. More...
 
QCPItemLine * mp_selectionRectangeLine2 = nullptr
 
QCPItemLine * mp_selectionRectangeLine3 = nullptr
 
QCPItemLine * mp_selectionRectangeLine4 = nullptr
 
QCPItemText * mp_xDeltaTextItem = nullptr
 Text describing the x-axis delta value during a drag operation. More...
 
QCPItemText * mp_yDeltaTextItem = nullptr
 
bool m_shouldTracersBeVisible = true
 Tells if the tracers should be visible. More...
 
QCPItemLine * mp_hPosTracerItem = nullptr
 Horizontal position tracer. More...
 
QCPItemLine * mp_vPosTracerItem = nullptr
 Vertical position tracer. More...
 
QCPItemLine * mp_vStartTracerItem = nullptr
 Vertical selection start tracer (typically in green). More...
 
QCPItemLine * mp_vEndTracerItem = nullptr
 Vertical selection end tracer (typically in red). More...
 
std::size_t m_lastAxisRangeHistoryIndex = 0
 Index of the last axis range history item. More...
 
std::vector< QCPRange * > m_xAxisRangeHistory
 List of x axis ranges occurring during the panning zooming actions. More...
 
std::vector< QCPRange * > m_yAxisRangeHistory
 List of y axis ranges occurring during the panning zooming actions. More...
 
int m_mouseMoveHandlerSkipAmount = 10
 How many mouse move events must be skipped *‍/. More...
 
int m_mouseMoveHandlerSkipCount = 0
 Counter to handle the "fat data" mouse move event handling. More...
 
QColor m_unfocusedColor = QColor("lightgray")
 Color used for the background of unfocused plot. More...
 
QBrush m_unfocusedBrush = QBrush(m_unfocusedColor)
 Color used for the background of unfocused plot. More...
 
QColor m_focusedColor = QColor(Qt::transparent)
 Color used for the background of focused plot. More...
 
QBrush m_focusedBrush = QBrush(m_focusedColor)
 Color used for the background of focused plot. More...
 
QPen m_pen
 Pen used to draw the graph and textual elements in the plot widget. More...
 

Detailed Description

Definition at line 59 of file basetraceplotwidget.h.

Constructor & Destructor Documentation

◆ BaseTracePlotWidget() [1/2]

pappso::BaseTracePlotWidget::BaseTracePlotWidget ( QWidget *  parent = 0)
explicit

Definition at line 44 of file basetraceplotwidget.cpp.

45  : BasePlotWidget(parent)
46 {
47  // We can afford to call createAllAncillaryItems() in this derived class
48  // because all the items will have been created *before* the addition of plots
49  // and then the rendering order will hide them to the viewer, since the
50  // rendering order is according to the order in which the items have been
51  // created.
52  //
53  // The fact that the ancillary items are created before trace plots is not a
54  // problem because the trace plots are sparse and do not effectively hide the
55  // data.
56  //
57  // But, in the color map plot widgets, we cannot afford to create the
58  // ancillary items *before* the plot itself because then, the rendering of the
59  // plot (created after) would screen off the ancillary items (created before).
60  //
61  // So, the createAllAncillaryItems() function needs to be called in the
62  // derived classes at the most appropriate moment in the setting up of the
63  // widget.
65 }
virtual void createAllAncillaryItems()
BasePlotWidget(QWidget *parent)

References pappso::BasePlotWidget::createAllAncillaryItems().

◆ BaseTracePlotWidget() [2/2]

pappso::BaseTracePlotWidget::BaseTracePlotWidget ( QWidget *  parent,
const QString &  x_axis_label,
const QString &  y_axis_label 
)
explicit

Definition at line 68 of file basetraceplotwidget.cpp.

71  : BasePlotWidget(parent, x_axis_label, y_axis_label)
72 {
73  // We can afford to call createAllAncillaryItems() in this derived class
74  // because all the items will have been created *before* the addition of plots
75  // and then the rendering order will hide them to the viewer, since the
76  // rendering order is according to the order in which the items have been
77  // created.
78  //
79  // The fact that the ancillary items are created before trace plots is not a
80  // problem because the trace plots are sparse and do not effectively hide the
81  // data.
82  //
83  // But, in the color map plot widgets, we cannot afford to create the
84  // ancillary items *before* the plot itself because then, the rendering of the
85  // plot (created after) would screen off the ancillary items (created before).
86  //
87  // So, the createAllAncillaryItems() function needs to be called in the
88  // derived classes at the most appropriate moment in the setting up of the
89  // widget.
91 }

References pappso::BasePlotWidget::createAllAncillaryItems().

◆ ~BaseTracePlotWidget()

pappso::BaseTracePlotWidget::~BaseTracePlotWidget ( )
virtual

Destruct this BaseTracePlotWidget instance.

The destruction involves clearing the history, deleting all the axis range history items for x and y axes.

Definition at line 101 of file basetraceplotwidget.cpp.

102 {
103 }

Member Function Documentation

◆ addTrace()

QCPGraph * pappso::BaseTracePlotWidget::addTrace ( const pappso::Trace trace,
const QColor &  color 
)
virtual

Definition at line 184 of file basetraceplotwidget.cpp.

185 {
186  // qDebug();
187 
188  if(!color.isValid())
189  throw PappsoException(
190  QString("The color to be used for the plot graph is invalid."));
191 
192  // This seems to be unpleasant.
193  // setFocus();
194 
195  QCPGraph *graph_p = addGraph();
196 
197  graph_p->setLayer("plotsLayer");
198 
199  // Now depracated as of 20200924
200  // graph_p->setData(QVector<double>::fromStdVector(trace.xValues()),
201  // QVector<double>::fromStdVector(trace.yValues()));
202 
203  QVector<double> key_qvector;
204  QVector<double> value_qvector;
205 
206 #if 0
207  // Now replace the graph's data. Note that the data are
208  // inherently sorted (true below).
209 
210  // The begin() -- end() ranges constructor did not work as of
211  // Qt 5.14.2 this day: 20200721
212 
213  key_qvector =
214  QVector(trace.xValues().begin(),
215  .trace.xValues()end());
216  value_qvector =
217  QVector(trace.yValues().begin(),
218  trace.yValues().end());
219 #endif
220 
221  for(auto &value : trace.xValues())
222  key_qvector.push_back(value);
223 
224  for(auto &value : trace.yValues())
225  value_qvector.push_back(value);
226 
227  graph_p->setData(key_qvector, value_qvector, true);
228 
229  QPen pen = graph()->pen();
230  pen.setColor(color);
231  graph()->setPen(pen);
232 
233  // Connect the signal of selection change so that we can re-emit it for the
234  // widget that is using *this widget.
235 
236  connect(graph_p,
237  static_cast<void (QCPAbstractPlottable::*)(bool)>(
238  &QCPAbstractPlottable::selectionChanged),
239  [this, graph_p]() {
240  emit plottableSelectionChangedSignal(graph_p, graph_p->selected());
241  });
242 
243  // Rescaling the axes is actually unpleasant if there are more than one
244  // graph in the plot widget and that we are adding one. So only, rescale if
245  // the number of graphs is == 1, that is we are adding the first one.
246 
247  if(graphCount() == 1)
248  {
249  rescaleAxes();
251  }
252 
253  replot();
254 
255  return graph_p;
256 }
virtual void resetAxesRangeHistory()
void plottableSelectionChangedSignal(QCPAbstractPlottable *plottable_p, bool selected)
std::vector< pappso_double > xValues() const
Definition: trace.cpp:623
std::vector< pappso_double > yValues() const
Definition: trace.cpp:637

References pappso::BasePlotWidget::plottableSelectionChangedSignal(), pappso::BasePlotWidget::resetAxesRangeHistory(), pappso::Trace::xValues(), and pappso::Trace::yValues().

◆ axisDoubleClickHandler()

void pappso::BaseTracePlotWidget::axisDoubleClickHandler ( QCPAxis *  axis,
QCPAxis::SelectablePart  part,
QMouseEvent *  event 
)
overridevirtual

Reimplemented from pappso::BasePlotWidget.

Definition at line 502 of file basetraceplotwidget.cpp.

506 {
507  //qDebug();
508 
509  m_context.m_keyboardModifiers = QGuiApplication::queryKeyboardModifiers();
510 
511  if(m_context.m_keyboardModifiers & Qt::ControlModifier)
512  {
513  //qDebug();
514 
515  // If the Ctrl modifiers is active, then both axes are to be reset. Also
516  // the histories are reset also.
517 
518  rescaleAxes();
520  }
521  else
522  {
523  //qDebug();
524 
525  // Only the axis passed as parameter is to be rescaled.
526  // Reset the range of that axis to the max view possible, but for the y
527  // axis check if the Shift keyboard key is pressed. If so the full scale
528  // should be calculated only on the data in the current x range.
529 
530  if(axis->orientation() == Qt::Vertical)
531  {
532  if(m_context.m_keyboardModifiers & Qt::ShiftModifier)
533  {
534 
535  // In this case, we want to make a rescale of the Y axis such
536  // that it displays full scale the data in the current X axis
537  // range only.
538 
539  bool ok = false;
540 
541  QCPRange value_range = getValueRangeOnKeyRange(nullptr, ok);
542 
543  yAxis->setRange(value_range);
544  }
545  else
546  axis->rescale();
547  }
548  else
549  axis->rescale();
550 
552 
553  event->accept();
554  }
555 
556  // The double-click event does not cancel the mouse press event. That is, if
557  // left-double-clicking, at the end of the operation the button still
558  // "pressed". We need to remove manually the button from the pressed buttons
559  // context member.
560 
561  m_context.m_pressedMouseButtons ^= event->button();
562 
564 
566 
567  replot();
568 }
Qt::KeyboardModifiers m_keyboardModifiers
Qt::MouseButtons m_pressedMouseButtons
virtual void updateAxesRangeHistory()
Create new axis range history items and append them to the history.
virtual void updateContextXandYAxisRanges()
void plotRangesChangedSignal(const BasePlotContext &context)
BasePlotContext m_context
QCPRange getValueRangeOnKeyRange(QCPAbstractPlottable *plottable_p, bool &ok)

References getValueRangeOnKeyRange(), pappso::BasePlotWidget::m_context, pappso::BasePlotContext::m_keyboardModifiers, pappso::BasePlotContext::m_pressedMouseButtons, pappso::BasePlotWidget::plotRangesChangedSignal(), pappso::BasePlotWidget::resetAxesRangeHistory(), pappso::BasePlotWidget::updateAxesRangeHistory(), and pappso::BasePlotWidget::updateContextXandYAxisRanges().

◆ axisPan()

void pappso::BaseTracePlotWidget::axisPan ( )
overridevirtual

Reimplemented from pappso::BasePlotWidget.

Definition at line 775 of file basetraceplotwidget.cpp.

776 {
777  //qDebug();
778 
779  // Sanity check
781  qFatal(
782  "This function can only be called if the mouse click was on one of the "
783  "axes");
784 
786  {
787  xAxis->setRange(m_context.m_xRange.lower - m_context.m_xDelta,
789 
790  // If the shift modifier key is pressed, then the user want the y axis
791  // to be full scale.
792  if(m_context.m_keyboardModifiers & Qt::ShiftModifier)
793  {
794 
795  bool ok = false;
796 
797  QCPRange value_range = getValueRangeOnKeyRange(nullptr, ok);
798 
799  yAxis->setRange(value_range);
800  }
801  // else nothing to do we do not change the y axis scale.
802  }
803 
805  {
806  yAxis->setRange(m_context.m_yRange.lower - m_context.m_yDelta,
808  }
809 
811 
812  //qDebug() << "The updated context:" << m_context.toString();
813 
814  // We cannot store the new ranges in the history, because the pan operation
815  // involved a huge quantity of micro-movements elicited upon each mouse move
816  // cursor event so we would have a huge history.
817  // updateAxesRangeHistory();
818 
819  // Now that the contex has the right range values, we can emit the
820  // signal that will be used by this plot widget users, typically to
821  // abide by the x/y range lock required by the user.
822 
824 
825  replot();
826 }

References getValueRangeOnKeyRange(), pappso::BasePlotWidget::m_context, pappso::BasePlotContext::m_keyboardModifiers, pappso::BasePlotContext::m_wasClickOnXAxis, pappso::BasePlotContext::m_wasClickOnYAxis, pappso::BasePlotContext::m_xDelta, pappso::BasePlotContext::m_xRange, pappso::BasePlotContext::m_yDelta, pappso::BasePlotContext::m_yRange, pappso::BasePlotWidget::plotRangesChangedSignal(), and pappso::BasePlotWidget::updateContextXandYAxisRanges().

◆ axisReframe()

void pappso::BaseTracePlotWidget::axisReframe ( )
overridevirtual

Reimplemented from pappso::BasePlotWidget.

Definition at line 692 of file basetraceplotwidget.cpp.

693 {
694  //qDebug();
695 
696  // double sorted_start_drag_point_x =
697  // std::min(m_context.m_startDragPoint.x(), m_context.m_currentDragPoint.x());
698 
699  // xAxis->setRange(sorted_start_drag_point_x,
700  // sorted_start_drag_point_x + fabs(m_context.m_xDelta));
701 
702  xAxis->setRange(
704 
705  // Note that the y axis should be rescaled from current lower value to new
706  // upper value matching the y-axis position of the cursor when the mouse
707  // button was released.
708 
709  yAxis->setRange(xAxis->range().lower,
710  std::max<double>(m_context.m_yRegionRangeStart,
712 
713  // qDebug() << "xaxis:" << xAxis->range().lower << "-" <<
714  // xAxis->range().upper
715  //<< "yaxis:" << yAxis->range().lower << "-" << yAxis->range().upper;
716 
717  // If the shift modifier key is pressed, then the user want the y axis
718  // to be full scale.
719  if(m_context.m_keyboardModifiers & Qt::ShiftModifier)
720  {
721 
722  bool ok = false;
723 
724  QCPRange value_range = getValueRangeOnKeyRange(nullptr, ok);
725 
726  yAxis->setRange(value_range);
727  }
728  // else do nothing, let the y axis range as is.
729 
731 
734 
735  replot();
736 }

References getValueRangeOnKeyRange(), pappso::BasePlotWidget::m_context, pappso::BasePlotContext::m_keyboardModifiers, pappso::BasePlotContext::m_xRegionRangeEnd, pappso::BasePlotContext::m_xRegionRangeStart, pappso::BasePlotContext::m_yRegionRangeEnd, pappso::BasePlotContext::m_yRegionRangeStart, pappso::BasePlotWidget::plotRangesChangedSignal(), pappso::BasePlotWidget::updateAxesRangeHistory(), and pappso::BasePlotWidget::updateContextXandYAxisRanges().

◆ axisRescale()

void pappso::BaseTracePlotWidget::axisRescale ( )
overridevirtual

RANGE-related functions.

PLOTTING / REPLOTTING functions

Reimplemented from pappso::BasePlotWidget.

Definition at line 572 of file basetraceplotwidget.cpp.

573 {
574  double xLower = xAxis->range().lower;
575  double xUpper = xAxis->range().upper;
576 
577  // Get the current y lower/upper range.
578  double yLower = yAxis->range().lower;
579  double yUpper = yAxis->range().upper;
580 
581  // This function is called only when the user has clicked on the x/y axis or
582  // when the user has dragged the left mouse button with the Ctrl key
583  // modifier. The m_context.m_wasClickOnXAxis is then simulated in the mouse
584  // move handler. So we need to test which axis was clicked-on.
585 
587  {
588 
589  // We are changing the range of the X axis.
590 
591  // What is the x delta ?
592  double xDelta =
594 
595  // If xDelta is < 0, the we were dragging from right to left, we are
596  // compressing the view on the x axis, by adding new data to the right
597  // hand size of the graph. So we add xDelta to the upper bound of the
598  // range. Otherwise we are uncompressing the view on the x axis and
599  // remove the xDelta from the upper bound of the range. This is why we
600  // have the
601  // '-'
602  // and not '+' below;
603 
604  // qDebug() << "Setting xaxis:" << xLower << "--" << xUpper - xDelta;
605 
606  xAxis->setRange(xLower, xUpper - xDelta);
607 
608 
609  // Old version
610  // if(xDelta < 0)
611  //{
612  //// The dragging operation was from right to left, we are enlarging
613  //// the range (thus, we are unzooming the view, since the widget
614  //// always has the same size).
615 
616  // xAxis->setRange(xLower, xUpper + fabs(xDelta));
617  //}
618  // else
619  //{
620  //// The dragging operation was from left to right, we are reducing
621  //// the range (thus, we are zooming the view, since the widget
622  //// always has the same size).
623 
624  // xAxis->setRange(xLower, xUpper - fabs(xDelta));
625  //}
626 
627  // We may either leave the scale of the Y axis as is (default) or
628  // the user may want an automatic scale of the Y axis such that the
629  // data displayed in the new X axis range are full scale on the Y
630  // axis. For this, the Shift modifier key should be pressed.
631 
632  if(m_context.m_keyboardModifiers & Qt::ShiftModifier)
633  {
634 
635  // In this case, we want to make a rescale of the Y axis such that
636  // it displays full scale the data in the current X axis range only.
637 
638  bool ok = false;
639 
640  QCPRange value_range = getValueRangeOnKeyRange(nullptr, ok);
641 
642  yAxis->setRange(value_range);
643  }
644  // else, do leave the Y axis range unchanged.
645  }
646  // End of
647  // if(m_context.m_wasClickOnXAxis)
648  else // that is, if(m_context.m_wasClickOnYAxis)
649  {
650  // We are changing the range of the Y axis.
651 
652  // What is the y delta ?
653  double yDelta =
655 
656  // See above for an explanation of the computation.
657 
658  yAxis->setRange(yLower, yUpper - yDelta);
659 
660  // Old version
661  // if(yDelta < 0)
662  //{
663  //// The dragging operation was from top to bottom, we are enlarging
664  //// the range (thus, we are unzooming the view, since the widget
665  //// always has the same size).
666 
667  // yAxis->setRange(yLower, yUpper + fabs(yDelta));
668  //}
669  // else
670  //{
671  //// The dragging operation was from bottom to top, we are reducing
672  //// the range (thus, we are zooming the view, since the widget
673  //// always has the same size).
674 
675  // yAxis->setRange(yLower, yUpper - fabs(yDelta));
676  //}
677  }
678  // End of
679  // else // that is, if(m_context.m_wasClickOnYAxis)
680 
681  // Update the context with the current axes ranges
682 
684 
686 
687  replot();
688 }

References getValueRangeOnKeyRange(), pappso::BasePlotWidget::m_context, pappso::BasePlotContext::m_currentDragPoint, pappso::BasePlotContext::m_keyboardModifiers, pappso::BasePlotContext::m_startDragPoint, pappso::BasePlotContext::m_wasClickOnXAxis, pappso::BasePlotWidget::plotRangesChangedSignal(), and pappso::BasePlotWidget::updateContextXandYAxisRanges().

◆ axisZoom()

void pappso::BaseTracePlotWidget::axisZoom ( )
overridevirtual

Reimplemented from pappso::BasePlotWidget.

Definition at line 740 of file basetraceplotwidget.cpp.

741 {
742 
743  // Use the m_context.m_xRegionRangeStart/End values, but we need to sort the
744  // values before using them, because now we want to really have the lower x
745  // value. Simply craft a QCPRange that will swap the values if lower is not
746  // < than upper QCustomPlot calls this normalization).
747 
748  xAxis->setRange(
750 
751  // If the shift modifier key is pressed, then the user want the y axis
752  // to be full scale.
753  if(m_context.m_keyboardModifiers & Qt::ShiftModifier)
754  {
755 
756  bool ok = false;
757 
758  QCPRange value_range = getValueRangeOnKeyRange(nullptr, ok);
759 
760  yAxis->setRange(value_range);
761  }
762  else
763  yAxis->setRange(
765 
767 
770 
771  replot();
772 }

References getValueRangeOnKeyRange(), pappso::BasePlotWidget::m_context, pappso::BasePlotContext::m_keyboardModifiers, pappso::BasePlotContext::m_xRegionRangeEnd, pappso::BasePlotContext::m_xRegionRangeStart, pappso::BasePlotContext::m_yRegionRangeEnd, pappso::BasePlotContext::m_yRegionRangeStart, pappso::BasePlotWidget::plotRangesChangedSignal(), pappso::BasePlotWidget::updateAxesRangeHistory(), and pappso::BasePlotWidget::updateContextXandYAxisRanges().

◆ clearGraphData()

void pappso::BaseTracePlotWidget::clearGraphData ( int  graph_index)
virtual

Definition at line 168 of file basetraceplotwidget.cpp.

169 {
170  QCPGraph *graph_p = graph(graph_index);
171 
172  if(graph_p == nullptr)
173  qFatal("Programming error.");
174 
175  graph_p->data().clear();
176 
177  rescaleAxes();
179  replot();
180 }

References pappso::BasePlotWidget::resetAxesRangeHistory().

◆ findIntegrationLowerRangeForKey()

bool pappso::BaseTracePlotWidget::findIntegrationLowerRangeForKey ( int  index,
double  key,
QCPRange &  range 
)
virtual

Find a minimal integration range starting at an existing data point.

If the user clicks onto a plot at a location that is not a true data point, get a data range that begins at the preceding data point and that ends at the clicked location point.

Definition at line 268 of file basetraceplotwidget.cpp.

271 {
272 
273  // Given a key double value, we want to know what is the range that will
274  // frame correctly the key double value if that key value is not exactly
275  // the one of a point of the trace.
276 
277  // First of all get the keys of the graph.
278 
279  QCPGraph *theGraph = graph(index);
280 
281  if(theGraph == nullptr)
282  throw ExceptionNotPossible(
283  "basetraceplotwidget.cpp @ indIntegrationLowerRangeForKey() -- ERROR "
284  "theGraph cannot be nullptr.");
285 
286  // QCPGraphDataContainer is a typedef QCPDataContainer<QCPGraphData> and
287  // QCPDataContainer< DataType > is a Class Template. So in this context,
288  // DataType is QCPGraphData.
289  // QCPGraphData is the data point, that is the (key,value) pair.
290  QSharedPointer<QCPGraphDataContainer> graph_data_container_p =
291  theGraph->data();
292 
293  QCPDataRange dataRange = graph_data_container_p->dataRange();
294 
295  if(!dataRange.isValid())
296  return false;
297 
298  if(!dataRange.size())
299  return false;
300 
301  if(dataRange.size() > 1)
302  {
303  double firstKey = graph_data_container_p->at(dataRange.begin())->key;
304  double lastKey = graph_data_container_p->at(dataRange.end())->key;
305 
306  // There is one check to be done: the user might erroneously set the mouse
307  // cursor beyond the last point of the graph. If that is the case, then
308  // upper key needs to be that very point. All we need to do is return the
309  // lower key, that is the pre-last key of the keys list. No need to
310  // iterate in the keys list.
311 
312  if(key > lastKey)
313  {
314  // No need to search for the key in the keys, just get the lower key
315  // immediately, that is, the key that is one slot left the last key.
316  range.lower = graph_data_container_p->at(dataRange.end() - 2)->key;
317  range.upper = graph_data_container_p->at(dataRange.end() - 1)->key;
318 
319  return true;
320  }
321 
322  // Likewise, if the cursor is set left of the first plot point, then that
323  // will be the lower range point. All we need is to provide the upper
324  // range point as the second point of the plot.
325 
326  if(key < firstKey)
327  {
328  range.lower = firstKey;
329  range.upper = graph_data_container_p->at(dataRange.begin() + 1)->key;
330 
331  return true;
332  }
333 
334  // Finally the generic case where the user point to any point *in* the
335  // graph.
336 
337  range.lower =
338  graph_data_container_p->findBegin(key, /*expandedRange*/ true)->key;
339  range.upper =
340  std::prev(graph_data_container_p->findEnd(key, /*expandedRange*/ true))
341  ->key;
342 
343  return true;
344  }
345 
346  return false;
347 }

◆ getValueRangeOnKeyRange() [1/2]

QCPRange pappso::BaseTracePlotWidget::getValueRangeOnKeyRange ( int  index,
bool &  ok 
)

Definition at line 456 of file basetraceplotwidget.cpp.

457 {
458 
459  // The X axis range is set. But we want to find for that X axis range the
460  // min and max Y values. This function is useful when the user asks that
461  // while changing the X axis range, the trace be always in full scale on the
462  // Y axis.
463 
464  QCPAbstractPlottable *plottable_p = plottable(index);
465 
466  if(plottable_p == nullptr)
467  qFatal("Programming error.");
468 
469  return getValueRangeOnKeyRange(plottable_p, ok);
470 }

References getValueRangeOnKeyRange().

◆ getValueRangeOnKeyRange() [2/2]

QCPRange pappso::BaseTracePlotWidget::getValueRangeOnKeyRange ( QCPAbstractPlottable *  plottable_p,
bool &  ok 
)

Definition at line 399 of file basetraceplotwidget.cpp.

401 {
402 
403  // The X axis range is set. But we want to find for that X axis range the
404  // min and max Y values. This function is useful when the user asks that
405  // while changing the X axis range, the trace be always in full scale on the
406  // Y axis.
407 
408  QCPRange key_range(xAxis->range().lower, xAxis->range().upper);
409 
410  if(plottable_p != nullptr)
411  {
412 
413  return plottable_p->getValueRange(ok, QCP::SignDomain::sdBoth, key_range);
414  }
415  else
416  {
417 
418  // How many graphs are currently plotted in this plot widget ?
419  int graph_count = graphCount();
420 
421  // Iterate in each graph and get the y max value. Then compare with the
422  // largest one and update if necessary. Store the pointer to the graph
423  // that has a larger y value. At the end of the iteration, it will be
424  // the winner.
425 
426  double temp_min_value = std::numeric_limits<double>::max();
427  double temp_max_value = std::numeric_limits<double>::min();
428 
429  bool found_range = false;
430 
431  for(int iter = 0; iter < graph_count; ++iter)
432  {
433  QCPGraph *plottable_p = graph(iter);
434 
435  QCPRange value_range =
436  plottable_p->getValueRange(ok, QCP::SignDomain::sdBoth, key_range);
437 
438  if(ok)
439  found_range = true;
440 
441  if(value_range.lower < temp_min_value)
442  temp_min_value = value_range.lower;
443  if(value_range.upper > temp_max_value)
444  temp_max_value = value_range.upper;
445  }
446 
447  // At this point return the range.
448 
449  ok = found_range;
450  return QCPRange(temp_min_value, temp_max_value);
451  }
452 }

Referenced by axisDoubleClickHandler(), axisPan(), axisReframe(), axisRescale(), axisZoom(), and getValueRangeOnKeyRange().

◆ getValuesX()

std::vector< double > pappso::BaseTracePlotWidget::getValuesX ( int  index) const

Definition at line 351 of file basetraceplotwidget.cpp.

352 {
353  std::vector<double> keys;
354 
355  QCPGraph *graph_p = graph(graph_index);
356 
357  if(graph_p == nullptr)
358  qFatal("Programming error.");
359 
360  QSharedPointer<QCPGraphDataContainer> graph_data_container_p =
361  graph_p->data();
362 
363  // Iterate in the keys
364  auto beginIt = graph_data_container_p->begin();
365  auto endIt = graph_data_container_p->end();
366 
367  for(auto iter = beginIt; iter != endIt; ++iter)
368  keys.push_back(iter->key);
369 
370  return keys;
371 }

◆ getValuesY()

std::vector< double > pappso::BaseTracePlotWidget::getValuesY ( int  index) const

Definition at line 375 of file basetraceplotwidget.cpp.

376 {
377  std::vector<double> values;
378 
379  QCPGraph *graph_p = graph(graph_index);
380 
381  if(graph_p == nullptr)
382  qFatal("Programming error.");
383 
384  QSharedPointer<QCPGraphDataContainer> graph_data_container_p =
385  graph_p->data();
386 
387  // Iterate in the values
388  auto beginIt = graph_data_container_p->begin();
389  auto endIt = graph_data_container_p->end();
390 
391  for(auto iter = beginIt; iter != endIt; ++iter)
392  values.push_back(iter->key);
393 
394  return values;
395 }

◆ getYatX() [1/2]

double pappso::BaseTracePlotWidget::getYatX ( double  x,
int  index = 0 
)

Definition at line 490 of file basetraceplotwidget.cpp.

491 {
492  QCPGraph *graph_p = graph(index);
493 
494  if(graph_p == nullptr)
495  qFatal("Programming error.");
496 
497  return getYatX(x, graph_p);
498 }
double getYatX(double x, QCPGraph *graph_p)

References getYatX(), and pappso::x.

◆ getYatX() [2/2]

double pappso::BaseTracePlotWidget::getYatX ( double  x,
QCPGraph *  graph_p 
)

Definition at line 474 of file basetraceplotwidget.cpp.

475 {
476  if(graph_p == nullptr)
477  qFatal("Programming error.");
478 
479  QCPItemTracer tracer(this);
480  tracer.setGraph(graph_p);
481  tracer.setInterpolating(true);
482  tracer.setGraphKey(x);
483  tracer.updatePosition();
484 
485  return tracer.position->value();
486 }

References pappso::x.

Referenced by getYatX().

◆ setGraphData() [1/2]

void pappso::BaseTracePlotWidget::setGraphData ( int  graph_index,
const std::vector< double > &  keys,
const std::vector< double > &  values 
)
virtual

Definition at line 107 of file basetraceplotwidget.cpp.

110 {
111  QCPGraph *graph_p = graph(graph_index);
112 
113  if(graph_p == nullptr)
114  qFatal("Programming error.");
115 
116  return setGraphData(graph_p, keys, values);
117 }
virtual void setGraphData(int graph_index, const std::vector< double > &keys, const std::vector< double > &values)

◆ setGraphData() [2/2]

void pappso::BaseTracePlotWidget::setGraphData ( QCPGraph *  graph_p,
const std::vector< double > &  keys,
const std::vector< double > &  values 
)
virtual

Definition at line 121 of file basetraceplotwidget.cpp.

124 {
125  if(graph_p == nullptr)
126  qFatal("Pointer cannot be nullptr.");
127 
128  // Version that is now deprecated (20200924)
129  // graph_p->setData(QVector<double>::fromStdVector(keys),
130  // QVector<double>::fromStdVector(values));
131 
132  QVector<double> key_qvector;
133  QVector<double> value_qvector;
134 
135 
136 #if 0
137  // Now replace the graph's data. Note that the data are
138  // inherently sorted (true below).
139 
140  // The begin() -- end() ranges constructor did not work as of
141  // Qt 5.14.2 this day: 20200721
142 
143  key_qvector =
144  QVector(keys.begin(),
145  keys.end());
146  value_qvector =
147  QVector(values.begin(),
148  values.end());
149 #endif
150 
151  for(auto &value : keys)
152  key_qvector.push_back(value);
153 
154  for(auto &value : values)
155  value_qvector.push_back(value);
156 
157  graph_p->setData(key_qvector, value_qvector, true);
158 
159  graph_p->setPen(m_pen);
160 
161  rescaleAxes();
163  replot();
164 }
QPen m_pen
Pen used to draw the graph and textual elements in the plot widget.

References pappso::BasePlotWidget::m_pen, and pappso::BasePlotWidget::resetAxesRangeHistory().

◆ toTrace() [1/4]

pappso::Trace pappso::BaseTracePlotWidget::toTrace ( const QCPGraph *  graph_p) const

Definition at line 839 of file basetraceplotwidget.cpp.

840 {
841  if(graph_p == nullptr)
842  qFatal("Programming error. Pointer cannot be nullptr.");
843 
844  pappso::Trace trace;
845 
846  QSharedPointer<QCPGraphDataContainer> graph_data_container_p =
847  graph_p->data();
848 
849  // Iterate in the keys
850  auto beginIt = graph_data_container_p->begin();
851  auto endIt = graph_data_container_p->end();
852 
853  for(auto iter = beginIt; iter != endIt; ++iter)
854  trace.push_back(pappso::DataPoint(iter->key, iter->value));
855 
856  return trace;
857 }
A simple container of DataPoint instances.
Definition: trace.h:148

◆ toTrace() [2/4]

pappso::Trace pappso::BaseTracePlotWidget::toTrace ( const QCPRange &  x_axis_range,
const QCPGraph *  graph_p 
) const

Definition at line 873 of file basetraceplotwidget.cpp.

875 {
876 
877  // Make a Trace with the data in the range.
878  Trace data_trace;
879 
880  QSharedPointer<QCPGraphDataContainer> graph_data_container_sp;
881 
882  graph_data_container_sp = graph_p->data();
883 
884  // Grab the iterator to the start to the x axis range
885  auto beginIt = graph_data_container_sp->findBegin(x_axis_range.lower,
886  /*expandedRange*/ true);
887  // Grab the iterator to the end of the axis range
888  auto endIt = graph_data_container_sp->findEnd(x_axis_range.upper,
889  /*expandedRange*/ true);
890 
891  for(auto iter = beginIt; iter != endIt; ++iter)
892  data_trace.push_back(DataPoint(iter->key, iter->value));
893 
894  return data_trace;
895 }

◆ toTrace() [3/4]

pappso::Trace pappso::BaseTracePlotWidget::toTrace ( const QCPRange &  x_axis_range,
int  index 
) const

Definition at line 861 of file basetraceplotwidget.cpp.

862 {
863  QCPGraph *graph_p = graph(index);
864 
865  if(graph_p == nullptr)
866  qFatal("Programming error.");
867 
868  return toTrace(x_axis_range, graph_p);
869 }
pappso::Trace toTrace(int index) const

References toTrace().

◆ toTrace() [4/4]

pappso::Trace pappso::BaseTracePlotWidget::toTrace ( int  index) const

Definition at line 830 of file basetraceplotwidget.cpp.

831 {
832  QCPGraph *graph_p = graph(index);
833 
834  return toTrace(graph_p);
835 }

Referenced by toTrace().


The documentation for this class was generated from the following files: