34 #include <QMessageBox> 37 #include <QDragEnterEvent> 39 #include <QHBoxLayout> 58 std::function<
void(
const QRectF&)> resizedViewCallback,
59 std::function<
void(QEvent*)> eventCallback)
61 , resized_callback(resizedViewCallback)
62 , event_callback(eventCallback)
63 , parent(parentObject)
81 magnifier->
setZoomInKey(Qt::Key_Plus, Qt::ControlModifier);
91 [
this](
const QRectF& r) {
96 [
this](
const QRectF& r) {
114 bottomAxis->installEventFilter(parent);
115 leftAxis->installEventFilter(parent);
116 this->
canvas()->installEventFilter(parent);
124 bottomAxis->installEventFilter(parent);
125 leftAxis->removeEventFilter(parent);
126 canvas()->removeEventFilter(parent);
177 const QwtPlot* PlotWidgetBase::qwtPlot()
const 182 void PlotWidgetBase::resetZoom()
184 updateMaximumZoomArea();
185 QRectF rect = maxZoomRect();
187 qwtPlot()->setAxisScale(
QwtPlot::yLeft, std::min(rect.bottom(), rect.top()),
188 std::max(rect.bottom(), rect.top()));
189 qwtPlot()->setAxisScale(
QwtPlot::xBottom, std::min(rect.left(), rect.right()),
190 std::max(rect.left(), rect.right()));
191 qwtPlot()->updateAxes();
196 Range PlotWidgetBase::getVisualizationRangeX()
const 198 double left = std::numeric_limits<double>::max();
199 double right = std::numeric_limits<double>::lowest();
201 for (
auto& it : curveList())
203 if (!it.curve->isVisible())
215 left = std::min(max_range_X->min, left);
216 right = std::max(max_range_X->max, right);
226 if (fabs(right - left) > std::numeric_limits<double>::epsilon())
228 margin = isXYPlot() ? ((right -
left) * 0.025) : 0.0;
230 right = right + margin;
231 left = left - margin;
236 Range PlotWidgetBase::getVisualizationRangeY(
Range range_X)
const 238 double top = std::numeric_limits<double>::lowest();
239 double bottom = std::numeric_limits<double>::max();
241 for (
auto& it : curveList())
243 if (!it.curve->isVisible())
256 double left = std::max(max_range_X->min, range_X.
min);
257 double right = std::min(max_range_X->max, range_X.
max);
258 left = std::nextafter(left, right);
259 right = std::nextafter(right, left);
261 auto range_Y = series->getVisualizationRangeY({
left, right });
264 qDebug() <<
" invalid range_Y in PlotWidget::maximumRangeY";
267 if (top < range_Y->max)
271 if (bottom > range_Y->min)
273 bottom = range_Y->min;
285 if (top - bottom > std::numeric_limits<double>::epsilon())
287 margin = (top - bottom) * 0.025;
293 return Range({ bottom, top });
296 bool PlotWidgetBase::isXYPlot()
const 301 QRectF PlotWidgetBase::currentBoundingRect()
const 303 return p->canvasBoundingRect();
306 QRectF PlotWidgetBase::maxZoomRect()
const 308 return _max_zoom_rect;
311 void PlotWidgetBase::setModeXY(
bool enable)
316 PlotWidgetBase::PlotWidgetBase(QWidget* parent)
317 : _xy_mode(false), _keep_aspect_ratio(false)
319 auto onViewResized = [
this](
const QRectF& r) {
323 auto onEvent = [
this](QEvent* event) {
324 if (
auto ev = dynamic_cast<QDragEnterEvent*>(event))
328 else if(
auto ev = dynamic_cast<QDragLeaveEvent*>(event))
332 else if (
auto ev = dynamic_cast<QDropEvent*>(event))
339 bool use_opengl = settings.value(
"Preferences::use_opengl",
true).toBool();
345 canvas->setFrameStyle(QFrame::NoFrame);
346 canvas->setFrameStyle(QFrame::Box | QFrame::Plain);
347 canvas->setLineWidth(1);
348 canvas->setPalette(Qt::white);
354 canvas->setFrameStyle(QFrame::NoFrame);
355 canvas->setFrameStyle(QFrame::Box | QFrame::Plain);
356 canvas->setLineWidth(1);
357 canvas->setPalette(Qt::white);
361 abs_canvas->setObjectName(
"qwtCanvas");
363 p =
new QwtPlotPimpl(
this, abs_canvas, onViewResized, onEvent);
365 auto layout =
new QHBoxLayout(
this);
366 layout->setMargin(0);
367 this->setLayout(layout);
368 layout->addWidget(
p);
370 qwtPlot()->setMinimumWidth(100);
371 qwtPlot()->setMinimumHeight(100);
373 qwtPlot()->sizePolicy().setHorizontalPolicy(QSizePolicy::Expanding);
374 qwtPlot()->sizePolicy().setVerticalPolicy(QSizePolicy::Expanding);
403 const auto qname = QString::fromStdString(name);
416 if (
auto ts_data = dynamic_cast<const PlotData*>(&data))
427 curve->setData(plot_qwt);
429 catch (std::exception& ex)
431 QMessageBox::warning(
qwtPlot(),
"Exception!", ex.what());
435 if (color == Qt::transparent)
440 curve->setPen(color);
449 marker->setVisible(
false);
453 marker->setSymbol(sym);
456 curve_info.
curve = curve;
457 curve_info.
marker = marker;
460 p->curve_list.push_back(curve_info);
462 return &(
p->curve_list.back());
467 return p->curve_list.empty();
472 auto it = std::find_if(
p->curve_list.begin(),
p->curve_list.end(),
474 return info.curve->title() == title;
477 if (it !=
p->curve_list.end())
481 it->marker->detach();
483 p->curve_list.erase(it);
491 return p->curve_list;
496 return p->curve_list;
500 const QString& transform_ID)
510 return p->curve_style;
533 qwtPlot()->setAcceptDrops(accept);
538 if (event->type() == QEvent::Destroy)
546 if (
magnifier() && (obj == bottomAxis || obj == leftAxis) &&
549 if (event->type() == QEvent::Wheel)
551 auto wheel_event =
dynamic_cast<QWheelEvent*
>(event);
552 if (obj == bottomAxis)
563 if (obj ==
qwtPlot()->canvas())
569 switch (event->type())
571 case QEvent::Wheel: {
572 auto mouse_event =
dynamic_cast<QWheelEvent*
>(event);
574 bool ctrl_modifier = mouse_event->modifiers() == Qt::ControlModifier;
582 int new_size = prev_size;
583 if (mouse_event->angleDelta().y() > 0)
585 new_size = std::min(13, prev_size + 1);
587 if (mouse_event->angleDelta().y() < 0)
589 new_size = std::max(7, prev_size - 1);
591 if (new_size != prev_size)
602 case QEvent::MouseButtonPress: {
603 QMouseEvent* mouse_event =
static_cast<QMouseEvent*
>(event);
604 if (mouse_event->button() == Qt::LeftButton &&
605 mouse_event->modifiers() == Qt::NoModifier)
613 bool autozoom_visibility = settings.value(
"Preferences::autozoom_visibility",
true).toBool();
614 if (clicked_item == it.curve)
619 if(autozoom_visibility)
638 bool remember_color = settings.value(
"Preferences::remember_color",
true).toBool();
643 if (remember_color && colorHint.isValid())
645 return colorHint.value<QColor>();
649 bool use_plot_color_index =
650 settings.value(
"Preferences::use_plot_color_index",
false).toBool();
651 int index =
p->curve_list.size();
653 if (!use_plot_color_index)
662 color = QColor(
"#1f77b4");
665 color = QColor(
"#d62728");
668 color = QColor(
"#1ac938");
671 color = QColor(
"#ff7f0e");
675 color = QColor(
"#f14cc1");
678 color = QColor(
"#9467bd");
681 color = QColor(
"#17becf");
684 color = QColor(
"#bcbd22");
697 std::map<QString, QColor> color_by_name;
699 for (
auto& it :
p->curve_list)
701 color_by_name.insert({ it.curve->title().text(), it.curve->pen().color() });
703 return color_by_name;
708 curve->
setPen(curve->
pen().color(), (style ==
DOTS) ? 4.0 : 1.3);
728 p->curve_style = style;
729 for (
auto& it :
p->curve_list)
738 for (
auto& info :
p->curve_list)
740 if (info.curve->title() == title)
744 if (info.src_name == title.toStdString())
754 auto font =
p->legend->font();
755 font.setPointSize(size);
756 p->legend->setFont(font);
762 p->legend->setAlignmentInCanvas(Qt::Alignment(Qt::AlignTop | alignment));
767 p->zoom_enabled = enabled;
768 p->zoomer->setEnabled(enabled);
769 p->magnifier->setEnabled(enabled);
770 p->panner1->setEnabled(enabled);
771 p->panner2->setEnabled(enabled);
776 return p->zoom_enabled;
783 p->zoomer->setZoomBase(
false);
821 max_rect.setLeft(rangeX.min);
822 max_rect.setRight(rangeX.max);
824 rangeX.min = std::numeric_limits<double>::lowest();
825 rangeX.max = std::numeric_limits<double>::max();
827 max_rect.setBottom(rangeY.min);
828 max_rect.setTop(rangeY.max);
832 const QRectF canvas_rect =
p->canvas()->contentsRect();
833 const double canvas_ratio = fabs(canvas_rect.width() / canvas_rect.height());
834 const double data_ratio = fabs(max_rect.width() / max_rect.height());
835 if (data_ratio < canvas_ratio)
838 double new_width = fabs(max_rect.height() * canvas_ratio);
839 double increment = new_width - max_rect.width();
840 max_rect.setWidth(new_width);
841 max_rect.moveLeft(max_rect.left() - 0.5 * increment);
846 double new_height = -(max_rect.width() / canvas_ratio);
847 double increment = fabs(new_height - max_rect.height());
848 max_rect.setHeight(new_height);
849 max_rect.moveTop(max_rect.top() + 0.5 * increment);
virtual RangeOpt getVisualizationRangeX()
const QwtPlotItem * processMousePressEvent(QMouseEvent *mouse_event)
void setStyle(CurveStyle style)
A plot item, that represents a series of points.
void setCanvasBackground(const QBrush &)
Change the background of the plotting area.
void setCanvas(QWidget *)
Set the drawing canvas of the plot widget.
virtual void replot()
Redraw the plot.
A class for drawing symbols.
virtual void widgetWheelEvent(QWheelEvent *event) override
void setAxisAutoScale(QwtAxisId, bool on=true)
Enable autoscaling for a specified axis.
void keepAspectRatio(bool doKeep)
void setDefaultMode(AxisMode mode)
void setZoomInKey(int key, Qt::KeyboardModifiers=Qt::NoModifier)
void setAxisEnabled(QwtAxisId, bool on)
En/Disable an axis.
void setAlignCanvasToScales(bool)
Set the align-canvas-to-axis-scales flag for all axes.
void rescaled(QRectF new_size)
void rescaled(QRectF new_size)
QVariant attribute(PlotAttribute id) const
void setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
void setZoomOutKey(int key, Qt::KeyboardModifiers=Qt::NoModifier)
virtual void setVisible(bool)
void attach(QwtPlot *plot)
Attach the item to a plot.
void setAxisLimits(int axis, double lower, double upper)
virtual bool event(QEvent *) QWT_OVERRIDE
Adds handling of layout requests.
virtual void resizeEvent(QResizeEvent *) QWT_OVERRIDE
virtual QRect geometry(const QRectF &canvasRect) const
void setAttribute(PlotAttribute id, const QVariant &value)
void setAxisScale(QwtAxisId, double min, double max, double stepSize=0)
Disable autoscaling and specify a fixed scale for a selected axis.
virtual QwtScaleMap canvasMap(QwtAxisId) const
void setMousePattern(MousePatternCode, Qt::MouseButton button, Qt::KeyboardModifiers=Qt::NoModifier)
const QwtScaleWidget * axisWidget(QwtAxisId) const
An alternative canvas for a QwtPlot derived from QOpenGLWidget.
span_constexpr std::size_t size(span< T, Extent > const &spn)
static const char * output
void setMouseButton(Qt::MouseButton, Qt::KeyboardModifiers=Qt::NoModifier)
void setRubberBandPen(const QPen &)
void setMouseButton(Qt::MouseButton, Qt::KeyboardModifiers=Qt::NoModifier)
void setAttribute(Attribute, bool on=true)
void zoomed(const QRectF &rect)
QwtScaleEngine * axisScaleEngine(QwtAxisId)
void setTrackerPen(const QPen &)
QwtPlotLayout * plotLayout()
A class for drawing markers.
Paint double buffered reusing the content of the pixmap buffer when possible.