]> Devoid-pointer.net GitWeb - anyanka.git/commitdiff
Move graph drawing functions to separate class
authorMichal Malý <madcatxster@prifuk.cz>
Fri, 13 Dec 2013 18:22:05 +0000 (19:22 +0100)
committerMichal Malý <madcatxster@prifuk.cz>
Fri, 13 Dec 2013 18:22:05 +0000 (19:22 +0100)
Anyanka.pro
graphdrawer.cpp [new file with mode: 0644]
graphdrawer.h [new file with mode: 0644]
gui/graphview.cpp
gui/graphview.h
singlerunsselectormodel.cpp

index 5d5babead0c43a0cbedf5e1ea2f279f2f4002cf5..76443c8d0c379ff968323a6674c3804996328097 100644 (file)
@@ -49,7 +49,8 @@ SOURCES += main.cpp\
     gui/exportrawdatadialog.cpp \
     datafileexporter.cpp \
     datawriterbackend.cpp \
-    csvdatawriterbackend.cpp
+    csvdatawriterbackend.cpp \
+    graphdrawer.cpp
 
 HEADERS  += \
     datafilesloader.h \
@@ -79,7 +80,8 @@ HEADERS  += \
     gui/exportrawdatadialog.h \
     datafileexporter.h \
     datawriterbackend.h \
-    csvdatawriterbackend.h
+    csvdatawriterbackend.h \
+    graphdrawer.h
 
 FORMS += \
     gui/mainwindow.ui \
diff --git a/graphdrawer.cpp b/graphdrawer.cpp
new file mode 100644 (file)
index 0000000..86142c5
--- /dev/null
@@ -0,0 +1,76 @@
+#include "graphdrawer.h"
+#include <QtGui/QPainter>
+
+#include <QDebug>
+
+GraphDrawer::GraphDrawer(QObject *parent) :
+  QObject(parent)
+{
+}
+
+QPixmap* GraphDrawer::drawGraph(const double* const data, const size_t len, size_t w, size_t h, double min, double max)
+{
+  QPixmap* pixmap;
+  QPainter p;
+  int fromX = 0;
+  int fromY;
+  double xStep;
+  double yStep;
+
+  if (w < 1 || h < 1 || data == nullptr || len < 1)
+    return nullptr;
+
+  pixmap = new QPixmap(w, h);
+  p.begin(pixmap);
+  p.fillRect(0, 0, w, h, Qt::white);
+  p.setPen(QColor(Qt::blue));
+
+  xStep = static_cast<double>(w) / len;
+  yStep = static_cast<double>(h) / fabs(max - min);
+  fromY = h - yStep * data[0] - min;
+  for (uint i = 1; i < len; i++) {
+    int toX = xStep * i;
+    int toY = h - yStep * (data[i] - min);
+    p.drawLine(fromX, fromY, toX, toY);
+
+    qDebug() << "fromX" << fromX << "fromY" << fromY << "toX" << toX << "toY" << toY;
+    fromX = toX;
+    fromY = toY;
+  }
+
+  p.end();
+  return pixmap;
+}
+
+bool GraphDrawer::overlayIntegratedPeak(QPixmap* canvas, int startX, int startY, int stopX, int stopY, int peakStartX, int peakStartY, const QString& time,
+                                        const QString& area)
+{
+  QPainter p;
+  QFont font("arial", 10);
+  QFontMetrics fm(font);
+  int textWidth;
+  if (canvas == nullptr)
+    return false;
+
+  p.begin(canvas);
+  p.setPen(Qt::red);
+  p.drawLine(startX, startY, stopX, stopY);
+
+  /* Draw AREA and TIME caption */
+  p.setFont(font);
+  p.setPen(Qt::black);
+  textWidth = fm.width(time);
+  if (peakStartY - textWidth < 2)
+    peakStartY += textWidth - peakStartY + 2;
+  p.save();
+  p.translate(peakStartX, peakStartY);
+  p.rotate(-90);
+  p.drawText(0, 0, time);
+  p.rotate(+90);
+  p.restore();
+  p.drawText(peakStartX + 5, peakStartY, area);
+  p.end();
+
+  //TODO: Report back what region of the canvas has been updated to allow drawing optimizations
+  return true;
+}
diff --git a/graphdrawer.h b/graphdrawer.h
new file mode 100644 (file)
index 0000000..ad4987b
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef GRAPHDRAWER_H
+#define GRAPHDRAWER_H
+
+#include <QtCore/QObject>
+
+class GraphDrawer : public QObject
+{
+  Q_OBJECT
+public:
+  explicit GraphDrawer(QObject* parent = nullptr);
+  QPixmap* drawGraph(const double* const data, const size_t len, size_t w, size_t h, double min, double max);
+  bool overlayIntegratedPeak(QPixmap* canvas, int startX, int startY, int stopX, int stopY, int peakStartX, int peakStartY, const QString& time,
+                             const QString& area);
+
+signals:
+
+public slots:
+
+};
+
+#endif // GRAPHDRAWER_H
index 6aa98f594255340cc8cdca42df30afeffe973c45..1a0fcdf7c7c84ee3c418e7ef5c905f817fce0da0 100644 (file)
@@ -35,6 +35,7 @@ GraphView::GraphView(QWidget* parent) :
   m_graphCrosshairX(-1),
   m_graphCrosshairY(-1)
 {
+  m_graphDrawer = std::unique_ptr<GraphDrawer>(new GraphDrawer);
   setMouseTracking(true);
   setCursor(Qt::BlankCursor);
 }
