2 #include "ui_simfigure.h" 13 #include <QMapIterator> 14 #include <QFileDialog> 19 #include <qwt_plot_grid.h> 20 #include <qwt_scale_engine.h> 21 #include <qwt_plot_curve.h> 22 #include <qwt_symbol.h> 23 #include <qwt_legend.h> 24 #include <qwt_plot_legenditem.h> 25 #include <qwt_plot_renderer.h> 27 #include "qwt_picker.h" 28 #include "qwt_plot_picker.h" 29 #include "qwt_plot_zoomer.h" 30 #include "qwt_plot_item.h" 31 #include "qwt_plot_shapeitem.h" 32 #include "qwt_picker_machine.h" 38 #define MIN(vec) *std::min_element(vec.constBegin(), vec.constEnd()) 39 #define MAX(vec) *std::max_element(vec.constBegin(), vec.constEnd()) 62 m_plot =
new QwtPlot(
this);
63 QVBoxLayout *lyt =
new QVBoxLayout(ui->pltWidgetSpace);
64 lyt->addWidget(m_plot);
65 m_plot->setCanvasBackground(QBrush(Qt::white));
67 ui->btn_standard->setChecked(
true);
70 m_plot->setAxisScaleEngine(QwtPlot::yLeft,
new QwtLinearScaleEngine(10));
71 m_plot->setAxisScaleEngine(QwtPlot::xBottom,
new QwtLinearScaleEngine(10));
73 m_plot->setAxisScale(QwtPlot::yLeft, 1, 100);
74 m_plot->setAxisScale(QwtPlot::xBottom, 1, 100);
78 m_picker =
new QwtPlotPicker(m_plot->canvas());
79 m_picker->setStateMachine(
new QwtPickerClickPointMachine);
81 m_picker->setTrackerMode(QwtPicker::AlwaysOn);
82 m_picker->setRubberBand(QwtPicker::RectRubberBand);
84 m_zoomer =
new QwtPlotZoomer(m_plot->canvas());
87 connect(m_picker, SIGNAL(selected(
const QPolygon &)),
this, SLOT(
on_picker_selected(
const QPolygon &)));
88 connect(m_picker, SIGNAL(appended(
const QPoint &)),
this, SLOT(
on_picker_appended(
const QPoint &)));
89 connect(m_picker, SIGNAL(moved(
const QPoint &)),
this, SLOT(
on_picker_moved(
const QPoint &)));
90 connect(m_picker, SIGNAL(removed(
const QPoint &)),
this, SLOT(
on_picker_removed(
const QPoint &)));
91 connect(m_picker, SIGNAL(changed(
const QPolygon &)),
this, SLOT(
on_picker_changed(
const QPolygon &)));
104 void SimFigure::axisTypeChanged(
void)
106 if (ui->btn_standard->isChecked())
111 m_plot->setAxisScaleEngine(QwtPlot::yLeft,
new QwtLinearScaleEngine(10));
112 m_plot->setAxisScaleEngine(QwtPlot::xBottom,
new QwtLinearScaleEngine(10));
119 else if (ui->btn_logX->isChecked())
124 m_plot->setAxisScaleEngine(QwtPlot::yLeft,
new QwtLinearScaleEngine(10));
125 m_plot->setAxisScaleEngine(QwtPlot::xBottom,
new QwtLogScaleEngine(10));
132 else if (ui->btn_logY->isChecked())
137 m_plot->setAxisScaleEngine(QwtPlot::yLeft,
new QwtLogScaleEngine(10));
138 m_plot->setAxisScaleEngine(QwtPlot::xBottom,
new QwtLinearScaleEngine(10));
145 else if (ui->btn_loglog->isChecked())
151 m_plot->setAxisMaxMajor( QwtPlot::yLeft, 6 );
152 m_plot->setAxisMaxMinor( QwtPlot::yLeft, 9 );
154 m_plot->setAxisMaxMajor( QwtPlot::xBottom, 6 );
155 m_plot->setAxisMaxMinor( QwtPlot::xBottom, 9 );
157 m_plot->setAxisScaleEngine(QwtPlot::yLeft,
new QwtLogScaleEngine(10));
158 m_plot->setAxisScaleEngine(QwtPlot::xBottom,
new QwtLogScaleEngine(10));
181 m_showMajorGrid = major;
182 m_showMinorGrid = minor;
197 switch (m_axisType) {
199 ui->btn_logX->setChecked(
true);
202 ui->btn_logY->setChecked(
true);
205 ui->btn_loglog->setChecked(
true);
208 ui->btn_standard->setChecked(
true);
211 this->axisTypeChanged();
230 if (x.length() <= 0 || y.length() <= 0)
return -1;
234 if (
MAX(x) > m_data_xmax) m_data_xmax=
MAX(x);
235 if (
MIN(x) < m_data_xmin) m_data_xmin=
MIN(x);
236 if (
MAX(y) > m_data_ymax) m_data_ymax=
MAX(y);
237 if (
MIN(y) < m_data_ymin) m_data_ymin=
MIN(y);
241 QwtPlotCurve *curve =
new QwtPlotCurve(
"default");
242 curve->setSamples(x,y);
248 curve->attach(m_plot);
250 m_curves.append(curve);
256 int idx = m_curves.length();
257 m_plotInvMap.insert(curve, idx);
285 return m_plot->axisTitle(QwtPlot::xBottom).text();
294 return m_plot->axisTitle(QwtPlot::yLeft).text();
302 int size = m_plot->axisTitle(QwtPlot::xBottom).font().pointSize();
311 int size = m_plot->title().font().pointSize();
322 QwtText text = m_plot->axisTitle(QwtPlot::xBottom);
323 QFont font = text.font();
324 font.setPointSize(sz);
326 m_plot->setAxisTitle(QwtPlot::xBottom, text);
328 text = m_plot->axisTitle(QwtPlot::yLeft);
330 m_plot->setAxisTitle(QwtPlot::yLeft, text);
341 QwtText text = m_plot->title();
342 QFont font = text.font();
343 font.setPointSize(sz);
345 m_plot->setTitle(text);
355 return m_plot->title().text();
363 m_plot->setAxisTitle(QwtPlot::xBottom, label);
371 m_plot->setAxisTitle(QwtPlot::yLeft, label);
379 m_plot->setTitle(title);
385 if (m_curves.length() > 0)
387 m_plot->setAxisScale(QwtPlot::yLeft, m_ymin, m_ymax);
388 m_plot->setAxisScale(QwtPlot::xBottom, m_xmin, m_xmax);
392 m_plot->setAxisScale(QwtPlot::yLeft, 1, 100);
393 m_plot->setAxisScale(QwtPlot::xBottom, 1, 100);
430 if (m_grid !=
nullptr)
439 m_grid =
new QwtPlotGrid();
440 m_grid->attach( m_plot );
441 m_grid->setAxes(QwtPlot::xBottom, QwtPlot::yLeft);
445 m_grid->setMajorPen(QPen(Qt::darkGray, 0.8));
446 m_grid->setMinorPen(QPen(Qt::lightGray, 0.5));
448 m_grid->enableX(
true);
449 m_grid->enableY(
true);
453 m_grid->enableXMin(
true);
454 m_grid->enableYMin(
true);
457 m_grid->enableXMin(
false);
458 m_grid->enableYMin(
false);
461 switch (m_axisType) {
463 m_plot->setAxisScaleEngine(QwtPlot::xBottom,
new QwtLinearScaleEngine);
464 m_plot->setAxisScaleEngine(QwtPlot::yLeft,
new QwtLinearScaleEngine);
467 m_plot->setAxisScaleEngine(QwtPlot::xBottom,
new QwtLogScaleEngine);
468 m_plot->setAxisScaleEngine(QwtPlot::yLeft,
new QwtLinearScaleEngine);
471 m_plot->setAxisScaleEngine(QwtPlot::xBottom,
new QwtLinearScaleEngine);
472 m_plot->setAxisScaleEngine(QwtPlot::yLeft,
new QwtLogScaleEngine);
475 m_plot->setAxisScaleEngine(QwtPlot::xBottom,
new QwtLogScaleEngine);
476 m_plot->setAxisScaleEngine(QwtPlot::yLeft,
new QwtLogScaleEngine);
496 foreach (QwtPlotCurve *curve, m_curves)
501 m_plotInvMap.clear();
509 lastSelection.object =
nullptr;
510 lastSelection.plotID = -1;
513 m_data_xmax = 1.e-20;
515 m_data_ymax = 1.e-20;
535 if (labels.length()>0)
545 if (m_legend ==
nullptr)
547 m_legend =
new QwtPlotLegendItem();
548 m_legend->attach(m_plot);
550 m_legend->setMaxColumns(1);
559 alignment = Qt::AlignTop|Qt::AlignHCenter;
563 alignment = Qt::AlignBottom|Qt::AlignHCenter;
567 alignment = Qt::AlignLeft|Qt::AlignVCenter;
571 alignment = Qt::AlignRight|Qt::AlignVCenter;
575 alignment = Qt::AlignTop|Qt::AlignLeft;
579 alignment = Qt::AlignBottom|Qt::AlignLeft;
583 alignment = Qt::AlignRight|Qt::AlignTop;
587 alignment = Qt::AlignRight|Qt::AlignBottom;
break;
590 m_legend->setAlignment(Qt::Alignment(alignment));
599 if (m_legend ==
nullptr)
601 m_legend =
new QwtPlotLegendItem();
602 m_legend->attach(m_plot);
604 m_legend->setMaxColumns(1);
621 return (m_legend!=
nullptr && m_legend->isVisible());
641 double coords[ QwtPlot::axisCnt ];
642 coords[ QwtPlot::xBottom ] = m_plot->canvasMap( QwtPlot::xBottom ).invTransform( pos.x() );
643 coords[ QwtPlot::xTop ] = m_plot->canvasMap( QwtPlot::xTop ).invTransform( pos.x() );
644 coords[ QwtPlot::yLeft ] = m_plot->canvasMap( QwtPlot::yLeft ).invTransform( pos.y() );
645 coords[ QwtPlot::yRight ] = m_plot->canvasMap( QwtPlot::yRight ).invTransform( pos.y() );
647 QwtPlotItem *item =
itemAt(pos);
651 if ( item->rtti() == QwtPlotItem::Rtti_PlotShape )
653 QwtPlotShapeItem *theShape =
static_cast<QwtPlotShapeItem *
>(item);
654 theShape->setPen(Qt::cyan, 4);
655 QBrush brush = theShape->brush();
656 QColor color = brush.color();
658 brush.setColor(color);
659 theShape->setBrush(brush);
662 if ( item->rtti() == QwtPlotItem::Rtti_PlotCurve )
664 QwtPlotCurve *theCurve =
static_cast<QwtPlotCurve *
>(item);
666 if (lastSelection.object != item)
680 qWarning() <<
"no item itentified at" << coords[QwtPlot::xBottom] << coords[QwtPlot::yLeft];
705 this->ui->axisControls->setVisible(show);
711 m_xmax = m_data_xmax;
712 m_xmin = m_data_xmin;
713 m_ymax = m_data_ymax;
714 m_ymin = m_data_ymin;
723 if ( m_plot ==
nullptr )
727 double coords[ QwtPlot::axisCnt ];
728 coords[ QwtPlot::xBottom ] = m_plot->canvasMap( QwtPlot::xBottom ).invTransform( pos.x() );
729 coords[ QwtPlot::xTop ] = m_plot->canvasMap( QwtPlot::xTop ).invTransform( pos.x() );
730 coords[ QwtPlot::yLeft ] = m_plot->canvasMap( QwtPlot::yLeft ).invTransform( pos.y() );
731 coords[ QwtPlot::yRight ] = m_plot->canvasMap( QwtPlot::yRight ).invTransform( pos.y() );
733 QwtPlotItemList items = m_plot->itemList();
734 for (
int i = items.size() - 1; i >= 0; i-- )
736 QwtPlotItem *item = items[ i ];
737 if ( item->isVisible() && item->rtti() == QwtPlotItem::Rtti_PlotCurve )
741 QwtPlotCurve *curveItem =
static_cast<QwtPlotCurve *
>( item );
742 const QPointF p( coords[ item->xAxis() ], coords[ item->yAxis() ] );
744 if ( curveItem->boundingRect().contains( p ) || true )
748 for (
size_t line=0; line < curveItem->dataSize() - 1; line++)
753 pnt = curveItem->sample(line);
754 x = m_plot->canvasMap( QwtPlot::xBottom ).transform( pnt.x() );
755 y = m_plot->canvasMap( QwtPlot::yLeft ).transform( pnt.y() );
758 pnt = curveItem->sample(line+1);
759 x = m_plot->canvasMap( QwtPlot::xBottom ).transform( pnt.x() );
760 y = m_plot->canvasMap( QwtPlot::yLeft ).transform( pnt.y() );
763 QPointF r = pos - x0;
765 double s2 = QPointF::dotProduct(s,s);
769 double xi = QPointF::dotProduct(r,s) / s2;
771 if ( 0.0 <= xi && xi <= 1.0 )
773 QPointF t(-s.y()/sqrt(s2), s.x()/sqrt(s2));
774 double d1 = QPointF::dotProduct(r,t);
775 if ( d1 < 0.0 ) { d1 = -d1; }
776 if ( d1 < dist ) { dist = d1;}
781 dist = sqrt(QPointF::dotProduct(r,r));
782 QPointF r2 = pos - x1;
783 double d2 = sqrt(QPointF::dotProduct(r2,r2));
784 if ( d2 < dist ) { dist = d2; }
790 if ( dist <= 5 )
return static_cast<QwtPlotItem *
>(curveItem);
793 if ( item->isVisible() && item->rtti() == QwtPlotItem::Rtti_PlotShape )
795 QwtPlotShapeItem *shapeItem =
static_cast<QwtPlotShapeItem *
>( item );
796 const QPointF p( coords[ item->xAxis() ], coords[ item->yAxis() ] );
798 if ( shapeItem->boundingRect().contains( p ) && shapeItem->shape().contains( p ) )
800 return static_cast<QwtPlotItem *
>(shapeItem);
814 QwtPlotItem *theItem =
nullptr;
816 if (ID > 0 && m_curves.length() >= ID && m_curves.value(ID-1) !=
nullptr)
817 theItem = m_curves.value(ID-1);
819 if (theItem)
select(theItem);
830 QwtPlotCurve *theCurve =
static_cast<QwtPlotCurve *
>(item);
833 lastSelection.object = item;
834 lastSelection.plotID = m_plotInvMap.value(theCurve, -1);
835 lastSelection.pen = theCurve->pen();
836 lastSelection.brush = theCurve->brush();
839 theCurve->setPen(Qt::cyan, 4);
842 int ID = m_plotInvMap.value(theCurve, -1);
852 if (lastSelection.object !=
nullptr)
855 QwtPlotCurve *lastCurve =
static_cast<QwtPlotCurve *
>(lastSelection.object);
856 lastCurve->setPen(lastSelection.pen);
857 lastCurve->setBrush(lastSelection.brush);
858 lastSelection.object =
nullptr;
859 lastSelection.plotID = -1;
872 if (ID > 0 && m_curves.length() <= ID && m_curves.value(ID-1) !=
nullptr)
874 QPen pen = m_curves.value(ID-1)->pen();
885 if (ID > 0 && m_curves.length() <= ID && m_curves.value(ID-1) !=
nullptr)
887 QPen pen = m_curves.value(ID-1)->pen();
896 if (ID > 0 && m_curves.length() <= ID && m_curves.value(ID-1) !=
nullptr)
898 QPen pen = m_curves.value(ID-1)->pen();
900 m_curves.value(ID-1)->setPen(pen);
907 if (ID > 0 && m_curves.length() <= ID && m_curves.value(ID-1) !=
nullptr)
909 QPen pen = m_curves.value(ID-1)->pen();
911 m_curves.value(ID-1)->setPen(pen);
924 if (ID > 0 && m_curves.length() <= ID && m_curves.value(ID-1) !=
nullptr)
934 QPen pen = curve->pen();
940 pen.setStyle(Qt::NoPen);
943 pen.setStyle(Qt::SolidLine);
946 pen.setStyle(Qt::DashLine);
949 pen.setStyle(Qt::DotLine);
952 pen.setStyle(Qt::DashDotLine);
966 if (ID > 0 && m_curves.length() <= ID && m_curves.value(ID-1) !=
nullptr)
968 const QwtSymbol *sym = m_curves.value(ID-1)->symbol();
969 int mk = sym->style();
971 case QwtSymbol::NoSymbol:
973 case QwtSymbol::XCross:
975 case QwtSymbol::Rect:
977 case QwtSymbol::Cross:
979 case QwtSymbol::Ellipse:
981 case QwtSymbol::Star1:
983 case QwtSymbol::Triangle:
985 case QwtSymbol::DTriangle:
987 case QwtSymbol::LTriangle:
989 case QwtSymbol::RTriangle:
1005 if (ID > 0 && m_curves.length() <= ID && m_curves.value(ID-1) !=
nullptr)
1007 const QwtSymbol *sym = m_curves.value(ID-1)->symbol();
1008 int size = sym->size().width();
1021 if (ID > 0 && m_curves.length() <= ID && m_curves.value(ID-1) !=
nullptr)
1036 color = curve->pen().color();
1037 brush = curve->brush().color();
1041 QwtSymbol *newSymbol =
nullptr;
1048 newSymbol =
new QwtSymbol(QwtSymbol::NoSymbol);
1051 newSymbol =
new QwtSymbol(QwtSymbol::XCross);
1054 newSymbol =
new QwtSymbol(QwtSymbol::Rect);
1057 newSymbol =
new QwtSymbol(QwtSymbol::Cross);
1060 newSymbol =
new QwtSymbol(QwtSymbol::Ellipse);
1063 newSymbol =
new QwtSymbol(QwtSymbol::Star1);
1066 newSymbol =
new QwtSymbol(QwtSymbol::Triangle);
1069 newSymbol =
new QwtSymbol(QwtSymbol::DTriangle);
1072 newSymbol =
new QwtSymbol(QwtSymbol::LTriangle);
1075 newSymbol =
new QwtSymbol(QwtSymbol::RTriangle);
1080 newSymbol =
new QwtSymbol(QwtSymbol::NoSymbol);
1083 newSymbol->setSize(size);
1085 newSymbol->setPen(color, 0.5);
1086 newSymbol->setColor(Qt::lightGray);
1088 curve->setSymbol(newSymbol);
1096 if (ID > 0 && m_curves.length() <= ID && m_curves.value(ID-1) !=
nullptr)
1098 color = m_curves.value(ID-1)->pen().color();
1109 if (ID > 0 && m_curves.length() <= ID && m_curves.value(ID-1) !=
nullptr)
1118 QPen pen = curve->pen();
1119 pen.setColor(color);
1140 QFileInfo *file =
new QFileInfo(filename);
1141 QString base = file->completeBaseName();
1142 QString ext = (file->suffix()).toLower();
1145 if (ext ==
"ps" || ext ==
"pdf" || ext ==
"png" || ext ==
"svg" || ext ==
"bmp")
1162 QString newFilename = base +
"." + ext;
1164 QwtPlotRenderer *renderer =
new QwtPlotRenderer(
this);
1165 renderer->renderDocument(m_plot, newFilename, ext, size, res);
1185 QFileInfo *file =
new QFileInfo(filename);
1186 QString base = file->completeBaseName();
1187 QString ext = (file->suffix()).toLower();
1190 if (ext ==
"ps" || ext ==
"pdf" || ext ==
"png" || ext ==
"svg" || ext ==
"bmp")
1207 QString newFilename = base +
"." + ext;
1209 QwtPlotRenderer *renderer =
new QwtPlotRenderer(
this);
1210 renderer->exportTo(m_plot, newFilename, size, res);