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