@@ -205,72 +206,6 @@ void GraphView::drawCrosshair(const int x, const int y)
   update(reg);
 }
 
-void GraphView::drawIntegratedPeak(const int fromX, const double fromY, const int toX, const double toY, const int peakX, const double peakY,
-                                   const QString& time, const QString& area, const bool valley)
-{
-  QPainter p;
-  QPainter pBB;
-  QRegion reg;
-  int w, h;
-  int startX, startY, stopX, stopY, peakStartX, peakStartY;
-  double yStep, xStep;
-  double dStartY, dStopY;
-  QFont font("arial", 10);
-  QFontMetrics fm(font);
-  int textWidth;
-  if (m_backbuffer == nullptr)
-    return;
-
-  w = this->width();
-  h = this->height();
-  xStep = static_cast<double>(w) / m_drawDataLen;
-  yStep = static_cast<double>(h) / (m_drawDataMax - m_drawDataMin);
-  startX = floor(fromX * xStep + 0.5);
-  stopX = floor(toX * xStep + 0.5);
-  startY = floor((h - yStep * (fromY - m_drawDataMin)) + 0.5);
-  stopY = floor((h - yStep * (toY - m_drawDataMin)) + 0.5);
-  peakStartX = floor(peakX * xStep + 0.5);
-  peakStartY = floor(h - yStep * (peakY - m_drawDataMin) + 0.5);
-
-  dStartY = h - yStep * (fromY - m_drawDataMin);
-  dStopY = h - yStep * (toY - m_drawDataMin);
-
-  /*qDebug("Drawing peak");
-  qDebug() << "RSX" << fromX << "RSY" << fromY << "REX" << toX << "REY" << toY;
-  qDebug() << "X step" << xStep << "Y step" << yStep;
-  qDebug() << "SX" << startX << "SY" << startY << "EX" << stopX << "EY" << stopY << "w/h" << w << h;
-  qDebug() << "DSY" << dStartY << "DEY" << dStopY << "Slope I" << (toY-fromY)/(toX-fromX) << "Slope D" << (dStopY-dStartY)/(toX-fromX);
-  qDebug("---");*/
-
-  p.begin(m_plainGraph);
-  p.setPen(Qt::red);
-  p.drawLine(startX, startY, stopX, stopY);
-
-  /* Draw AREA and TIME caption */
-  p.setFont(font);
-  p.setPen(Qt::black);
-  textWidth = fm.width(time);
-  if (peakStartY - textWidth < 2)
-    peakStartY += textWidth - peakStartY + 2;
-  p.save();
-  p.translate(peakStartX, peakStartY);
-  p.rotate(-90);
-  p.drawText(0, 0, time);
-  p.rotate(+90);
-  p.restore();
-  p.drawText(peakStartX + 5, peakStartY, area);
-  p.end();
-
-  /* Copy updated plainGraph to backbuffer */
-  pBB.begin(m_backbuffer);
-  pBB.drawPixmap(QRect(0, 0, w, h), *m_plainGraph); // Can be optimized!
-  //pBB.drawPixmap(startX, 0, *m_plainGraph, startX, 0, w - startX, h);
-  pBB.end();
-
-  //reg = QRect(startX, 0, w - startX, h);
-  update(); //Again - can be optimized!
-}
-
 void GraphView::drawIntegrationBaseline(const int x, const int y)
 {
   QPainter p;
@@ -317,70 +252,10 @@ void GraphView::drawGraph()
 {
   int w = this->width();
   int h = this->height();
-  uint lastColumn = 0;
-  double yAvg = 0;
-  double yStep;
-  QPainter p;
-  QPixmap* fresh;
-
-  if (m_drawData == nullptr)
-    return;
-  if (w < 1 || h < 1)
+  QPixmap* fresh = m_graphDrawer->drawGraph(m_drawData, m_drawDataLen, w, h, m_drawDataMin, m_drawDataMax);
+  if (fresh == nullptr)
     return;
 
-  fresh = new QPixmap(w, h);
-  qDebug() << "DGR" << w << h;
-
-  p.begin(fresh);
-  p.fillRect(0, 0, w, h, Qt::white);
-  p.setPen(QColor(Qt::blue));
-
-  /* Scaling */
-  yStep = static_cast<double>(h) / fabs(m_drawDataMax - m_drawDataMin);
-
-  /* Downscale to grid */
-  if (w < m_drawDataLen) {
-    double columnsPerPixel = static_cast<double>(m_drawDataLen) / w;
-    uint columnsPerLastPixel = 0;
-    int* block = new int[w];
-    //qDebug() << "CPP" << columnsPerPixel << "yStep" << yStep << "Dims" << h << w << "Data" << w*columnsPerPixel << m_graphLen;
-    for (uint i = 0; i < m_drawDataLen; i++) {
-      uint column = i / columnsPerPixel;
-      if (column != lastColumn) {
-        yAvg /= columnsPerLastPixel;
-        block[lastColumn] = h - yStep * (yAvg -m_drawDataMin);
-        //qDebug() << "YAVG" << block[lastColumn] << "CPLP" << columnsPerLastPixel;
-        yAvg = 0;
-        columnsPerLastPixel= 0;
-        lastColumn = column;
-      }
-      yAvg += m_drawData[i];
-      columnsPerLastPixel++;
-    }
-    /* Add the last column */
-    yAvg /= columnsPerLastPixel;
-    block[w-1] = h - yStep * (yAvg - m_drawDataMin);
-    /* Draw the pixmap */
-    for (int i = 1; i < w; i++)
-      p.drawLine(i-1, floor(block[i-1]+0.5), i, floor(block[i]+0.5));
-    //qDebug() << "LAST YAVG" << block[m_graphLen-1] << "CPLP" << columnsPerLastPixel;
-    delete[] block;
-  } else { /* Upscale to grid */
-    double pixelsPerValue = static_cast<double>(w) / m_drawDataLen;
-    uint cPixX;
-    uint pPixX = 0;
-    uint cPixY;
-    uint pPixY = floor((h - yStep * (m_drawData[0] - m_drawDataMin)) + 0.5);
-    for (int i = 1; i < m_drawDataLen; i++) {
-      cPixX= floor(i * pixelsPerValue + 0.5);
-      cPixY = h - yStep * (m_drawData[i] - m_drawDataMin);
-      //qDebug() << "Upscale" << pPixX << pPixY << cPixX << cPixY;
-      p.drawLine(pPixX, pPixY, cPixX, cPixY);
-      pPixX = cPixX;
-      pPixY = cPixY;
-    }
-  }
-
   if (m_backbuffer != nullptr)
     delete m_backbuffer;
   m_backbuffer = fresh;
@@ -560,7 +435,23 @@ QRegion GraphView::eraseZoomRect(bool apply)
 void GraphView::onDrawIntegration(const int fromX, const double fromY, const int toX, const double toY, const int peakX, const double peakY,
                                   const QString& time, const QString& area, const bool valley)
 {
-  this->drawIntegratedPeak(fromX, fromY, toX, toY, peakX, peakY, time, area, valley);
+  int w = this->width();
+  int h = this->height();
+  double xStep = static_cast<double>(w) / m_drawDataLen;
+  double yStep = static_cast<double>(h) / (m_drawDataMax - m_drawDataMin);
+  int startX = floor(fromX * xStep + 0.5);
+  int stopX = floor(toX * xStep + 0.5);
+  int startY = floor((h - yStep * (fromY - m_drawDataMin)) + 0.5);
+  int stopY = floor((h - yStep * (toY - m_drawDataMin)) + 0.5);
+  int peakStartX = floor(peakX * xStep + 0.5);
+  int peakStartY = floor(h - yStep * (peakY - m_drawDataMin) + 0.5);
+
+  if (m_graphDrawer->overlayIntegratedPeak(m_plainGraph, startX, startY, stopX, stopY, peakStartX, peakStartY, time, area)) {
+    //TODO: Optimize so that the whole graph is not redrawn on each integration
+    QPainter pBB(m_backbuffer);
+    pBB.drawPixmap(QRect(0, 0, w, h), *m_plainGraph);
+    update();
+  }
 }
 
 void GraphView::onUpdateGraph(double* data, size_t len, double min, double max)
index c26f034b7f0bdf5928c55419b2bf824719f57e28..9511d82f39089a3e72dcaab2a16b39f9c737f413 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <QtGui/QMouseEvent>
 #include <QtWidgets/QWidget>
+#include "graphdrawer.h"
 #include "mathhelpers.h"
 #include "metatypes.h"
 
@@ -49,8 +50,6 @@ public:
 private:
   void drawCrosshair(const int x, const int y);
   void drawGraph();
-  void drawIntegratedPeak(const int fromX, const double fromY, const int toX, const double toY, const int peakX, const double peakY,
-                          const QString& time, const QString& area, const bool valley);
   void drawIntegrationBaseline(const int x, const int y);
   void drawZoomRect(const int x, const int y);
   QRegion eraseCrosshair(bool apply = false);
@@ -59,6 +58,7 @@ private:
 
   void resizeEvent(QResizeEvent* ev);
 
+  std::unique_ptr<GraphDrawer> m_graphDrawer;
   bool m_ctxMenuOpen;
   QPixmap* m_backbuffer;
   QPixmap* m_plainGraph;
index bf11ec29b972800892d720cecee7cc37b656119e..8624726569be09d49fc24d0e1411ccbfb8e5b1e0 100644 (file)
@@ -37,12 +37,6 @@ QVariant SingleRunsSelectorModel::data(const QModelIndex& index, int role) const
   if (m_singleRunKeys.size() == 0)
     return QVariant();
 
-  /*std::vector<std::string>::const_iterator cit = m_singleRunKeys->cbegin();
-  while (cit != m_singleRunKeys->cend()) {
-    if (runIdx == index.row())
-      return cit->first;
-    runIdx++; cit++;
-  }*/
   for (const std::string& s : m_singleRunKeys) {
     if (runIdx == index.row())
       return QString::fromStdString(s);