I found a solution by implementing a custom PlotPicker and evaluating following method within the trackerText() method.
bool PlotPicker
::curveSelected(const QPoint pMousePos, PlotCurve
* &pPlotCurve,
double &pYValue
) const {
double lDist = 10e10;
int lIndex = -1;
// get nearest curve point by iterating over plot items, filtering for curves and calculating minimum distance
const QwtPlotItemList& lPlotItemList = plot()->itemList();
for ( QwtPlotItemIterator lPlotItemIterator = lPlotItemList.begin();
lPlotItemIterator != lPlotItemList.end(); ++lPlotItemIterator )
{
if ( (*lPlotItemIterator
)->rtti
() == QwtPlotItem::Rtti_PlotCurve ) {
PlotCurve *lTmpCurve = (PlotCurve*)(*lPlotItemIterator);
double lTmpDist;
int lTmpIndex = lTmpCurve->closestPoint(pMousePos, &lTmpDist);
if ( lTmpDist < lDist && lTmpIndex > -1)
{
pPlotCurve = lTmpCurve;
lDist = lTmpDist;
lIndex = lTmpIndex;
}
}
}
// check if mouse position is in tolerance
if ( pPlotCurve && lDist < _pix_tolerance_ )
{
pYValue = pPlotCurve->y(lIndex);
return true;
}
pPlotCurve = 0;
return false;
}
{
double lSelectedYValue = 0.0;
PlotCurve* lSelectedCurve = 0;
if(curveSelected(pMousePos, lSelectedCurve, lSelectedYValue)) {
// ... the code creating the label at the cursor position
}
return lText;
}
bool PlotPicker::curveSelected(const QPoint pMousePos, PlotCurve* &pPlotCurve, double &pYValue) const
{
double lDist = 10e10;
int lIndex = -1;
// get nearest curve point by iterating over plot items, filtering for curves and calculating minimum distance
const QwtPlotItemList& lPlotItemList = plot()->itemList();
for ( QwtPlotItemIterator lPlotItemIterator = lPlotItemList.begin();
lPlotItemIterator != lPlotItemList.end(); ++lPlotItemIterator )
{
if ( (*lPlotItemIterator)->rtti() == QwtPlotItem::Rtti_PlotCurve )
{
PlotCurve *lTmpCurve = (PlotCurve*)(*lPlotItemIterator);
double lTmpDist;
int lTmpIndex = lTmpCurve->closestPoint(pMousePos, &lTmpDist);
if ( lTmpDist < lDist && lTmpIndex > -1)
{
pPlotCurve = lTmpCurve;
lDist = lTmpDist;
lIndex = lTmpIndex;
}
}
}
// check if mouse position is in tolerance
if ( pPlotCurve && lDist < _pix_tolerance_ )
{
pYValue = pPlotCurve->y(lIndex);
return true;
}
pPlotCurve = 0;
return false;
}
QwtText PlotPicker::trackerText(const QPoint &pMousePos) const
{
QwtText lText;
double lSelectedYValue = 0.0;
PlotCurve* lSelectedCurve = 0;
if(curveSelected(pMousePos, lSelectedCurve, lSelectedYValue)) {
// ... the code creating the label at the cursor position
}
return lText;
}
To copy to clipboard, switch view to plain text mode
In advance I implemented there also a vertical marker following the cursor position. By adding a horizontal marker we would get crosshair functionality...
PlotPicker
::PlotPicker(QwtPlot *pPlot
) :{
// create vertical mouse marker
mMouseMarker->attach(pPlot);
mMouseMarker->setVisible(false);
mMouseMarker
->setLinePen
(QPen(Qt
::DotLine));
}
void PlotPicker
::widgetMouseMoveEvent(QMouseEvent *pMouseEvent
) {
qreal lXPosition = invTransform(pMouseEvent->pos()).x();
mMouseMarker->setXValue(lXPosition);
mMouseMarker->setVisible(true);
plot()->replot();
}
void PlotPicker
::widgetLeaveEvent(QEvent *pEvent
) {
mMouseMarker->setVisible(false);
plot()->replot();
}
PlotPicker::PlotPicker(QwtPlot *pPlot) :
QwtPlotPicker(pPlot->canvas())
{
// create vertical mouse marker
mMouseMarker = new QwtPlotMarker();
mMouseMarker->attach(pPlot);
mMouseMarker->setVisible(false);
mMouseMarker->setLineStyle(QwtPlotMarker::VLine);
mMouseMarker->setLinePen(QPen(Qt::DotLine));
}
void PlotPicker::widgetMouseMoveEvent(QMouseEvent *pMouseEvent)
{
QwtPlotPicker::widgetMouseMoveEvent(pMouseEvent);
qreal lXPosition = invTransform(pMouseEvent->pos()).x();
mMouseMarker->setXValue(lXPosition);
mMouseMarker->setVisible(true);
plot()->replot();
}
void PlotPicker::widgetLeaveEvent(QEvent *pEvent)
{
QwtPlotPicker::widgetLeaveEvent(pEvent);
mMouseMarker->setVisible(false);
plot()->replot();
}
To copy to clipboard, switch view to plain text mode
... and it works!
Regards
Stefan
Bookmarks