1 // Copyright (c) 2011-2013 The Bitcoin developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #include "trafficgraphwidget.h"
6 #include "clientmodel.h"
9 #include <QPainterPath>
15 #define DESIRED_SAMPLES 800
20 TrafficGraphWidget::TrafficGraphWidget(QWidget *parent) :
31 timer = new QTimer(this);
32 connect(timer, SIGNAL(timeout()), SLOT(updateRates()));
35 void TrafficGraphWidget::setClientModel(ClientModel *model)
39 nLastBytesIn = model->getTotalBytesRecv();
40 nLastBytesOut = model->getTotalBytesSent();
44 int TrafficGraphWidget::getGraphRangeMins() const
49 void TrafficGraphWidget::paintPath(QPainterPath &path, QQueue<float> &samples)
51 int h = height() - YMARGIN * 2, w = width() - XMARGIN * 2;
52 int sampleCount = samples.size(), x = XMARGIN + w, y;
54 path.moveTo(x, YMARGIN + h);
55 for(int i = 0; i < sampleCount; ++i) {
56 x = XMARGIN + w - w * i / DESIRED_SAMPLES;
57 y = YMARGIN + h - (int)(h * samples.at(i) / fMax);
60 path.lineTo(x, YMARGIN + h);
64 void TrafficGraphWidget::paintEvent(QPaintEvent *)
66 QPainter painter(this);
67 painter.fillRect(rect(), Qt::black);
69 if(fMax <= 0.0f) return;
71 QColor axisCol(Qt::gray);
72 int h = height() - YMARGIN * 2;
73 painter.setPen(axisCol);
74 painter.drawLine(XMARGIN, YMARGIN + h, width() - XMARGIN, YMARGIN + h);
76 // decide what order of magnitude we are
77 int base = floor(log10(fMax));
78 float val = pow(10.0f, base);
80 const QString units = tr("KB/s");
81 const float yMarginText = 2.0;
84 painter.setPen(axisCol);
85 painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax-yMarginText, QString("%1 %2").arg(val).arg(units));
86 for(float y = val; y < fMax; y += val) {
87 int yy = YMARGIN + h - h * y / fMax;
88 painter.drawLine(XMARGIN, yy, width() - XMARGIN, yy);
90 // if we drew 3 or fewer lines, break them up at the next lower order of magnitude
91 if(fMax / val <= 3.0f) {
92 axisCol = axisCol.darker();
93 val = pow(10.0f, base - 1);
94 painter.setPen(axisCol);
95 painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax-yMarginText, QString("%1 %2").arg(val).arg(units));
97 for(float y = val; y < fMax; y += val, count++) {
98 // don't overwrite lines drawn above
101 int yy = YMARGIN + h - h * y / fMax;
102 painter.drawLine(XMARGIN, yy, width() - XMARGIN, yy);
106 if(!vSamplesIn.empty()) {
108 paintPath(p, vSamplesIn);
109 painter.fillPath(p, QColor(0, 255, 0, 128));
110 painter.setPen(Qt::green);
113 if(!vSamplesOut.empty()) {
115 paintPath(p, vSamplesOut);
116 painter.fillPath(p, QColor(255, 0, 0, 128));
117 painter.setPen(Qt::red);
122 void TrafficGraphWidget::updateRates()
124 if(!clientModel) return;
126 quint64 bytesIn = clientModel->getTotalBytesRecv(),
127 bytesOut = clientModel->getTotalBytesSent();
128 float inRate = (bytesIn - nLastBytesIn) / 1024.0f * 1000 / timer->interval();
129 float outRate = (bytesOut - nLastBytesOut) / 1024.0f * 1000 / timer->interval();
130 vSamplesIn.push_front(inRate);
131 vSamplesOut.push_front(outRate);
132 nLastBytesIn = bytesIn;
133 nLastBytesOut = bytesOut;
135 while(vSamplesIn.size() > DESIRED_SAMPLES) {
136 vSamplesIn.pop_back();
138 while(vSamplesOut.size() > DESIRED_SAMPLES) {
139 vSamplesOut.pop_back();
143 foreach(float f, vSamplesIn) {
144 if(f > tmax) tmax = f;
146 foreach(float f, vSamplesOut) {
147 if(f > tmax) tmax = f;
153 void TrafficGraphWidget::setGraphRangeMins(int mins)
156 int msecsPerSample = nMins * 60 * 1000 / DESIRED_SAMPLES;
158 timer->setInterval(msecsPerSample);
163 void TrafficGraphWidget::clear()
172 nLastBytesIn = clientModel->getTotalBytesRecv();
173 nLastBytesOut = clientModel->getTotalBytesSent();