libpappsomspp
Library for mass spectrometry
basetraceplotwidget.cpp
Go to the documentation of this file.
1 /* This code comes right from the msXpertSuite software project.
2  *
3  * msXpertSuite - mass spectrometry software suite
4  * -----------------------------------------------
5  * Copyright(C) 2009,...,2018 Filippo Rusconi
6  *
7  * http://www.msxpertsuite.org
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  *
22  * END software license
23  */
24 
25 
26 /////////////////////// StdLib includes
27 #include <vector>
28 
29 
30 /////////////////////// Qt includes
31 #include <QVector>
32 
33 
34 /////////////////////// Local includes
35 #include "basetraceplotwidget.h"
36 #include "../../exception/exceptionnotpossible.h"
37 #include "../../pappsoexception.h"
38 
39 
40 namespace pappso
41 {
42 
43 
45  : BasePlotWidget(parent)
46 {
47 }
48 
49 
51  const QString &x_axis_label,
52  const QString &y_axis_label)
53  : BasePlotWidget(parent, x_axis_label, y_axis_label)
54 {
55 }
56 
57 
58 //! Destruct \c this BaseTracePlotWidget instance.
59 /*!
60 
61  The destruction involves clearing the history, deleting all the axis range
62  history items for x and y axes.
63 
64 */
66 {
67 }
68 
69 
70 void
72  const std::vector<double> &keys,
73  const std::vector<double> &values)
74 {
75  QCPGraph *graph_p = graph(graph_index);
76 
77  if(graph_p == nullptr)
78  qFatal("Programming error.");
79 
80  return setGraphData(graph_p, keys, values);
81 }
82 
83 
84 void
86  const std::vector<double> &keys,
87  const std::vector<double> &values)
88 {
89  if(graph_p == nullptr)
90  qFatal("Pointer cannot be nullptr.");
91 
92  graph_p->setData(QVector<double>::fromStdVector(keys),
93  QVector<double>::fromStdVector(values));
94 
95  graph_p->setPen(m_pen);
96 
97  rescaleAxes();
99  replot();
100 }
101 
102 
103 void
105 {
106  QCPGraph *graph_p = graph(graph_index);
107 
108  if(graph_p == nullptr)
109  qFatal("Programming error.");
110 
111  graph_p->data().clear();
112 
113  rescaleAxes();
115  replot();
116 }
117 
118 
119 QCPGraph *
120 BaseTracePlotWidget::addTrace(const pappso::Trace &trace, const QColor &color)
121 {
122  // qDebug();
123 
124  if(!color.isValid())
125  throw PappsoException(
126  QString("The color to be used for the plot graph is invalid."));
127 
128  // This seems to be unpleasant.
129  // setFocus();
130 
131  QCPGraph *graph_p = addGraph();
132 
133  graph_p->setData(QVector<double>::fromStdVector(trace.xToVector()),
134  QVector<double>::fromStdVector(trace.yToVector()));
135 
136  QPen pen = graph()->pen();
137  pen.setColor(color);
138  graph()->setPen(pen);
139 
140  // Connect the signal of selection change so that we can re-emit it for the
141  // widget that is using *this widget.
142 
143  connect(graph_p,
144  static_cast<void (QCPAbstractPlottable::*)(bool)>(
145  &QCPAbstractPlottable::selectionChanged),
146  [this, graph_p]() {
147  emit plottableSelectionChangedSignal(graph_p, graph_p->selected());
148  });
149 
150  // Rescaling the axes is actually unpleasant if there are more than one
151  // graph in the plot widget and that we are adding one. So only, rescale if
152  // the number of graphs is == 1, that is we are adding the first one.
153 
154  if(graphCount() == 1)
155  {
156  rescaleAxes();
158  }
159 
160  replot();
161 
162  return graph_p;
163 }
164 
165 
166 //! Find a minimal integration range starting at an existing data point
167 /*!
168 
169  If the user clicks onto a plot at a location that is not a true data point,
170  get a data range that begins at the preceding data point and that ends at
171  the clicked location point.
172 
173 */
174 bool
176  double key,
177  QCPRange &range)
178 {
179 
180  // Given a key double value, we want to know what is the range that will
181  // frame correctly the key double value if that key value is not exactly
182  // the one of a point of the trace.
183 
184  // First of all get the keys of the graph.
185 
186  QCPGraph *theGraph = graph(index);
187 
188  if(theGraph == nullptr)
189  throw ExceptionNotPossible(
190  "basetraceplotwidget.cpp @ indIntegrationLowerRangeForKey() -- ERROR "
191  "theGraph cannot be nullptr.");
192 
193  // QCPGraphDataContainer is a typedef QCPDataContainer<QCPGraphData> and
194  // QCPDataContainer< DataType > is a Class Template. So in this context,
195  // DataType is QCPGraphData.
196  // QCPGraphData is the data point, that is the (key,value) pair.
197  QSharedPointer<QCPGraphDataContainer> graph_data_container_p =
198  theGraph->data();
199 
200  QCPDataRange dataRange = graph_data_container_p->dataRange();
201 
202  if(!dataRange.isValid())
203  return false;
204 
205  if(!dataRange.size())
206  return false;
207 
208  if(dataRange.size() > 1)
209  {
210  double firstKey = graph_data_container_p->at(dataRange.begin())->key;
211  double lastKey = graph_data_container_p->at(dataRange.end())->key;
212 
213  // There is one check to be done: the user might erroneously set the mouse
214  // cursor beyond the last point of the graph. If that is the case, then
215  // upper key needs to be that very point. All we need to do is return the
216  // lower key, that is the pre-last key of the keys list. No need to
217  // iterate in the keys list.
218 
219  if(key > lastKey)
220  {
221  // No need to search for the key in the keys, just get the lower key
222  // immediately, that is, the key that is one slot left the last key.
223  range.lower = graph_data_container_p->at(dataRange.end() - 2)->key;
224  range.upper = graph_data_container_p->at(dataRange.end() - 1)->key;
225 
226  return true;
227  }
228 
229  // Likewise, if the cursor is set left of the first plot point, then that
230  // will be the lower range point. All we need is to provide the upper
231  // range point as the second point of the plot.
232 
233  if(key < firstKey)
234  {
235  range.lower = firstKey;
236  range.upper = graph_data_container_p->at(dataRange.begin() + 1)->key;
237 
238  return true;
239  }
240 
241  // Finally the generic case where the user point to any point *in* the
242  // graph.
243 
244  range.lower =
245  graph_data_container_p->findBegin(key, /*expandedRange*/ true)->key;
246  range.upper =
247  std::prev(graph_data_container_p->findEnd(key, /*expandedRange*/ true))
248  ->key;
249 
250  return true;
251  }
252 
253  return false;
254 }
255 
256 
257 std::vector<double>
258 BaseTracePlotWidget::getValuesX(int graph_index) const
259 {
260  std::vector<double> keys;
261 
262  QCPGraph *graph_p = graph(graph_index);
263 
264  if(graph_p == nullptr)
265  qFatal("Programming error.");
266 
267  QSharedPointer<QCPGraphDataContainer> graph_data_container_p =
268  graph_p->data();
269 
270  // Iterate in the keys
271  auto beginIt = graph_data_container_p->begin();
272  auto endIt = graph_data_container_p->end();
273 
274  for(auto iter = beginIt; iter != endIt; ++iter)
275  keys.push_back(iter->key);
276 
277  return keys;
278 }
279 
280 
281 std::vector<double>
282 BaseTracePlotWidget::getValuesY(int graph_index) const
283 {
284  std::vector<double> values;
285 
286  QCPGraph *graph_p = graph(graph_index);
287 
288  if(graph_p == nullptr)
289  qFatal("Programming error.");
290 
291  QSharedPointer<QCPGraphDataContainer> graph_data_container_p =
292  graph_p->data();
293 
294  // Iterate in the values
295  auto beginIt = graph_data_container_p->begin();
296  auto endIt = graph_data_container_p->end();
297 
298  for(auto iter = beginIt; iter != endIt; ++iter)
299  values.push_back(iter->key);
300 
301  return values;
302 }
303 
304 
305 QCPRange
306 BaseTracePlotWidget::getValueRangeOnKeyRange(QCPAbstractPlottable *plottable_p,
307  bool &ok)
308 {
309 
310  // The X axis range is set. But we want to find for that X axis range the
311  // min and max Y values. This function is useful when the user asks that
312  // while changing the X axis range, the trace be always in full scale on the
313  // Y axis.
314 
315  QCPRange key_range(xAxis->range().lower, xAxis->range().upper);
316 
317  if(plottable_p != nullptr)
318  {
319 
320  return plottable_p->getValueRange(ok, QCP::SignDomain::sdBoth, key_range);
321  }
322  else
323  {
324 
325  // How many graphs are currently plotted in this plot widget ?
326  int graph_count = graphCount();
327 
328  // Iterate in each graph and get the y max value. Then compare with the
329  // largest one and update if necessary. Store the pointer to the graph
330  // that has a larger y value. At the end of the iteration, it will be
331  // the winner.
332 
333  double temp_min_value = std::numeric_limits<double>::max();
334  double temp_max_value = std::numeric_limits<double>::min();
335 
336  bool found_range = false;
337 
338  for(int iter = 0; iter < graph_count; ++iter)
339  {
340  QCPGraph *plottable_p = graph(iter);
341 
342  QCPRange value_range =
343  plottable_p->getValueRange(ok, QCP::SignDomain::sdBoth, key_range);
344 
345  if(ok)
346  found_range = true;
347 
348  if(value_range.lower < temp_min_value)
349  temp_min_value = value_range.lower;
350  if(value_range.upper > temp_max_value)
351  temp_max_value = value_range.upper;
352  }
353 
354  // At this point return the range.
355 
356  ok = found_range;
357  return QCPRange(temp_min_value, temp_max_value);
358  }
359 }
360 
361 
362 QCPRange
364 {
365 
366  // The X axis range is set. But we want to find for that X axis range the
367  // min and max Y values. This function is useful when the user asks that
368  // while changing the X axis range, the trace be always in full scale on the
369  // Y axis.
370 
371  QCPAbstractPlottable *plottable_p = plottable(index);
372 
373  if(plottable_p == nullptr)
374  qFatal("Programming error.");
375 
376  return getValueRangeOnKeyRange(plottable_p, ok);
377 }
378 
379 
380 double
381 BaseTracePlotWidget::getYatX(double x, QCPGraph *graph_p)
382 {
383  if(graph_p == nullptr)
384  qFatal("Programming error.");
385 
386  QCPItemTracer tracer(this);
387  tracer.setGraph(graph_p);
388  tracer.setInterpolating(true);
389  tracer.setGraphKey(x);
390  tracer.updatePosition();
391 
392  return tracer.position->value();
393 }
394 
395 
396 double
397 BaseTracePlotWidget::getYatX(double x, int index)
398 {
399  QCPGraph *graph_p = graph(index);
400 
401  if(graph_p == nullptr)
402  qFatal("Programming error.");
403 
404  return getYatX(x, graph_p);
405 }
406 
407 
408 void
410  QCPAxis *axis,
411  [[maybe_unused]] QCPAxis::SelectablePart part,
412  QMouseEvent *event)
413 {
414 
415  m_context.keyboardModifiers = QGuiApplication::queryKeyboardModifiers();
416 
417  if(m_context.keyboardModifiers & Qt::ControlModifier)
418  {
419 
420  // If the Ctrl modifiers is active, then both axes are to be reset. Also
421  // the histories are reset also.
422 
423  rescaleAxes();
425  }
426  else
427  {
428  // Only the axis passed as parameter is to be rescaled.
429  // Reset the range of that axis to the max view possible, but for the y
430  // axis check if the Shift keyboard key is pressed. If so the full scale
431  // should be calculated only on the data in the current x range.
432 
433  if(axis->orientation() == Qt::Vertical)
434  {
435  if(m_context.keyboardModifiers & Qt::ShiftModifier)
436  {
437 
438  // In this case, we want to make a rescale of the Y axis such
439  // that it displays full scale the data in the current X axis
440  // range only.
441 
442  bool ok = false;
443 
444  QCPRange value_range = getValueRangeOnKeyRange(nullptr, ok);
445 
446  yAxis->setRange(value_range);
447  }
448  else
449  axis->rescale();
450  }
451  else
452  axis->rescale();
453 
455 
456  event->accept();
457  }
458 
459  // The double-click event does not cancel the mouse press event. That is, if
460  // left-double-clicking, at the end of the operation the button still
461  // "pressed". We need to remove manually the button from the pressed buttons
462  // context member.
463 
464  m_context.pressedMouseButtons ^= event->button();
465 
467 
469 
470  replot();
471 }
472 
473 
474 void
476 {
477  double xLower = xAxis->range().lower;
478  double xUpper = xAxis->range().upper;
479 
480  // Get the current y lower/upper range.
481  double yLower = yAxis->range().lower;
482  double yUpper = yAxis->range().upper;
483 
484  // This function is called only when the user has clicked on the x/y axis or
485  // when the user has dragged the left mouse button with the Ctrl key
486  // modifier. The m_context.wasClickOnXAxis is then simulated in the mouse
487  // move handler. So we need to test which axis was clicked-on.
488 
490  {
491 
492  // We are changing the range of the X axis.
493 
494  // What is the x delta ?
495  double xDelta =
497 
498  // If xDelta is < 0, the we were dragging from right to left, we are
499  // compressing the view on the x axis, by adding new data to the right
500  // hand size of the graph. So we add xDelta to the upper bound of the
501  // range. Otherwise we are uncompressing the view on the x axis and
502  // remove the xDelta from the upper bound of the range. This is why we
503  // have the
504  // '-'
505  // and not '+' below;
506 
507  // qDebug() << "Setting xaxis:" << xLower << "--" << xUpper - xDelta;
508 
509  xAxis->setRange(xLower, xUpper - xDelta);
510 
511 
512  // Old version
513  // if(xDelta < 0)
514  //{
515  //// The dragging operation was from right to left, we are enlarging
516  //// the range (thus, we are unzooming the view, since the widget
517  //// always has the same size).
518 
519  // xAxis->setRange(xLower, xUpper + fabs(xDelta));
520  //}
521  // else
522  //{
523  //// The dragging operation was from left to right, we are reducing
524  //// the range (thus, we are zooming the view, since the widget
525  //// always has the same size).
526 
527  // xAxis->setRange(xLower, xUpper - fabs(xDelta));
528  //}
529 
530  // We may either leave the scale of the Y axis as is (default) or
531  // the user may want an automatic scale of the Y axis such that the
532  // data displayed in the new X axis range are full scale on the Y
533  // axis. For this, the Shift modifier key should be pressed.
534 
535  if(m_context.keyboardModifiers & Qt::ShiftModifier)
536  {
537 
538  // In this case, we want to make a rescale of the Y axis such that
539  // it displays full scale the data in the current X axis range only.
540 
541  bool ok = false;
542 
543  QCPRange value_range = getValueRangeOnKeyRange(nullptr, ok);
544 
545  yAxis->setRange(value_range);
546  }
547  // else, do leave the Y axis range unchanged.
548  }
549  // End of
550  // if(m_context.wasClickOnXAxis)
551  else // that is, if(m_context.wasClickOnYAxis)
552  {
553  // We are changing the range of the Y axis.
554 
555  // What is the y delta ?
556  double yDelta =
558 
559  // See above for an explanation of the computation.
560 
561  yAxis->setRange(yLower, yUpper - yDelta);
562 
563  // Old version
564  // if(yDelta < 0)
565  //{
566  //// The dragging operation was from top to bottom, we are enlarging
567  //// the range (thus, we are unzooming the view, since the widget
568  //// always has the same size).
569 
570  // yAxis->setRange(yLower, yUpper + fabs(yDelta));
571  //}
572  // else
573  //{
574  //// The dragging operation was from bottom to top, we are reducing
575  //// the range (thus, we are zooming the view, since the widget
576  //// always has the same size).
577 
578  // yAxis->setRange(yLower, yUpper - fabs(yDelta));
579  //}
580  }
581  // End of
582  // else // that is, if(m_context.wasClickOnYAxis)
583 
584  // Update the context with the current axes ranges
585 
587 
589 
590  replot();
591 }
592 
593 
594 void
596 {
597 
598  // double sorted_start_drag_point_x =
599  // std::min(m_context.startDragPoint.x(), m_context.currentDragPoint.x());
600 
601  // xAxis->setRange(sorted_start_drag_point_x,
602  // sorted_start_drag_point_x + fabs(m_context.xDelta));
603 
604  xAxis->setRange(
606 
607  // Note that the y axis should be rescaled from current lower value to new
608  // upper value matching the y-axis position of the cursor when the mouse
609  // button was released.
610 
611  yAxis->setRange(
612  xAxis->range().lower,
614 
615  // qDebug() << "xaxis:" << xAxis->range().lower << "-" <<
616  // xAxis->range().upper
617  //<< "yaxis:" << yAxis->range().lower << "-" << yAxis->range().upper;
618 
619  // If the shift modifier key is pressed, then the user want the y axis
620  // to be full scale.
621  if(m_context.keyboardModifiers & Qt::ShiftModifier)
622  {
623 
624  bool ok = false;
625 
626  QCPRange value_range = getValueRangeOnKeyRange(nullptr, ok);
627 
628  yAxis->setRange(value_range);
629  }
630  // else do nothing, let the y axis range as is.
631 
633 
636 
637  replot();
638 }
639 
640 
641 void
643 {
644 
645  // Use the m_context.xRegionRangeStart/End values, but we need to sort the
646  // values before using them, because now we want to really have the lower x
647  // value. Simply craft a QCPRange that will swap the values if lower is not
648  // < than upper QCustomPlot calls this normalization).
649 
650  xAxis->setRange(
652 
653  // If the shift modifier key is pressed, then the user want the y axis
654  // to be full scale.
655  if(m_context.keyboardModifiers & Qt::ShiftModifier)
656  {
657 
658  bool ok = false;
659 
660  QCPRange value_range = getValueRangeOnKeyRange(nullptr, ok);
661 
662  yAxis->setRange(value_range);
663  }
664  else
665  yAxis->setRange(
667 
669 
672 
673  replot();
674 }
675 
676 void
678 {
680  {
681  xAxis->setRange(m_context.xRange.lower - m_context.xDelta,
682  m_context.xRange.upper - m_context.xDelta);
683 
684  // If the shift modifier key is pressed, then the user want the y axis
685  // to be full scale.
686  if(m_context.keyboardModifiers & Qt::ShiftModifier)
687  {
688 
689  bool ok = false;
690 
691  QCPRange value_range = getValueRangeOnKeyRange(nullptr, ok);
692 
693  yAxis->setRange(value_range);
694  }
695  // else nothing to do we do not change the y axis scale.
696  }
697 
699  {
700  yAxis->setRange(m_context.yRange.lower - m_context.yDelta,
701  m_context.yRange.upper - m_context.yDelta);
702  }
703 
705 
706  // We cannot store the new ranges in the history, because the pan operation
707  // involved a huge quantity of micro-movements elicited upon each mouse move
708  // cursor event so we would have a huge history.
709  // updateAxesRangeHistory();
710 
711  // Now that the contex has the right range values, we can emit the
712  // signal that will be used by this plot widget users, typically to
713  // abide by the x/y range lock required by the user.
714 
716 
717  replot();
718 }
719 
720 
723 {
724  QCPGraph *graph_p = graph(index);
725 
726  return toTrace(graph_p);
727 }
728 
729 
731 BaseTracePlotWidget::toTrace(const QCPGraph *graph_p) const
732 {
733  if(graph_p == nullptr)
734  qFatal("Programming error. Pointer cannot be nullptr.");
735 
736  pappso::Trace trace;
737 
738  QSharedPointer<QCPGraphDataContainer> graph_data_container_p =
739  graph_p->data();
740 
741  // Iterate in the keys
742  auto beginIt = graph_data_container_p->begin();
743  auto endIt = graph_data_container_p->end();
744 
745  for(auto iter = beginIt; iter != endIt; ++iter)
746  trace.push_back(pappso::DataPoint(iter->key, iter->value));
747 
748  return trace;
749 }
750 
751 
753 BaseTracePlotWidget::toTrace(const QCPRange &x_axis_range, int index) const
754 {
755  QCPGraph *graph_p = graph(index);
756 
757  if(graph_p == nullptr)
758  qFatal("Programming error.");
759 
760  return toTrace(x_axis_range, graph_p);
761 }
762 
763 
765 BaseTracePlotWidget::toTrace(const QCPRange &x_axis_range,
766  const QCPGraph *graph_p) const
767 {
768 
769  // Make a Trace with the data in the range.
770  Trace data_trace;
771 
772  QSharedPointer<QCPGraphDataContainer> graph_data_container_sp;
773 
774  graph_data_container_sp = graph_p->data();
775 
776  // Grab the iterator to the start to the x axis range
777  auto beginIt = graph_data_container_sp->findBegin(x_axis_range.lower,
778  /*expandedRange*/ true);
779  // Grab the iterator to the end of the axis range
780  auto endIt = graph_data_container_sp->findEnd(x_axis_range.upper,
781  /*expandedRange*/ true);
782 
783  for(auto iter = beginIt; iter != endIt; ++iter)
784  data_trace.push_back(DataPoint(iter->key, iter->value));
785 
786  return data_trace;
787 }
788 
789 
790 } // namespace pappso
pappso::BaseTracePlotWidget::addTrace
virtual QCPGraph * addTrace(const pappso::Trace &trace, const QColor &color)
Definition: basetraceplotwidget.cpp:120
pappso::BasePlotContext::xRegionRangeStart
double xRegionRangeStart
Definition: baseplotwidget.h:104
pappso::BasePlotWidget::updateAxesRangeHistory
virtual void updateAxesRangeHistory()
Create new axis range history items and append them to the history.
Definition: baseplotwidget.cpp:393
pappso::BasePlotContext::pressedMouseButtons
Qt::MouseButtons pressedMouseButtons
Definition: baseplotwidget.h:121
pappso::BasePlotWidget::m_pen
QPen m_pen
Pen used to draw the graph and textual elements in the plot widget.
Definition: baseplotwidget.h:392
pappso::Trace::xToVector
std::vector< pappso_double > xToVector() const
Definition: trace.cpp:495
pappso::BasePlotContext::currentDragPoint
QPointF currentDragPoint
Definition: baseplotwidget.h:82
pappso::BasePlotWidget
Definition: baseplotwidget.h:135
pappso
Definition: aa.cpp:38
pappso::BaseTracePlotWidget::getValuesY
std::vector< double > getValuesY(int index) const
Definition: basetraceplotwidget.cpp:282
pappso::BaseTracePlotWidget::getValueRangeOnKeyRange
QCPRange getValueRangeOnKeyRange(QCPAbstractPlottable *plottable_p, bool &ok)
Definition: basetraceplotwidget.cpp:306
basetraceplotwidget.h
pappso::BasePlotContext::xRange
QCPRange xRange
Definition: baseplotwidget.h:86
pappso::BasePlotContext::wasClickOnXAxis
bool wasClickOnXAxis
Definition: baseplotwidget.h:93
pappso::BaseTracePlotWidget::axisReframe
virtual void axisReframe() override
Definition: basetraceplotwidget.cpp:595
pappso::DataPoint
Definition: datapoint.h:20
pappso::Trace::yToVector
std::vector< pappso_double > yToVector() const
Definition: trace.cpp:507
pappso::ExceptionNotPossible
Definition: exceptionnotpossible.h:52
pappso::BasePlotWidget::updateContextRanges
virtual void updateContextRanges()
Definition: baseplotwidget.cpp:2225
pappso::PeptideIonCter::x
@ x
pappso::BasePlotWidget::plottableSelectionChangedSignal
void plottableSelectionChangedSignal(QCPAbstractPlottable *plottable_p, bool selected)
pappso::BasePlotContext::keyboardModifiers
Qt::KeyboardModifiers keyboardModifiers
Definition: baseplotwidget.h:116
pappso::Trace
A simple container of DataPoint instances.
Definition: trace.h:126
pappso::BaseTracePlotWidget::BaseTracePlotWidget
BaseTracePlotWidget(QWidget *parent=0)
Definition: basetraceplotwidget.cpp:44
pappso::BaseTracePlotWidget::toTrace
pappso::Trace toTrace(int index) const
Definition: basetraceplotwidget.cpp:722
pappso::BasePlotContext::yRegionRangeStart
double yRegionRangeStart
Definition: baseplotwidget.h:107
pappso::BasePlotContext::yRange
QCPRange yRange
Definition: baseplotwidget.h:87
pappso::BaseTracePlotWidget::getValuesX
std::vector< double > getValuesX(int index) const
Definition: basetraceplotwidget.cpp:258
pappso::BasePlotWidget::resetAxesRangeHistory
virtual void resetAxesRangeHistory()
Definition: baseplotwidget.cpp:366
pappso::BaseTracePlotWidget::axisRescale
virtual void axisRescale() override
RANGE-related functions.
Definition: basetraceplotwidget.cpp:475
pappso::BasePlotContext::wasClickOnYAxis
bool wasClickOnYAxis
Definition: baseplotwidget.h:94
pappso::BaseTracePlotWidget::axisZoom
virtual void axisZoom() override
Definition: basetraceplotwidget.cpp:642
pappso::BasePlotContext::xRegionRangeEnd
double xRegionRangeEnd
Definition: baseplotwidget.h:105
pappso::BaseTracePlotWidget::clearGraphData
virtual void clearGraphData(int graph_index)
Definition: basetraceplotwidget.cpp:104
pappso::BaseTracePlotWidget::setGraphData
virtual void setGraphData(int graph_index, const std::vector< double > &keys, const std::vector< double > &values)
Definition: basetraceplotwidget.cpp:71
pappso::BaseTracePlotWidget::~BaseTracePlotWidget
virtual ~BaseTracePlotWidget()
Destruct this BaseTracePlotWidget instance.
Definition: basetraceplotwidget.cpp:65
pappso::BasePlotContext::yDelta
double yDelta
Definition: baseplotwidget.h:111
pappso::BasePlotContext::yRegionRangeEnd
double yRegionRangeEnd
Definition: baseplotwidget.h:108
pappso::BaseTracePlotWidget::axisDoubleClickHandler
virtual void axisDoubleClickHandler(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event) override
Definition: basetraceplotwidget.cpp:409
pappso::BasePlotContext::xDelta
double xDelta
Definition: baseplotwidget.h:110
pappso::BaseTracePlotWidget::getYatX
double getYatX(double x, QCPGraph *graph_p)
Definition: basetraceplotwidget.cpp:381
pappso::BaseTracePlotWidget::findIntegrationLowerRangeForKey
virtual bool findIntegrationLowerRangeForKey(int index, double key, QCPRange &range)
Find a minimal integration range starting at an existing data point.
Definition: basetraceplotwidget.cpp:175
pappso::BasePlotContext::startDragPoint
QPointF startDragPoint
Definition: baseplotwidget.h:81
pappso::BasePlotWidget::m_context
BasePlotContext m_context
Definition: baseplotwidget.h:312
pappso::BaseTracePlotWidget::axisPan
virtual void axisPan() override
Definition: basetraceplotwidget.cpp:677
pappso::PappsoException
Definition: pappsoexception.h:62
pappso::BasePlotWidget::plotRangesChangedSignal
void plotRangesChangedSignal(const BasePlotContext &context)