Files
qwt/playground/curvetracker/CurveTracker.cpp
2023-10-31 09:22:42 +01:00

138 lines
3.4 KiB
C++

/*****************************************************************************
* Qwt Examples - Copyright (C) 2002 Uwe Rathmann
* This file may be used under the terms of the 3-clause BSD License
*****************************************************************************/
#include "CurveTracker.h"
#include <QwtPickerMachine>
#include <QwtPlot>
#include <QwtPlotCurve>
#include <QwtText>
#include <QPen>
struct compareX
{
inline bool operator()( const double x, const QPointF& pos ) const
{
return ( x < pos.x() );
}
};
CurveTracker::CurveTracker( QWidget* canvas )
: QwtPlotPicker( canvas )
{
setTrackerMode( QwtPlotPicker::ActiveOnly );
setRubberBand( VLineRubberBand );
setStateMachine( new QwtPickerDragPointMachine() );
}
QRect CurveTracker::trackerRect( const QFont& font ) const
{
QRect r = QwtPlotPicker::trackerRect( font );
// align r to the first curve
const QwtPlotItemList curves = plot()->itemList( QwtPlotItem::Rtti_PlotCurve );
if ( curves.size() > 0 )
{
QPointF pos = invTransform( trackerPosition() );
const QLineF line = curveLineAt(
static_cast< const QwtPlotCurve* >( curves[0] ), pos.x() );
if ( !line.isNull() )
{
const double curveY = line.pointAt(
( pos.x() - line.p1().x() ) / line.dx() ).y();
pos.setY( curveY );
pos = transform( pos );
r.moveBottom( pos.y() );
}
}
return r;
}
QwtText CurveTracker::trackerTextF( const QPointF& pos ) const
{
QwtText trackerText;
trackerText.setColor( Qt::black );
QColor c( "#333333" );
trackerText.setBorderPen( QPen( c, 2 ) );
c.setAlpha( 200 );
trackerText.setBackgroundBrush( c );
QString info;
const QwtPlotItemList curves =
plot()->itemList( QwtPlotItem::Rtti_PlotCurve );
for ( int i = 0; i < curves.size(); i++ )
{
const QString curveInfo = curveInfoAt(
static_cast< const QwtPlotCurve* >( curves[i] ), pos );
if ( !curveInfo.isEmpty() )
{
if ( !info.isEmpty() )
info += "<br>";
info += curveInfo;
}
}
trackerText.setText( info );
return trackerText;
}
QString CurveTracker::curveInfoAt(
const QwtPlotCurve* curve, const QPointF& pos ) const
{
const QLineF line = curveLineAt( curve, pos.x() );
if ( line.isNull() )
return QString();
const double y = line.pointAt(
( pos.x() - line.p1().x() ) / line.dx() ).y();
QString info( "<font color=" "%1" ">%2</font>" );
return info.arg( curve->pen().color().name() ).arg( y );
}
QLineF CurveTracker::curveLineAt(
const QwtPlotCurve* curve, double x ) const
{
QLineF line;
if ( curve->dataSize() >= 2 )
{
const QRectF br = curve->boundingRect();
if ( ( br.width() > 0 ) && ( x >= br.left() ) && ( x <= br.right() ) )
{
int index = qwtUpperSampleIndex< QPointF >(
*curve->data(), x, compareX() );
if ( index == -1 &&
x == curve->sample( curve->dataSize() - 1 ).x() )
{
// the last sample is excluded from qwtUpperSampleIndex
index = curve->dataSize() - 1;
}
if ( index > 0 )
{
line.setP1( curve->sample( index - 1 ) );
line.setP2( curve->sample( index ) );
}
}
}
return line;
}