You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

trafficgraphwidget.cpp 4.7KB

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