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