10

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 ?

Nejat
  • 31,784
  • 12
  • 106
  • 138
Rajeshwar
  • 11,179
  • 26
  • 86
  • 158

3 Answers3

10

Reimplement QCustomPlot::mouseMoveEvent or connect to QCustomPlot::mouseMove.

Then use axes' coordToPixel to translate (cursor) pixel coords to plot coords and search nearest points in your QCPDataMap with QMap::lowerBound(cursorX).

Obey-Kun
  • 419
  • 4
  • 9
  • @Rajeshwar `coordToPixel` translates plot coordinates to pixel coordinates. How did it solve your problem? – Nejat Jan 20 '15 at 09:42
10

You can easily just connect a slot to the mouseMove signal that QCustomPlot emits. You can then use QCPAxis::pixelToCoord to find the coordinate :

connect(this, SIGNAL(mouseMove(QMouseEvent*)), this,SLOT(showPointToolTip(QMouseEvent*)));

void QCustomPlot::showPointToolTip(QMouseEvent *event)
{

    int x = this->xAxis->pixelToCoord(event->pos().x());
    int y = this->yAxis->pixelToCoord(event->pos().y());

    setToolTip(QString("%1 , %2").arg(x).arg(y));

}
Nejat
  • 31,784
  • 12
  • 106
  • 138
  • If I have two graphs on the ui, `ui->widget_graph1` and `ui->widget_graph2`, how could I do it for both the graphs? Should I change the function name `void CustomPlot::showPointToolTip(QMouseEvent *event){}` to fit my case? I want both graphs to show coordinates on mouse hover, thanks – Wei Jul 07 '17 at 09:16
  • @Wei If you implement the slot in `QCustomPlot` source code like i did, the tool-tip is shown for all of the plots. You can also have the slot in another class and use `sender()` to find out the plot that has emitted `mouseMove` signal. – Nejat Jul 08 '17 at 12:03
  • I only managed to find `QCustomPlot::toolTip` and I changed your `void QCustomPlot::showPointToolTip(QMouseEvent *event){}` into `void QCustomPlot::toolTip(QMouseEvent *event){}` Would it be the same? – Wei Jul 09 '17 at 16:35
2

when You use datetime format (including more point per second) of X axis, then pixel to coord fails. If you want to display coordinates between points, then this is the fastest way

maybe usefull (with connected signal QCustomplot::MouseMove)

void MainWindow::onMouseMoveGraph(QMouseEvent* evt)
    {
    int x = this->ui->customPlot->xAxis->pixelToCoord(evt->pos().x());
    int y = this->ui->customPlot->yAxis->pixelToCoord(evt->pos().y());
    qDebug()<<"pixelToCoord: "<<data.key<<data.value; //this is correct when step is greater 1 second

if (this->ui->customPlot->selectedGraphs().count()>0)
        {
        QCPGraph* graph = this->ui->customPlot->selectedGraphs().first();
        QCPData data = graph->data()->lowerBound(x).value();

        double dbottom = graph->valueAxis()->range().lower;        //Yaxis bottom value
        double dtop = graph->valueAxis()->range().upper;           //Yaxis top value
        long ptop = graph->valueAxis()->axisRect()->top();         //graph top margin
        long pbottom = graph->valueAxis()->axisRect()->bottom();   //graph bottom position
// result for Y axis
        double valueY = (evt->pos().y() - ptop) / (double)(pbottom - ptop)*(double)(dbottom - dtop) + dtop;

//or shortly for X-axis
        double valueX = (evt->pos().x() - graph->keyAxis()->axisRect()->left());  //graph width in pixels
        double ratio = (double)(graph->keyAxis()->axisRect()->right() - graph->keyAxis()->axisRect()->left()) / (double)(graph->keyAxis()->range().lower - graph->keyAxis()->range().upper);    //ratio px->graph width
//and result for X-axis
        valueX=-valueX / ratio + graph->keyAxis()->range().lower;


        qDebug()<<"calculated:"<<valueX<<valueY;
        }
}