34 #include <QMessageBox>
37 #include <QDragEnterEvent>
39 #include <QHBoxLayout>
58 std::function<
void(
const QRectF&)> resizedViewCallback,
59 std::function<
void(QEvent*)> eventCallback)
107 bottomAxis->installEventFilter(
parent);
108 leftAxis->installEventFilter(
parent);
109 this->
canvas()->installEventFilter(parent);
117 bottomAxis->installEventFilter(
parent);
118 leftAxis->removeEventFilter(
parent);
181 std::max(rect.bottom(), rect.top()));
183 std::max(rect.left(), rect.right()));
191 double left = std::numeric_limits<double>::max();
192 double right = std::numeric_limits<double>::lowest();
196 if (!it.curve->isVisible())
208 left = std::min(max_range_X->min,
left);
219 if (fabs(
right -
left) > std::numeric_limits<double>::epsilon())
231 double top = std::numeric_limits<double>::lowest();
232 double bottom = std::numeric_limits<double>::max();
236 if (!it.curve->isVisible())
249 double left = std::max(max_range_X->min, range_X.
min);
250 double right = std::min(max_range_X->max, range_X.
max);
254 auto range_Y = series->getVisualizationRangeY({
left,
right });
257 qDebug() <<
" invalid range_Y in PlotWidget::maximumRangeY";
260 if (top < range_Y->max)
264 if (bottom > range_Y->min)
266 bottom = range_Y->min;
278 if (
top - bottom > std::numeric_limits<double>::epsilon())
280 margin = (
top - bottom) * 0.025;
296 return p->canvasBoundingRect();
310 : _xy_mode(false), _keep_aspect_ratio(false)
312 auto onViewResized = [
this](
const QRectF& r) { emit
viewResized(r); };
314 auto onEvent = [
this](QEvent* event) {
315 if (
auto ev =
dynamic_cast<QDragEnterEvent*
>(event))
319 else if (
auto ev =
dynamic_cast<QDragLeaveEvent*
>(event))
323 else if (
auto ev =
dynamic_cast<QDropEvent*
>(event))
330 bool use_opengl = settings.value(
"Preferences::use_opengl",
true).toBool();
336 canvas->setFrameStyle(QFrame::NoFrame);
337 canvas->setFrameStyle(QFrame::Box | QFrame::Plain);
338 canvas->setLineWidth(1);
339 canvas->setPalette(Qt::white);
345 canvas->setFrameStyle(QFrame::NoFrame);
346 canvas->setFrameStyle(QFrame::Box | QFrame::Plain);
347 canvas->setLineWidth(1);
348 canvas->setPalette(Qt::white);
352 abs_canvas->setObjectName(
"qwtCanvas");
354 p =
new QwtPlotPimpl(
this, abs_canvas, onViewResized, onEvent);
356 auto layout =
new QHBoxLayout(
this);
357 layout->setMargin(0);
358 this->setLayout(layout);
359 layout->addWidget(
p);
361 qwtPlot()->setMinimumWidth(100);
362 qwtPlot()->setMinimumHeight(100);
364 qwtPlot()->sizePolicy().setHorizontalPolicy(QSizePolicy::Expanding);
365 qwtPlot()->sizePolicy().setVerticalPolicy(QSizePolicy::Expanding);
394 const auto qname = QString::fromStdString(name);
407 if (
auto ts_data =
dynamic_cast<const PlotData*
>(&
data))
418 curve->setData(plot_qwt);
420 catch (std::exception& ex)
422 QMessageBox::warning(
qwtPlot(),
"Exception!", ex.what());
426 if (
color == Qt::transparent)
431 curve->setPen(
color);
440 marker->setVisible(
false);
444 marker->setSymbol(sym);
447 curve_info.
curve = curve;
448 curve_info.
marker = marker;
451 p->curve_list.push_back(curve_info);
453 return &(
p->curve_list.back());
458 return p->curve_list.empty();
463 auto it = std::find_if(
p->curve_list.begin(),
p->curve_list.end(),
465 return info.curve->title() == title;
468 if (it !=
p->curve_list.end())
472 it->marker->detach();
474 p->curve_list.erase(it);
482 return p->curve_list;
487 return p->curve_list;
491 const QString& transform_ID)
494 output->setTransform(transform_ID);
495 output->updateCache(
true);
501 return p->curve_style;
524 qwtPlot()->setAcceptDrops(accept);
529 if (event->type() == QEvent::Destroy)
537 if (
magnifier() && (obj == bottomAxis || obj == leftAxis) &&
540 if (event->type() == QEvent::Wheel)
542 auto wheel_event =
dynamic_cast<QWheelEvent*
>(event);
543 if (obj == bottomAxis)
554 if (obj ==
qwtPlot()->canvas())
560 switch (event->type())
562 case QEvent::Wheel: {
563 auto mouse_event =
dynamic_cast<QWheelEvent*
>(event);
565 bool ctrl_modifier = mouse_event->modifiers() == Qt::ControlModifier;
570 if (legend_rect.contains(mouse_event->pos()) &&
legend()->isVisible())
573 int new_size = prev_size;
574 if (mouse_event->angleDelta().y() > 0)
576 new_size = std::min(13, prev_size + 1);
578 if (mouse_event->angleDelta().y() < 0)
580 new_size = std::max(7, prev_size - 1);
582 if (new_size != prev_size)
593 case QEvent::MouseButtonPress: {
594 QMouseEvent* mouse_event =
static_cast<QMouseEvent*
>(event);
595 if (mouse_event->button() == Qt::LeftButton &&
596 mouse_event->modifiers() == Qt::NoModifier)
604 bool autozoom_visibility =
605 settings.value(
"Preferences::autozoom_visibility",
true).toBool();
606 if (clicked_item == it.curve)
611 if (autozoom_visibility)
630 bool remember_color = settings.value(
"Preferences::remember_color",
true).toBool();
635 if (remember_color && colorHint.isValid())
637 return colorHint.value<QColor>();
641 bool use_plot_color_index =
642 settings.value(
"Preferences::use_plot_color_index",
false).toBool();
643 int index =
p->curve_list.size();
645 if (!use_plot_color_index)
654 color = QColor(
"#1f77b4");
657 color = QColor(
"#d62728");
660 color = QColor(
"#1ac938");
663 color = QColor(
"#ff7f0e");
667 color = QColor(
"#f14cc1");
670 color = QColor(
"#9467bd");
673 color = QColor(
"#17becf");
676 color = QColor(
"#bcbd22");
689 std::map<QString, QColor> color_by_name;
691 for (
auto& it :
p->curve_list)
693 color_by_name.insert({ it.curve->title().text(), it.curve->pen().color() });
695 return color_by_name;
700 curve->
setPen(curve->
pen().color(), (style ==
DOTS) ? 4.0 : 1.3);
729 p->curve_style = style;
730 for (
auto& it :
p->curve_list)
739 for (
auto& info :
p->curve_list)
741 if (info.curve->title() == title)
745 if (info.src_name == title.toStdString())
755 auto font =
p->legend->font();
756 font.setPointSize(
size);
757 p->legend->setFont(font);
763 p->legend->setAlignmentInCanvas(Qt::Alignment(Qt::AlignTop | alignment));
768 p->zoom_enabled = enabled;
769 p->zoomer->setEnabled(enabled);
770 p->magnifier->setEnabled(enabled);
771 p->panner1->setEnabled(enabled);
772 p->panner2->setEnabled(enabled);
777 return p->zoom_enabled;
784 p->zoomer->setZoomBase(
false);
822 max_rect.setLeft(rangeX.min);
823 max_rect.setRight(rangeX.max);
825 rangeX.min = std::numeric_limits<double>::lowest();
826 rangeX.max = std::numeric_limits<double>::max();
828 max_rect.setBottom(rangeY.min);
829 max_rect.setTop(rangeY.max);
833 const QRectF canvas_rect =
p->canvas()->contentsRect();
834 const double canvas_ratio = fabs(canvas_rect.width() / canvas_rect.height());
835 const double data_ratio = fabs(max_rect.width() / max_rect.height());
836 if (data_ratio < canvas_ratio)
839 double new_width = fabs(max_rect.height() * canvas_ratio);
840 double increment = new_width - max_rect.width();
841 max_rect.setWidth(new_width);
842 max_rect.moveLeft(max_rect.left() - 0.5 * increment);
847 double new_height = -(max_rect.width() / canvas_ratio);
848 double increment = fabs(new_height - max_rect.height());
849 max_rect.setHeight(new_height);
850 max_rect.moveTop(max_rect.top() + 0.5 * increment);