Get the plot curve to which the mouse is pointing to
Hi,
I have a QwtPlot showing several QwtPlotCurves.
As the y-values of the curves are spread over a big range, the curves are created by applying a scale factor to the values. That means i.e. curve 1 is created with values divided by 100, curve 2 is created with values multiplied by 10 and so on.
(By the way, I use only one y-axis as the number of curves can change dynamically. The data unit as well as the scale factor are indicated at the legend, i.e. [ft / 100])
For better user friendlyness it's needed to indicate the correct original y-value when the mouse is pointing to a certain curve, i.e. 12'300ft. For that purpose I need to figure out the curve the mouse is pointing to in order to apply the correct scale factor to the transformed value.
Any idea about that?
Thank's in advance.
Best Regards
Stefan
Re: Get the plot curve to which the mouse is pointing to
A QwtPlotPicker gives you the current position of the mouse ( in screen and plot coordinates ). Then you need to find the closest points of your curves. You can use QwtPlotCurve::closestPoint(), but in most cases you can find a much faster implementation depending on the characteristics of your data.
When you need to compare the mouse position with the lines between the points you need the pixel position of these points ( use QwtPlot::canvasMap ).
Maybe looking at the CanvasPicker of the eventfilter example helps.
Uwe
Re: Get the plot curve to which the mouse is pointing to
I found a solution by implementing a custom PlotPicker and evaluating following method within the trackerText() method.
Code:
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;
}
In advance I implemented there also a vertical marker following the cursor position. By adding a horizontal marker we would get crosshair functionality...
Code:
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();
}
... and it works!
Regards
Stefan
Re: Get the plot curve to which the mouse is pointing to
Your solution adds a marker inside the plot, what means the plot needs to be re-rendered ( replot ) for each mouse movement !
This might be no problem for trivial scenes, but is by far too slow for more complex ones.
The rubberband of the picker is implemented using a overlay widget, what is a much faster solution. ( F.e. press + move the mouse in the bode example. ) The picker offers various built in styles ( including crosshair, horizontal/vertical lines ) and you can add your own by overloading QwtPlotPicker::drawRubberband().
Together with overloading QwtPlotPicker::trackerText() you should be able to implement a much faster solution than using markers.
Uwe
Re: Get the plot curve to which the mouse is pointing to
I miss the rubberbands remaining always on. The question has already been asked by this thread.
http://www.qtcentre.org/forum/f-qwt-...ght=rubberband
What I did by the vertical marker is exactly that, as I did'nt find out another way.
Regards
Stefan