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 void CurveTracker::setPosition(const QPointF& position)
00066 {
00067 const QwtPlotItemList curves = _plot->itemList( QwtPlotItem::Rtti_PlotCurve );
00068
00069 _line_marker->setValue( position );
00070
00071 QRectF rect;
00072 rect.setBottom( _plot->canvasMap( QwtPlot::yLeft ).s1() );
00073 rect.setTop( _plot->canvasMap( QwtPlot::yLeft ).s2() );
00074 rect.setLeft( _plot->canvasMap( QwtPlot::xBottom ).s1() );
00075 rect.setRight( _plot->canvasMap( QwtPlot::xBottom ).s2() );
00076
00077 double tot_Y = 0;
00078 int visible_points = 0;
00079
00080 while( _marker.size() > curves.size())
00081 {
00082 _marker.back()->detach();
00083 _marker.pop_back();
00084 }
00085
00086 for (int i = _marker.size() ; i < curves.size(); i++ )
00087 {
00088 _marker.push_back( new QwtPlotMarker );
00089 _marker[i]->attach( _plot );
00090 }
00091
00092 double text_X_offset = 0;
00093
00094 std::multimap<double,QString> text_lines;
00095
00096 for ( int i = 0; i < curves.size(); i++ )
00097 {
00098 QwtPlotCurve *curve = static_cast<QwtPlotCurve *>(curves[i]);
00099 _marker[i]->setVisible( curve->isVisible() );
00100
00101 if( curve->isVisible() == false)
00102 {
00103 continue;
00104 }
00105 QColor color = curve->pen().color();
00106
00107 text_X_offset = rect.width() * 0.02;
00108
00109 if( !_marker[i]->symbol() )
00110 {
00111 QwtSymbol *sym = new QwtSymbol(
00112 QwtSymbol::Diamond,
00113 color,
00114 color,
00115 QSize(5,5));
00116 _marker[i]->setSymbol(sym);
00117 }
00118
00119 const QLineF line = curveLineAt( curve, position.x() );
00120
00121 if( line.isNull() )
00122 {
00123 continue;
00124 }
00125
00126 QPointF point;
00127 double middle_X = (line.p1().x() + line.p2().x()) / 2.0;
00128
00129 if( position.x() < middle_X )
00130 point = line.p1();
00131 else
00132 point = line.p2();
00133
00134 _marker[i]->setValue( point );
00135
00136 if( rect.contains( point ) && _visible )
00137 {
00138 tot_Y += point.y();
00139 visible_points++;
00140 double val = point.y();
00141
00142 QString line;
00143
00144 if( _param == VALUE)
00145 {
00146 line = QString( "<font color=%1>%2</font>" ).arg( color.name() ).arg( val );
00147 }
00148 else if( _param == VALUE_NAME)
00149 {
00150 QString value = QString::number( val, 'f', 3);
00151 int whitespaces = 8 - value.length();
00152 while(whitespaces-- > 0) value.prepend(" ");
00153
00154 line = QString( "<font color=%1>%2 : %3</font>" )
00155 .arg( color.name() ).arg( value ).arg(curve->title().text() );
00156 }
00157
00158 text_lines.insert( std::make_pair(val, line) );
00159 _marker[i]->setVisible( true );
00160 }
00161 else{
00162 _marker[i]->setVisible( false );
00163 }
00164 _marker[i]->setValue( point );
00165 }
00166
00167 QwtText mark_text;
00168 mark_text.setColor( Qt::black );
00169
00170 QString text_marker_info;
00171
00172 int count = 0;
00173 for(auto it = text_lines.rbegin(); it != text_lines.rend(); it++)
00174 {
00175 text_marker_info += it->second;
00176 if( count++ < text_lines.size() -1 )
00177 {
00178 text_marker_info += "<br>";
00179 }
00180 }
00181
00182 QColor col( "#FFFFFF" );
00183 mark_text.setBorderPen( QPen( col, 2 ) );
00184 col.setAlpha( 220 );
00185 mark_text.setBackgroundBrush( col );
00186 mark_text.setText( text_marker_info );
00187
00188 QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
00189 font.setPointSize( 9 );
00190
00191 mark_text.setFont( font );
00192 mark_text.setRenderFlags( _param == VALUE ? Qt::AlignCenter : Qt::AlignLeft);
00193
00194 _text_marker->setLabel(mark_text);
00195 _text_marker->setLabelAlignment( Qt::AlignRight );
00196
00197 _text_marker->setXValue( position.x() + text_X_offset );
00198
00199 if(visible_points > 0){
00200 _text_marker->setYValue( tot_Y/visible_points );
00201 }
00202
00203 double canvas_ratio = rect.width() / double(_plot->width());
00204 double text_width = mark_text.textSize().width() * canvas_ratio;
00205 bool exceed_right = (_text_marker->boundingRect().right() + text_width) > rect.right();
00206
00207 if( exceed_right )
00208 {
00209 _text_marker->setXValue( position.x() - text_X_offset - text_width );
00210 }
00211
00212 _text_marker->setVisible( visible_points > 0 && _visible && _param != LINE_ONLY );
00213
00214 _prev_trackerpoint = position;
00215
00216 }
00217
00218
00219 QLineF CurveTracker::curveLineAt(
00220 const QwtPlotCurve *curve, double x ) const
00221 {
00222 QLineF line;
00223
00224 if ( curve->dataSize() >= 2 )
00225 {
00226 int index = qwtUpperSampleIndex<QPointF>(
00227 *curve->data(), x, compareX() );
00228
00229 if ( index > 0 )
00230 {
00231 line.setP1( curve->sample( index - 1 ) );
00232 line.setP2( curve->sample( index ) );
00233 }
00234 }
00235 return line;
00236 }
00237