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