QCustomPlot Discussion and Comments

Display the plot values on mouse over. - Detect Scatter pointsReturn to overview

I am attempting to display the plot values of different points on my QCustomPlot in which I have a Line style of lsLine. I know i could set a mouse over signal on the QCustomPlot but that wont really help since I just need to be informed when the mouse is over my plotted line.My question is is there any way to find out if the mouse is over my scatter point. Is there a signal i could connect to that would tell me when the mouse is over a scatter point ?

Interaction with individual data points is not implemented in the current version but planned for future releases. At the moment, you'd have to implement that capability yourself by reacting to mouse events and using QCustomPlot's methods to find the point that was clicked/hovered. You start by testing whether the graph is actually under the cursor position via QCPGraph::selectTest (If you only want to know whether the cursor is anywhere on the graph line, you can stop here). To find the actual point under the cursor, transform the x mouse pixel position to plot coordinates with QCPAxis::pixelToCoord. Finally, find the point that's closest to that x coordinate. The latter is easy since the graph's data is stored in a sorted QMap, see QCPGraph::data() and the Qt's QMap-related methods qLowerBound/qUpperBound.

Hey, I'd like to know if this is still valid for the latest release, QCP 1.0.1 or if there was anything implemented. Thanks :)

Hey

This function is a rather interesting one, I just read your very cool update 1.2 news and planned features. Do you plan on implement a new class to handle mouse/graph/display interactions any time soon?

Hi guys, can you show me the code for the qlowerbound, I tried google for it but could not find anything

The work you've done is very impressively professional and beautiful. It's a pleasure to work with your library.
Please tell me how can i help you implementing sensing the data being mouse hovered. I give you my email to keep close contact for future helping and reference.

To make a scatter coordinate indicator:
1) Derive your class, Xxx, from QCustomPlot
class Xxx : public QCustomPlot

2) Save cursor position when mouse move.
void Xxx::mouseMoveEvent(QMouseEvent * event)
{
cursor_pos = event->pos();
replot();
QCustomPlot::mouseMoveEvent(event);
}

3) Overwrite paintEvent() to hook up paintCoordinate()
void Xxx::paintEvent(QPaintEvent *event)
{
QCustomPlot::paintEvent(event);
paintCoordinate();
}

4) drawLine() and drawText() using QPainter
void Xxx::paintCoordinate()
{
double price = getPrice(cursor_pos);
int y = yAxis->coordToPixel(price);

QPainter painter(this);

painter.drawLine(QPoint(50, y), QPoint(width(), y));
painter.drawLine(cursor_pos, QPoint(cursor_pos.x(), y));

painter.drawText(QPoint(0, y), QString::number(price));
painter.drawText(cursor_pos, timestamp);
}

Now it is possible to do by means of the QCPItemTracer class. But, little customization is still needed:
1) add signal that emits xvalue into customplot's mouseMoveEvent (emit xValue(xAxis->pixelToCoord(event->pos().x())););
2) make setGraphKey() to be public slot of the QCPItemTracer;
3) on graph view creation connect customplot's xValue() witch tracer's setGraphKey() (connect(customplot, SIGNAL(xValue(qreal)), tracer, SLOT(setGraphKey(double)));)

Hi all, could somebody elaborate on pu-lnull-mezon's comment?

Below is what I'm currently using, but it is not reliable as: if you select a graph and then click on a point, it will show the correct value. However, if you select a point the second time (while the graph is still selected), it will show the value from the first click after graph selection. Only upon clicking on the new point a second time will it show the correct value.

bool MainWindow::eventFilter(QObject *target, QEvent *event)
{

}if(target == ui->myPlot && event->type() == QEvent::MouseButtonPress &&
            ui->myPlot->selectedGraphs().size() > 0)
    {
        QMouseEvent *_mouseEvent = static_cast<QMouseEvent*>(event);
        // find a data point's value at closest coordinate to mouse click
        double xCoord = ui->myPlot->xAxis->pixelToCoord(_mouseEvent->pos().x());
        double yCoord = ui->myPlot->yAxis->pixelToCoord(_mouseEvent->pos().y());

        // works but has an issue:
        // if the first click after graph selection was on the graph, the second click will be incorrect
        // must click on the plot point twice

        // this is absolute magic to me... http://www.qmyPlot.com/documentation/dataselection.html#dataselection-accessing
        QCPDataSelection selection = ui->myPlot->selectedGraphs().front()->selection();
        foreach (QCPDataRange dataRange, selection.dataRanges())
        {
            QCPGraphDataContainer::const_iterator begin = ui->myPlot->selectedGraphs().front()->data()->at(dataRange.begin()); // get range begin iterator from index
            QCPGraphDataContainer::const_iterator end = ui->myPlot->selectedGraphs().front()->data()->at(dataRange.end()); // get range end iterator from index
            int i = 0;
            for (QCPGraphDataContainer::const_iterator it=begin; it!=end; ++it)
            {
              // iterator "it" will go through all selected data points
              qDebug("Value closest to (%f,%f) on graph: %f", xCoord, yCoord, it->value);
            i++;
            }
        }
    }

    return false;

Cheers