summaryrefslogtreecommitdiff
path: root/QmlCustomPlot.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'QmlCustomPlot.cpp')
-rw-r--r--QmlCustomPlot.cpp335
1 files changed, 335 insertions, 0 deletions
diff --git a/QmlCustomPlot.cpp b/QmlCustomPlot.cpp
new file mode 100644
index 0000000..48ec917
--- /dev/null
+++ b/QmlCustomPlot.cpp
@@ -0,0 +1,335 @@
+#include "QmlCustomPlot.h"
+
+#include <QDebug>
+
+#include <qcustomplot.h>
+
+QmlCustomPlot::QmlCustomPlot(QQuickItem* parent)
+ : QQuickPaintedItem(parent)
+ , m_timerId(0)
+{
+ setFlag(QQuickItem::ItemHasContents, true);
+ setAcceptedMouseButtons(Qt::AllButtons);
+
+ connect(this, &QQuickPaintedItem::widthChanged,
+ this, &QmlCustomPlot::updateCustomPlotSize);
+ connect(this, &QQuickPaintedItem::heightChanged,
+ this, &QmlCustomPlot::updateCustomPlotSize);
+
+ auto t = new QTimer(this);
+ t->setInterval(1000);
+ t->setTimerType(Qt::VeryCoarseTimer);
+ t->setSingleShot(false);
+
+ connect(t, &QTimer::timeout, this, [&](){
+ setFps(m_fpsCounter);
+ m_fpsCounter = 0;
+ });
+
+ t->start();
+}
+
+QmlCustomPlot::~QmlCustomPlot()
+{
+ delete m_plot;
+ m_plot = nullptr;
+
+ if(m_timerId != 0)
+ {
+ killTimer(m_timerId);
+ }
+}
+
+void QmlCustomPlot::initCustomPlot()
+{
+ setPlot(new QCustomPlot());
+}
+
+void QmlCustomPlot::setPlot(QCustomPlot *plot)
+{
+ // m_plot = new QCustomPlot();
+ m_plot = plot;
+
+ m_plot->setBackgroundScaled(true);
+ m_plot->setBackgroundScaledMode(Qt::KeepAspectRatio);
+
+ updateCustomPlotSize();
+ m_plot->xAxis->setLabel("x");
+ m_plot->yAxis->setLabel("y");
+ m_plot->xAxis->setRange(-50, 50);
+ m_plot->yAxis->setRange(0, 100);
+ m_plot ->setInteractions(QCP::iRangeDrag |
+ QCP::iRangeZoom |
+ QCP::iSelectPlottables |
+ QCP::iSelectItems |
+ QCP::iSelectOther);
+
+ if(m_profileGraph == nullptr)
+ {
+ m_profileGraph = m_plot->addGraph();
+
+ m_profileGraph->setLineStyle(QCPGraph::lsNone);
+ m_profileGraph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, 2));
+ m_profileGraph->setPen(QPen(QColor(Qt::red)));
+ }
+
+ startTimer(1000 / 24);
+
+ connect(m_plot, &QCustomPlot::afterReplot, this, &QmlCustomPlot::onCustomReplot);
+
+ m_plot->replot();
+}
+
+void QmlCustomPlot::setPoints(const QVector<QVector2D> points)
+{
+ QVector<double> x; //(qsizetype(points.count()));
+ QVector<double> y; //(qsizetype(points.count()));
+
+ for(const auto & p : points)
+ {
+ // break;
+ if(qFuzzyIsNull(p.x()) && qFuzzyIsNull(p.y()))
+ {
+ qt_noop();
+ }
+
+ x << p.x();
+ y << p.y();
+
+ }
+
+ m_profileGraph->setData(x, y);
+
+ // setLines({
+ // QLineF(rand() % 100 - 50, rand() % 100, rand() % 100 - 50, rand() % 100),
+ // QLineF(rand() % 100 - 50, rand() % 100, rand() % 100 - 50, rand() % 100)
+ // });
+}
+
+void QmlCustomPlot::setLines(const QVector<QLineF> lines)
+{
+ while(m_lineItems.count() > lines.count())
+ {
+ m_plot->removeItem(m_lineItems.takeLast());
+ }
+
+ m_lineItems.reserve(lines.count());
+
+ const QCPLineEnding lineEnding(QCPLineEnding::esNone);
+
+ for(int i = 0; i < lines.count(); i++)
+ {
+ // const QPen linePen(QColor(Qt::green), 4);
+ // const QColor color(Qt::green);
+ // QRgb green = QRandomGenerator::generate();
+ // QRgb blue = QRandomGenerator::generate();
+ const QColor color { QRgb { QRandomGenerator::global()->generate() } };
+ const QPen linePen(color, 4);
+ QCPItemLine * l;
+
+ if(i >= m_lineItems.count())
+ {
+ l = new QCPItemLine(m_plot);
+ l->setPen(linePen);
+ l->setHead(lineEnding);
+ l->setTail(lineEnding);
+
+ m_lineItems << l;
+ }
+ else
+ {
+ l = m_lineItems[i];
+ }
+
+ const QPointF offset(0, 2);
+
+ const auto & lineToSet = lines.at(i);
+ l->start->setCoords(lineToSet.p1() + offset);
+ l->end->setCoords(lineToSet.p2() + offset);
+ }
+}
+
+void QmlCustomPlot::setContours(const QVector<Points2D> contours)
+{
+ qDebug() << "contours count" << contours.count();
+
+ while(m_contourGraphs.count() > contours.count())
+ {
+ m_plot->removeGraph(m_contourGraphs.takeLast());
+ }
+
+ m_contourGraphs.reserve(contours.count());
+
+ for(int i = 0; i < contours.count(); i++)
+ {
+ const QColor color(rand() % 0xff, rand() % 0xff, rand() % 0xff);
+ const QPen contourPen(color, 4);
+
+ QCPGraph * c;
+
+ // create new
+ if(i >= m_contourGraphs.count())
+ {
+ c = m_plot->addGraph();
+
+ c->setLineStyle(QCPGraph::lsNone);
+ c->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, 2));
+ c->setPen(contourPen);
+
+ m_contourGraphs << c;
+ }
+ // use existing graph object
+ else
+ {
+ c = m_contourGraphs[i];
+ }
+
+ // set data
+ const auto & contourToAdd = contours.at(i);
+
+ QVector<double> x; //(qsizetype(contourToAdd.count()));
+ QVector<double> y; //(qsizetype(contourToAdd.count()));
+
+ for(const auto & p : contourToAdd)
+ {
+ x << p.x();
+ y << p.y() + 5;
+ }
+
+ c->setData(x, y);
+ }
+}
+
+void QmlCustomPlot::setFps(int fps)
+{
+ m_fps = fps;
+ emit fpsChanged();
+}
+
+//void QmlCustomPlot::setPlot(QCustomPlot *plot)
+//{
+
+//}
+
+void QmlCustomPlot::paint(QPainter* painter)
+{
+ if(m_plot)
+ {
+
+ QPixmap picture(boundingRect().size().toSize());
+ QCPPainter qcpPainter(&picture);
+
+ m_plot->toPainter(&qcpPainter);
+
+ // m_bg->topLeft->setCoords(m_plot->xAxis->range().minRange, m_plot->yAxis->range().minRange);
+ // m_bg->bottomRight->setCoords(m_plot->xAxis->range().maxRange, m_plot->yAxis->range().maxRange);
+ // m_bg->topLeft->setCoords(0, 0);
+ // m_bg->bottomRight->setCoords(640, 480);
+
+ painter->drawPixmap(QPoint(), picture);
+
+ // qDebug() << m_plot->axisRect();
+ }
+}
+
+QCustomPlot *QmlCustomPlot::plot() const
+{
+ return m_plot;
+}
+
+int QmlCustomPlot::fps() const
+{
+ return m_fps;
+}
+
+void QmlCustomPlot::mousePressEvent(QMouseEvent* event)
+{
+ routeMouseEvents(event);
+}
+
+void QmlCustomPlot::mouseReleaseEvent(QMouseEvent* event)
+{
+ routeMouseEvents(event);
+}
+
+void QmlCustomPlot::mouseMoveEvent(QMouseEvent* event)
+{
+ routeMouseEvents(event);
+}
+
+void QmlCustomPlot::mouseDoubleClickEvent(QMouseEvent* event)
+{
+ qDebug() << Q_FUNC_INFO;
+ routeMouseEvents(event);
+}
+
+void QmlCustomPlot::wheelEvent(QWheelEvent *event)
+{
+ routeWheelEvents(event);
+}
+
+void QmlCustomPlot::timerEvent(QTimerEvent *event)
+{
+ // static double t, U;
+ // U = ((double)rand() / RAND_MAX) * 5;
+ // m_plot->graph(0)->addData(t, U);
+ // qDebug() << Q_FUNC_INFO << QString("Adding dot t = %1, S = %2").arg(t).arg(U);
+ // t++;
+ m_plot->replot();
+}
+
+void QmlCustomPlot::graphClicked(QCPAbstractPlottable* plottable)
+{
+ qDebug() << Q_FUNC_INFO << QString("Clicked on graph '%1 ").arg(plottable->name());
+}
+
+void QmlCustomPlot::routeMouseEvents(QMouseEvent* event)
+{
+ if(m_plot)
+ {
+ QMouseEvent* newEvent = new QMouseEvent(
+ event->type(),
+ event->position(),
+ event->scenePosition(),
+ event->globalPosition(),
+ event->button(),
+ event->buttons(),
+ event->modifiers(),
+ event->source());
+ QCoreApplication::postEvent(m_plot, newEvent);
+ }
+}
+
+void QmlCustomPlot::routeWheelEvents(QWheelEvent* event)
+{
+ if(m_plot)
+ {
+ QWheelEvent* newEvent = new QWheelEvent(
+ event->position(),
+ event->globalPosition(),
+ event->pixelDelta(),
+ event->angleDelta(),
+ event->buttons(),
+ event->modifiers(),
+ event->phase(),
+ false);
+ QCoreApplication::postEvent(m_plot, newEvent);
+ }
+}
+
+void QmlCustomPlot::updateCustomPlotSize()
+{
+ if(m_plot)
+ {
+ const QRect r(0, 0, int(width()), int(height()));
+ m_plot->setGeometry(r);
+ m_plot->setViewport(r);
+ }
+}
+
+void QmlCustomPlot::onCustomReplot()
+{
+ // qDebug() << Q_FUNC_INFO;
+ m_fpsCounter++;
+ update();
+}