improved display in bw statistics

This commit is contained in:
csoler 2017-05-11 14:42:06 +02:00
parent d73e850122
commit eb30af57bd
3 changed files with 73 additions and 36 deletions

View File

@ -59,6 +59,7 @@ RSGraphSource::RSGraphSource()
#endif #endif
_timer = new QTimer ; _timer = new QTimer ;
_digits = 2 ; _digits = 2 ;
_filtering_enabled = true;
QObject::connect(_timer,SIGNAL(timeout()),this,SLOT(updateIfPossible())) ; QObject::connect(_timer,SIGNAL(timeout()),this,SLOT(updateIfPossible())) ;
} }
@ -123,6 +124,9 @@ void RSGraphSource::getDataPoints(int index,std::vector<QPointF>& pts,float filt
pts.clear() ; pts.clear() ;
qint64 now = getTime() ; qint64 now = getTime() ;
if(!_filtering_enabled)
filter_factor = 0 ;
std::map<std::string,std::list<std::pair<qint64,float> > >::const_iterator it = _points.begin(); std::map<std::string,std::list<std::pair<qint64,float> > >::const_iterator it = _points.begin();
int n=0; int n=0;
@ -267,11 +271,13 @@ RSGraphWidget::RSGraphWidget(QWidget *parent)
_timer = new QTimer ; _timer = new QTimer ;
QObject::connect(_timer,SIGNAL(timeout()),this,SLOT(updateIfPossible())) ; QObject::connect(_timer,SIGNAL(timeout()),this,SLOT(updateIfPossible())) ;
_y_scale = 1.0f ; _y_scale = 1.0f ;
_timer->start(1000); _timer->start(1000);
float FS = QFontMetricsF(font()).height(); float FS = QFontMetricsF(font()).height();
setMinimumHeight(12*FS); setMinimumHeight(12*FS);
_graph_base = FS*GRAPH_BASE;
} }
void RSGraphWidget::updateIfPossible() void RSGraphWidget::updateIfPossible()
@ -292,7 +298,13 @@ RSGraphWidget::~RSGraphWidget()
delete _source ; delete _source ;
} }
/** Gets the width of the desktop, which is the maximum number of points void RSGraphWidget::setFiltering(bool b)
{
if(_source != NULL)
_source->setFiltering(b) ;
}
/** Gets the width of the desktop, which is the maximum number of points
* we can plot in the graph. */ * we can plot in the graph. */
int int
RSGraphWidget::getNumPoints() RSGraphWidget::getNumPoints()
@ -465,42 +477,43 @@ void RSGraphWidget::pointsFromData(const std::vector<QPointF>& values,QVector<QP
qreal px = x - (values[i].x()-last)*_time_scale ; qreal px = x - (values[i].x()-last)*_time_scale ;
qreal py = y - valueToPixels(values[i].y()) ; qreal py = y - valueToPixels(values[i].y()) ;
if(px >= SCALE_WIDTH*fact && last_px < SCALE_WIDTH*fact) if(!(_flags & RSGRAPH_FLAGS_PAINT_STYLE_DOTS))
{ {
float alpha = (SCALE_WIDTH*fact - last_px)/(px - last_px) ; if(px >= SCALE_WIDTH*fact && last_px < SCALE_WIDTH*fact)
float ipx = SCALE_WIDTH*fact ; {
float ipy = (1-alpha)*last_py + alpha*py ; float alpha = (SCALE_WIDTH*fact - last_px)/(px - last_px) ;
float ipx = SCALE_WIDTH*fact ;
float ipy = (1-alpha)*last_py + alpha*py ;
points << QPointF(ipx,y) ; points << QPointF(ipx,y - _graph_base) ;
points << QPointF(ipx,ipy) ; points << QPointF(ipx,ipy) ;
} }
else if(i==0) else if(i==0)
{ {
if(px < SCALE_WIDTH*fact) if(px < SCALE_WIDTH*fact)
points << QPointF(SCALE_WIDTH*fact,py) ; points << QPointF(SCALE_WIDTH*fact,py) ;
else else
points << QPointF(px,y) ; points << QPointF(px,y - _graph_base) ;
}
} }
if(px < SCALE_WIDTH*fact) if(px < SCALE_WIDTH*fact)
continue ; continue ;
if((_flags & RSGRAPH_FLAGS_PAINT_STYLE_DOTS) && values[i].y() == 0)
continue ;
_maxValue = std::max(_maxValue,values[i].y()) ; _maxValue = std::max(_maxValue,values[i].y()) ;
// remove midle point when 3 consecutive points have the same value. // remove midle point when 3 consecutive points have the same value.
if(points.size() > 1 && points[points.size()-2].y() == points.back().y() && points.back().y() == py) if(!(_flags & RSGRAPH_FLAGS_PAINT_STYLE_DOTS))
points.pop_back() ; if(points.size() > 1 && points[points.size()-2].y() == points.back().y() && points.back().y() == py)
points.pop_back() ;
// if(fabs(px - last_px)/_time_scale > min_x_no_data_threshold)
// {
// points << QPointF(last_px,y) ;
// points << QPointF(px,y) ;
// }
points << QPointF(px,py) ; points << QPointF(px,py) ;
if(i==values.size()-1) if(!(_flags & RSGRAPH_FLAGS_PAINT_STYLE_DOTS) && (i==values.size()-1))
points << QPointF(px,y) ; points << QPointF(px,y) ;
last_px = px ; last_px = px ;
@ -512,17 +525,17 @@ void RSGraphWidget::pointsFromData(const std::vector<QPointF>& values,QVector<QP
qreal RSGraphWidget::valueToPixels(qreal val) qreal RSGraphWidget::valueToPixels(qreal val)
{ {
if(_flags & RSGRAPH_FLAGS_LOG_SCALE_Y) if(_flags & RSGRAPH_FLAGS_LOG_SCALE_Y)
return log(std::max((qreal)1.0,val))*_y_scale ; return _graph_base + log(std::max((qreal)1.0,val))*_y_scale ;
else else
return val*_y_scale ; return _graph_base + val*_y_scale ;
} }
qreal RSGraphWidget::pixelsToValue(qreal val) qreal RSGraphWidget::pixelsToValue(qreal val)
{ {
if(_flags & RSGRAPH_FLAGS_LOG_SCALE_Y) if(_flags & RSGRAPH_FLAGS_LOG_SCALE_Y)
return exp(val / _y_scale) ; return exp( (val - _graph_base) / _y_scale) ;
else else
return val/_y_scale ; return (val - _graph_base)/_y_scale ;
} }
/** Plots an integral using the data points in <b>points</b>. The area will be /** Plots an integral using the data points in <b>points</b>. The area will be
@ -560,7 +573,7 @@ void RSGraphWidget::paintDots(const QVector<QPointF>& points, QColor color)
_painter->setBrush(QBrush(color)); _painter->setBrush(QBrush(color));
for(int i=0;i<points.size();++i) for(int i=0;i<points.size();++i)
_painter->drawEllipse(QRect(points[i].x(),points[i].y(),5*_linewidthscale,5*_linewidthscale)) ; _painter->drawEllipse(QRect(points[i].x()-2.5*_linewidthscale,points[i].y()-2.5*_linewidthscale,5*_linewidthscale,5*_linewidthscale)) ;
_painter->setPen(oldPen); _painter->setPen(oldPen);
_painter->setBrush(oldBrush); _painter->setBrush(oldBrush);
@ -603,8 +616,8 @@ void RSGraphWidget::paintScale1()
float fact = FS/14.0 ; float fact = FS/14.0 ;
int top = _rec.y(); int top = _rec.y();
int bottom = _rec.height(); int bottom = _rec.height() - _graph_base;
qreal paintStep = (bottom - (bottom/10)) / 4; qreal paintStep = (bottom - top) / 5;
/* Draw the other marks in their correctly scaled locations */ /* Draw the other marks in their correctly scaled locations */
qreal scale; qreal scale;
@ -615,16 +628,23 @@ void RSGraphWidget::paintScale1()
QString unit_name = _source->unitName() ; QString unit_name = _source->unitName() ;
for (int i = 1; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
pos = bottom - (i * paintStep); pos = bottom - (i * paintStep) ;
scale = pixelsToValue(i * paintStep); scale = pixelsToValue(_graph_base + i * paintStep);
// If legend contains integers only the value should be rounded to the nearest integer
if(_flags & RSGRAPH_FLAGS_LEGEND_INTEGER)
{
scale = (int)scale ;
pos = bottom - (valueToPixels(scale) - _graph_base) ;
}
QString text = _source->displayValue(scale) ; QString text = _source->displayValue(scale) ;
_painter->setPen(SCALE_COLOR); _painter->setPen(SCALE_COLOR);
_painter->drawText(QPointF(5*fact, pos+0.5*FS), text); _painter->drawText(QPointF(5*fact, pos+0.4*FS), text);
_painter->setPen(GRID_COLOR); _painter->setPen(GRID_COLOR);
_painter->drawLine(QPointF(SCALE_WIDTH*fact, pos), QPointF(_rec.width(), pos)); _painter->drawLine(QPointF(SCALE_WIDTH*fact, pos), QPointF(_rec.width(), pos));
} }
@ -710,7 +730,11 @@ void RSGraphWidget::paintLegend()
QString text = _source->legend(i,vals[i]) ; QString text = _source->legend(i,vals[i]) ;
QPen oldPen = _painter->pen(); QPen oldPen = _painter->pen();
_painter->setPen(QPen(getColor(i), Qt::SolidLine));
QPen pen(getColor(i), Qt::SolidLine) ;
pen.setWidth(_linewidthscale);
_painter->setPen(pen);
_painter->drawLine(QPointF(SCALE_WIDTH*fact+10.0*fact, pos+FS/3), QPointF(SCALE_WIDTH*fact+30.0*fact, pos+FS/3)); _painter->drawLine(QPointF(SCALE_WIDTH*fact+10.0*fact, pos+FS/3), QPointF(SCALE_WIDTH*fact+30.0*fact, pos+FS/3));
_painter->setPen(oldPen); _painter->setPen(oldPen);

View File

@ -32,8 +32,9 @@
#include <stdint.h> #include <stdint.h>
#define GRAPH_BASE 2 /** Position of the 0 of the scale, in count of the text height */
#define SCALE_WIDTH 75 /** Width of the scale */ #define SCALE_WIDTH 75 /** Width of the scale */
#define MINUSER_SCALE 2000 /** 2000 users is the minimum scale */ #define MINUSER_SCALE 2000 /** 2000 users is the minimum scale */
#define SCROLL_STEP 4 /** Horizontal change on graph update */ #define SCROLL_STEP 4 /** Horizontal change on graph update */
#define BACK_COLOR Qt::white #define BACK_COLOR Qt::white
@ -87,6 +88,9 @@ public:
// Sets the time period for collecting new values. Units=milliseconds. // Sets the time period for collecting new values. Units=milliseconds.
void setCollectionTimePeriod(qint64 msecs) ; void setCollectionTimePeriod(qint64 msecs) ;
// Enables/disables time filtering of the data
void setFiltering(bool b) { _filtering_enabled = b; }
void setDigits(int d) { _digits = d ;} void setDigits(int d) { _digits = d ;}
protected slots: protected slots:
@ -112,6 +116,7 @@ protected:
qint64 _update_period_msecs ; qint64 _update_period_msecs ;
qint64 _time_orig_msecs ; qint64 _time_orig_msecs ;
int _digits ; int _digits ;
bool _filtering_enabled ;
}; };
class RSGraphWidget: public QFrame class RSGraphWidget: public QFrame
@ -127,6 +132,7 @@ public:
static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_FLAT = 0x0020 ;// do not interpolate, and draw flat colored boxes static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_FLAT = 0x0020 ;// do not interpolate, and draw flat colored boxes
static const uint32_t RSGRAPH_FLAGS_LEGEND_CUMULATED = 0x0040 ;// show the total in the legend rather than current values static const uint32_t RSGRAPH_FLAGS_LEGEND_CUMULATED = 0x0040 ;// show the total in the legend rather than current values
static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_DOTS = 0x0080 ;// use dots static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_DOTS = 0x0080 ;// use dots
static const uint32_t RSGRAPH_FLAGS_LEGEND_INTEGER = 0x0100 ;// use integer number in the legend, and move the lines to match integers
/** Bandwidth graph style. */ /** Bandwidth graph style. */
enum GraphStyle enum GraphStyle
@ -156,6 +162,8 @@ public:
void setShowEntry(uint32_t entry, bool show) ; void setShowEntry(uint32_t entry, bool show) ;
void setCurvesOpacity(float f) ; void setCurvesOpacity(float f) ;
void setFiltering(bool b) ;
void setFlags(uint32_t flag) { _flags |= flag ; } void setFlags(uint32_t flag) { _flags |= flag ; }
void resetFlags(uint32_t flag) { _flags &= ~flag ; } void resetFlags(uint32_t flag) { _flags &= ~flag ; }
protected: protected:
@ -209,6 +217,7 @@ private:
/** The maximum number of points to store. */ /** The maximum number of points to store. */
qreal _y_scale ; qreal _y_scale ;
qreal _opacity ; qreal _opacity ;
qreal _graph_base;
qreal pixelsToValue(qreal) ; qreal pixelsToValue(qreal) ;
qreal valueToPixels(qreal) ; qreal valueToPixels(qreal) ;

