QCustomPlot Discussion and Comments

QCPItemPixmap scaling problemReturn to overview

Hi, i have problem with QCPItemPixmap scaling. I have static X and dynamic Y axis. I can shrink/expand Y range, with mouse, but image does not scale correctly.
As seen in the alarm pic.

http://imgur.com/Tcg4B8P

            QCPItemPixmap *alarmPix = new QCPItemPixmap(customPlot);

            alarmPix->setLayer("legend");
            alarmPix->topLeft->setAxes(axisRect(0)->axis(QCPAxis::atBottom), axisRect(0)->axis(QCPAxis::atRight));
            alarmPix->bottomRight->setAxes(axisRect(0)->axis(QCPAxis::atBottom), axisRect(0)->axis(QCPAxis::atRight));
            alarmPix->setPixmap(QPixmap(":/Slike/Alarm.png"));
            alarmPix->setObjectName("Alarm");

            alarmPix->setScaled(true, Qt::KeepAspectRatio);

            alarmPix->topLeft->setTypeX(QCPItemPosition::ptAbsolute);
            alarmPix->topLeft->setTypeY(QCPItemPosition::ptPlotCoords);

            alarmPix->bottomRight->setTypeX(QCPItemPosition::ptAbsolute);
            alarmPix->bottomRight->setTypeY(QCPItemPosition::ptPlotCoords);
             alarmPix->topLeft->setCoords(axisRect(0)->right() - 26.0f, yAxis2->pixelToCoord(mouseEvent->pos().y() - 13));
             alarmPix->bottomRight->setCoords(axisRect(0)->right(), yAxis2->pixelToCoord(mouseEvent->pos().y() + 13));

Code for changing Y range..

        if(mouseYDif > 0.0f)
        {
            yAxis2->scaleRange(0.99f, yAxis2->range().center());
        }
        else if(mouseYDif < 0.0f)
        {
            yAxis2->scaleRange(1.01f, yAxis2->range().center());
        }

How did you expect it to scale? At the moment I don't quite understand the issue, I'm afraid. If you want it to stretch without keeping the original aspect ratio of the image, you should leave out the Qt::KeepAspectRatio flag in the setScaled call.

Also note that you're missing a
customPlot->addItem(alarmPix);
call, which is important for proper deconstruction (in QCustomPlot 1.x).

What i need is to not scale at all, so it allways stay the same size, even if i change range of Y axis.
I was thinking i do not have to call

customPlot->addItem(alarmPix);

if i have it here

new QCPItemPixmap(customPlot);

Then you shouldn't call setScaled(true), but setScaled(false). Note that the pixmap will align with the topLeft position.. If you want the pixmap centered, you could place a QCPItemTracer (with style tsNone, so invisible) on the desired coordinate. Tracers can be used as general anchors, they don't necessarily need to be connected to a graph. Then use that tracer's position as position-parent for the pixmap item (alarmPix->topLeft->setParentAnchor(tracer->position)). Then the coordinates of the alarmPix will be in pixels, relative to the parent anchor. So to center it on the parent anchor, set the coordinates of the top left pixmap position to minus half the pixmap height and width.
For details about the anchoring and positioning that I sketched here, have a look at the classQCPItemPositiondocumentation, especially setParentAnchor.

The addItem is necessary. Only in QCP2.0 (not yet released) will it become obsolete.

I'm still having problem with this, i set scale to false, but i do not know, how can i use QCPItemTracer as i have QCPFinancial

With scale set on false, if i set it at position 700 on Y axis, after i zoom out, or zoom in, it changes to 680 or 720 depends on zoom.

