diff --git a/retroshare-gui/src/gui/common/RSGraphWidget.cpp b/retroshare-gui/src/gui/common/RSGraphWidget.cpp index 6d92166a4..bcb365baf 100644 --- a/retroshare-gui/src/gui/common/RSGraphWidget.cpp +++ b/retroshare-gui/src/gui/common/RSGraphWidget.cpp @@ -113,7 +113,7 @@ QString RSGraphSource::legend(int i,float v) const return displayName(i) + " (" + displayValue(v) + " )"; } -void RSGraphSource::getDataPoints(int index,std::vector& pts) const +void RSGraphSource::getDataPoints(int index,std::vector& pts,float filter_factor) const { pts.clear() ; qint64 now = getTime() ; @@ -126,8 +126,15 @@ void RSGraphSource::getDataPoints(int index,std::vector& pts) const if(n != index) return ; + float last_value = it->second.empty()?0.0f:(it->second.begin()->second) ; + for(std::list >::const_iterator it2=it->second.begin();it2!=it->second.end();++it2) - pts.push_back(QPointF( (now - (*it2).first)/1000.0f,(*it2).second)) ; + { + float val = (1-filter_factor)*(*it2).second + filter_factor*last_value; + last_value = val ; + + pts.push_back(QPointF( (now - (*it2).first)/1000.0f, val)) ; + } } void RSGraphWidget::setShowEntry(uint32_t entry,bool b) @@ -231,6 +238,7 @@ RSGraphWidget::RSGraphWidget(QWidget *parent) _opacity = 0.6 ; _flags = 0; _time_scale = 5.0f ; // in pixels per second. + _time_filter = 1.0f ; _timer = new QTimer ; QObject::connect(_timer,SIGNAL(timeout()),this,SLOT(updateIfPossible())) ; @@ -370,7 +378,8 @@ void RSGraphWidget::paintData() if( _masked_entries.find(source.displayName(i).toStdString()) == _masked_entries.end() ) { std::vector values ; - source.getDataPoints(i,values) ; + //std::cerr << "time filter = " << _time_filter << ", factor=" << 1./_time_scale*_time_filter/(1+_time_filter/_time_scale) << std::endl; + source.getDataPoints(i,values,1./_time_scale*_time_filter/(1.0f+_time_filter/_time_scale)) ; QVector points ; pointsFromData(values,points) ; @@ -394,79 +403,79 @@ void RSGraphWidget::paintData() * of rsdht or alldht values. */ void RSGraphWidget::pointsFromData(const std::vector& values,QVector& points) { - points.clear(); + points.clear(); - int x = _rec.width(); - int y = _rec.height(); + int x = _rec.width(); + int y = _rec.height(); - float time_step = 1.0f ; // number of seconds per pixel + float time_step = 1.0f ; // number of seconds per pixel - /* Translate all data points to points on the graph frame */ + /* Translate all data points to points on the graph frame */ - // take 0 as the origin, otherwise the different curves are not aligned properly - float last = 0;//values.back().x(); + // take 0 as the origin, otherwise the different curves are not aligned properly + float last = 0;//values.back().x(); - //std::cerr << "Got " << values.size() << " values for index 0" << std::endl; + //std::cerr << "Got " << values.size() << " values for index 0" << std::endl; - float FS = QFontMetricsF(font()).height(); - float fact = FS/14.0 ; + float FS = QFontMetricsF(font()).height(); + float fact = FS/14.0 ; - float last_px = SCALE_WIDTH*fact ; - float last_py = 0.0f ; + float last_px = SCALE_WIDTH*fact ; + float last_py = 0.0f ; - // float min_x_no_data_threshold = 1.5 ; // 1.5 sec. + // float min_x_no_data_threshold = 1.5 ; // 1.5 sec. - for (uint i = 0; i < values.size(); ++i) - { - //std::cerr << "Value: (" << values[i].x() << " , " << values[i].y() << ")" << std::endl; + for (uint i = 0; i < values.size(); ++i) + { + //std::cerr << "Value: (" << values[i].x() << " , " << values[i].y() << ")" << std::endl; - // compute point in pixels + // compute point in pixels - qreal px = x - (values[i].x()-last)*_time_scale ; - qreal py = y - valueToPixels(values[i].y()) ; + qreal px = x - (values[i].x()-last)*_time_scale ; + qreal py = y - valueToPixels(values[i].y()) ; - if(px >= SCALE_WIDTH*fact && last_px < SCALE_WIDTH*fact) - { - float alpha = (SCALE_WIDTH*fact - last_px)/(px - last_px) ; - float ipx = SCALE_WIDTH*fact ; - float ipy = (1-alpha)*last_py + alpha*py ; + if(px >= SCALE_WIDTH*fact && last_px < SCALE_WIDTH*fact) + { + 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,ipy) ; - } - else if(i==0) - { - if(px < SCALE_WIDTH*fact) - points << QPointF(SCALE_WIDTH*fact,py) ; - else - points << QPointF(px,y) ; - } + points << QPointF(ipx,y) ; + points << QPointF(ipx,ipy) ; + } + else if(i==0) + { + if(px < SCALE_WIDTH*fact) + points << QPointF(SCALE_WIDTH*fact,py) ; + else + points << QPointF(px,y) ; + } - if(px < SCALE_WIDTH*fact) - continue ; + if(px < SCALE_WIDTH*fact) + 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) - 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) ; -// } + // 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) - points << QPointF(px,y) ; + if(i==values.size()-1) + points << QPointF(px,y) ; - last_px = px ; - last_py = py ; + last_px = px ; + last_py = py ; - } + } } qreal RSGraphWidget::valueToPixels(qreal val) @@ -601,12 +610,18 @@ void RSGraphWidget::paintScale2() void RSGraphWidget::wheelEvent(QWheelEvent *e) { - if(e->delta() > 0) - _time_scale *= 1.1 ; - else - _time_scale /= 1.1 ; + if(e->modifiers() & Qt::ShiftModifier) + if(e->delta() > 0) + _time_filter *= 1.1 ; + else + _time_filter /= 1.1 ; + else + if(e->delta() > 0) + _time_scale *= 1.1 ; + else + _time_scale /= 1.1 ; - update() ; + update() ; } void RSGraphWidget::paintLegend() diff --git a/retroshare-gui/src/gui/common/RSGraphWidget.h b/retroshare-gui/src/gui/common/RSGraphWidget.h index c1a32974c..84a4ee3be 100644 --- a/retroshare-gui/src/gui/common/RSGraphWidget.h +++ b/retroshare-gui/src/gui/common/RSGraphWidget.h @@ -73,7 +73,7 @@ public: virtual QString legend(int i,float v) const ; // Returns the n^th interpolated value at the given time in floating point seconds backward. - virtual void getDataPoints(int index, std::vector& pts) const ; + virtual void getDataPoints(int index, std::vector& pts, float filter_factor=0.0f) const ; // returns the name to give to the nth entry in the graph virtual QString displayName(int index) const ; @@ -113,108 +113,109 @@ class RSGraphWidget: public QFrame { Q_OBJECT - public: - static const uint32_t RSGRAPH_FLAGS_AUTO_SCALE_Y = 0x0001 ;// automatically adjust Y scale - static const uint32_t RSGRAPH_FLAGS_LOG_SCALE_Y = 0x0002 ;// log scale in Y - static const uint32_t RSGRAPH_FLAGS_ALWAYS_COLLECT = 0x0004 ;// keep collecting while not displayed - static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_PLAIN = 0x0008 ;// use plain / line drawing style - static const uint32_t RSGRAPH_FLAGS_SHOW_LEGEND = 0x0010 ;// show legend in the graph - static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_FLAT = 0x0020 ;// do not interpolate, and draw flat colored boxes +public: + static const uint32_t RSGRAPH_FLAGS_AUTO_SCALE_Y = 0x0001 ;// automatically adjust Y scale + static const uint32_t RSGRAPH_FLAGS_LOG_SCALE_Y = 0x0002 ;// log scale in Y + static const uint32_t RSGRAPH_FLAGS_ALWAYS_COLLECT = 0x0004 ;// keep collecting while not displayed + static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_PLAIN = 0x0008 ;// use plain / line drawing style + static const uint32_t RSGRAPH_FLAGS_SHOW_LEGEND = 0x0010 ;// show legend in the graph + static const uint32_t RSGRAPH_FLAGS_PAINT_STYLE_FLAT = 0x0020 ;// do not interpolate, and draw flat colored boxes - /** Bandwidth graph style. */ - enum GraphStyle - { - SolidLine = 0, /**< Plot bandwidth as solid lines. */ - AreaGraph = 1 /**< Plot bandwidth as alpha blended area graphs. */ - }; + /** Bandwidth graph style. */ + enum GraphStyle + { + SolidLine = 0, /**< Plot bandwidth as solid lines. */ + AreaGraph = 1 /**< Plot bandwidth as alpha blended area graphs. */ + }; - /** Default Constructor */ - RSGraphWidget(QWidget *parent = 0); - /** Default Destructor */ - ~RSGraphWidget(); + /** Default Constructor */ + RSGraphWidget(QWidget *parent = 0); + /** Default Destructor */ + ~RSGraphWidget(); - // sets the update interval period. - // - void setTimerPeriod(int miliseconds) ; - void setSource(RSGraphSource *gs) ; - void setTimeScale(float pixels_per_second) ; + // sets the update interval period. + // + void setTimerPeriod(int miliseconds) ; + void setSource(RSGraphSource *gs) ; + void setTimeScale(float pixels_per_second) ; - /** Add data points. */ - //void addPoints(qreal rsDHT, qreal allDHT); - /** Clears the graph. */ - void resetGraph(); - /** Toggles display of data counters. */ - //void setShowCounters(bool showRSDHT, bool showALLDHT); + /** Add data points. */ + //void addPoints(qreal rsDHT, qreal allDHT); + /** Clears the graph. */ + void resetGraph(); + /** Toggles display of data counters. */ + //void setShowCounters(bool showRSDHT, bool showALLDHT); - void setShowEntry(uint32_t entry, bool show) ; - void setCurvesOpacity(float f) ; + void setShowEntry(uint32_t entry, bool show) ; + void setCurvesOpacity(float f) ; - void setFlags(uint32_t flag) { _flags |= flag ; } - void resetFlags(uint32_t flag) { _flags &= ~flag ; } - protected: - /** Overloaded QWidget::paintEvent() */ - void paintEvent(QPaintEvent *event); + void setFlags(uint32_t flag) { _flags |= flag ; } + void resetFlags(uint32_t flag) { _flags &= ~flag ; } +protected: + /** Overloaded QWidget::paintEvent() */ + void paintEvent(QPaintEvent *event); - virtual QSizeF sizeHint( Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const; + virtual QSizeF sizeHint( Qt::SizeHint which, const QSizeF & constraint = QSizeF() ) const; - protected slots: - void updateIfPossible() ; +protected slots: + void updateIfPossible() ; - virtual void wheelEvent(QWheelEvent *e); - private: - /** Gets the width of the desktop, the max # of points. */ - int getNumPoints(); + virtual void wheelEvent(QWheelEvent *e); +private: + /** Gets the width of the desktop, the max # of points. */ + int getNumPoints(); - /** Paints an integral and an outline of that integral for each data set + /** Paints an integral and an outline of that integral for each data set * (rsdht and/or alldht) that is to be displayed. */ - void paintData(); - /** Paints the rsdht/alldht totals. */ - void paintTotals(); - /** Paints the scale in the graph. */ - void paintLegend(); - /** Paints the scale in the graph. */ - void paintScale1(); - void paintScale2(); + void paintData(); + /** Paints the rsdht/alldht totals. */ + void paintTotals(); + /** Paints the scale in the graph. */ + void paintLegend(); + /** Paints the scale in the graph. */ + void paintScale1(); + void paintScale2(); - QColor getColor(int i) ; + QColor getColor(int i) ; - /** Returns a formatted string representation of total. */ - QString totalToStr(qreal total); - /** Returns a list of points on the bandwidth graph based on the supplied set + /** Returns a formatted string representation of total. */ + QString totalToStr(qreal total); + /** Returns a list of points on the bandwidth graph based on the supplied set * of rsdht or alldht values. */ - void pointsFromData(const std::vector& values, QVector &points ) ; + void pointsFromData(const std::vector& values, QVector &points ) ; - /** Paints a line with the data in points. */ - void paintLine(const QVector& points, QColor color, - Qt::PenStyle lineStyle = Qt::SolidLine); - /** Paints an integral using the supplied data. */ - void paintIntegral(const QVector& points, QColor color, qreal alpha = 1.0); + /** Paints a line with the data in points. */ + void paintLine(const QVector& points, QColor color, + Qt::PenStyle lineStyle = Qt::SolidLine); + /** Paints an integral using the supplied data. */ + void paintIntegral(const QVector& points, QColor color, qreal alpha = 1.0); - /** A QPainter object that handles drawing the various graph elements. */ - QPainter* _painter; - /** The current dimensions of the graph. */ - QRect _rec; - /** The maximum data value plotted. */ - qreal _maxValue; - /** The maximum number of points to store. */ - qreal _y_scale ; - qreal _opacity ; + /** A QPainter object that handles drawing the various graph elements. */ + QPainter* _painter; + /** The current dimensions of the graph. */ + QRect _rec; + /** The maximum data value plotted. */ + qreal _maxValue; + /** The maximum number of points to store. */ + qreal _y_scale ; + qreal _opacity ; - qreal pixelsToValue(qreal) ; - qreal valueToPixels(qreal) ; - int _maxPoints; + qreal pixelsToValue(qreal) ; + qreal valueToPixels(qreal) ; + int _maxPoints; - std::set _masked_entries ; + std::set _masked_entries ; - qreal _time_scale ; // horizontal scale in pixels per sec. + qreal _time_scale ; // horizontal scale in pixels per sec. + qreal _time_filter ; // time filter. Goes from 0 to infinity. Will be converted into 1-1/(1+f) - /** Show the respective lines and counters. */ - //bool _showRSDHT; - //bool _showALLDHT; + /** Show the respective lines and counters. */ + //bool _showRSDHT; + //bool _showALLDHT; - uint32_t _flags ; - QTimer *_timer ; + uint32_t _flags ; + QTimer *_timer ; - RSGraphSource *_source ; + RSGraphSource *_source ; };