View File

@ -202,12 +202,16 @@ void BandwidthStatsWidget::updateUnitSelection(int n)
{ {
ui.bwgraph_BW->setUnit(BWGraphSource::UNIT_KILOBYTES) ; ui.bwgraph_BW->setUnit(BWGraphSource::UNIT_KILOBYTES) ;
ui.bwgraph_BW->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_PAINT_STYLE_DOTS); ui.bwgraph_BW->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_PAINT_STYLE_DOTS);
ui.bwgraph_BW->resetFlags(RSGraphWidget::RSGRAPH_FLAGS_LEGEND_INTEGER);
ui.legend_CB->setItemText(1,tr("Average")); ui.legend_CB->setItemText(1,tr("Average"));
ui.bwgraph_BW->setFiltering(true) ;
} }
else else
{ {
ui.bwgraph_BW->setUnit(BWGraphSource::UNIT_COUNT) ; ui.bwgraph_BW->setUnit(BWGraphSource::UNIT_COUNT) ;
ui.bwgraph_BW->setFlags(RSGraphWidget::RSGRAPH_FLAGS_PAINT_STYLE_DOTS); ui.bwgraph_BW->setFlags(RSGraphWidget::RSGRAPH_FLAGS_PAINT_STYLE_DOTS);
ui.bwgraph_BW->setFlags(RSGraphWidget::RSGRAPH_FLAGS_LEGEND_INTEGER);
ui.bwgraph_BW->setFiltering(false) ;
ui.legend_CB->setItemText(1,tr("Total")); ui.legend_CB->setItemText(1,tr("Total"));
} }
} }