Bitcoin Core 22.99.0
P2P Digital Currency
trafficgraphwidget.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-2020 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>
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
22 QWidget(parent),
23 timer(nullptr),
24 fMax(0.0f),
25 nMins(0),
26 vSamplesIn(),
27 vSamplesOut(),
28 nLastBytesIn(0),
29 nLastBytesOut(0),
30 clientModel(nullptr)
31{
32 timer = new QTimer(this);
33 connect(timer, &QTimer::timeout, this, &TrafficGraphWidget::updateRates);
34}
35
37{
38 clientModel = model;
39 if(model) {
42 }
43}
44
46{
47 return nMins;
48}
49
50void TrafficGraphWidget::paintPath(QPainterPath &path, QQueue<float> &samples)
51{
52 int sampleCount = samples.size();
53 if(sampleCount > 0) {
54 int h = height() - YMARGIN * 2, w = width() - XMARGIN * 2;
55 int x = XMARGIN + w;
56 path.moveTo(x, YMARGIN + h);
57 for(int i = 0; i < sampleCount; ++i) {
58 x = XMARGIN + w - w * i / DESIRED_SAMPLES;
59 int y = YMARGIN + h - (int)(h * samples.at(i) / fMax);
60 path.lineTo(x, y);
61 }
62 path.lineTo(x, YMARGIN + h);
63 }
64}
65
67{
68 QPainter painter(this);
69 painter.fillRect(rect(), Qt::black);
70
71 if(fMax <= 0.0f) return;
72
73 QColor axisCol(Qt::gray);
74 int h = height() - YMARGIN * 2;
75 painter.setPen(axisCol);
76 painter.drawLine(XMARGIN, YMARGIN + h, width() - XMARGIN, YMARGIN + h);
77
78 // decide what order of magnitude we are
79 int base = floor(log10(fMax));
80 float val = pow(10.0f, base);
81
82 const QString units = tr("kB/s");
83 const float yMarginText = 2.0;
84
85 // draw lines
86 painter.setPen(axisCol);
87 painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax-yMarginText, QString("%1 %2").arg(val).arg(units));
88 for(float y = val; y < fMax; y += val) {
89 int yy = YMARGIN + h - h * y / fMax;
90 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 if(fMax / val <= 3.0f) {
94 axisCol = axisCol.darker();
95 val = pow(10.0f, base - 1);
96 painter.setPen(axisCol);
97 painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax-yMarginText, QString("%1 %2").arg(val).arg(units));
98 int count = 1;
99 for(float y = val; y < fMax; y += val, count++) {
100 // don't overwrite lines drawn above
101 if(count % 10 == 0)
102 continue;
103 int yy = YMARGIN + h - h * y / fMax;
104 painter.drawLine(XMARGIN, yy, width() - XMARGIN, yy);
105 }
106 }
107
108 painter.setRenderHint(QPainter::Antialiasing);
109 if(!vSamplesIn.empty()) {
110 QPainterPath p;
112 painter.fillPath(p, QColor(0, 255, 0, 128));
113 painter.setPen(Qt::green);
114 painter.drawPath(p);
115 }
116 if(!vSamplesOut.empty()) {
117 QPainterPath p;
119 painter.fillPath(p, QColor(255, 0, 0, 128));
120 painter.setPen(Qt::red);
121 painter.drawPath(p);
122 }
123}
124
126{
127 if(!clientModel) return;
128
129 quint64 bytesIn = clientModel->node().getTotalBytesRecv(),
130 bytesOut = clientModel->node().getTotalBytesSent();
131 float in_rate_kilobytes_per_sec = static_cast<float>(bytesIn - nLastBytesIn) / timer->interval();
132 float out_rate_kilobytes_per_sec = static_cast<float>(bytesOut - nLastBytesOut) / timer->interval();
133 vSamplesIn.push_front(in_rate_kilobytes_per_sec);
134 vSamplesOut.push_front(out_rate_kilobytes_per_sec);
135 nLastBytesIn = bytesIn;
136 nLastBytesOut = bytesOut;
137
138 while(vSamplesIn.size() > DESIRED_SAMPLES) {
139 vSamplesIn.pop_back();
140 }
141 while(vSamplesOut.size() > DESIRED_SAMPLES) {
142 vSamplesOut.pop_back();
143 }
144
145 float tmax = 0.0f;
146 for (const float f : vSamplesIn) {
147 if(f > tmax) tmax = f;
148 }
149 for (const float f : vSamplesOut) {
150 if(f > tmax) tmax = f;
151 }
152 fMax = tmax;
153 update();
154}
155
157{
158 nMins = mins;
159 int msecsPerSample = nMins * 60 * 1000 / DESIRED_SAMPLES;
160 timer->stop();
161 timer->setInterval(msecsPerSample);
162
163 clear();
164}
165
167{
168 timer->stop();
169
170 vSamplesOut.clear();
171 vSamplesIn.clear();
172 fMax = 0.0f;
173
174 if(clientModel) {
177 }
178 timer->start();
179}
Model for Bitcoin network client.
Definition: clientmodel.h:48
interfaces::Node & node() const
Definition: clientmodel.h:55
void paintEvent(QPaintEvent *) override
ClientModel * clientModel
TrafficGraphWidget(QWidget *parent=nullptr)
void setClientModel(ClientModel *model)
void setGraphRangeMins(int mins)
QQueue< float > vSamplesOut
void paintPath(QPainterPath &path, QQueue< float > &samples)
QQueue< float > vSamplesIn
virtual int64_t getTotalBytesRecv()=0
Get total bytes recv.
virtual int64_t getTotalBytesSent()=0
Get total bytes sent.
static int count
Definition: tests.c:41
#define YMARGIN
#define XMARGIN
#define DESIRED_SAMPLES