2 #include <QActionGroup> 3 #include <QApplication> 6 #include <QDragEnterEvent> 7 #include <QDragMoveEvent> 12 #include <QPushButton> 13 #include <QWheelEvent> 19 #include <QtXml/QDomElement> 41 QDateTime dt = QDateTime::fromMSecsSinceEpoch((qint64)(v*1000));
42 if( dt.date().year() == 1970 && dt.date().month() == 1 && dt.date().day() == 1)
44 return dt.toString(
"hh:mm:ss.z");
46 return dt.toString(
"hh:mm:ss.z\nyyyy MMM dd");
51 const double MAX_DOUBLE = std::numeric_limits<double>::max() / 2 ;
67 _magnifier( nullptr ),
73 _mapped_data( datamap ),
86 this->setAcceptDrops(
true );
88 this->setMinimumWidth( 100 );
89 this->setMinimumHeight( 100 );
91 this->sizePolicy().setHorizontalPolicy( QSizePolicy::Expanding);
92 this->sizePolicy().setVerticalPolicy( QSizePolicy::Expanding);
96 canvas->setFrameStyle( QFrame::NoFrame );
148 this->
canvas()->setMouseTracking(
true);
160 bottomAxis->installEventFilter(
this);
161 leftAxis->installEventFilter(
this);
167 QIcon iconDeleteList;
169 auto getActionAndIcon = [
this](
const char* text,
const char* file)
172 icon.addFile( tr(file), QSize(30,30));
173 auto action =
new QAction( tr(text),
this);
179 ":/icons/resources/light/remove_list.png" );
184 ":/icons/resources/light/remove.png" );
189 ":/icons/resources/light/colored_charts.png" );
194 ":/icons/resources/light/point_chart.png" );
209 ":/icons/resources/light/zoom_horizontal.png" );
210 connect(_action_zoomOutHorizontally, &QAction::triggered,
this, [
this]()
218 ":/icons/resources/light/zoom_vertical.png" );
219 connect(_action_zoomOutVertically, &QAction::triggered,
this, [
this]()
227 font.setPointSize(10);
241 _action_1stDerivativeTransform->setCheckable(
true );
242 connect(_action_1stDerivativeTransform, &QAction::triggered,
this, [
this, font]()
244 QwtText text(
"1st Derivative");
251 _action_2ndDerivativeTransform->setCheckable(
true );
252 connect(_action_2ndDerivativeTransform, &QAction::triggered,
this, [
this, font]()
254 QwtText text(
"2nd Derivative");
261 _action_phaseXY->setCheckable(
true );
263 _action_phaseXY->setEnabled(
false);
273 ":/icons/resources/light/save.png" );
276 auto transform_group =
new QActionGroup(
this);
279 transform_group->addAction(_action_1stDerivativeTransform);
280 transform_group->addAction(_action_2ndDerivativeTransform);
281 transform_group->addAction(_action_phaseXY);
288 QString edit(
"&Edit Axis Limits ");
319 menu.setToolTipsVisible(
true);
321 "To show a XY plot, you must first provide the X axis.\n" 322 "Drag andn drop a curve using the RIGHT mouse\n" 323 "button instead of the left one." );
326 menu.exec(
canvas()->mapToGlobal(pos) );
337 QColor color( Qt::black );
340 QColor c( Qt::white );
354 font.setPointSize( 9 );
380 const auto qname = QString::fromStdString( name );
389 curve->setData( plot_qwt );
391 catch( std::exception& ex)
393 QMessageBox::warning(
this,
"Exception!", ex.what());
400 if( color == Qt::black)
408 curve->attach(
this );
413 marker->attach(
this );
421 marker->setSymbol(sym);
431 auto& curve = it->second;
438 auto marker = marker_it->second;
456 auto& curve = it.second;
461 const auto&
data = data_it->second;
463 curve->setData( data_series );
487 const QMimeData *mimeData =
event->mimeData();
488 QStringList mimeFormats = mimeData->formats();
491 for(
const QString&
format: mimeFormats)
493 QByteArray encoded = mimeData->data(
format );
494 QDataStream stream(&encoded, QIODevice::ReadOnly);
496 while (!stream.atEnd())
499 stream >> curve_name;
500 if(!curve_name.isEmpty()) {
505 if(
format.contains(
"curveslist/add_curve") )
508 event->acceptProposedAction();
513 event->acceptProposedAction();
515 if(
format.contains(
"plot_area") )
521 event->acceptProposedAction();
530 QPoint local_pos =
canvas()->mapFromGlobal(QCursor::pos()) ;
532 if(
canvas()->rect().contains( local_pos ))
545 bool curves_changed =
false;
546 bool background_changed =
false;
552 bool added =
addCurve( curve_name.toStdString() );
553 curves_changed = curves_changed || added;
560 curves_changed =
true;
575 background_changed =
true;
584 if( curves_changed || background_changed )
595 for(
auto& it:
_curve_list) { it.second->detach(); }
605 _point_marker.clear();
621 QDomElement plot_el = doc.createElement(
"plot");
623 QDomElement range_el = doc.createElement(
"range");
625 range_el.setAttribute(
"bottom", QString::number(rect.bottom(),
'f', 6) );
626 range_el.setAttribute(
"top", QString::number(rect.top(),
'f', 6));
627 range_el.setAttribute(
"left", QString::number(rect.left(),
'f', 6));
628 range_el.setAttribute(
"right", QString::number(rect.right() ,
'f', 6));
629 plot_el.appendChild(range_el);
631 QDomElement limitY_el = doc.createElement(
"limitY");
638 plot_el.appendChild(limitY_el);
642 auto&
name = it.first;
643 auto& curve = it.second;
644 QDomElement curve_el = doc.createElement(
"curve");
645 curve_el.setAttribute(
"name", QString::fromStdString(
name ));
646 curve_el.setAttribute(
"R", curve->pen().color().red());
647 curve_el.setAttribute(
"G", curve->pen().color().green());
648 curve_el.setAttribute(
"B", curve->pen().color().blue());
651 plot_el.appendChild(curve_el);
654 QDomElement
transform = doc.createElement(
"transform");
666 transform.setAttribute(
"axisX", QString::fromStdString(
_axisX->
name()) );
669 plot_el.appendChild(transform);
676 std::set<std::string> added_curve_names;
678 QDomElement
transform = plot_widget.firstChildElement(
"transform" );
680 QDomElement limitY_el = plot_widget.firstChildElement(
"limitY");
681 if( !limitY_el.isNull() )
683 if( limitY_el.hasAttribute(
"min") ) {
692 if( limitY_el.hasAttribute(
"max") ) {
702 static bool warning_message_shown =
false;
704 bool curve_added =
false;
706 for (QDomElement curve_element = plot_widget.firstChildElement(
"curve" ) ;
707 !curve_element.isNull();
708 curve_element = curve_element.nextSiblingElement(
"curve" ) )
710 std::string curve_name = curve_element.attribute(
"name").toStdString();
711 int R = curve_element.attribute(
"R").toInt();
712 int G = curve_element.attribute(
"G").toInt();
713 int B = curve_element.attribute(
"B").toInt();
718 auto added =
addCurve( curve_name );
719 curve_added = curve_added || added;
721 added_curve_names.insert(curve_name );
723 else if( ! warning_message_shown )
725 QMessageBox::warning(
this,
"Warning",
726 tr(
"Can't find one or more curves.\n" 727 "This message will be shown only once.") );
728 warning_message_shown =
true;
732 bool curve_removed =
true;
734 while( curve_removed )
736 curve_removed =
false;
739 auto curve_name = it.first;
740 if( added_curve_names.find( curve_name ) == added_curve_names.end())
743 curve_removed =
true;
749 if( !transform.isNull() )
751 QString trans_value = transform.attribute(
"value");
752 if( trans_value.isEmpty() || trans_value ==
"noTransform" )
764 else if( trans_value ==
"XYPlot" )
769 else if( trans_value.startsWith(
"Custom::" ) )
775 for (QDomElement curve_element = plot_widget.firstChildElement(
"curve" ) ;
776 !curve_element.isNull();
777 curve_element = curve_element.nextSiblingElement(
"curve" ) )
779 std::string curve_name = curve_element.attribute(
"name").toStdString();
780 auto custom_attribute = curve_element.attribute(
"custom_transform");
781 if( !custom_attribute.isNull() )
791 if( curve_removed || curve_added)
800 QDomElement rectangle = plot_widget.firstChildElement(
"range" );
806 if( !rectangle.isNull() )
809 rect.setBottom( rectangle.attribute(
"bottom").toDouble());
810 rect.setTop( rectangle.attribute(
"top").toDouble());
811 rect.setLeft( rectangle.attribute(
"left").toDouble());
812 rect.setRight( rectangle.attribute(
"right").toDouble());
835 max_rect.setLeft( rangeX.min );
836 max_rect.setRight( rangeX.max );
839 max_rect.setBottom( rangeY.min );
840 max_rect.setTop( rangeY.max );
844 const QRectF canvas_rect =
canvas()->contentsRect();
845 const double canvas_ratio = fabs( canvas_rect.width() / canvas_rect.height() );
846 const double data_ratio = fabs(max_rect.width() / max_rect.height());
847 if( data_ratio < canvas_ratio )
850 double new_width = fabs( max_rect.height() * canvas_ratio );
851 double increment = new_width - max_rect.width();
852 max_rect.setWidth( new_width );
853 max_rect.moveLeft( max_rect.left() - 0.5*increment );
857 double new_height = -(max_rect.width() / canvas_ratio);
858 double increment = fabs(new_height - max_rect.height());
859 max_rect.setHeight( new_height );
860 max_rect.moveTop( max_rect.top() + 0.5*increment );
879 QRectF canvas_rect =
canvas()->contentsRect();
880 canvas_rect = canvas_rect.normalized();
881 const double x1 = xMap.
invTransform( canvas_rect.left() );
882 const double x2 = xMap.
invTransform( canvas_rect.right() );
883 const double y1 = yMap.
invTransform( canvas_rect.bottom() );
884 const double y2 = yMap.
invTransform( canvas_rect.top() );
886 const double data_ratio = ( x2 - x1 ) / ( y2 - y1 );
887 const double canvas_ratio = canvas_rect.width() / canvas_rect.height();
890 QRectF rect( QPointF(x1,y2), QPointF(x2,y1) );
892 if( data_ratio < canvas_ratio )
894 double new_width = fabs( rect.height() * canvas_ratio );
895 double increment = new_width - rect.width();
896 rect.setWidth( new_width );
897 rect.moveLeft( rect.left() - 0.5*increment );
900 double new_height = -(rect.width() / canvas_ratio);
901 double increment = fabs(new_height - rect.height());
902 rect.setHeight( new_height );
903 rect.moveTop( rect.top() + 0.5*increment );
911 std::min(rect.bottom(), rect.top() ),
912 std::max(rect.bottom(), rect.top() ));
914 std::min( rect.left(), rect.right()),
915 std::max( rect.left(), rect.right()) );
952 if( current_rect == rect)
957 std::min(rect.bottom(), rect.top() ),
958 std::max(rect.bottom(), rect.top() ));
960 std::min( rect.left(), rect.right()),
961 std::max( rect.left(), rect.right()) );
995 auto& curve = curve_it.second;
996 const auto& curve_name = curve_it.first;
1001 const auto&
data = data_it->second;
1004 curve->setData( data_series );
1008 if( _curve_list.size() == 0){
1042 auto&
name = it.first;
1061 if( fabs( prev_offset - offset) > std::numeric_limits<double>::epsilon() )
1071 double delta = prev_offset - offset;
1072 rect.moveLeft( rect.left() + delta );
1096 double left = std::numeric_limits<double>::max();
1097 double right = -std::numeric_limits<double>::max();
1103 if( !max_range_X )
continue;
1105 left = std::min(max_range_X->min, left);
1106 right = std::max(max_range_X->max, right);
1114 double margin = 0.0;
1115 if( fabs(right - left) > std::numeric_limits<double>::epsilon() )
1117 margin =
isXYPlot() ? ((right-left) * 0.025) : 0.0;
1119 right = right + margin;
1120 left = left - margin;
1122 return PlotData::RangeTime( {left,right} );
1128 double top = -std::numeric_limits<double>::max();
1129 double bottom = std::numeric_limits<double>::max();
1136 if( !max_range_X )
continue;
1138 double left = std::max(max_range_X->min, range_X.min);
1139 double right = std::min(max_range_X->max, range_X.max);
1143 left = std::nextafter(left, right);
1144 right = std::nextafter(right, left);
1146 auto range_Y = series->getVisualizationRangeY( {left, right} );
1149 qDebug() <<
" invalid range_Y in PlotWidget::maximumRangeY";
1152 if( top < range_Y->max ) top = range_Y->max;
1153 if( bottom > range_Y->min ) bottom = range_Y->min;
1156 double margin = 0.1;
1163 if( top - bottom > std::numeric_limits<double>::epsilon() )
1165 margin = (top-bottom) * 0.025;
1174 if( top < bottom ) top = bottom + margin;
1180 if( top < bottom ) bottom = top - margin;
1183 if( !lower_limit && !upper_limit )
1210 dialog->
addCurveName( QString::fromStdString( it.first ),
1211 it.second->pen().color() );
1216 if( prev_curve_count != _curve_list.size() )
1224 std::map<std::string,QColor> color_by_name;
1228 const auto& curve_name = it.first;
1229 auto& curve = it.second;
1230 color_by_name.insert(std::make_pair( curve_name, curve->pen().color() ));
1236 Qt::DirectConnection);
1248 auto it =
_curve_list.find(curve_name.toStdString());
1251 auto& curve = it->second;
1252 if( curve->pen().color() != new_color)
1254 curve->setPen( new_color, 1.0 );
1277 auto& curve = it.second;
1287 if( current_rect == rect)
1306 QRectF rect(0, 1, 1, -1);
1320 act.setLeft( rangeX.min );
1321 act.setRight( rangeX.max );
1331 rect.setBottom( rangeY.min );
1332 rect.setTop( rangeY.max );
1346 const auto& curve_name = it.first;
1347 auto& curve = it.second;
1350 curve->setTitle( QString::fromStdString( curve_name ) );
1356 const auto&
data = data_it->second;
1358 curve->setData( data_series );
1378 QMessageBox::warning(
this, tr(
"Warning"),
1379 tr(
"To show a XY plot, you must first provide an alternative X axis.\n" 1380 "You can do this drag'n dropping a curve using the RIGHT mouse button " 1381 "instead of the left mouse button.") );
1386 std::deque<PointSeriesXY*> xy_timeseries;
1391 const auto& curve_name = it.first;
1392 auto& curve = it.second;
1398 catch(std::exception& ex)
1400 QMessageBox::warning(
this, tr(
"Error"), tr(ex.what()) );
1410 const auto& curve_name = it.first;
1411 auto& curve = it.second;
1412 curve->setData( xy_timeseries.front() );
1413 xy_timeseries.pop_front();
1418 font_footer.setPointSize(10);
1432 QByteArray xml_text = settings.value(
"AddCustomPlotDialog.savedXML",
1433 QByteArray() ).toByteArray();
1434 if( !xml_text.isEmpty() )
1442 std::string error_message;
1446 auto& curve = curve_it.second;
1447 const auto& curve_name = curve_it.first;
1453 auto&
data = data_it->second;
1456 curve->setData( data_series );
1460 curve->setTitle( QString::fromStdString(curve_name) );
1463 curve->setTitle( QString::fromStdString(curve_name) + tr(
" [") +
transform + tr(
"]") );
1470 curve->setData( data_series );
1472 error_message += curve_name + (
" [") +
transform.toStdString() + (
"]\n");
1474 curve->setTitle( QString::fromStdString(curve_name) );
1478 if( error_message.size() > 0)
1480 QMessageBox msgBox(
this);
1481 msgBox.setWindowTitle(
"Warnings");
1482 msgBox.setText(tr(
"Something went wront while creating the following curves. " 1483 "Please check that the transform equation is correct.\n\n") +
1484 QString::fromStdString(error_message) );
1493 QStringList available_trans;
1498 for (
const auto& channel: required_channels)
1506 valid = valid && it.second.equation.contains(
"value");
1510 available_trans.push_back( it.first );
1518 if (dialog.exec() == QDialog::Rejected )
1545 QFileDialog saveDialog;
1546 saveDialog.setAcceptMode(QFileDialog::AcceptSave);
1547 saveDialog.setDefaultSuffix(
"png");
1549 saveDialog.setNameFilter(
"Compatible formats (*.jpg *.jpeg *.png)");
1553 if(saveDialog.result() == QDialog::Accepted && !saveDialog.selectedFiles().empty())
1555 fileName = saveDialog.selectedFiles().first();
1557 QPixmap pixmap (1200,900);
1558 QPainter * painter =
new QPainter(&pixmap);
1560 if ( !fileName.isEmpty() )
1563 rend.
render(
this, painter, QRect(0, 0, pixmap.width(), pixmap.height()));
1564 pixmap.save(fileName);
1595 if(
_magnifier && (obj == bottomAxis || obj == leftAxis)
1598 if( event->type() == QEvent::Wheel)
1600 auto wheel_event =
dynamic_cast<QWheelEvent*
>(
event);
1601 if( obj == bottomAxis ) {
1624 switch( event->type() )
1628 auto mouse_event =
dynamic_cast<QWheelEvent*
>(
event);
1630 bool ctrl_modifier = mouse_event->modifiers() == Qt::ControlModifier;
1635 if( legend_rect.contains( mouse_event->pos() )
1639 if( mouse_event->delta() > 0 && point_size < 12)
1643 if( mouse_event->delta() < 0 && point_size > 6)
1654 case QEvent::MouseButtonPress:
1661 QMouseEvent *mouse_event =
static_cast<QMouseEvent*
>(
event);
1663 if( mouse_event->button() == Qt::LeftButton )
1665 const QPoint press_point = mouse_event->pos();
1666 if( mouse_event->modifiers() == Qt::ShiftModifier)
1673 else if( mouse_event->modifiers() == Qt::ControlModifier)
1675 QApplication::setOverrideCursor(QCursor(QPixmap(
":/icons/resources/light/move.png")));
1683 if( clicked_item == curve_it.second)
1685 auto &curve = _curve_list.at( curve_it.first );
1696 else if ( mouse_event->buttons() == Qt::MidButton &&
1697 mouse_event->modifiers() == Qt::NoModifier )
1699 QApplication::setOverrideCursor(QCursor(QPixmap(
":/icons/resource/lights/move.png")));
1702 else if( mouse_event->button() == Qt::RightButton )
1704 if( mouse_event->modifiers() == Qt::NoModifier)
1709 else if( mouse_event->modifiers() == Qt::ControlModifier)
1712 QDrag *drag =
new QDrag(
this);
1713 QMimeData *mimeData =
new QMimeData;
1716 QDataStream dataStream(&data, QIODevice::WriteOnly);
1718 dataStream << this->windowTitle();
1720 mimeData->setData(
"plot_area", data );
1721 drag->setMimeData(mimeData);
1729 case QEvent::MouseMove:
1736 QMouseEvent *mouse_event =
static_cast<QMouseEvent*
>(
event);
1738 if ( mouse_event->buttons() == Qt::LeftButton &&
1739 mouse_event->modifiers() == Qt::ShiftModifier )
1741 const QPoint point = mouse_event->pos();
1754 QApplication::restoreOverrideCursor();
1758 case QEvent::MouseButtonRelease :
1763 QApplication::restoreOverrideCursor();
1788 double min = std::numeric_limits<double>::max();
1789 double max = -std::numeric_limits<double>::max();
1793 if( data.
size() > 0){
1795 double B = data.
back().
x;
1796 min = std::min( A, min );
1797 max = std::max( B, max );
1825 catch (std::runtime_error& ex)
1829 QMessageBox msgBox(
this);
1830 msgBox.setWindowTitle(
"Warnings");
1831 msgBox.setText( tr(
"The creation of the XY plot failed with the following message:\n %1")
1836 msgBox.addButton(
"Continue", QMessageBox::AcceptRole);
1844 throw std::runtime_error(
"Creation of XY plot failed");
1850 const auto& snippet = custom_it->second;
1855 throw std::runtime_error(
"Not recognized ID in createSeriesData: ");
1873 font.setPointSize( size );
1906 static int replot_count = 0;
void setSpacing(int)
Set the spacing between the legend items.
const QwtPlotItem * processMousePressEvent(QMouseEvent *mouse_event)
std::unordered_map< std::string, PlotData > numeric
bool anyColorModified() const
void setBackgroundMode(BackgroundMode)
Set the background mode.
A plot item, that represents a series of points.
void setFont(const QFont &)
virtual QwtText label(double v) const
Convert a value into its representing label.
void setCanvasBackground(const QBrush &)
Change the background of the plotting area.
void setAxisEnabled(int axis, bool on)
En/Disable an axis.
virtual nonstd::optional< QPointF > sampleFromTime(double t)=0
void changeColor(QString, QColor)
void enableMin(bool enabled, double value)
virtual PlotData::RangeTimeOpt getVisualizationRangeX()
void setBackgroundBrush(const QBrush &)
Set the background brush.
void enableXMin(bool tf)
Enable or disable minor vertical grid lines.
void setAxisScaleDraw(int axisId, QwtScaleDraw *)
Set a scale draw.
void setCanvas(QWidget *)
Set the drawing canvas of the plot widget.
void setFont(const QFont &)
Y axis right of the canvas.
virtual QRect geometry(const QRectF &canvasRect) const
virtual void replot()
Redraw the plot.
double invTransform(int axisId, int pos) const
void enableX(bool tf)
Enable or disable vertical grid lines.
void setTextPen(const QPen &)
Set the pen for drawing text labels.
A class for drawing symbols.
void setMargin(int)
Set the margin around legend items.
Y axis left of the canvas.
Renderer for exporting a plot to a document, a printer or anything else, that is supported by QPainte...
const std::string & name() const
virtual bool event(QEvent *)
Adds handling of layout requests.
const QwtScaleWidget * axisWidget(int axisId) const
void setTimeOffset(double offset)
QBrush canvasBackground() const
void setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
void setAlignment(Qt::Alignment)
Set the alignmnet.
virtual void widgetWheelEvent(QWheelEvent *event) override
void setEnabled(bool)
En/disable the magnifier.
static QStringList getChannelsFromFuntion(const QString &function)
void enableMax(bool enabled, double value)
virtual void updateLayout()
Adjust plot content to its current size.
void setAxisAutoScale(int axisId, bool on=true)
Enable autoscaling for a specified axis.
void setDefaultMode(AxisMode mode)
bool limitsEnabled() const
void setZoomInKey(int key, Qt::KeyboardModifiers=Qt::NoModifier)
const Point & front() const
A class which draws a coordinate grid.
A class representing a text.
virtual QwtScaleMap canvasMap(int axisId) const
void setAlignCanvasToScales(bool)
Set the align-canvas-to-axis-scales flag for all axes.
SnippetsMap GetSnippetsFromXML(const QString &xml_text)
void rescaled(QRectF new_size)
void setFooter(const QString &)
std::string format(const std::string &, const time_point< seconds > &, const femtoseconds &, const time_zone &)
void panned(int dx, int dy)
void enableYMin(bool tf)
Enable or disable minor horizontal grid lines.
void keepAspectratio(bool doKeep)
void setPaintAttribute(PaintAttribute, bool on=true)
Changing the paint attributes.
virtual size_t size() const
double invTransform(double p) const
void setBorderRadius(double)
void setEnabled(bool enable)
void setZoomOutKey(int key, Qt::KeyboardModifiers=Qt::NoModifier)
void setEnabled(bool)
En/disable the picker.
void setBorderPen(const QPen &)
QColor getColorHint() const
virtual bool updateCache()=0
void addCurveName(const QString &name, const QColor &color)
virtual void setVisible(bool)
virtual void setZoomBase(bool doReplot=true)
void attach(QwtPlot *plot)
Attach the item to a plot.
void setAxisLimits(int axis, double lower, double upper)
QwtPlotPanner provides panning of a plot canvas.
double transform(int axisId, double value) const
Transform a value into a coordinate in the plotting region.
QwtScaleEngine * axisScaleEngine(int axisId)
void setRenderHint(RenderHint, bool on=true)
void setMousePattern(MousePatternCode, Qt::MouseButton button, Qt::KeyboardModifiers=Qt::NoModifier)
A class for drawing scales.
void setPosition(const QPointF &pos)
virtual void render(QwtPlot *, QPainter *, const QRectF &rect) const
const Point & back() const
void setColorHint(QColor color)
empty_struct data[sizeof(T)/sizeof(empty_struct)]
void setMouseButton(Qt::MouseButton, Qt::KeyboardModifiers=Qt::NoModifier)
virtual void resizeEvent(QResizeEvent *e)
void setParameter(Parameter par)
void enableY(bool tf)
Enable or disable horizontal grid lines.
void setRubberBandPen(const QPen &)
void setAxisScale(int axisId, double min, double max, double step=0)
Disable autoscaling and specify a fixed scale for a selected axis.
void setMouseButton(Qt::MouseButton, Qt::KeyboardModifiers=Qt::NoModifier)
void setAttribute(Attribute, bool on=true)
void zoomed(const QRectF &rect)
void updateAxes()
Rebuild the axes scales.
void setEnabled(bool)
En/disable the panner.
void setTrackerPen(const QPen &)
QwtPlotLayout * plotLayout()
A class for drawing markers.
PlotData::RangeValue rangeY() const
void setMaxColumns(uint)
Limit the number of columns.
void setDefaultRange(PlotData::RangeValue range)
Paint double buffered reusing the content of the pixmap buffer when possible.