LCOV - code coverage report
Current view: top level - src/qt - trafficgraphwidget.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 0 118 0.0 %
Date: 2020-09-26 01:30:44 Functions: 0 9 0.0 %

          Line data    Source code
       1             : // Copyright (c) 2011-2019 The Bitcoin Core developers
       2             : // Distributed under the MIT software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #include <interfaces/node.h>
       6             : #include <qt/trafficgraphwidget.h>
       7             : #include <qt/clientmodel.h>
       8             : 
       9             : #include <QPainter>
      10             : #include <QPainterPath>
      11             : #include <QColor>
      12             : #include <QTimer>
      13             : 
      14             : #include <cmath>
      15             : 
      16             : #define DESIRED_SAMPLES         800
      17             : 
      18             : #define XMARGIN                 10
      19             : #define YMARGIN                 10
      20             : 
      21           0 : TrafficGraphWidget::TrafficGraphWidget(QWidget *parent) :
      22           0 :     QWidget(parent),
      23           0 :     timer(nullptr),
      24           0 :     fMax(0.0f),
      25           0 :     nMins(0),
      26           0 :     vSamplesIn(),
      27           0 :     vSamplesOut(),
      28           0 :     nLastBytesIn(0),
      29           0 :     nLastBytesOut(0),
      30           0 :     clientModel(nullptr)
      31           0 : {
      32           0 :     timer = new QTimer(this);
      33           0 :     connect(timer, &QTimer::timeout, this, &TrafficGraphWidget::updateRates);
      34           0 : }
      35             : 
      36           0 : void TrafficGraphWidget::setClientModel(ClientModel *model)
      37             : {
      38           0 :     clientModel = model;
      39           0 :     if(model) {
      40           0 :         nLastBytesIn = model->node().getTotalBytesRecv();
      41           0 :         nLastBytesOut = model->node().getTotalBytesSent();
      42           0 :     }
      43           0 : }
      44             : 
      45           0 : int TrafficGraphWidget::getGraphRangeMins() const
      46             : {
      47           0 :     return nMins;
      48             : }
      49             : 
      50           0 : void TrafficGraphWidget::paintPath(QPainterPath &path, QQueue<float> &samples)
      51             : {
      52           0 :     int sampleCount = samples.size();
      53           0 :     if(sampleCount > 0) {
      54           0 :         int h = height() - YMARGIN * 2, w = width() - XMARGIN * 2;
      55           0 :         int x = XMARGIN + w;
      56           0 :         path.moveTo(x, YMARGIN + h);
      57           0 :         for(int i = 0; i < sampleCount; ++i) {
      58           0 :             x = XMARGIN + w - w * i / DESIRED_SAMPLES;
      59           0 :             int y = YMARGIN + h - (int)(h * samples.at(i) / fMax);
      60           0 :             path.lineTo(x, y);
      61             :         }
      62           0 :         path.lineTo(x, YMARGIN + h);
      63           0 :     }
      64           0 : }
      65             : 
      66           0 : void TrafficGraphWidget::paintEvent(QPaintEvent *)
      67             : {
      68           0 :     QPainter painter(this);
      69           0 :     painter.fillRect(rect(), Qt::black);
      70             : 
      71           0 :     if(fMax <= 0.0f) return;
      72             : 
      73           0 :     QColor axisCol(Qt::gray);
      74           0 :     int h = height() - YMARGIN * 2;
      75           0 :     painter.setPen(axisCol);
      76           0 :     painter.drawLine(XMARGIN, YMARGIN + h, width() - XMARGIN, YMARGIN + h);
      77             : 
      78             :     // decide what order of magnitude we are
      79           0 :     int base = floor(log10(fMax));
      80           0 :     float val = pow(10.0f, base);
      81             : 
      82           0 :     const QString units     = tr("KB/s");
      83             :     const float yMarginText = 2.0;
      84             : 
      85             :     // draw lines
      86           0 :     painter.setPen(axisCol);
      87           0 :     painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax-yMarginText, QString("%1 %2").arg(val).arg(units));
      88           0 :     for(float y = val; y < fMax; y += val) {
      89           0 :         int yy = YMARGIN + h - h * y / fMax;
      90           0 :         painter.drawLine(XMARGIN, yy, width() - XMARGIN, yy);
      91             :     }
      92             :     // if we drew 3 or fewer lines, break them up at the next lower order of magnitude
      93           0 :     if(fMax / val <= 3.0f) {
      94           0 :         axisCol = axisCol.darker();
      95           0 :         val = pow(10.0f, base - 1);
      96           0 :         painter.setPen(axisCol);
      97           0 :         painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax-yMarginText, QString("%1 %2").arg(val).arg(units));
      98             :         int count = 1;
      99           0 :         for(float y = val; y < fMax; y += val, count++) {
     100             :             // don't overwrite lines drawn above
     101           0 :             if(count % 10 == 0)
     102             :                 continue;
     103           0 :             int yy = YMARGIN + h - h * y / fMax;
     104           0 :             painter.drawLine(XMARGIN, yy, width() - XMARGIN, yy);
     105           0 :         }
     106           0 :     }
     107             : 
     108           0 :     painter.setRenderHint(QPainter::Antialiasing);
     109           0 :     if(!vSamplesIn.empty()) {
     110           0 :         QPainterPath p;
     111           0 :         paintPath(p, vSamplesIn);
     112           0 :         painter.fillPath(p, QColor(0, 255, 0, 128));
     113           0 :         painter.setPen(Qt::green);
     114           0 :         painter.drawPath(p);
     115           0 :     }
     116           0 :     if(!vSamplesOut.empty()) {
     117           0 :         QPainterPath p;
     118           0 :         paintPath(p, vSamplesOut);
     119           0 :         painter.fillPath(p, QColor(255, 0, 0, 128));
     120           0 :         painter.setPen(Qt::red);
     121           0 :         painter.drawPath(p);
     122           0 :     }
     123           0 : }
     124             : 
     125           0 : void TrafficGraphWidget::updateRates()
     126             : {
     127           0 :     if(!clientModel) return;
     128             : 
     129           0 :     quint64 bytesIn = clientModel->node().getTotalBytesRecv(),
     130           0 :             bytesOut = clientModel->node().getTotalBytesSent();
     131           0 :     float inRate = (bytesIn - nLastBytesIn) / 1024.0f * 1000 / timer->interval();
     132           0 :     float outRate = (bytesOut - nLastBytesOut) / 1024.0f * 1000 / timer->interval();
     133           0 :     vSamplesIn.push_front(inRate);
     134           0 :     vSamplesOut.push_front(outRate);
     135           0 :     nLastBytesIn = bytesIn;
     136           0 :     nLastBytesOut = bytesOut;
     137             : 
     138           0 :     while(vSamplesIn.size() > DESIRED_SAMPLES) {
     139           0 :         vSamplesIn.pop_back();
     140             :     }
     141           0 :     while(vSamplesOut.size() > DESIRED_SAMPLES) {
     142           0 :         vSamplesOut.pop_back();
     143             :     }
     144             : 
     145             :     float tmax = 0.0f;
     146           0 :     for (const float f : vSamplesIn) {
     147           0 :         if(f > tmax) tmax = f;
     148             :     }
     149           0 :     for (const float f : vSamplesOut) {
     150           0 :         if(f > tmax) tmax = f;
     151             :     }
     152           0 :     fMax = tmax;
     153           0 :     update();
     154           0 : }
     155             : 
     156           0 : void TrafficGraphWidget::setGraphRangeMins(int mins)
     157             : {
     158           0 :     nMins = mins;
     159           0 :     int msecsPerSample = nMins * 60 * 1000 / DESIRED_SAMPLES;
     160           0 :     timer->stop();
     161           0 :     timer->setInterval(msecsPerSample);
     162             : 
     163           0 :     clear();
     164           0 : }
     165             : 
     166           0 : void TrafficGraphWidget::clear()
     167             : {
     168           0 :     timer->stop();
     169             : 
     170           0 :     vSamplesOut.clear();
     171           0 :     vSamplesIn.clear();
     172           0 :     fMax = 0.0f;
     173             : 
     174           0 :     if(clientModel) {
     175           0 :         nLastBytesIn = clientModel->node().getTotalBytesRecv();
     176           0 :         nLastBytesOut = clientModel->node().getTotalBytesSent();
     177           0 :     }
     178           0 :     timer->start();
     179           0 : }

Generated by: LCOV version 1.15