24 #include <QGraphicsScene>
25 #include <QGraphicsView>
26 #include <QGraphicsItem>
27 #include <QGraphicsRectItem>
28 #include <QHBoxLayout>
29 #include <QFormLayout>
30 #include <QtGui/QResizeEvent>
31 #include <QtGui/QMouseEvent>
32 #include <QtCore/QTime>
33 #include <QtCore/QTimer>
34 #include <QtCore/QFileInfo>
35 #include <QPushButton>
36 #include <QToolButton>
40 #include <QActionGroup>
41 #include <QInputDialog>
42 #include <QMessageBox>
43 #include <QFileDialog>
44 #include <QtGui/QClipboard>
45 #include <QApplication>
47 #include <QColorDialog>
50 #include <QtSvg/QSvgGenerator>
58 QGraphicsEllipseItem(0, 0, width, width, 0),
64 this->
init(dataX, dataY);
68 QGraphicsEllipseItem(0, 0, width, width, 0),
81 this->setAcceptHoverEvents(
true);
82 this->setFlag(QGraphicsItem::ItemIsFocusable,
true);
144 if(this->parentItem() && this->parentItem() !=
_textBackground->parentItem())
150 if(this->scene() && shown)
155 this->setPen(QPen(this->pen().color(), 2));
157 QRectF rect = this->scene()->sceneRect();
158 QPointF
p = this->
pos();
159 QRectF br =
_text->boundingRect();
163 if(
p.x() - br.width() < 0)
167 else if(
p.x() > rect.width())
169 p.setX(rect.width() - br.width());
173 p.setX(
p.x() - br.width());
176 if(
p.y() - br.height() < 0)
182 p.setY(
p.y() - br.height());
189 this->setPen(QPen(this->pen().color(), 1));
197 QGraphicsEllipseItem::hoverEnterEvent(event);
202 if(!this->hasFocus())
206 QGraphicsEllipseItem::hoverLeaveEvent(event);
212 QGraphicsEllipseItem::focusInEvent(event);
218 QGraphicsEllipseItem::focusOutEvent(event);
224 if(keyEvent->key() == Qt::Key_Right)
227 while(next && !next->isVisible())
231 if(next && next->isVisible())
237 else if(keyEvent->key() == Qt::Key_Left)
240 while(previous && !previous->isVisible())
244 if(previous && previous->isVisible())
247 previous->setFocus();
250 QGraphicsEllipseItem::keyReleaseEvent(keyEvent);
265 _itemsColor(0,0,0,150)
278 _itemsColor(0,0,0,150)
292 _itemsColor(0,0,0,150)
313 if(!plot || plot ==
_plot)
328 ULOGGER_DEBUG(
"curve=\"%s\" from plot=\"%s\"", this->objectName().toStdString().
c_str(), plot?plot->objectName().toStdString().c_str():
"");
330 if(plot &&
_plot == plot)
354 item = qgraphicsitem_cast<const UPlotItem *>(
_items.at(
i));
357 x = item->
data().x();
358 y = item->
data().y();
382 qreal
x =
data->data().x();
383 qreal
y =
data->data().y();
392 QGraphicsLineItem * line =
new QGraphicsLineItem(
_rootItem);
394 line->setVisible(
false);
412 data->setVisible(
false);
439 UWARN(
"New value (%f) added to curve \"%s\" is smaller "
440 "than the last added (%f). Clearing the curve.",
467 qreal
v =
value.toDouble(&ok);
474 ULOGGER_ERROR(
"Value not valid, must be a number, received %s",
value.toStdString().c_str());
480 for(
int i=0;
i<
data.size(); ++
i)
490 for(
int i=0;
i<xs.size() &&
i<ys.size(); ++
i)
501 for(
int i=0;
i<ys.size(); ++
i)
521 for(
int i=0;
i<ys.size(); ++
i)
541 for(
unsigned int i=0;
i<ys.size(); ++
i)
561 for(
unsigned int i=0;
i<ys.size(); ++
i)
579 if(index >= 0 && index <
_items.size())
584 delete _items.takeAt(index);
588 delete _items.takeAt(index+1);
600 qreal
x = tmp->
data().x();
601 qreal
y = tmp->
data().y();
646 item->scene()->removeItem(item);
691 void UPlotCurve::update(qreal scaleX, qreal scaleY, qreal offsetX, qreal offsetY, qreal xDir, qreal yDir,
int maxItemsKept)
695 xDir<0?xDir=-1:xDir=1;
696 yDir<0?yDir=-1:yDir=1;
707 if(maxItemsKept == 0 ||
j <= maxItemsKept)
710 if(!item->isVisible())
714 item->setVisible(
false);
724 QPointF newPos(((xDir*item->
data().x()+offsetX)*scaleX-item->rect().width()/2.0f),
725 ((yDir*item->
data().y()+offsetY)*scaleY-item->rect().width()/2.0f));
726 if(!item->isVisible())
728 item->setVisible(
true);
730 item->setPos(newPos);
738 _items.at(
i)->setVisible(
false);
744 QGraphicsLineItem * lineItem = (QGraphicsLineItem *)
_items.at(
i);
745 lineItem->setLine((xDir*from->
data().x()+offsetX)*scaleX,
746 (yDir*from->
data().y()+offsetY)*scaleY,
747 (xDir*to->
data().x()+offsetX)*scaleX,
748 (yDir*to->
data().y()+offsetY)*scaleY);
749 if(!lineItem->isVisible())
751 lineItem->setVisible(
true);
755 QLineF line = lineItem->line();
756 if((line.x1() <= line.x2() && line.x2() < 0-((line.x2() - line.x1()))) ||
757 (line.x1() > line.x2() && line.x2() > lineItem->scene()->sceneRect().width() + ((line.x1() - line.x2()))))
776 int x = (
int)item->x();
786 const QGraphicsLineItem * lineItem = (
const QGraphicsLineItem *)
_items.at(
i-1);
787 QLine line = lineItem->line().toLine();
788 if(limits.contains(line.p1()) || limits.contains(line.p2()))
791 QLineF::IntersectType
type;
792 #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 3)
793 type = lineItem->line().intersects(QLineF(limits.topLeft(), limits.bottomLeft()), &
intersection);
795 type = lineItem->line().intersect(QLineF(limits.topLeft(), limits.bottomLeft()), &
intersection);
797 if(
type == QLineF::BoundedIntersection)
803 #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 3)
804 type = lineItem->line().intersects(QLineF(limits.topLeft(), limits.topRight()), &
intersection);
806 type = lineItem->line().intersect(QLineF(limits.topLeft(), limits.topRight()), &
intersection);
808 if(
type == QLineF::BoundedIntersection)
814 #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 3)
815 type = lineItem->line().intersects(QLineF(limits.bottomLeft(), limits.bottomRight()), &
intersection);
817 type = lineItem->line().intersect(QLineF(limits.bottomLeft(), limits.bottomRight()), &
intersection);
819 if(
type == QLineF::BoundedIntersection)
825 #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 3)
826 type = lineItem->line().intersects(QLineF(limits.topRight(), limits.bottomRight()), &
intersection);
828 type = lineItem->line().intersect(QLineF(limits.topRight(), limits.bottomRight()), &
intersection);
830 if(
type == QLineF::BoundedIntersection)
838 painter->setPen(this->
pen());
839 painter->setBrush(this->
brush());
840 painter->drawLine(line);
865 if(index>=0 && index <
_items.size() && index % 2 == 0 )
881 _items.at(
i)->setVisible(visible);
898 for(
int i = 0;
i<
data.size(); ++
i)
906 if(
x.size() ==
y.size())
909 int margin =
int((
_items.size()+1)/2) -
x.size();
924 QVector<qreal>::const_iterator
i=
x.begin();
925 QVector<qreal>::const_iterator
j=
y.begin();
926 for(;
i!=
x.end() &&
j!=
y.end(); ++
i, ++
j, index+=2)
935 else if(
y.size()>0 &&
x.size()==0)
947 if(
x.size() ==
y.size())
965 std::vector<qreal>::const_iterator
i=
x.begin();
966 std::vector<qreal>::const_iterator
j=
y.begin();
967 for(;
i!=
x.end() &&
j!=
y.end(); ++
i, ++
j, index+=2)
976 else if(
y.size()>0 &&
x.size()==0)
988 this->
setData(std::vector<qreal>(
y.begin(),
y.end()));
1010 std::vector<qreal>::const_iterator
j=
y.begin();
1011 for(;
j!=
y.end(); ++
j, index+=2)
1027 x.resize((
_items.size()-1)/2+1);
1088 item->
setData(QPointF(item->
data().x(), threshold));
1090 item->
setData(QPointF(item->
data().x(), threshold));
1095 item->
setData(QPointF(threshold, item->
data().y()));
1097 item->
setData(QPointF(threshold, item->
data().y()));
1102 ULOGGER_ERROR(
"A threshold must has only 3 items (1 PlotItem + 1 QGraphicsLineItem + 1 PlotItem)");
1121 ULOGGER_ERROR(
"A threshold must has only 3 items (1 PlotItem + 1 QGraphicsLineItem + 1 PlotItem)");
1137 item->
setData(QPointF(-(offsetX-item->rect().width()/scaleX)/xDir, item->
data().y()));
1139 item->
setData(QPointF( (
_plot->
sceneRect().width()/scaleX-(offsetX+item->rect().width()/scaleX))/xDir, item->
data().y()));
1144 item->
setData(QPointF(item->
data().x(), -(offsetY-item->rect().height()/scaleY)/yDir));
1146 item->
setData(QPointF(item->
data().x(), (
_plot->
sceneRect().height()/scaleY-(offsetY+item->rect().height()/scaleY))/yDir));
1153 ULOGGER_ERROR(
"A threshold must has only 3 items (1 PlotItem + 1 QGraphicsLineItem + 1 PlotItem)");
1180 this->setMinimumSize(15, 25);
1182 this->setMinimumSize(15, 25);
1212 borderMin = borderMax = this->fontMetrics().height()/2;
1216 #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
1217 borderMin = this->fontMetrics().horizontalAdvance(QString::number(
_min,
'g',
_gradMaxDigits))/2;
1218 borderMax = this->fontMetrics().horizontalAdvance(QString::number(
_max,
'g',
_gradMaxDigits))/2;
1224 int border = borderMin>borderMax?borderMin:borderMax;
1269 qreal rangef =
max -
min;
1272 for(
int i=0;
i<6; ++
i)
1275 if( val >= 1.0
f && val < 10.0
f)
1316 if(borderDelta%2 != 0)
1330 #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
1331 if(this->fontMetrics().horizontalAdvance(
n) > minWidth)
1333 minWidth = this->fontMetrics().horizontalAdvance(
n);
1336 if(this->fontMetrics().width(
n) > minWidth)
1338 minWidth = this->fontMetrics().width(
n);
1343 this->setMinimumWidth(15+minWidth);
1349 QPainter painter(
this);
1352 painter.translate(0,
_border);
1357 painter.drawLine(this->width(), 0, this->width()-10, 0);
1359 painter.drawText(this->width()-(12+
n.sizeHint().width()),
n.sizeHint().height()/2-2,
n.text());
1363 painter.drawLine(this->width(), 0, this->width()-5, 0);
1365 painter.translate(0,
_step);
1370 painter.translate(
_border, 0);
1375 painter.drawLine(0, 0, 0, 10);
1377 painter.drawText(-(
n.sizeHint().width()/2)+1, 22,
n.text());
1381 painter.drawLine(0, 0, 0, 5);
1383 painter.translate(
_step, 0);
1392 QPushButton(parent),
1396 nameSpaced.replace(
'_',
' ');
1397 this->setText(nameSpaced);
1400 this->setIconSize(QSize(25,20));
1402 _aChangeText =
new QAction(tr(
"Change text..."),
this);
1403 _aResetText =
new QAction(tr(
"Reset text..."),
this);
1408 _aMoveUp =
new QAction(tr(
"Move up"),
this);
1409 _aMoveDown =
new QAction(tr(
"Move down"),
this);
1411 _menu =
new QMenu(tr(
"Curve"),
this);
1417 _menu->addSeparator();
1420 _menu->addSeparator();
1430 QAction *
action =
_menu->exec(event->globalPos());
1434 QString
text = QInputDialog::getText(
this,
_aChangeText->text(), tr(
"Name :"), QLineEdit::Normal, this->text(), &ok);
1435 if(ok && !
text.isEmpty())
1437 this->setText(
text);
1452 QColor color = QColorDialog::getColor(pen.color(),
this);
1455 pen.setColor(color);
1473 for(
int i=0;
i<
x.size(); ++
i)
1475 text.append(QString::number(
x[
i]));
1477 text.append(QString::number(
y[
i]));
1483 QClipboard * clipboard = QApplication::clipboard();
1484 clipboard->setText(
text);
1517 nameSpaced.replace(
'_',
' ');
1518 this->setText(nameSpaced);
1524 QPixmap pixmap(50, 50);
1525 pixmap.fill(Qt::transparent);
1526 QPainter painter(&pixmap);
1530 painter.drawLine(0.0, 25.0, 50.0, 25.0);
1536 QVector<qreal>
x,
y;
1542 nameSpaced.replace(
'_',
' ');
1543 nameSpaced += QString(
"\n(%1=%2, %3=%4, max=%5, n=%6)").arg(QChar(0xbc, 0x03)).arg(QString::number(
mean,
'f', 3)).arg(QChar(0xc3, 0x03)).arg(QString::number(stdDev,
'f', 3)).arg(QString::number(
max,
'f', 3)).arg(
y.size());
1544 this->setText(nameSpaced);
1564 _menu =
new QMenu(tr(
"Legend"),
this);
1573 this->setLayout(
new QVBoxLayout());
1574 this->layout()->setContentsMargins(0,0,0,0);
1577 QWidget * _scrollAreaWidgetContent =
new QWidget();
1578 _scrollArea->setWidget( _scrollAreaWidgetContent );
1599 QList<UPlotLegendItem*> items = this->findChildren<UPlotLegendItem*>();
1600 for(
int i=0;
i<items.size(); ++
i)
1602 items.at(
i)->setFlat(
_flat);
1603 items.at(
i)->setChecked(!items.at(
i)->isChecked());
1614 legendItem->setAutoDefault(
false);
1615 legendItem->setFlat(
_flat);
1616 legendItem->setCheckable(
true);
1617 legendItem->setChecked(
false);
1618 connect(legendItem, SIGNAL(toggled(
bool)),
this, SLOT(
redirectToggled(
bool)));
1624 QHBoxLayout * hLayout =
new QHBoxLayout();
1625 hLayout->addWidget(legendItem);
1626 hLayout->addStretch(0);
1627 hLayout->setContentsMargins(0,0,0,0);
1632 _scrollArea->setMinimumWidth(
std::min(480,
_scrollArea->widget()->sizeHint().width()+QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent)));
1638 QList<UPlotLegendItem *> items = this->findChildren<UPlotLegendItem*>();
1639 for(
int i=0;
i<items.size(); ++
i)
1641 if(items.at(
i)->curve() == curve)
1644 _scrollArea->setMinimumWidth(
std::min(480,
_scrollArea->widget()->sizeHint().width()+QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent)));
1662 QLayoutItem * layoutItem = 0;
1673 if(index > 0 && layoutItem)
1676 QHBoxLayout * hLayout =
new QHBoxLayout();
1677 hLayout->addWidget(layoutItem->layout()->itemAt(0)->widget());
1678 hLayout->addStretch(0);
1679 hLayout->setContentsMargins(0,0,0,0);
1689 QLayoutItem * layoutItem = 0;
1700 if(index < _contentLayout->
count()-2 && layoutItem)
1703 QHBoxLayout * hLayout =
new QHBoxLayout();
1704 hLayout->addWidget(layoutItem->layout()->itemAt(0)->widget());
1705 hLayout->addStretch(0);
1706 hLayout->setContentsMargins(0,0,0,0);
1715 QList<UPlotLegendItem *> items = this->findChildren<UPlotLegendItem*>();
1719 QMap<qreal, qreal> xAxisMap;
1720 for(
int i=0;
i<items.size(); ++
i)
1722 QMap<qreal, qreal>
data;
1723 items.at(
i)->curve()->getData(
data);
1729 QList<qreal> xAxis = xAxisMap.keys();
1731 QVector<QVector<qreal> > axes;
1732 for(
int i=0;
i<items.size(); ++
i)
1734 QMap<qreal, qreal>
data;
1735 items.at(
i)->curve()->getData(
data);
1737 QVector<qreal>
y(xAxis.size(), std::numeric_limits<qreal>::quiet_NaN());
1740 for(QList<qreal>::iterator
iter=xAxis.begin();
iter!=xAxis.end(); ++
iter)
1752 axes.push_front(xAxis.toVector());
1756 for(
int i=0;
i<items.size(); ++
i)
1758 text.append(items.at(
i)->curve()->name());
1765 for(
int i=0;
i<axes[0].size(); ++
i)
1767 for(
int j=0;
j<axes.size(); ++
j)
1775 text.append(QString::number(axes[
j][
i],
'f'));
1782 if(
i+1<axes[0].
size())
1795 QAction *
action =
_menu->exec(event->globalPos());
1805 QClipboard * clipboard = QApplication::clipboard();
1806 clipboard->setText(
data);
1811 QList<UPlotLegendItem *> items = this->findChildren<UPlotLegendItem*>();
1812 for(
int i=0;
i<items.size(); ++
i)
1838 QLabel(
text, parent),
1849 QSize
size = QLabel::sizeHint();
1858 QSize
size = QLabel::minimumSizeHint();
1870 setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
1874 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
1889 p.translate(-height(), 0);
1890 QSize
size = r.size();
1895 p.drawText(r, this->alignment() | (this->wordWrap()?Qt::TextWordWrap:0), this->
text());
1915 _graphicsViewHolder(0),
1919 _maxVisibleItems(-1),
1924 _workingDirectory(QDir::homePath()),
1925 _lowestRefreshRate(99),
1926 _autoScreenCaptureFormat(
"png"),
1927 _bgColor(Qt::white),
1939 _aAddVerticalLine(0),
1940 _aAddHorizontalLine(0),
1944 _aChangeBackgroundColor(0),
1945 _aYLabelVertical(0),
1946 _aShowRefreshRate(0),
1949 _aAutoScreenCapture(0),
1965 for(
int i=0;
i<4; ++
i)
1993 _view =
new QGraphicsView(
this);
1994 _view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1995 _view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1996 _view->setScene(
new QGraphicsScene(0,0,0,0,
this));
1997 _view->setStyleSheet(
"QGraphicsView { border-style: none; }" );
1999 _sceneRoot->setTransform(QTransform::fromTranslate(0, 0),
true);
2010 _title->setAlignment(Qt::AlignCenter);
2011 _xLabel->setAlignment(Qt::AlignCenter);
2012 _yLabel->setAlignment(Qt::AlignCenter);
2014 _title->setWordWrap(
true);
2017 _title->setVisible(
false);
2024 vLayout->setContentsMargins(0,0,0,0);
2025 vLayout->addWidget(
_view);
2027 QGridLayout * grid =
new QGridLayout(
this);
2028 grid->setContentsMargins(0,0,0,0);
2029 grid->addWidget(
_title, 0, 2);
2030 grid->addWidget(
_yLabel, 1, 0);
2034 grid->setColumnStretch(2, 1);
2035 grid->setRowStretch(1, 1);
2037 grid->addWidget(
_xLabel, 3, 2);
2038 grid->addWidget(
_legend, 1, 3);
2049 _aShowGrid =
new QAction(tr(
"Show grid"),
this);
2059 _aLimit0 =
new QAction(tr(
"No maximum items shown"),
this);
2060 _aLimit10 =
new QAction(tr(
"10"),
this);
2061 _aLimit50 =
new QAction(tr(
"50"),
this);
2083 _aSaveFigure =
new QAction(tr(
"Save figure..."),
this);
2086 _aClearData =
new QAction(tr(
"Clear data"),
this);
2088 QActionGroup * grpLimit =
new QActionGroup(
this);
2101 _menu =
new QMenu(tr(
"Plot"),
this);
2108 _menu->addSeparator()->setStatusTip(tr(
"Maximum items shown"));
2116 _menu->addSeparator();
2117 QMenu * addLineMenu =
_menu->addMenu(tr(
"Add line"));
2120 _menu->addSeparator();
2123 QMenu * yLabelMenu =
_menu->addMenu(tr(
"Y label"));
2129 _menu->addSeparator();
2155 ULOGGER_DEBUG(
"Adding curve \"%s\" to plot \"%s\"...", curve->
name().toStdString().c_str(),
this->title().toStdString().c_str());
2158 if(!qobject_cast<UPlotCurveThreshold*>(curve))
2162 if(!qobject_cast<UPlotCurveThreshold*>(
_curves.at(
i)))
2174 if(ownershipTransferred)
2176 curve->setParent(
this);
2186 ULOGGER_DEBUG(
"Curve \"%s\" added to plot \"%s\"", curve->
name().toStdString().c_str(),
this->title().toStdString().c_str());
2205 names.append((*iter)->name());
2215 if(*
iter && (*iter)->name().compare(curveName) == 0)
2217 return qobject_cast<UPlotCurveThreshold*>(*
iter) != 0;
2227 if(*
iter && (*iter)->name().compare(curveName) == 0)
2236 UERROR(
"Curve \"%s\" not found as theshold!", curveName.toStdString().c_str());
2244 if(*
iter && (*iter)->name().compare(curveName) == 0)
2255 bool colorNotUsed =
false;
2256 for(
int i=0;
i<12; ++
i)
2258 QColor tmp((Qt::GlobalColor)((penStyle+
i) % 12 + 7 ));
2259 bool colorAlreadyUsed =
false;
2262 colorAlreadyUsed = (*iter)->pen().color() == tmp;
2264 if(!colorAlreadyUsed)
2266 colorNotUsed =
true;
2288 if((*i)->isVisible() && ((
UPlotCurve *)(*
i))->itemsSize() > maxItem)
2291 maxItem =
c->itemsSize();
2300 qreal
axis[4] = {0};
2301 for(
int i=0;
i<4; ++
i)
2317 _view->scene()->setSceneRect(newRect);
2329 qreal
w = newRect.width()-(borderHor*2);
2330 qreal
h = newRect.height()-(borderVer*2);
2333 QPen dashPen(Qt::DashLine);
2335 QPen pen(dashPen.color());
2336 for(qreal
i=0.0
f;
i*stepV <=
h+stepV;
i+=5.0f)
2344 painter->setPen(pen);
2345 painter->drawLine(0, stepV*
i+borderVer+0.5
f, borderHor, stepV*
i+borderVer+0.5
f);
2347 painter->setPen(dashPen);
2348 painter->drawLine(borderHor, stepV*
i+borderVer+0.5
f,
w+borderHor, stepV*
i+borderVer+0.5
f);
2350 painter->setPen(pen);
2351 painter->drawLine(
w+borderHor, stepV*
i+borderVer+0.5
f,
w+borderHor*2, stepV*
i+borderVer+0.5
f);
2357 hGridLines.append(
new QGraphicsLineItem(0, stepV*
i+borderVer, borderHor, stepV*
i+borderVer,
_sceneRoot));
2359 hGridLines.append(
new QGraphicsLineItem(borderHor, stepV*
i+borderVer,
w+borderHor, stepV*
i+borderVer,
_sceneRoot));
2361 hGridLines.append(
new QGraphicsLineItem(
w+borderHor, stepV*
i+borderVer,
w+borderHor*2, stepV*
i+borderVer,
_sceneRoot));
2365 for(qreal
i=0;
i*stepH <
w+stepH;
i+=5.0f)
2373 painter->setPen(pen);
2374 painter->drawLine(stepH*
i+borderHor+0.5
f, 0, stepH*
i+borderHor+0.5
f, borderVer);
2376 painter->setPen(dashPen);
2377 painter->drawLine(stepH*
i+borderHor+0.5
f, borderVer, stepH*
i+borderHor+0.5
f,
h+borderVer);
2379 painter->setPen(pen);
2380 painter->drawLine(stepH*
i+borderHor+0.5
f,
h+borderVer, stepH*
i+borderHor+0.5
f,
h+borderVer*2);
2386 vGridLines.append(
new QGraphicsLineItem(stepH*
i+borderHor, 0, stepH*
i+borderHor, borderVer,
_sceneRoot));
2388 vGridLines.append(
new QGraphicsLineItem(stepH*
i+borderHor, borderVer, stepH*
i+borderHor,
h+borderVer,
_sceneRoot));
2390 vGridLines.append(
new QGraphicsLineItem(stepH*
i+borderHor,
h+borderVer, stepH*
i+borderHor,
h+borderVer*2,
_sceneRoot));
2403 scaleX = (newRect.width()-(borderHor*2)) / den;
2408 scaleY = (newRect.height()-(borderVer*2)) / den;
2412 if((*i)->isVisible())
2416 (*i)->update(scaleX,
2418 xDir<0?
axis[1]+borderHor/scaleX:-(
axis[0]-borderHor/scaleX),
2419 yDir<0?
axis[3]+borderVer/scaleY:-(
axis[2]-borderVer/scaleY),
2466 const QVector<qreal> & minMax = curve->
getMinMax();
2468 if(minMax.size() != 4)
2473 this->
updateAxis(minMax[0], minMax[1], minMax[2], minMax[3]);
2480 bool modified =
false;
2496 bool modified =
false;
2531 for(
int i=0;
i<4; ++
i)
2544 const QVector<qreal> & minMax =
_curves.at(
i)->getMinMax();
2545 this->
updateAxis(minMax[0], minMax[1], minMax[2], minMax[3]);
2561 QPainter painter(
this);
2565 painter.setPen(QPen(Qt::NoPen));
2574 int left, top, right, bottom;
2595 painter.setPen(Qt::NoPen);
2598 painter.drawRect(0, top, left, bottom-top);
2606 QWidget::paintEvent(event);
2616 QWidget::resizeEvent(event);
2623 QWidget::mousePressEvent(event);
2630 if(!(QApplication::mouseButtons() & Qt::LeftButton))
2638 if(QApplication::mouseButtons() & Qt::LeftButton)
2646 if((QApplication::mouseButtons() & Qt::LeftButton) ||
2647 (
_aMouseTracking->isChecked() && xPos>=0 && yPos>=0 && xPos<_graphicsViewHolder->width() && yPos<_graphicsViewHolder->height()))
2649 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
2650 QToolTip::showText(event->globalPosition().toPoint(), QString(
"%1,%2").
arg(
x).
arg(
y));
2652 QToolTip::showText(event->globalPos(), QString(
"%1,%2").
arg(
x).
arg(
y));
2657 QToolTip::hideText();
2662 QToolTip::hideText();
2665 QWidget::mouseMoveEvent(event);
2672 int left,top,bottom,right;
2679 if(right - left > 5 || bottom - top > 5)
2688 for(
int i=0;
i<4; ++
i)
2700 QWidget::mouseReleaseEvent(event);
2706 QWidget::mouseDoubleClickEvent(event);
2715 if(maxX == 0 || maxY == 0)
2724 else if(xPos > maxX)
2733 else if(yPos > maxY)
2754 QAction *
action =
_menu->exec(event->globalPos());
2797 QString
text = QInputDialog::getText(
this,
action->text(), tr(
"New line name :"), QLineEdit::Normal,
"", &ok);
2798 while(ok &&
text.isEmpty())
2800 QMessageBox::warning(
this,
action->text(), tr(
"The name is not valid or it is already used in this plot."));
2801 text = QInputDialog::getText(
this,
action->text(), tr(
"New line name :"), QLineEdit::Normal,
"", &ok);
2814 double value = QInputDialog::getDouble(
this,
2841 text = this->objectName();
2843 text = QInputDialog::getText(
this,
_aChangeTitle->text(), tr(
"Title :"), QLineEdit::Normal,
text, &ok);
2852 QString
text = QInputDialog::getText(
this,
_aChangeXLabel->text(), tr(
"X axis label :"), QLineEdit::Normal,
_xLabel->text(), &ok);
2861 QString
text = QInputDialog::getText(
this,
_aChangeYLabel->text(), tr(
"Y axis label :"), QLineEdit::Normal,
_yLabel->text(), &ok);
2873 QColor color = QColorDialog::getColor(
_bgColor,
this);
2884 text = QFileDialog::getSaveFileName(
this, tr(
"Save figure to ..."), (QDir::homePath() +
"/") + this->
title() +
".png",
"*.png *.xpm *.jpg *.pdf *.svg");
2886 text = QFileDialog::getSaveFileName(
this, tr(
"Save figure to ..."), (QDir::homePath() +
"/") + this->
title() +
".png",
"*.png *.xpm *.jpg *.pdf");
2890 bool flatModified =
false;
2894 flatModified =
true;
2897 QPalette
p(palette());
2899 QColor
c =
p.color(QPalette::Window);
2900 p.setColor(QPalette::Window, Qt::white);
2906 QSvgGenerator generator;
2907 generator.setFileName(
text);
2908 generator.setSize(this->
size());
2910 painter.begin(&generator);
2911 this->render(&painter);
2920 printer.setOutputFormat(QPrinter::PdfFormat);
2921 printer.setOutputFileName(
text);
2922 this->render(&printer);
2926 QPixmap figure = this->grab();
2933 p.setColor(QPalette::Window,
c);
2967 ULOGGER_ERROR(
"The directory \"%s\" doesn't exist", workingDirectory.toStdString().c_str());
2979 if(!dir.exists(targetDir))
2981 dir.mkdir(targetDir);
2984 targetDir += this->
title().replace(
" ",
"_");
2985 if(!dir.exists(targetDir))
2987 dir.mkdir(targetDir);
2991 QPixmap figure = this->grab();
2992 figure.save(targetDir +
name);
2998 items << QString(
"png") << QString(
"jpg");
3000 QString item = QInputDialog::getItem(
this, tr(
"Select format"), tr(
"Format:"), items, 0,
false, &ok);
3001 if(ok && !item.isEmpty())
3013 if(qobject_cast<UPlotCurveThreshold*>(
_curves.at(
i)) == 0)
3023 if(!xAxis && !yAxis)
3031 if(qobject_cast<UPlotCurveThreshold*>(
_curves.at(
i)) == 0)
3033 const QVector<qreal> & minMax =
_curves.at(
i)->getMinMax();
3034 if(minMax.size() == 4)
3036 if(minMax[0] < minX)
3040 if(minMax[2] < minY)
3051 if(qobject_cast<UPlotCurveThreshold*>(
_curves.at(
i)) == 0)
3056 for(
int j=0;
j<
x.size(); ++
j)
3078 QPen pen = curve->
pen();
3102 QTimer::singleShot(10,
this, SLOT(
updateAxis()));
3113 QTimer::singleShot(10,
this, SLOT(
updateAxis()));
3126 QTimer::singleShot(10,
this, SLOT(
updateAxis()));
3146 item->setZValue(1.0
f);
3156 QTimer::singleShot(10,
this, SLOT(
updateAxis()));
3173 QTimer::singleShot(10,
this, SLOT(
updateAxis()));
3180 this->setMouseTracking(tracking);
3186 _view->setVisible(on);
3198 if(maxVisibleItems <= 0)
3202 else if(maxVisibleItems == 10)
3206 else if(maxVisibleItems == 50)
3210 else if(maxVisibleItems == 100)
3214 else if(maxVisibleItems == 500)
3218 else if(maxVisibleItems == 1000)
3234 return _view->sceneRect();
3239 QList<UPlotCurve*> tmp =
_curves;
3240 for(QList<UPlotCurve*>::iterator
iter=tmp.begin();
iter!=tmp.end(); ++
iter)
3249 QList<UPlotCurve *>::iterator
iter = std::find(
_curves.begin(),
_curves.end(), curve);
3251 ULOGGER_DEBUG(
"Plot=\"%s\" removing curve=\"%s\"", this->objectName().toStdString().
c_str(), curve?curve->
name().toStdString().c_str():
"");
3259 if(!qobject_cast<UPlotCurveThreshold*>(
c))
3264 if(!qobject_cast<UPlotCurveThreshold*>(
_curves.at(
i)))
3272 if(
c->parent() ==
this)
3283 QList<UPlotCurve *>::iterator
iter = std::find(
_curves.begin(),
_curves.end(), curve);
3287 if(
value->isVisible() != shown)
3289 value->setVisible(shown);
3298 int currentIndex = -1;
3310 if(
c && currentIndex != index)
3312 _curves.removeAt(currentIndex);
3313 QList<QGraphicsItem *> children =
_sceneRoot->childItems();
3315 if(currentIndex > index)
3317 children[currentIndex]->stackBefore(children[index]);
3321 if(currentIndex<children.size()-2)
3323 if(index < children.size()-1)
3325 children[index]->stackBefore(children[currentIndex]);
3329 children[currentIndex]->stackBefore(children[index]);
3332 if(currentIndex == children.size()-2 && currentIndex < index)
3334 children[index]->stackBefore(children[currentIndex]);