PDA

View Full Version : QwtPlotIntervalCurve's constant width.



Toniy
17th August 2015, 11:06
Here is situation. I have a class inherited from QwtPlot. I use QwtPlotIntervalCurve to plot squares of certain height regardless of scaling (i.e. width between top and bottom side of square set by QwtPlotInterval must be always constant if I zoom in or zoom out). But it looks like if I use something like QWidget::mapToGlobal() or QWidget::mapFromGlobal of QwtPlotCanvas (this->canvas()->mapFromGlobal()) all conversions are done inside of QwtPlotCanvas automatically, and size of square is wrong. Am I right about it? In that case is it possible in Qwt to play with local and global coordinates for solving that situation, and if answer is "yes", how can it be done?

P.S. Am I right that every coordinate that we specify to plot elements are firstly exist in global coordinate space and QwtPlot converts it to local coordinate space itself?

Here is code I used:



...

const qreal c_dYCoord = findMiddleYCoordByInterval(m_vYCoords[c_uCurveNum]);
const qreal c_dSquareheight = qMax(static_cast<qreal>(msc_iTextHeight), msc_iLineNonEmptyWidth * c_dPercents / msc_uMaxPercents);
const QPointF c_top = this->canvas()->mapFromGlobal(QPoint(0, c_dYCoord + c_dSquareheight));
const QPointF c_bottom = this->canvas()->mapFromGlobal(QPoint(0, c_dYCoord - c_dSquareheight));

const qreal c_dRealHeight = c_top.y() - c_bottom.y();

const QwtInterval c_intervalToAttach(c_dYCoord - c_dRealHeight, c_dYCoord + c_dRealHeight);

...

currentCurve.push_back(QwtIntervalSample(dCurTime_ sec, c_intervalToAttach)); //currentCurve is actually vector of QwtIntervalSample

currPlotElement->setSamples(currentCurve); //currPlotElement is QwtPlotIntervalCurve* sample.

...



Thanks,
Toniy.

Uwe
17th August 2015, 12:23
I use QwtPlotIntervalCurve to plot squares of certain height regardless of scaling (i.e. width between top and bottom side of square set by QwtPlotInterval must be always constant if I zoom in or zoom out).
Then QwtPlotIntervalCurve is obviously not the right plot item - it is for plotting series of x vs. y1->y2 samples.

But before recommending any solution I need to know the answer to my standard questions:



how does your data look like ?
how do you want to have it displayed ?



Am I right that every coordinate that we specify to plot elements are firstly exist in global coordinate space and QwtPlot converts it to local coordinate space itself?
No, there are also geometries, that are in paint device coordinates.

Uwe

Toniy
17th August 2015, 12:42
Thanks for quick response.

Picture is attached to post.

P.S.: "Zooming in", maybe, not very accurate term. My fault. Actually I change scale of Y axis.

11323

Uwe
17th August 2015, 13:19
Before recommending any solution I need to know the answer to my standard questions ...

Uwe

Toniy
17th August 2015, 14:17
Data is represented as a vector of values which are follow each other after some interval. For each temporal discrete I must plot square with value typed inside if value != 0 (I use QwtPlotMarker for it) or plot nothing if value equals zero (actually I do it with making QwtPlotIntervalCurve's pen's color equal to canvas' color). Every square that represents value of the same vector must be placed at the same Y coordinate. But if I change Y axis' scale, actual size of square must be same (like at the picture I attached in my previous post)

Uwe
17th August 2015, 14:54
For each temporal discrete I must plot square with value typed inside if value != 0. Every square that represents value of the same vector must be placed at the same Y coordinate.
Assuming that the center of each square in plot coordinates is related to the data ( right ? ) - what about the size of the square. Is it something related to plot or widget coordinates ?

Uwe

Toniy
17th August 2015, 15:03
Yes, there is value typed in centre of square.
Size must not be smaller than text inside the square (all markers have the same font size which is not mutable). Actually later it will be necessary to change square size but according to text size, not to axis' scale.
I just need to understand how can I get real square's height to compare it with text's size.

Uwe
17th August 2015, 15:27
Well then the size of the square depends on some QFontMetrics and is of course in widget coordinates.

This is something you can do with symbols - in you case ( as you need to draw a value inside ) it would be a symbol made of a QPixmap or QwtGraphic ( what would give nicer results in a PDF document ). All geometries of a symbol are in widget coordinates, what means, that a square remains a square ( but don't you have this already using QwtPlotMarker ? ).

Another option would be to derive from QwtPlotItem and do the squares for each vector in YourItem::draw(). Implementing such an item wouldn't be hard - simply translating the center into widget coordinates, then doing a QPainter::fillRect() followed by a QPainter::drawText().

Uwe

Toniy
17th August 2015, 15:48
Thanks! I almost get it. One more question: are coordinates on canvas widget and coordinates that shown at QwtScaleDraw not the same (coordinates that shown at QwtScaleDraw are converted coordinates of canvas widget)? I mean if, for example, our Y axis has 100 as min value and 200 for max value and X axis has the same limits, then is point [0;0] of canvas widget (top-left corner) the same as point [200, 100] of our graph (or it is more complicated)?

Uwe
17th August 2015, 17:52
The widget coordinates are usually bounded by plot->canvas()->contentsRect() ( = QWidget::rect() without margins ). Then it depends on your configuration how the scales are aligned to the canvas - f.e. there might be extra margins to have some space for the tick labels ( see QwtPlotLayout ). The necessary space depends on some factors f.e if a horizontal scale can be extended below a vertical scale etc.

So the answer is yes - usually it is more complicated. Better use QwtPlot::canvasMap() to translate between plot ( = what is spanned by the scales ) and paint device coordinates ( = widget ).

Uwe