Go to the documentation of this file.00001 #include "customtracker.h"
00002 #include <qwt_series_data.h>
00003 #include <qwt_plot.h>
00004 #include <qwt_plot_curve.h>
00005 #include "qwt_event_pattern.h"
00006 #include <qwt_symbol.h>
00007 #include <qevent.h>
00008 #include <QFontDatabase>
00009
00010 struct compareX
00011 {
00012 inline bool operator()( const double x, const QPointF &pos ) const
00013 {
00014 return ( x < pos.x() );
00015 }
00016 };
00017
00018
00019
00020 CurveTracker::CurveTracker( QwtPlot *plot ):
00021 QObject( plot ),
00022 _plot( plot ),
00023 _param( VALUE )
00024 {
00025 _line_marker = ( new QwtPlotMarker );
00026
00027 _line_marker->setLinePen(QPen(Qt::red));
00028 _line_marker->setLineStyle(QwtPlotMarker::VLine);
00029 _line_marker->setValue(0,0);
00030 _line_marker->attach(plot);
00031
00032 _text_marker = ( new QwtPlotMarker );
00033 _text_marker->attach(plot);
00034
00035 _visible = true;
00036 }
00037
00038 QPointF CurveTracker::actualPosition() const
00039 {
00040 return _prev_trackerpoint;
00041 }
00042
00043 void CurveTracker::setParameter(Parameter par)
00044 {
00045 bool changed = _param != par;
00046 _param = par;
00047
00048 if( changed ){
00049 setPosition( _prev_trackerpoint );
00050 }
00051 }
00052
00053 void CurveTracker::setEnabled(bool enable)
00054 {
00055 _visible = enable;
00056 _line_marker->setVisible( enable );
00057 _text_marker->setVisible( enable );
00058
00059 for (int i = 0 ; i < _marker.size(); i++ )
00060 {
00061 _marker[i]->setVisible( enable );
00062 }
00063
00064 }
00065
00066 void CurveTracker::setPosition(const QPointF& position)
00067 {
00068 const QwtPlotItemList curves = _plot->itemList( QwtPlotItem::Rtti_PlotCurve );
00069
00070 _line_marker->setValue( position );
00071
00072 QRectF rect;
00073 rect.setBottom( _plot->canvasMap( QwtPlot::yLeft ).s1() );
00074 rect.setTop( _plot->canvasMap( QwtPlot::yLeft ).s2() );
00075 rect.setLeft( _plot->canvasMap( QwtPlot::xBottom ).s1() );
00076 rect.setRight( _plot->canvasMap( QwtPlot::xBottom ).s2() );
00077
00078 double tot_Y = 0;
00079 int visible_points = 0;
00080
00081 while( _marker.size() > curves.size())
00082 {
00083 _marker.back()->detach();
00084 _marker.pop_back();
00085 }
00086
00087 for (int i = _marker.size() ; i < curves.size(); i++ )
00088 {
00089 _marker.push_back( new QwtPlotMarker );
00090 _marker[i]->attach( _plot );
00091 }
00092
00093
00094 double text_X_offset = 0;
00095
00096 std::multimap<double,QString> text_lines;
00097
00098 for ( int i = 0; i < curves.size(); i++ )
00099 {
00100 QwtPlotCurve *curve = static_cast<QwtPlotCurve *>(curves[i]);
00101 QColor color = curve->pen().color();
00102
00103 text_X_offset = rect.width() * 0.02;
00104
00105 if( !_marker[i]->symbol() )
00106 {
00107 QwtSymbol *sym = new QwtSymbol(
00108 QwtSymbol::Diamond,
00109 color,
00110 color,
00111 QSize(5,5));
00112 _marker[i]->setSymbol(sym);
00113 }
00114
00115 const QLineF line = curveLineAt( curve, position.x() );
00116
00117 if( line.isNull() )
00118 {
00119 continue;
00120 }
00121
00122 QPointF point;
00123 double middle_X = (line.p1().x() + line.p2().x()) / 2.0;
00124
00125 if( position.x() < middle_X )
00126 point = line.p1();
00127 else
00128 point = line.p2();
00129
00130 _marker[i]->setValue( point );
00131
00132 if( rect.contains( point ) && _visible )
00133 {
00134 tot_Y += point.y();
00135 visible_points++;
00136 double val = point.y();
00137
00138 QString line;
00139
00140 if( _param == VALUE)
00141 {
00142 line = QString( "<font color=%1>%2</font>" ).arg( color.name() ).arg( val );
00143 }
00144 else if( _param == VALUE_NAME)
00145 {
00146 QString value = QString::number( val, 'f', 3);
00147 int whitespaces = 8 - value.length();
00148 while(whitespaces-- > 0) value.prepend(" ");
00149
00150 line = QString( "<font color=%1>%2 : %3</font>" )
00151 .arg( color.name() ).arg( value ).arg(curve->title().text() );
00152 }
00153
00154 text_lines.insert( std::make_pair(val, line) );
00155 _marker[i]->setVisible( true );
00156 }
00157 else{
00158 _marker[i]->setVisible( false );
00159 }
00160 _marker[i]->setValue( point );
00161 }
00162
00163 QwtText mark_text;
00164 mark_text.setColor( Qt::black );
00165
00166 QString text_marker_info;
00167
00168 int count = 0;
00169 for(auto it = text_lines.rbegin(); it != text_lines.rend(); it++)
00170 {
00171 text_marker_info += it->second;
00172 if( count++ < text_lines.size() -1 )
00173 {
00174 text_marker_info += "<br>";
00175 }
00176 }
00177
00178 QColor c( "#FFFFFF" );
00179 mark_text.setBorderPen( QPen( c, 2 ) );
00180 c.setAlpha( 220 );
00181 mark_text.setBackgroundBrush( c );
00182 mark_text.setText( text_marker_info );
00183 mark_text.setFont( QFontDatabase::systemFont(QFontDatabase::FixedFont) );
00184 mark_text.setRenderFlags( _param == VALUE ? Qt::AlignCenter : Qt::AlignLeft);
00185
00186 _text_marker->setLabel(mark_text);
00187 _text_marker->setLabelAlignment( Qt::AlignRight );
00188
00189 _text_marker->setXValue( position.x() + text_X_offset );
00190
00191 if(visible_points > 0){
00192 _text_marker->setYValue( tot_Y/visible_points );
00193 }
00194
00195 _text_marker->setVisible( visible_points > 0 && _visible && _param != LINE_ONLY );
00196
00197 _prev_trackerpoint = position;
00198
00199 }
00200
00201
00202 QLineF CurveTracker::curveLineAt(
00203 const QwtPlotCurve *curve, double x ) const
00204 {
00205 QLineF line;
00206
00207 if ( curve->dataSize() >= 2 )
00208 {
00209 int index = qwtUpperSampleIndex<QPointF>(
00210 *curve->data(), x, compareX() );
00211
00212 if ( index > 0 )
00213 {
00214 line.setP1( curve->sample( index - 1 ) );
00215 line.setP2( curve->sample( index ) );
00216 }
00217 }
00218 return line;
00219 }
00220