This is my new code

            QCPItemTracer *alarmTracer = new QCPItemTracer(customPlot);
            customPlot->addItem(alarmTracer);

            alarmTracer->setInterpolating(false);
            alarmTracer->setStyle(QCPItemTracer::tsNone);

            QCPItemPixmap *alarmPix = new QCPItemPixmap(customPlot);
            customPlot->addItem(alarmPix);

            alarmPix->setLayer("legend");
            alarmPix->topLeft->setAxes(axisRect(0)->axis(QCPAxis::atBottom), axisRect(0)->axis(QCPAxis::atRight));
            alarmPix->bottomRight->setAxes(axisRect(0)->axis(QCPAxis::atBottom), axisRect(0)->axis(QCPAxis::atRight));
            alarmPix->setPixmap(QPixmap(":/Slike/Alarm.png"));
            alarmPix->setObjectName("Alarm");

            alarmPix->setScaled(false);

            alarmPix->topLeft->setTypeX(QCPItemPosition::ptAbsolute);
            alarmPix->topLeft->setTypeY(QCPItemPosition::ptAbsolute);

            alarmPix->bottomRight->setTypeX(QCPItemPosition::ptAbsolute);
            alarmPix->bottomRight->setTypeY(QCPItemPosition::ptAbsolute);

            alarmPix->topLeft->setCoords(-32, -32);
            alarmPix->bottomRight->setCoords(32, 32);

            alarmPix->topLeft->setParentAnchor(alarmTracer->position);
            alarmTracer->position->setAxes(axisRect(0)->axis(QCPAxis::atBottom), axisRect(0)->axis(QCPAxis::atRight));
            alarmTracer->position->setTypeX(QCPItemPosition::ptAbsolute);
            alarmTracer->position->setTypeY(QCPItemPosition::ptPlotCoords);

            alarmTracer->position->setCoords(axisRect(0)->right() - 64.0f, yAxis2->pixelToCoord(mouseEvent->pos().y() - 32));

            alarmPix->setClipToAxisRect(false);
            alarmPix->setSelectable(true);

http://imgur.com/XFdTg0S

On the right picture, i set alarm on 697.998, and then after i zoom out, it is way off, the same value, is almost at the top of icon, but it should be in the middle, icon size is 64x64

So now i finally get it, how it works, and now it works correct! Than DerManu for helping me. I will post code if anyone need it.

            QCPItemTracer *alarmTracer = new QCPItemTracer(customPlot);
            customPlot->addItem(alarmTracer);

            alarmTracer->setInterpolating(false);
            alarmTracer->setStyle(QCPItemTracer::tsNone);

            QCPItemPixmap *alarmPix = new QCPItemPixmap(customPlot);
            customPlot->addItem(alarmPix);

            alarmPix->setLayer("legend");
            alarmPix->topLeft->setAxes(axisRect(0)->axis(QCPAxis::atBottom), axisRect(0)->axis(QCPAxis::atRight));
            alarmPix->bottomRight->setAxes(axisRect(0)->axis(QCPAxis::atBottom), axisRect(0)->axis(QCPAxis::atRight));
            alarmPix->setPixmap(QPixmap(":/Slike/Alarm.png"));
            alarmPix->setObjectName("Alarm");

            alarmPix->setScaled(false);

            alarmPix->topLeft->setParentAnchor(alarmTracer->position);
            alarmTracer->position->setAxes(axisRect(0)->axis(QCPAxis::atBottom), axisRect(0)->axis(QCPAxis::atRight));
            alarmTracer->position->setTypeX(QCPItemPosition::ptAbsolute);
            alarmTracer->position->setTypeY(QCPItemPosition::ptPlotCoords);

             // This is important!
            alarmPix->topLeft->setCoords(-64, -32);

            alarmTracer->position->setCoords(axisRect(0)->right(), yAxis2->pixelToCoord(mouseEvent->pos().y()));

            alarmPix->setClipToAxisRect(false);
            alarmPix->setSelectable(true);

I need to display a set of points(nearly 200) on my custom plot. Thereafter when I click on a specific point ,it should display its coordinates using mouse event. The mouse event should be able to display only those points coordinates where I click and not the remaining empty region. I have tried using event->pos().x() to a pixeltocoord. But no use. I need a help in mouse event. Can anyone please help me with such example. Thanks in advance!!

The QCustomPlot::plottableClick signal (and selection methods like selectionChanged ) gives you the index of the clicked point. You can use that to get the data coordinates.