/src/qt/trafficgraphwidget.cpp
https://gitlab.com/Ltaimao/bitcoin · C++ · 175 lines · 143 code · 25 blank · 7 comment · 17 complexity · 39ac9ca3c1cf900d087486efd8d2d998 MD5 · raw file
- // Copyright (c) 2011-2013 The Bitcoin developers
- // Distributed under the MIT/X11 software license, see the accompanying
- // file COPYING or http://www.opensource.org/licenses/mit-license.php.
- #include "trafficgraphwidget.h"
- #include "clientmodel.h"
- #include <QPainter>
- #include <QColor>
- #include <QTimer>
- #include <cmath>
- #define DESIRED_SAMPLES 800
- #define XMARGIN 10
- #define YMARGIN 10
- TrafficGraphWidget::TrafficGraphWidget(QWidget *parent) :
- QWidget(parent),
- timer(0),
- fMax(0.0f),
- nMins(0),
- vSamplesIn(),
- vSamplesOut(),
- nLastBytesIn(0),
- nLastBytesOut(0),
- clientModel(0)
- {
- timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), SLOT(updateRates()));
- }
- void TrafficGraphWidget::setClientModel(ClientModel *model)
- {
- clientModel = model;
- if(model) {
- nLastBytesIn = model->getTotalBytesRecv();
- nLastBytesOut = model->getTotalBytesSent();
- }
- }
- int TrafficGraphWidget::getGraphRangeMins() const
- {
- return nMins;
- }
- void TrafficGraphWidget::paintPath(QPainterPath &path, QQueue<float> &samples)
- {
- int h = height() - YMARGIN * 2, w = width() - XMARGIN * 2;
- int sampleCount = samples.size(), x = XMARGIN + w, y;
- if(sampleCount > 0) {
- path.moveTo(x, YMARGIN + h);
- for(int i = 0; i < sampleCount; ++i) {
- x = XMARGIN + w - w * i / DESIRED_SAMPLES;
- 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);
- }
- }
- 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->getTotalBytesRecv(),
- bytesOut = clientModel->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;
- foreach(float f, vSamplesIn) {
- if(f > tmax) tmax = f;
- }
- foreach(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->getTotalBytesRecv();
- nLastBytesOut = clientModel->getTotalBytesSent();
- }
- timer->start();
- }