git / moonbite-core / src/qt/trafficgraphwidget.cpp · raw
// Copyright (c) 2011-2019 The Bitcoin Core developers// Distributed under the MIT software license, see the accompanying// file COPYING or http://www.opensource.org/licenses/mit-license.php.#include <interfaces/node.h>#include <qt/trafficgraphwidget.h>#include <qt/clientmodel.h>#include <QPainter>#include <QPainterPath>#include <QColor>#include <QTimer>#include <cmath>#define DESIRED_SAMPLES 800#define XMARGIN 10#define YMARGIN 10TrafficGraphWidget::TrafficGraphWidget(QWidget *parent) : QWidget(parent), timer(nullptr), fMax(0.0f), nMins(0), vSamplesIn(), vSamplesOut(), nLastBytesIn(0), nLastBytesOut(0), clientModel(nullptr){ timer = new QTimer(this); connect(timer, &QTimer::timeout, this, &TrafficGraphWidget::updateRates);}void TrafficGraphWidget::setClientModel(ClientModel *model){ clientModel = model; if(model) { nLastBytesIn = model->node().getTotalBytesRecv(); nLastBytesOut = model->node().getTotalBytesSent(); }}int TrafficGraphWidget::getGraphRangeMins() const{ return nMins;}void TrafficGraphWidget::paintPath(QPainterPath &path, QQueue<float> &samples){ int sampleCount = samples.size(); if(sampleCount > 0) { int h = height() - YMARGIN * 2, w = width() - XMARGIN * 2; int x = XMARGIN + w; path.moveTo(x, YMARGIN + h); for(int i = 0; i < sampleCount; ++i) { x = XMARGIN + w - w * i / DESIRED_SAMPLES; int y = YMARGIN + h - (int)(h * samples.at(i) / fMax); path.lineTo(x, y); } path.lineTo(x, YMARGIN + h); }}void TrafficGraphWidget::paintEvent(QPaintEvent *){ QPainter painter(this); painter.fillRect(rect(), Qt::black); if(fMax <= 0.0f) return; QColor axisCol(Qt::gray); int h = height() - YMARGIN * 2; painter.setPen(axisCol); painter.drawLine(XMARGIN, YMARGIN + h, width() - XMARGIN, YMARGIN + h); // decide what order of magnitude we are int base = floor(log10(fMax)); float val = pow(10.0f, base); const QString units = tr("KB/s"); const float yMarginText = 2.0; // draw lines painter.setPen(axisCol); painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax-yMarginText, QString("%1 %2").arg(val).arg(units)); for(float y = val; y < fMax; y += val) { int yy = YMARGIN + h - h * y / fMax; painter.drawLine(XMARGIN, yy, width() - XMARGIN, yy); } // if we drew 3 or fewer lines, break them up at the next lower order of magnitude if(fMax / val <= 3.0f) { axisCol = axisCol.darker(); val = pow(10.0f, base - 1); painter.setPen(axisCol); painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax-yMarginText, QString("%1 %2").arg(val).arg(units)); int count = 1; for(float y = val; y < fMax; y += val, count++) { // don't overwrite lines drawn above if(count % 10 == 0) continue; int yy = YMARGIN + h - h * y / fMax; painter.drawLine(XMARGIN, yy, width() - XMARGIN, yy); } } painter.setRenderHint(QPainter::Antialiasing); if(!vSamplesIn.empty()) { QPainterPath p; paintPath(p, vSamplesIn); painter.fillPath(p, QColor(0, 255, 0, 128)); painter.setPen(Qt::green); painter.drawPath(p); } if(!vSamplesOut.empty()) { QPainterPath p; paintPath(p, vSamplesOut); painter.fillPath(p, QColor(255, 0, 0, 128)); painter.setPen(Qt::red); painter.drawPath(p); }}void TrafficGraphWidget::updateRates(){ if(!clientModel) return; quint64 bytesIn = clientModel->node().getTotalBytesRecv(), bytesOut = clientModel->node().getTotalBytesSent(); float inRate = (bytesIn - nLastBytesIn) / 1024.0f * 1000 / timer->interval(); float outRate = (bytesOut - nLastBytesOut) / 1024.0f * 1000 / timer->interval(); vSamplesIn.push_front(inRate); vSamplesOut.push_front(outRate); nLastBytesIn = bytesIn; nLastBytesOut = bytesOut; while(vSamplesIn.size() > DESIRED_SAMPLES) { vSamplesIn.pop_back(); } while(vSamplesOut.size() > DESIRED_SAMPLES) { vSamplesOut.pop_back(); } float tmax = 0.0f; for (const float f : vSamplesIn) { if(f > tmax) tmax = f; } for (const float f : vSamplesOut) { if(f > tmax) tmax = f; } fMax = tmax; update();}void TrafficGraphWidget::setGraphRangeMins(int mins){ nMins = mins; int msecsPerSample = nMins * 60 * 1000 / DESIRED_SAMPLES; timer->stop(); timer->setInterval(msecsPerSample); clear();}void TrafficGraphWidget::clear(){ timer->stop(); vSamplesOut.clear(); vSamplesIn.clear(); fMax = 0.0f; if(clientModel) { nLastBytesIn = clientModel->node().getTotalBytesRecv(); nLastBytesOut = clientModel->node().getTotalBytesSent(); } timer->start();}