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