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();}